Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tfilepath.h"
Toshihiro Shimizu 890ddd
#include "tfiletype.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#include "timageinfo.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tmeshimage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzExt includes
Toshihiro Shimizu 890ddd
#include "ext/meshutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshchildlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjectspline.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneresources.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage2.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/icongenerator.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//    Local namespace
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
const TDimension IconSize(80, 60);
Toshihiro Shimizu 890ddd
TDimension FilmstripIconSize(0, 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Access name-based storage
Toshihiro Shimizu 890ddd
std::set<std::string> iconsMap;</std::string>
Toshihiro Shimizu 890ddd
typedef std::set<std::string>::iterator IconIterator;</std::string>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Returns true if the image request was already submitted.
Shinya Kitaoka 120a6e
bool getIcon(const std::string &iconName, QPixmap &pix,
Shinya Kitaoka 120a6e
             TXshSimpleLevel *simpleLevel = 0) {
Shinya Kitaoka 120a6e
  IconIterator it;
Shinya Kitaoka 120a6e
  it = iconsMap.find(iconName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it != iconsMap.end()) {
Shinya Kitaoka 120a6e
    TImageP im         = TImageCache::instance()->get(iconName, false);
Shinya Kitaoka 120a6e
    TToonzImage *timgp = dynamic_cast<ttoonzimage *="">(im.getPointer());</ttoonzimage>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (simpleLevel && timgp) {
Shinya Kitaoka 120a6e
      IconGenerator::Settings settings =
Shinya Kitaoka 120a6e
          IconGenerator::instance()->getSettings();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TRaster32P icon(timgp->getSize());
Shinya Kitaoka 120a6e
      icon->clear();
Shinya Kitaoka 120a6e
      icon->fill((settings.m_blackBgCheck) ? TPixel::Black : TPixel::White);
Shinya Kitaoka 120a6e
      if (settings.m_transparencyCheck || settings.m_inkIndex != -1 ||
Shinya Kitaoka 120a6e
          settings.m_paintIndex != -1) {
Shinya Kitaoka 120a6e
        TRop::CmappedQuickputSettings s;
Shinya Kitaoka 120a6e
        s.m_globalColorScale  = TPixel32::Black;
Shinya Kitaoka 120a6e
        s.m_inksOnly          = false;
Shinya Kitaoka 120a6e
        s.m_transparencyCheck = settings.m_transparencyCheck;
Shinya Kitaoka 120a6e
        s.m_blackBgCheck      = settings.m_blackBgCheck;
Shinya Kitaoka 120a6e
        s.m_inkIndex          = settings.m_inkIndex;
Shinya Kitaoka 120a6e
        s.m_paintIndex        = settings.m_paintIndex;
Shinya Kitaoka 120a6e
        Preferences::instance()->getTranspCheckData(
Shinya Kitaoka 120a6e
            s.m_transpCheckBg, s.m_transpCheckInk, s.m_transpCheckPaint);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        TRop::quickPut(icon, timgp->getRaster(), simpleLevel->getPalette(),
Shinya Kitaoka 120a6e
                       TAffine(), s);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        TRop::quickPut(icon, timgp->getRaster(), simpleLevel->getPalette(),
Shinya Kitaoka 120a6e
                       TAffine());
Shinya Kitaoka 120a6e
      pix = rasterToQPixmap(icon, false);
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TRasterImageP img = static_cast<trasterimagep>(im);</trasterimagep>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!img) {
Shinya Kitaoka 120a6e
      pix = QPixmap();
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    assert(!(TRasterGR8P)img->getRaster());
Shinya Kitaoka 120a6e
    const TRaster32P &ras = img->getRaster();
Shinya Kitaoka 120a6e
    pix                   = rasterToQPixmap(ras, false);
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void setIcon(const std::string &iconName, const TRaster32P &icon) {
Shinya Kitaoka 120a6e
  if (iconsMap.find(iconName) != iconsMap.end())
Shinya Kitaoka 120a6e
    TImageCache::instance()->add(iconName, TRasterImageP(icon), true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
/*! Cache icon data in TToonzImage format if ToonzImageIconRenderer generates
Shinya Kitaoka 120a6e
 * them
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void setIcon_TnzImg(const std::string &iconName, const TRasterCM32P &icon) {
Shinya Kitaoka 120a6e
  if (iconsMap.find(iconName) != iconsMap.end())
Shinya Kitaoka 120a6e
    TImageCache::instance()->add(
Shinya Kitaoka 120a6e
        iconName, TToonzImageP(icon, TRect(icon->getSize())), true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void removeIcon(const std::string &iconName) {
Shinya Kitaoka 120a6e
  IconIterator it;
Shinya Kitaoka 120a6e
  it = iconsMap.find(iconName);
Shinya Kitaoka 120a6e
  if (it != iconsMap.end()) {
Shinya Kitaoka 120a6e
    TImageCache::instance()->remove(iconName);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  iconsMap.erase(iconName);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool isUnpremultiplied(const TRaster32P &r) {
Shinya Kitaoka 120a6e
  int lx = r->getLx();
Shinya Kitaoka 120a6e
  int y  = r->getLy();
Shinya Kitaoka 120a6e
  r->lock();
Shinya Kitaoka 120a6e
  while (--y >= 0) {
Shinya Kitaoka 120a6e
    TPixel32 *pix    = r->pixels(y);
Shinya Kitaoka 120a6e
    TPixel32 *endPix = pix + lx;
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      if (pix->r > pix->m || pix->g > pix->m || pix->b > pix->m) {
Shinya Kitaoka 120a6e
        r->unlock();
Shinya Kitaoka 120a6e
        return true;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      ++pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  r->unlock();
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void makeChessBackground(const TRaster32P &ras) {
Shinya Kitaoka 120a6e
  ras->lock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const TPixel32 gray1(230, 230, 230, 255), gray2(180, 180, 180, 255);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int lx = ras->getLx(), ly = ras->getLy();
Shinya Kitaoka 120a6e
  for (int y = 0; y != ly; ++y) {
Shinya Kitaoka 120a6e
    TPixel32 *pix = ras->pixels(y), *lineEnd = pix + lx;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int yCol = (y & 4);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (int x                = 0; pix != lineEnd; ++x, ++pix)
Shinya Kitaoka 120a6e
      if (pix->m != 255) *pix = overPix((x & 4) == yCol ? gray1 : gray2, *pix);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==========================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//    Image-to-Icon convertion methods
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
TRaster32P convertToIcon(TVectorImageP vimage, int frame,
Shinya Kitaoka 120a6e
                         const TDimension &iconSize,
Shinya Kitaoka 120a6e
                         const IconGenerator::Settings &settings) {
Shinya Kitaoka 120a6e
  if (!vimage) return TRaster32P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPalette *plt = vimage->getPalette()->clone();
Shinya Kitaoka 120a6e
  if (!plt) return TRaster32P();
Shinya Kitaoka 120a6e
  plt->setFrame(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TOfflineGL *glContext = IconGenerator::instance()->getOfflineGLContext();
Shinya Kitaoka 120a6e
Campbell Barton d6e3ed
  // The image and contained within Imagebox
Campbell Barton d6e3ed
  // (add a small margin also to prevent problems with empty images)
Shinya Kitaoka 120a6e
  TRectD imageBox;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QMutexLocker sl(vimage->getMutex());
Shinya Kitaoka 120a6e
    imageBox = vimage->getBBox().enlarge(.1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TPointD imageCenter = (imageBox.getP00() + imageBox.getP11()) * 0.5;
Shinya Kitaoka 120a6e
Campbell Barton d6e3ed
  // Calculate a transformation matrix that moves the image inside the icon.
Campbell Barton d6e3ed
  // The scale factor is chosen so that the image is entirely
Campbell Barton d6e3ed
  // contained in the icon (with a margin of 'margin' pixels)
Shinya Kitaoka 120a6e
  const int margin = 10;
Shinya Kitaoka 120a6e
  double scx       = (iconSize.lx - margin) / imageBox.getLx();
Shinya Kitaoka 120a6e
  double scy       = (iconSize.ly - margin) / imageBox.getLy();
Shinya Kitaoka 120a6e
  double sc        = std::min(scx, scy);
Campbell Barton d6e3ed
  // Add the translation: the center point of the image is at the point
Campbell Barton d6e3ed
  // middle of the pixmap.
Shinya Kitaoka 120a6e
  TPointD iconCenter(iconSize.lx * 0.5, iconSize.ly * 0.5);
Shinya Kitaoka 120a6e
  TAffine aff = TScale(sc).place(imageCenter, iconCenter);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // RenderData
Shinya Kitaoka 120a6e
  TVectorRenderData rd(aff, TRect(iconSize), plt, 0, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rd.m_tcheckEnabled     = settings.m_transparencyCheck;
Shinya Kitaoka 120a6e
  rd.m_blackBgEnabled    = settings.m_blackBgCheck;
Shinya Kitaoka 120a6e
  rd.m_drawRegions       = !settings.m_inksOnly;
Shinya Kitaoka 120a6e
  rd.m_inkCheckEnabled   = settings.m_inkIndex != -1;
Shinya Kitaoka 120a6e
  rd.m_paintCheckEnabled = settings.m_paintIndex != -1;
Shinya Kitaoka 120a6e
  rd.m_colorCheckIndex =
Shinya Kitaoka 120a6e
      rd.m_inkCheckEnabled ? settings.m_inkIndex : settings.m_paintIndex;
Shinya Kitaoka 120a6e
  rd.m_isIcon = true;
Shinya Kitaoka 120a6e
Campbell Barton d6e3ed
  // Draw the image.
Shinya Kitaoka 120a6e
  glContext->makeCurrent();
Shinya Kitaoka 120a6e
  glContext->clear(rd.m_blackBgEnabled ? TPixel::Black : TPixel32::White);
Shinya Kitaoka 120a6e
  glContext->draw(vimage, rd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P ras(iconSize);
Shinya Kitaoka 120a6e
  glContext->getRaster(ras);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glContext->doneCurrent();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delete plt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P convertToIcon(TToonzImageP timage, int frame,
Shinya Kitaoka 120a6e
                         const TDimension &iconSize,
Shinya Kitaoka 120a6e
                         const IconGenerator::Settings &settings) {
Shinya Kitaoka 120a6e
  if (!timage) return TRaster32P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPalette *plt = timage->getPalette();
Shinya Kitaoka 120a6e
  if (!plt) return TRaster32P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  plt->setFrame(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P rasCM32 = timage->getRaster();
Shinya Kitaoka 120a6e
  if (!rasCM32.getPointer()) return TRaster32P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int lx     = rasCM32->getSize().lx;
Shinya Kitaoka 120a6e
  int ly     = rasCM32->getSize().ly;
Shinya Kitaoka 120a6e
  int iconLx = iconSize.lx, iconLy = iconSize.ly;
Shinya Kitaoka 120a6e
  if (std::max(double(lx) / iconSize.lx, double(ly) / iconSize.ly) ==
Shinya Kitaoka 120a6e
      double(ly) / iconSize.ly)
Shinya Kitaoka 120a6e
    iconLx = tround((double(lx) * iconSize.ly) / ly);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    iconLy = tround((double(ly) * iconSize.lx) / lx);
Shinya Kitaoka 120a6e
Campbell Barton d6e3ed
  // icon size with correct aspect ratio
Campbell Barton d6e3ed
  TDimension iconSize2 = TDimension(iconLx, iconLy);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P icon(iconSize2);
Shinya Kitaoka 120a6e
  icon->clear();
Shinya Kitaoka 120a6e
  icon->fill(settings.m_blackBgCheck ? TPixel::Black : TPixel::White);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TDimension dim = rasCM32->getSize();
Shinya Kitaoka 120a6e
  if (dim != iconSize2) {
Shinya Kitaoka 120a6e
    TRasterCM32P auxCM32(icon->getSize());
Shinya Kitaoka 120a6e
    auxCM32->clear();
Shinya Kitaoka 120a6e
    TRop::makeIcon(auxCM32, rasCM32);
Shinya Kitaoka 120a6e
    rasCM32 = auxCM32;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (settings.m_transparencyCheck || settings.m_inksOnly ||
Shinya Kitaoka 120a6e
      settings.m_inkIndex != -1 || settings.m_paintIndex != -1) {
Shinya Kitaoka 120a6e
    TRop::CmappedQuickputSettings s;
Shinya Kitaoka 120a6e
    s.m_globalColorScale  = TPixel32::Black;
Shinya Kitaoka 120a6e
    s.m_inksOnly          = settings.m_inksOnly;
Shinya Kitaoka 120a6e
    s.m_transparencyCheck = settings.m_transparencyCheck;
Shinya Kitaoka 120a6e
    s.m_blackBgCheck      = settings.m_blackBgCheck;
Shinya Kitaoka 120a6e
    s.m_inkIndex          = settings.m_inkIndex;
Shinya Kitaoka 120a6e
    s.m_paintIndex        = settings.m_paintIndex;
Shinya Kitaoka 120a6e
    Preferences::instance()->getTranspCheckData(
Shinya Kitaoka 120a6e
        s.m_transpCheckBg, s.m_transpCheckInk, s.m_transpCheckPaint);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRop::quickPut(icon, rasCM32, timage->getPalette(), TAffine(), s);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    TRop::quickPut(icon, rasCM32, timage->getPalette(), TAffine());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(iconSize2.lx <= iconSize.lx && iconSize2.ly <= iconSize.ly);
Shinya Kitaoka 120a6e
  TRaster32P outIcon(iconSize);
Shinya Kitaoka 120a6e
  outIcon->clear();
Shinya Kitaoka 120a6e
  int dx = (outIcon->getLx() - icon->getLx()) / 2;
Shinya Kitaoka 120a6e
  int dy = (outIcon->getLy() - icon->getLy()) / 2;
Shinya Kitaoka 120a6e
  assert(dx >= 0 && dy >= 0);
Shinya Kitaoka 120a6e
  TRect box = outIcon->getBounds().enlarge(-dx, -dy);
Shinya Kitaoka 120a6e
  TRop::copy(outIcon->extract(box), icon);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return outIcon;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P convertToIcon(TRasterImageP rimage, const TDimension &iconSize) {
Shinya Kitaoka 120a6e
  if (!rimage) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterP ras = rimage->getRaster();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!(TRaster32P)ras && !(TRasterGR8P)ras) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (ras->getSize() == iconSize) return ras;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P icon(iconSize);
Shinya Kitaoka 120a6e
  icon->fill(TPixel32(235, 235, 235));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double sx = (double)icon->getLx() / ras->getLx();
Shinya Kitaoka 120a6e
  double sy = (double)icon->getLy() / ras->getLy();
Shinya Kitaoka 120a6e
  double sc = sx < sy ? sx : sy;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TAffine aff = TScale(sc).place(ras->getCenterD(), icon->getCenterD());
Shinya Kitaoka 120a6e
  TRop::resample(icon, ras, aff, TRop::Bilinear);
Shinya Kitaoka 120a6e
  TRop::addBackground(icon, TPixel32::White);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return icon;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P convertToIcon(TMeshImageP mi, int frame, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                         const IconGenerator::Settings &settings) {
Shinya Kitaoka 120a6e
  if (!mi) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TOfflineGL *glContext = IconGenerator::instance()->getOfflineGLContext();
Toshihiro Shimizu 890ddd
Campbell Barton d6e3ed
  // The image and contained within Imagebox
Campbell Barton d6e3ed
  // (add a small margin also to prevent problems with empty images)
Shinya Kitaoka 120a6e
  TRectD imageBox;
Shinya Kitaoka 120a6e
  imageBox = mi->getBBox().enlarge(.1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPointD imageCenter(0.5 * (imageBox.getP00() + imageBox.getP11()));
Toshihiro Shimizu 890ddd
Campbell Barton d6e3ed
  // Calculate a transformation matrix that moves the image inside the icon.
Campbell Barton d6e3ed
  // The scale factor is chosen so that the image is entirely
Campbell Barton d6e3ed
  // contained in the icon (with a margin of 'margin' pixels)
Shinya Kitaoka 120a6e
  const int margin = 10;
Shinya Kitaoka 120a6e
  double scx       = (iconSize.lx - margin) / imageBox.getLx();
Shinya Kitaoka 120a6e
  double scy       = (iconSize.ly - margin) / imageBox.getLy();
Shinya Kitaoka 120a6e
  double sc        = std::min(scx, scy);
Toshihiro Shimizu 890ddd
Campbell Barton d6e3ed
  // Add the translation: the center point of the image is at the point
Campbell Barton d6e3ed
  // middle of the pixmap.
Shinya Kitaoka 120a6e
  TPointD iconCenter(iconSize.lx * 0.5, iconSize.ly * 0.5);
Shinya Kitaoka 120a6e
  TAffine aff = TScale(sc).place(imageCenter, iconCenter);
Toshihiro Shimizu 890ddd
Campbell Barton d6e3ed
  // Draw the image.
Shinya Kitaoka 120a6e
  glContext->makeCurrent();
Shinya Kitaoka 120a6e
  glContext->clear(settings.m_blackBgCheck ? TPixel::Black : TPixel32::White);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
Shinya Kitaoka 120a6e
  glEnable(GL_BLEND);
Shinya Kitaoka 120a6e
  glEnable(GL_LINE_SMOOTH);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glPushMatrix();
Shinya Kitaoka 120a6e
  tglMultMatrix(aff);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glColor4f(0.0f, 1.0f, 0.0f, 0.7f);
Shinya Kitaoka 120a6e
  tglDrawEdges(*mi);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glPopMatrix();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glPopAttrib();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P ras(iconSize);
Shinya Kitaoka 120a6e
  glContext->getRaster(ras);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glContext->doneCurrent();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P convertToIcon(TImageP image, int frame, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                         const IconGenerator::Settings &settings) {
Shinya Kitaoka 120a6e
  TRasterImageP ri(image);
Shinya Kitaoka 120a6e
  if (ri) return convertToIcon(ri, iconSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TToonzImageP ti(image);
Shinya Kitaoka 120a6e
  if (ti) return convertToIcon(ti, frame, iconSize, settings);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TVectorImageP vi(image);
Shinya Kitaoka 120a6e
  if (vi) return convertToIcon(vi, frame, iconSize, settings);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TMeshImageP mi(image);
Shinya Kitaoka 120a6e
  if (mi) return convertToIcon(mi, frame, iconSize, settings);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TRaster32P();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//    IconRenderer class
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//----------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class IconRenderer : public TThread::Runnable {
Shinya Kitaoka 120a6e
  TRaster32P m_icon;
Shinya Kitaoka 120a6e
  TDimension m_iconSize;
Shinya Kitaoka 120a6e
  std::string m_id;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_started;
Shinya Kitaoka 120a6e
  bool m_terminated;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  IconRenderer(const std::string &id, const TDimension &iconSize);
Shinya Kitaoka 120a6e
  virtual ~IconRenderer();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void run() override = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void setIcon(const TRaster32P &icon) { m_icon = icon; }
Shinya Kitaoka 120a6e
  TRaster32P getIcon() const { return m_icon; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDimension getIconSize() { return m_iconSize; }
Shinya Kitaoka 120a6e
  const std::string &getId() const { return m_id; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool &hasStarted() { return m_started; }
Shinya Kitaoka 120a6e
  bool &wasTerminated() { return m_terminated; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
IconRenderer::IconRenderer(const std::string &id, const TDimension &iconSize)
Shinya Kitaoka 120a6e
    : m_icon()
Shinya Kitaoka 120a6e
    , m_iconSize(iconSize)
Shinya Kitaoka 120a6e
    , m_id(id)
Shinya Kitaoka 120a6e
    , m_started(false)
Shinya Kitaoka 120a6e
    , m_terminated(false) {
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(started(TThread::RunnableP)), IconGenerator::instance(),
Shinya Kitaoka 120a6e
          SLOT(onStarted(TThread::RunnableP)));
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(finished(TThread::RunnableP)), IconGenerator::instance(),
Shinya Kitaoka 120a6e
          SLOT(onFinished(TThread::RunnableP)));
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(canceled(TThread::RunnableP)), IconGenerator::instance(),
Shinya Kitaoka 120a6e
          SLOT(onCanceled(TThread::RunnableP)), Qt::QueuedConnection);
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(terminated(TThread::RunnableP)),
Shinya Kitaoka 120a6e
          IconGenerator::instance(), SLOT(onTerminated(TThread::RunnableP)),
Shinya Kitaoka 120a6e
          Qt::QueuedConnection);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
IconRenderer::~IconRenderer() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//    Specific icon renderers
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================
Toshihiro Shimizu 890ddd
//    VectorImageIconRenderer class
Toshihiro Shimizu 890ddd
//--------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class VectorImageIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  TVectorImageP m_vimage;
Shinya Kitaoka 120a6e
  TXshSimpleLevelP m_sl;
Shinya Kitaoka 120a6e
  TFrameId m_fid;
Shinya Kitaoka 120a6e
  IconGenerator::Settings m_settings;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  VectorImageIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                          TXshSimpleLevelP sl, const TFrameId &fid,
Shinya Kitaoka 120a6e
                          const IconGenerator::Settings &settings)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize)
Shinya Kitaoka 120a6e
      , m_vimage()
Shinya Kitaoka 120a6e
      , m_sl(sl)
Shinya Kitaoka 120a6e
      , m_fid(fid)
Shinya Kitaoka 120a6e
      , m_settings(settings) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  VectorImageIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                          TVectorImageP vimage,
Shinya Kitaoka 120a6e
                          const IconGenerator::Settings &settings)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize)
Shinya Kitaoka 120a6e
      , m_vimage(vimage)
Shinya Kitaoka 120a6e
      , m_sl(0)
Shinya Kitaoka 120a6e
      , m_fid(-1)
Shinya Kitaoka 120a6e
      , m_settings(settings) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P generateRaster(const TDimension &iconSize) const;
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P VectorImageIconRenderer::generateRaster(
Shinya Kitaoka 120a6e
    const TDimension &iconSize) const {
Shinya Kitaoka 120a6e
  TVectorImageP vimage;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int frame = 0;
Shinya Kitaoka 120a6e
  if (!m_vimage) {
Shinya Kitaoka 120a6e
    assert(m_sl);
Shinya Kitaoka 120a6e
    if (!m_sl->isFid(m_fid)) return TRaster32P();
Shinya Kitaoka 120a6e
    TImageP image = m_sl->getFrameIcon(m_fid);
Shinya Kitaoka 120a6e
    if (!image) return TRaster32P();
Shinya Kitaoka 120a6e
    vimage = (TVectorImageP)image;
Shinya Kitaoka 120a6e
    if (!vimage) return TRaster32P();
Shinya Kitaoka 120a6e
    frame = m_sl->guessIndex(m_fid);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    vimage = m_vimage;
Shinya Kitaoka 120a6e
  assert(vimage);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P ras(convertToIcon(vimage, frame, iconSize, m_settings));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void VectorImageIconRenderer::run() {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    TRaster32P ras(generateRaster(getIconSize()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (ras) setIcon(ras);
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================
Toshihiro Shimizu 890ddd
//    SplineImageIconRenderer class
Toshihiro Shimizu 890ddd
//--------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class SplineIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  TStageObjectSpline *m_spline;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  SplineIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                     TStageObjectSpline *spline)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize), m_spline(spline) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P generateRaster(const TDimension &iconSize) const;
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P SplineIconRenderer::generateRaster(
Shinya Kitaoka 120a6e
    const TDimension &iconSize) const {
Shinya Kitaoka 120a6e
  // get the glContext
Shinya Kitaoka 120a6e
  TOfflineGL *glContext = IconGenerator::instance()->getOfflineGLContext();
Shinya Kitaoka 120a6e
  glContext->makeCurrent();
Shinya Kitaoka 120a6e
  glContext->clear(TPixel32::White);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const TStroke *stroke = m_spline->getStroke();
Shinya Kitaoka 120a6e
  assert(stroke);
tomosu 8d9526
  if (!stroke) {
tomosu 8d9526
    glContext->doneCurrent();
tomosu 8d9526
    return TRaster32P();
tomosu 8d9526
  }
Shinya Kitaoka 120a6e
  TRectD sbbox = stroke->getBBox();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  glColor3d(0, 0, 0);
Shinya Kitaoka 120a6e
  double scaleX = 1, scaleY = 1;
Shinya Kitaoka 120a6e
  if (sbbox.getLx() > 0.0) scaleX = (double)iconSize.lx / sbbox.getLx();
Shinya Kitaoka 120a6e
  if (sbbox.getLy() > 0.0) scaleY = (double)iconSize.ly / sbbox.getLy();
Shinya Kitaoka 120a6e
  double scale                    = 0.8 * std::min(scaleX, scaleY);
Shinya Kitaoka 120a6e
  TPointD centerStroke            = 0.5 * (sbbox.getP00() + sbbox.getP11());
Shinya Kitaoka 120a6e
  TPointD centerPixmap(iconSize.lx * 0.5, iconSize.ly * 0.5);
Shinya Kitaoka 120a6e
  glPushMatrix();
Shinya Kitaoka 120a6e
  tglMultMatrix(TScale(scale).place(centerStroke, centerPixmap));
Shinya Kitaoka 120a6e
  int n = 50;
Shinya Kitaoka 120a6e
  glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
  for (int i = 0; i < n; i++)
Shinya Kitaoka 120a6e
    tglVertex(stroke->getPoint((double)i / (double)(n - 1)));
Shinya Kitaoka 120a6e
  glEnd();
Shinya Kitaoka 120a6e
  glPopMatrix();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P ras(iconSize);
Shinya Kitaoka 120a6e
  glContext->getRaster(ras);
Shinya Kitaoka 120a6e
  glContext->doneCurrent();
Shinya Kitaoka 120a6e
  return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SplineIconRenderer::run() {
Shinya Kitaoka 120a6e
  TRaster32P raster = generateRaster(getIconSize());
Shinya Kitaoka 120a6e
  if (raster) setIcon(raster);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================
Toshihiro Shimizu 890ddd
//    RasterImageIconRenderer class
Toshihiro Shimizu 890ddd
//--------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterImageIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  TXshSimpleLevelP m_sl;
Shinya Kitaoka 120a6e
  TFrameId m_fid;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RasterImageIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                          TXshSimpleLevelP sl, const TFrameId &fid)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize), m_sl(sl), m_fid(fid) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RasterImageIconRenderer::run() {
Shinya Kitaoka 120a6e
  if (!m_sl->isFid(m_fid)) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageP image = m_sl->getFrameIcon(m_fid);
Shinya Kitaoka 120a6e
  if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterImageP rimage = (TRasterImageP)image;
Shinya Kitaoka 120a6e
  assert(rimage);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P icon(convertToIcon(rimage, getIconSize()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (icon) setIcon(icon);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================
Toshihiro Shimizu 890ddd
//    ToonzImageIconRenderer class
Toshihiro Shimizu 890ddd
//--------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ToonzImageIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  TXshSimpleLevelP m_sl;
Shinya Kitaoka 120a6e
  TFrameId m_fid;
Shinya Kitaoka 120a6e
  IconGenerator::Settings m_settings;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterCM32P m_tnzImgIcon;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ToonzImageIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                         TXshSimpleLevelP sl, const TFrameId &fid,
Shinya Kitaoka 120a6e
                         const IconGenerator::Settings &settings)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize)
Shinya Kitaoka 120a6e
      , m_sl(sl)
Shinya Kitaoka 120a6e
      , m_fid(fid)
Shinya Kitaoka 120a6e
      , m_settings(settings)
Shinya Kitaoka 120a6e
      , m_tnzImgIcon(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void run() override;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setIcon_TnzImg(const TRasterCM32P &timgp) { m_tnzImgIcon = timgp; }
Shinya Kitaoka 120a6e
  TRasterCM32P getIcon_TnzImg() const { return m_tnzImgIcon; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void ToonzImageIconRenderer::run() {
Shinya Kitaoka 120a6e
  if (!m_sl->isFid(m_fid)) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageP image = m_sl->getFrameIcon(m_fid);
Shinya Kitaoka 120a6e
  if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterImageP rimage(image);
Shinya Kitaoka 120a6e
  if (rimage) {
Shinya Kitaoka 120a6e
    TRaster32P icon(convertToIcon(rimage, getIconSize()));
Shinya Kitaoka 120a6e
    if (icon) setIcon(icon);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TToonzImageP timage = (TToonzImageP)image;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDimension iconSize(getIconSize());
Shinya Kitaoka 120a6e
  if (!timage) {
Shinya Kitaoka 120a6e
    TRaster32P p(iconSize.lx, iconSize.ly);
Shinya Kitaoka 120a6e
    p->fill(TPixelRGBM32::Yellow);
Shinya Kitaoka 120a6e
    setIcon(p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterCM32P rasCM32 = timage->getRaster();
Shinya Kitaoka 120a6e
  if (!rasCM32.getPointer()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int lx     = rasCM32->getSize().lx;
Shinya Kitaoka 120a6e
  int ly     = rasCM32->getSize().ly;
Shinya Kitaoka 120a6e
  int iconLx = iconSize.lx, iconLy = iconSize.ly;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P icon(iconSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  icon->fill(m_settings.m_blackBgCheck ? TPixel::Black : TPixel::White);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (lx != iconLx && ly != iconLy) {
Shinya Kitaoka 120a6e
    // The icons stored in the tlv file don't have the required size.
Shinya Kitaoka 120a6e
    // Fetch the original and iconize it.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    image = m_sl->getFrame(m_fid, ImageManager::dontPutInCache,
Shinya Kitaoka 120a6e
                           0);  // 0 uses the level properties' subsampling
Shinya Kitaoka 120a6e
    if (!image) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    timage = (TToonzImageP)image;
Shinya Kitaoka 120a6e
    if (!timage) {
Shinya Kitaoka 120a6e
      TRaster32P p(iconSize.lx, iconSize.ly);
Shinya Kitaoka 120a6e
      p->fill(TPixelRGBM32::Yellow);
Shinya Kitaoka 120a6e
      setIcon(p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    rasCM32 = timage->getRaster();
Shinya Kitaoka 120a6e
    if (!rasCM32.getPointer()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRasterCM32P auxCM32(icon->getSize());
Shinya Kitaoka 120a6e
    auxCM32->clear();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRop::makeIcon(auxCM32, rasCM32);
Shinya Kitaoka 120a6e
    rasCM32 = auxCM32;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_sl->getPalette()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPaletteP plt = m_sl->getPalette()->clone();
Shinya Kitaoka 120a6e
  if (!plt) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int frame = m_sl->guessIndex(m_fid);
Shinya Kitaoka 120a6e
  plt->setFrame(frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setIcon_TnzImg(rasCM32);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================
Toshihiro Shimizu 890ddd
//    MeshImageIconRenderer class
Toshihiro Shimizu 890ddd
//--------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MeshImageIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  TMeshImageP m_image;
Shinya Kitaoka 120a6e
  TXshSimpleLevelP m_sl;
Shinya Kitaoka 120a6e
  TFrameId m_fid;
Shinya Kitaoka 120a6e
  IconGenerator::Settings m_settings;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MeshImageIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                        TXshSimpleLevelP sl, const TFrameId &fid,
Shinya Kitaoka 120a6e
                        const IconGenerator::Settings &settings)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize)
Shinya Kitaoka 120a6e
      , m_image()
Shinya Kitaoka 120a6e
      , m_sl(sl)
Shinya Kitaoka 120a6e
      , m_fid(fid)
Shinya Kitaoka 120a6e
      , m_settings(settings) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  MeshImageIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                        TMeshImageP image,
Shinya Kitaoka 120a6e
                        const IconGenerator::Settings &settings)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize)
Shinya Kitaoka 120a6e
      , m_image(image)
Shinya Kitaoka 120a6e
      , m_sl(0)
Shinya Kitaoka 120a6e
      , m_fid(-1)
Shinya Kitaoka 120a6e
      , m_settings(settings) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P generateRaster(const TDimension &iconSize) const;
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P MeshImageIconRenderer::generateRaster(
Shinya Kitaoka 120a6e
    const TDimension &iconSize) const {
Shinya Kitaoka 120a6e
  TMeshImageP mi;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int frame = 0;
Shinya Kitaoka 120a6e
  if (!m_image) {
Shinya Kitaoka 120a6e
    assert(m_sl);
Shinya Kitaoka 120a6e
    if (!m_sl->isFid(m_fid)) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TImageP image = m_sl->getFrameIcon(m_fid);
Shinya Kitaoka 120a6e
    if (!image) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    mi = (TMeshImageP)image;
Shinya Kitaoka 120a6e
    if (!mi) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    frame = m_sl->guessIndex(m_fid);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    mi = m_image;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(mi);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return convertToIcon(mi, frame, iconSize, m_settings);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MeshImageIconRenderer::run() {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    TRaster32P ras(generateRaster(getIconSize()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (ras) setIcon(ras);
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================
Toshihiro Shimizu 890ddd
//    XsheetIconRenderer class
Toshihiro Shimizu 890ddd
//----------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class XsheetIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  TXsheet *m_xsheet;
Shinya Kitaoka 120a6e
  int m_row;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  XsheetIconRenderer(const std::string &id, const TDimension &iconSize,
Shinya Kitaoka 120a6e
                     TXsheet *xsheet, int row = 0)
Shinya Kitaoka 120a6e
      : IconRenderer(id, iconSize), m_xsheet(xsheet), m_row(row) {
Shinya Kitaoka 120a6e
    if (m_xsheet) {
Shinya Kitaoka 120a6e
      assert(m_xsheet->getRefCount() > 0);
Shinya Kitaoka 120a6e
      m_xsheet->addRef();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~XsheetIconRenderer() {
Shinya Kitaoka 120a6e
    if (m_xsheet) m_xsheet->release();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static std::string getId(TXshChildLevel *level, int row) {
Shinya Kitaoka 120a6e
    return "sub:" + ::to_string(level->getName()) + std::to_string(row);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P generateRaster(const TDimension &iconSize) const;
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P XsheetIconRenderer::generateRaster(
Shinya Kitaoka 120a6e
    const TDimension &iconSize) const {
Shinya Kitaoka 120a6e
  ToonzScene *scene = m_xsheet->getScene();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P ras(iconSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPixel32 bgColor = scene->getProperties()->getBgColor();
Shinya Kitaoka 120a6e
  bgColor.m        = 255;
Shinya Kitaoka 120a6e
  ras->fill(bgColor);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageCache::instance()->setEnabled(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // All checks are disabled
Shinya Kitaoka 120a6e
  scene->renderFrame(ras, m_row, m_xsheet, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageCache::instance()->setEnabled(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void XsheetIconRenderer::run() {
Shinya Kitaoka 120a6e
  TRaster32P ras = generateRaster(getIconSize());
Shinya Kitaoka 120a6e
  if (ras) setIcon(ras);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================
Toshihiro Shimizu 890ddd
//    FileIconRenderer class
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class FileIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  TFilePath m_path;
Shinya Kitaoka 120a6e
  TFrameId m_fid;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  FileIconRenderer(const TDimension &iconSize, const TFilePath &path,
Shinya Kitaoka 120a6e
                   const TFrameId &fid)
Shinya Kitaoka 120a6e
      : IconRenderer(getId(path, fid), iconSize), m_path(path), m_fid(fid) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static std::string getId(const TFilePath &path, const TFrameId &fid);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::string FileIconRenderer::getId(const TFilePath &path,
Shinya Kitaoka 120a6e
                                    const TFrameId &fid) {
Shinya Kitaoka 120a6e
  std::string type(path.getType());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (type == "tab" || type == "tnz" ||
Shinya Kitaoka 120a6e
      type == "mesh" ||  // meshes are not currently viewable
Shinya Kitaoka 120a6e
      TFileType::isViewable(TFileType::getInfo(path))) {
Shinya Kitaoka 120a6e
    std::string fidNumber;
Shinya Kitaoka 120a6e
    if (fid != TFrameId::NO_FRAME)
Shinya Kitaoka 120a6e
      fidNumber = "frame:" + fid.expand(TFrameId::NO_PAD);
Shinya Kitaoka 120a6e
    return "$:" + ::to_string(path) + fidNumber;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // All the other types whose icon is the same for file type, get the same id
Shinya Kitaoka 120a6e
  // per type.
Shinya Kitaoka 120a6e
  else if (type == "tpl")
Shinya Kitaoka 120a6e
    return "$:tpl";
Shinya Kitaoka 120a6e
  else if (type == "tzp")
Shinya Kitaoka 120a6e
    return "$:tzp";
Shinya Kitaoka 120a6e
  else if (type == "svg")
Shinya Kitaoka 120a6e
    return "$:svg";
Shinya Kitaoka 120a6e
  else if (type == "tzu")
Shinya Kitaoka 120a6e
    return "$:tzu";
Shinya Kitaoka 120a6e
  else if (TFileType::getInfo(path) == TFileType::AUDIO_LEVEL)
Shinya Kitaoka 120a6e
    return "$:audio";
Shinya Kitaoka 120a6e
  else if (type == "scr")
Shinya Kitaoka 120a6e
    return "$:scr";
Shinya Kitaoka 120a6e
  else if (type == "mpath")
Shinya Kitaoka 120a6e
    return "$:mpath";
Shinya Kitaoka 120a6e
  else if (type == "curve")
Shinya Kitaoka 120a6e
    return "$:curve";
Shinya Kitaoka 120a6e
  else if (type == "cln")
Shinya Kitaoka 120a6e
    return "$:cln";
Shinya Kitaoka 120a6e
  else if (type == "tnzbat")
Shinya Kitaoka 120a6e
    return "$:tnzbat";
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return "$:unknown";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P IconGenerator::generateVectorFileIcon(const TFilePath &path,
Shinya Kitaoka 120a6e
                                                 const TDimension &iconSize,
Shinya Kitaoka 120a6e
                                                 const TFrameId &fid) {
Shinya Kitaoka 120a6e
  TLevelReaderP lr(path);
Shinya Kitaoka 120a6e
  TLevelP level = lr->loadInfo();
Shinya Kitaoka 120a6e
  if (level->begin() == level->end()) return TRaster32P();
Shinya Kitaoka 120a6e
  TFrameId frameId                       = fid;
Shinya Kitaoka 120a6e
  if (fid == TFrameId::NO_FRAME) frameId = level->begin()->first;
Shinya Kitaoka 120a6e
  TImageP img                            = lr->getFrameReader(frameId)->load();
Shinya Kitaoka 120a6e
  TVectorImageP vi                       = img;
Shinya Kitaoka 120a6e
  if (!vi) return TRaster32P();
Shinya Kitaoka 120a6e
  vi->setPalette(level->getPalette());
Shinya Kitaoka 120a6e
  VectorImageIconRenderer vir("", iconSize, vi.getPointer(),
Shinya Kitaoka 120a6e
                              IconGenerator::Settings());
Shinya Kitaoka 120a6e
  return vir.generateRaster(iconSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P IconGenerator::generateRasterFileIcon(const TFilePath &path,
Shinya Kitaoka 120a6e
                                                 const TDimension &iconSize,
Shinya Kitaoka 120a6e
                                                 const TFrameId &fid) {
Shinya Kitaoka 120a6e
  TImageP img;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    // Attempt image reading
Shinya Kitaoka 120a6e
    TLevelReaderP lr(path);
Shinya Kitaoka 120a6e
    TLevelP level = lr->loadInfo();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (level->begin() == level->end()) return TRaster32P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TFrameId frameId = fid;
Shinya Kitaoka 120a6e
    if (fid == TFrameId::NO_FRAME)  // In case no frame was specified, pick the
Shinya Kitaoka 120a6e
      frameId = level->begin()->first;  // first level frame
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TImageReaderP ir = lr->getFrameReader(frameId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (const TImageInfo *ii = ir->getImageInfo()) {
Shinya Kitaoka 120a6e
      int shrinkX = ii->m_lx / iconSize.lx;
Shinya Kitaoka 120a6e
      int shrinkY = ii->m_ly / iconSize.ly;
Shinya Kitaoka 120a6e
      int shrink  = shrinkX < shrinkY ? shrinkX : shrinkY;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (shrink > 1) ir->setShrink(shrink);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    img = (toUpper(path.getType()) == "TLV") ? ir->loadIcon() : ir->load();
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Extract a 32-bit fullcolor raster from img
Shinya Kitaoka 120a6e
  TRaster32P ras32;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TRasterImageP ri = img) {
Shinya Kitaoka 120a6e
    ras32 = ri->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!ras32) {
Shinya Kitaoka 120a6e
      if (TRasterGR8P rasGR8 = ri->getRaster()) {
Shinya Kitaoka 120a6e
        TRaster32P raux(rasGR8->getSize());
Shinya Kitaoka 120a6e
        TRop::convert(raux, rasGR8);
Shinya Kitaoka 120a6e
        ras32 = raux;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
    }
Shinya Kitaoka 120a6e
  } else if (TToonzImageP ti = img) {
Shinya Kitaoka 120a6e
    TRasterCM32P auxRaster = ti->getRaster();
Shinya Kitaoka 120a6e
    TRaster32P dstRaster(auxRaster->getSize());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (TPaletteP plt = ti->getPalette())
Shinya Kitaoka 120a6e
      TRop::convert(dstRaster, auxRaster, plt, false);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      dstRaster->fill(TPixel32::Magenta);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ras32 = dstRaster;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!ras32) return TRaster32P();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
// NOTE: The following was possible with the old Qt version 4.3.3 - but in the
Shinya Kitaoka 120a6e
new 4.5.0
Shinya Kitaoka 120a6e
// it's not: 'It is not safe to use QPixmaps outside the GUI thread'...
Shinya Kitaoka 120a6e
TRaster32P icon;
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
QPixmap p(rasterToQPixmap(ras32));
Shinya Kitaoka 120a6e
icon = rasterFromQPixmap(
Shinya Kitaoka 120a6e
  scalePixmapKeepingAspectRatio(p, QSize(iconSize.lx, iconSize.ly),
Shinya Kitaoka 120a6e
Qt::transparent)
Shinya Kitaoka 120a6e
  , false);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRaster32P icon(iconSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double sx = double(iconSize.lx) / ras32->getLx();
Shinya Kitaoka 120a6e
  double sy = double(iconSize.ly) / ras32->getLy();
Shinya Kitaoka 120a6e
  double sc = std::min(sx, sy);  // show all the image, possibly adding bands
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TAffine aff = TScale(sc).place(ras32->getCenterD(), icon->getCenterD());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  icon->fill(TPixel32(160, 160, 160));  // "bands" color
Shinya Kitaoka 120a6e
  TRop::resample(icon, ras32, aff, TRop::Triangle);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (icon) {
Shinya Kitaoka 120a6e
    if (::isUnpremultiplied(icon))  // APPALLING. I'm not touching this, but
Shinya Kitaoka 120a6e
      TRop::premultiply(
Shinya Kitaoka 120a6e
          icon);  // YOU JUST CAN'T TELL IF AN IMAGE IS PREMULTIPLIED
Shinya Kitaoka 120a6e
                  // OR NOT BY SCANNING ITS PIXELS.
Shinya Kitaoka 120a6e
                  // You either know it FOR A GIVEN, or you don't...      >_<
Shinya Kitaoka 120a6e
    TRectI srcBBoxI = ras32->getBounds();
Shinya Kitaoka 120a6e
    TRectD srcBBoxD = aff * TRectD(srcBBoxI.x0, srcBBoxI.y0, srcBBoxI.x1 + 1,
Shinya Kitaoka 120a6e
                                   srcBBoxI.y1 + 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRect bbox = TRect(tfloor(srcBBoxD.x0), tceil(srcBBoxD.y0) - 1,
Shinya Kitaoka 120a6e
                       tfloor(srcBBoxD.x1), tceil(srcBBoxD.y1) - 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bbox = (bbox * icon->getBounds())
Shinya Kitaoka 120a6e
               .enlarge(-1);  // Add a 1 pixel transparent margin - this
Shinya Kitaoka 120a6e
    if (bbox.getLx() > 0 &&
Shinya Kitaoka 120a6e
        bbox.getLy() > 0)  // way the actual content doesn't look trimmed.
Shinya Kitaoka 120a6e
      ::makeChessBackground(icon->extract(bbox));
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    icon->fill(TPixel32(255, 0, 0));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return icon;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P IconGenerator::generateSplineFileIcon(const TFilePath &path,
Shinya Kitaoka 120a6e
                                                 const TDimension &iconSize) {
Shinya Kitaoka 120a6e
  TStageObjectSpline *spline = new TStageObjectSpline();
Shinya Kitaoka 120a6e
  TIStream is(path);
Shinya Kitaoka 120a6e
  spline->loadData(is);
Shinya Kitaoka 120a6e
  SplineIconRenderer sr("", iconSize, spline);
Shinya Kitaoka 120a6e
  TRaster32P icon = sr.generateRaster(iconSize);
Shinya Kitaoka 120a6e
  delete spline;
Shinya Kitaoka 120a6e
  return icon;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P IconGenerator::generateMeshFileIcon(const TFilePath &path,
Shinya Kitaoka 120a6e
                                               const TDimension &iconSize,
Shinya Kitaoka 120a6e
                                               const TFrameId &fid) {
Shinya Kitaoka 120a6e
  TLevelReaderP lr(path);
Shinya Kitaoka 120a6e
  TLevelP level = lr->loadInfo();
Shinya Kitaoka 120a6e
  if (level->begin() == level->end()) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFrameId frameId                       = fid;
Shinya Kitaoka 120a6e
  if (fid == TFrameId::NO_FRAME) frameId = level->begin()->first;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TMeshImageP mi = lr->getFrameReader(frameId)->load();
Shinya Kitaoka 120a6e
  if (!mi) return TRaster32P();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  MeshImageIconRenderer mir("", iconSize, mi.getPointer(),
Shinya Kitaoka 120a6e
                            IconGenerator::Settings());
Shinya Kitaoka 120a6e
  return mir.generateRaster(iconSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P IconGenerator::generateSceneFileIcon(const TFilePath &path,
Shinya Kitaoka 120a6e
                                                const TDimension &iconSize,
Shinya Kitaoka 120a6e
                                                int row) {
Shinya Kitaoka 120a6e
  if (row == 0 || row == TFrameId::NO_FRAME - 1) {
Shinya Kitaoka 120a6e
    TFilePath iconPath =
Shinya Kitaoka 120a6e
        path.getParentDir() + "sceneIcons" + (path.getWideName() + L" .png");
Shinya Kitaoka 120a6e
    return generateRasterFileIcon(iconPath, iconSize, TFrameId::NO_FRAME);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // obsolete
Shinya Kitaoka 120a6e
    ToonzScene scene;
Shinya Kitaoka 120a6e
    scene.load(path);
Shinya Kitaoka 120a6e
    XsheetIconRenderer ir("", iconSize, scene.getXsheet(), row);
Shinya Kitaoka 120a6e
    return ir.generateRaster(iconSize);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FileIconRenderer::run() {
Shinya Kitaoka 120a6e
  TDimension iconSize(getIconSize());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    TRaster32P iconRaster;
Shinya Kitaoka 120a6e
    std::string type(m_path.getType());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (type == "tnz" || type == "tab")
Shinya Kitaoka 120a6e
      iconRaster = IconGenerator::generateSceneFileIcon(m_path, iconSize,
Shinya Kitaoka 120a6e
                                                        m_fid.getNumber() - 1);
Shinya Kitaoka 120a6e
    else if (type == "pli")
Shinya Kitaoka 120a6e
      iconRaster =
Shinya Kitaoka 120a6e
          IconGenerator::generateVectorFileIcon(m_path, iconSize, m_fid);
Shinya Kitaoka 120a6e
    else if (type == "tpl") {
Shinya Kitaoka 120a6e
      QImage palette(":Resources/paletteicon.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(palette));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "tzp") {
Shinya Kitaoka 120a6e
      QImage palette(":Resources/tzpicon.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(palette));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "svg") {
Shinya Kitaoka 120a6e
      QImage palette(":Resources/svg.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(palette));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "tzu") {
Shinya Kitaoka 120a6e
      QImage palette(":Resources/tzuicon.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(palette));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (TFileType::getInfo(m_path) == TFileType::AUDIO_LEVEL) {
Shinya Kitaoka 120a6e
      QImage loudspeaker(":Resources/audio.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(loudspeaker));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "scr") {
Shinya Kitaoka 120a6e
      QImage screensaver(":Resources/savescreen.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(screensaver));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "psd") {
Shinya Kitaoka 120a6e
      QImage psdPath(":Resources/psd.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(psdPath));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "mesh")
Shinya Kitaoka 120a6e
      iconRaster = IconGenerator::generateMeshFileIcon(m_path, iconSize, m_fid);
Shinya Kitaoka 120a6e
    else if (TFileType::isViewable(TFileType::getInfo(m_path)) || type == "tlv")
Shinya Kitaoka 120a6e
      iconRaster =
Shinya Kitaoka 120a6e
          IconGenerator::generateRasterFileIcon(m_path, iconSize, m_fid);
Shinya Kitaoka 120a6e
    else if (type == "mpath") {
Shinya Kitaoka 120a6e
      QImage motionPath(":Resources/motionpath.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(motionPath));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "curve") {
Shinya Kitaoka 120a6e
      QImage motionPath(":Resources/curve.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(motionPath));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "cln") {
Shinya Kitaoka 120a6e
      QImage motionPath(":Resources/cleanup.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(motionPath));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "tnzbat") {
Shinya Kitaoka 120a6e
      QImage motionPath(":Resources/tasklist.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(motionPath));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "tls") {
Shinya Kitaoka 120a6e
      QImage magpie(":Resources/magpie.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(magpie));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if (type == "js") {
Shinya Kitaoka 120a6e
      QImage script(":Resources/scripticon.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(script));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      QImage unknown(":Resources/unknown.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(unknown));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!iconRaster) {
Shinya Kitaoka 120a6e
      QImage broken(":Resources/broken.png");
Shinya Kitaoka 120a6e
      setIcon(rasterFromQImage(broken));
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    setIcon(iconRaster);
Shinya Kitaoka 120a6e
  } catch (const TImageVersionException &) {
Shinya Kitaoka 120a6e
    QImage unknown(":Resources/unknown.png");
Shinya Kitaoka 120a6e
    setIcon(rasterFromQImage(unknown));
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
    QImage broken(":Resources/broken.png");
Shinya Kitaoka 120a6e
    setIcon(rasterFromQImage(broken));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================
Toshihiro Shimizu 890ddd
//    SceneIconRenderer class
Toshihiro Shimizu 890ddd
//--------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class SceneIconRenderer final : public IconRenderer {
Shinya Kitaoka 120a6e
  ToonzScene *m_toonzScene;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  SceneIconRenderer(const TDimension &iconSize, ToonzScene *scene)
Shinya Kitaoka 120a6e
      : IconRenderer(getId(), iconSize), m_toonzScene(scene) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static std::string getId() { return "currentScene"; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void run() override;
Shinya Kitaoka 120a6e
  TRaster32P generateIcon(const TDimension &iconSize) const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRaster32P SceneIconRenderer::generateIcon(const TDimension &iconSize) const {
Shinya Kitaoka 120a6e
  TRaster32P ras(iconSize);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPixel32 bgColor = m_toonzScene->getProperties()->getBgColor();
Shinya Kitaoka 120a6e
  bgColor.m        = 255;
Shinya Kitaoka 120a6e
  ras->fill(bgColor);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_toonzScene->renderFrame(ras, 0, 0, false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SceneIconRenderer::run() { setIcon(generateIcon(getIconSize())); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//    IconGenerator class
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
IconGenerator::IconGenerator() : m_iconSize(FilmstripIconSize) {
Shinya Kitaoka 120a6e
  m_executor.setMaxActiveTasks(1);  // Only one thread to render icons...
Shinya Kitaoka 120a6e
  m_executor.setDedicatedThreads(true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
IconGenerator::~IconGenerator() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
IconGenerator *IconGenerator::instance() {
Shinya Kitaoka 120a6e
  static IconGenerator _instance;
Shinya Kitaoka 120a6e
  return &_instance;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::setFilmstripIconSize(const TDimension &dim) {
Shinya Kitaoka 120a6e
  FilmstripIconSize = dim;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TDimension IconGenerator::getIconSize() const { return FilmstripIconSize; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TOfflineGL *IconGenerator::getOfflineGLContext() {
Shinya Kitaoka 120a6e
  // One context per rendering thread
Shinya Kitaoka 120a6e
  if (!m_contexts.hasLocalData()) {
Shinya Kitaoka 120a6e
    TDimension contextSize(std::max(FilmstripIconSize.lx, IconSize.lx),
Shinya Kitaoka 120a6e
                           std::max(FilmstripIconSize.ly, IconSize.ly));
Shinya Kitaoka 120a6e
    m_contexts.setLocalData(new TOfflineGL(contextSize));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return m_contexts.localData();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::addTask(const std::string &id,
Shinya Kitaoka 120a6e
                            TThread::RunnableP iconRenderer) {
Shinya Kitaoka 120a6e
  iconsMap.insert(id);
Shinya Kitaoka 120a6e
  m_executor.addTask(iconRenderer);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QPixmap IconGenerator::getIcon(TXshLevel *xl, const TFrameId &fid,
Shinya Kitaoka 120a6e
                               bool filmStrip, bool onDemand) {
Shinya Kitaoka 120a6e
  if (!xl) return QPixmap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TXshChildLevel *cl = xl->getChildLevel()) {
Shinya Kitaoka 120a6e
    if (filmStrip) return QPixmap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string id = XsheetIconRenderer::getId(cl, fid.getNumber() - 1);
Shinya Kitaoka 120a6e
    QPixmap pix;
Shinya Kitaoka 120a6e
    if (::getIcon(id, pix)) return pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (onDemand) return pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TDimension iconSize = TDimension(80, 60);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // The icon must be calculated - add an IconRenderer task.
Shinya Kitaoka 120a6e
    // storeIcon(id, QPixmap());   //It was automatically added by the former
Shinya Kitaoka 120a6e
    // access
Shinya Kitaoka 120a6e
    addTask(id, new XsheetIconRenderer(id, iconSize, cl->getXsheet()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TXshSimpleLevel *sl = xl->getSimpleLevel()) {
Shinya Kitaoka 120a6e
    // make thumbnails for cleanup preview and cameratest to be the same as
Shinya Kitaoka 120a6e
    // normal TLV
Shinya Kitaoka 120a6e
    std::string id;
Shinya Kitaoka 120a6e
    int status = sl->getFrameStatus(fid);
Shinya Kitaoka 120a6e
    if (sl->getType() == TZP_XSHLEVEL &&
Shinya Kitaoka 120a6e
        status & TXshSimpleLevel::CleanupPreview) {
Shinya Kitaoka 120a6e
      sl->setFrameStatus(fid, status & ~TXshSimpleLevel::CleanupPreview);
Shinya Kitaoka 120a6e
      id = sl->getIconId(fid);
Shinya Kitaoka 120a6e
      sl->setFrameStatus(fid, status);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      id = sl->getIconId(fid);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!filmStrip) id += "_small";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QPixmap pix;
Shinya Kitaoka 120a6e
    if (::getIcon(id, pix, xl->getSimpleLevel())) return pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (onDemand) return pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    IconGenerator::Settings oldSettings = m_settings;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Disable transparency check for cast and xsheet icons
Shinya Kitaoka 120a6e
    if (!filmStrip) m_settings = IconGenerator::Settings();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TDimension iconSize = filmStrip ? m_iconSize : TDimension(80, 60);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // storeIcon(id, QPixmap());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int type = sl->getType();
Shinya Kitaoka 120a6e
    switch (type) {
Shinya Kitaoka 120a6e
    case OVL_XSHLEVEL:
Shinya Kitaoka 120a6e
    case TZI_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id, new RasterImageIconRenderer(id, iconSize, sl, fid));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case PLI_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id,
Shinya Kitaoka 120a6e
              new VectorImageIconRenderer(id, iconSize, sl, fid, m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case TZP_XSHLEVEL:
Shinya Kitaoka 120a6e
      // Yep, we could have rasters, due to a cleanupping process
Shinya Kitaoka 120a6e
      if (status == TXshSimpleLevel::Scanned)
Shinya Kitaoka 120a6e
        addTask(id, new RasterImageIconRenderer(id, iconSize, sl, fid));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        addTask(id,
Shinya Kitaoka 120a6e
                new ToonzImageIconRenderer(id, iconSize, sl, fid, m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case MESH_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id, new MeshImageIconRenderer(id, iconSize, sl, fid, m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_settings = oldSettings;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return QPixmap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::invalidate(TXshLevel *xl, const TFrameId &fid,
Shinya Kitaoka 120a6e
                               bool onlyFilmStrip) {
Shinya Kitaoka 120a6e
  if (!xl) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TXshSimpleLevel *sl = xl->getSimpleLevel()) {
Shinya Kitaoka 120a6e
    std::string id = sl->getIconId(fid);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int type = sl->getType();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    switch (type) {
Shinya Kitaoka 120a6e
    case OVL_XSHLEVEL:
Shinya Kitaoka 120a6e
    case TZI_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id, new RasterImageIconRenderer(id, getIconSize(), sl, fid));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case PLI_XSHLEVEL:
Shinya Kitaoka 120a6e
      removeIcon(id);
Shinya Kitaoka 120a6e
      addTask(id, new VectorImageIconRenderer(id, getIconSize(), sl, fid,
Shinya Kitaoka 120a6e
                                              m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case TZP_XSHLEVEL:
Shinya Kitaoka 120a6e
      if (sl->getFrameStatus(fid) == TXshSimpleLevel::Scanned)
Shinya Kitaoka 120a6e
        addTask(id, new RasterImageIconRenderer(id, getIconSize(), sl, fid));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        addTask(id, new ToonzImageIconRenderer(id, getIconSize(), sl, fid,
Shinya Kitaoka 120a6e
                                               m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case MESH_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id, new MeshImageIconRenderer(id, getIconSize(), sl, fid,
Shinya Kitaoka 120a6e
                                            m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (onlyFilmStrip) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    id += "_small";
Shinya Kitaoka 120a6e
    if (iconsMap.find(id) == iconsMap.end()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Not-filmstrip icons diable all checks
Shinya Kitaoka 120a6e
    IconGenerator::Settings oldSettings = m_settings;
Shinya Kitaoka 120a6e
    m_settings.m_transparencyCheck      = false;
Shinya Kitaoka 120a6e
    m_settings.m_inkIndex               = -1;
Shinya Kitaoka 120a6e
    m_settings.m_paintIndex             = -1;
Shinya Kitaoka 120a6e
    m_settings.m_blackBgCheck           = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    switch (type) {
Shinya Kitaoka 120a6e
    case OVL_XSHLEVEL:
Shinya Kitaoka 120a6e
    case TZI_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id, new RasterImageIconRenderer(id, TDimension(80, 60), sl, fid));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case PLI_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id, new VectorImageIconRenderer(id, TDimension(80, 60), sl, fid,
Shinya Kitaoka 120a6e
                                              m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case TZP_XSHLEVEL:
Shinya Kitaoka 120a6e
      if (sl->getFrameStatus(fid) == TXshSimpleLevel::Scanned)
Shinya Kitaoka 120a6e
        addTask(id,
Shinya Kitaoka 120a6e
                new RasterImageIconRenderer(id, TDimension(80, 60), sl, fid));
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        addTask(id, new ToonzImageIconRenderer(id, TDimension(80, 60), sl, fid,
Shinya Kitaoka 120a6e
                                               m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case MESH_XSHLEVEL:
Shinya Kitaoka 120a6e
      addTask(id, new MeshImageIconRenderer(id, TDimension(80, 60), sl, fid,
Shinya Kitaoka 120a6e
                                            m_settings));
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_settings = oldSettings;
Shinya Kitaoka 120a6e
  } else if (TXshChildLevel *cl = xl->getChildLevel()) {
Shinya Kitaoka 120a6e
    if (onlyFilmStrip) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string id = XsheetIconRenderer::getId(cl, fid.getNumber() - 1);
Shinya Kitaoka 120a6e
    removeIcon(id);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    getIcon(xl, fid);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::remove(TXshLevel *xl, const TFrameId &fid,
Shinya Kitaoka 120a6e
                           bool onlyFilmStrip) {
Shinya Kitaoka 120a6e
  if (!xl) return;
Shinya Kitaoka 120a6e
  if (TXshSimpleLevel *sl = xl->getSimpleLevel()) {
Shinya Kitaoka 120a6e
    std::string id(sl->getIconId(fid));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    removeIcon(id);
Shinya Kitaoka 120a6e
    if (!onlyFilmStrip) removeIcon(id + "_small");
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TXshChildLevel *cl = xl->getChildLevel();
Shinya Kitaoka 120a6e
    if (cl && !onlyFilmStrip)
Shinya Kitaoka 120a6e
      removeIcon(XsheetIconRenderer::getId(cl, fid.getNumber() - 1));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QPixmap IconGenerator::getIcon(TStageObjectSpline *spline) {
Shinya Kitaoka 120a6e
  if (!spline) return QPixmap();
Shinya Kitaoka 120a6e
  std::string iconName = spline->getIconId();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QPixmap pix;
Shinya Kitaoka 120a6e
  if (::getIcon(iconName, pix)) return pix;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // storeIcon(id, QPixmap());
Shinya Kitaoka 120a6e
  addTask(iconName, new SplineIconRenderer(iconName, getIconSize(), spline));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return QPixmap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::invalidate(TStageObjectSpline *spline) {
Shinya Kitaoka 120a6e
  if (!spline) return;
Shinya Kitaoka 120a6e
  std::string iconName = spline->getIconId();
Shinya Kitaoka 120a6e
  removeIcon(iconName);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  addTask(iconName, new SplineIconRenderer(iconName, getIconSize(), spline));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::remove(TStageObjectSpline *spline) {
Shinya Kitaoka 120a6e
  if (!spline) return;
Shinya Kitaoka 120a6e
  std::string iconName = spline->getIconId();
Shinya Kitaoka 120a6e
  removeIcon(iconName);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QPixmap IconGenerator::getIcon(const TFilePath &path, const TFrameId &fid) {
Shinya Kitaoka 120a6e
  std::string id = FileIconRenderer::getId(path, fid);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QPixmap pix;
Shinya Kitaoka 120a6e
  if (::getIcon(id, pix)) return pix;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  addTask(id, new FileIconRenderer(TDimension(80, 60), path, fid));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return QPixmap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::invalidate(const TFilePath &path, const TFrameId &fid) {
Shinya Kitaoka 120a6e
  std::string id = FileIconRenderer::getId(path, fid);
Shinya Kitaoka 120a6e
  removeIcon(id);
Shinya Kitaoka 120a6e
  addTask(id, new FileIconRenderer(TDimension(80, 60), path, fid));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::remove(const TFilePath &path, const TFrameId &fid) {
Shinya Kitaoka 120a6e
  removeIcon(FileIconRenderer::getId(path, fid));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QPixmap IconGenerator::getSceneIcon(ToonzScene *scene) {
Shinya Kitaoka 120a6e
  std::string id(SceneIconRenderer::getId());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QPixmap pix;
Shinya Kitaoka 120a6e
  if (::getIcon(id, pix)) return pix;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // storeIcon(id, QPixmap());
Shinya Kitaoka 120a6e
  addTask(id, new SceneIconRenderer(getIconSize(), scene));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return QPixmap();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::invalidateSceneIcon() {
Shinya Kitaoka 120a6e
  removeIcon(SceneIconRenderer::getId());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::remap(const std::string &newIconId,
Shinya Kitaoka 120a6e
                          const std::string &oldIconId) {
Shinya Kitaoka 120a6e
  IconIterator it = iconsMap.find(oldIconId);
Shinya Kitaoka 120a6e
  if (it == iconsMap.end()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  iconsMap.erase(it);
Shinya Kitaoka 120a6e
  iconsMap.insert(newIconId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageCache::instance()->remap(newIconId, oldIconId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::clearRequests() { m_executor.cancelAll(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::clearSceneIcons() {
Shinya Kitaoka 120a6e
  // Eliminate all icons whose prefix is not "$:" (that is, scene-independent
Shinya Kitaoka 120a6e
  // images).
Shinya Kitaoka 120a6e
  // The abovementioned prefix is internally recognized by the image cache when
Shinya Kitaoka 120a6e
  // the scene
Shinya Kitaoka 120a6e
  // changes to avoid clearing file browser's icons.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Observe that image cache's clear function invoked during scene changes is
Shinya Kitaoka 120a6e
  // called through
Shinya Kitaoka 120a6e
  // the ImageManager::clear() method, including FilmStrip icons.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // note the ';' - which follows ':' in the ascii table
Shinya Kitaoka 120a6e
  iconsMap.erase(iconsMap.begin(), iconsMap.lower_bound("$:"));
Shinya Kitaoka 120a6e
  iconsMap.erase(iconsMap.lower_bound("$;"), iconsMap.end());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::onStarted(TThread::RunnableP iconRenderer) {
Shinya Kitaoka 120a6e
  IconRenderer *ir = static_cast<iconrenderer *="">(iconRenderer.getPointer());</iconrenderer>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ir->hasStarted() = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::onCanceled(TThread::RunnableP iconRenderer) {
Shinya Kitaoka 120a6e
  IconRenderer *ir = static_cast<iconrenderer *="">(iconRenderer.getPointer());</iconrenderer>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!ir->hasStarted()) {
Shinya Kitaoka 120a6e
    removeIcon(ir->getId());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::onFinished(TThread::RunnableP iconRenderer) {
Shinya Kitaoka 120a6e
  IconRenderer *ir = static_cast<iconrenderer *="">(iconRenderer.getPointer());</iconrenderer>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // if the icon was generated in TToonzImage format, cache it instead
Shinya Kitaoka 120a6e
  ToonzImageIconRenderer *tir = dynamic_cast<toonzimageiconrenderer *="">(ir);</toonzimageiconrenderer>
Shinya Kitaoka 120a6e
  if (tir) {
Shinya Kitaoka 120a6e
    TRasterCM32P timgp = tir->getIcon_TnzImg();
Shinya Kitaoka 120a6e
    if (timgp) {
Shinya Kitaoka 120a6e
      ::setIcon_TnzImg(ir->getId(), timgp);
Shinya Kitaoka 120a6e
      emit iconGenerated();
Shinya Kitaoka 120a6e
      if (ir->wasTerminated()) m_iconsTerminationLoop.quit();
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Update the icons map
Shinya Kitaoka 120a6e
  if (ir->getIcon()) {
Shinya Kitaoka 120a6e
    ::setIcon(ir->getId(), ir->getIcon());
Shinya Kitaoka 120a6e
    emit iconGenerated();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (ir->wasTerminated()) m_iconsTerminationLoop.quit();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::onException(TThread::RunnableP iconRenderer) {
Shinya Kitaoka 120a6e
  IconRenderer *ir = static_cast<iconrenderer *="">(iconRenderer.getPointer());</iconrenderer>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (ir->wasTerminated()) m_iconsTerminationLoop.quit();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void IconGenerator::onTerminated(TThread::RunnableP iconRenderer) {
Shinya Kitaoka 120a6e
  IconRenderer *ir = static_cast<iconrenderer *="">(iconRenderer.getPointer());</iconrenderer>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ir->wasTerminated() = true;
Shinya Kitaoka 120a6e
  m_iconsTerminationLoop.exec();
Toshihiro Shimizu 890ddd
}