| |
| |
|
|
| #include "tvectorimage.h" |
| #include "trasterimage.h" |
| #include "tlevel_io.h" |
| #include "tofflinegl.h" |
| #include "tropcm.h" |
| #include "tvectorrenderdata.h" |
| #include "tsystem.h" |
| |
| |
| #include <QDir> |
| #include <QImage> |
| |
| #include "toonz/stylemanager.h" |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| TFilePath rootPath; |
| |
| |
| |
| void convertRaster32ToImage(TRaster32P ras, QImage *image) |
| { |
| int lx = ras->getLx(); |
| int ly = ras->getLy(); |
| int i, j; |
| ras->lock(); |
| for (i = 0; i < lx; i++) |
| for (j = 0; j < ly; j++) { |
| TPixel32 pix = ras->pixels(ly - 1 - j)[i]; |
| QRgb value; |
| value = qRgba(pix.r, pix.g, pix.b, pix.m); |
| image->setPixel(i, j, value); |
| } |
| ras->unlock(); |
| } |
| |
| } |
| |
| |
| |
| |
| |
| class CustomStyleManager::StyleLoaderTask : public TThread::Runnable |
| { |
| CustomStyleManager *m_manager; |
| TFilePath m_fp; |
| PatternData m_data; |
| |
| public: |
| StyleLoaderTask(CustomStyleManager *manager, const TFilePath &fp); |
| |
| void run(); |
| |
| void onFinished(TThread::RunnableP sender); |
| }; |
| |
| |
| |
| CustomStyleManager::StyleLoaderTask::StyleLoaderTask(CustomStyleManager *manager, const TFilePath &fp) |
| : m_manager(manager), m_fp(fp) |
| { |
| connect(this, SIGNAL(finished(TThread::RunnableP)), this, SLOT(onFinished(TThread::RunnableP))); |
| } |
| |
| |
| |
| void CustomStyleManager::StyleLoaderTask::run() |
| { |
| try { |
| |
| TLevelReaderP lr(m_fp); |
| TLevelP level = lr->loadInfo(); |
| if (!level || level->getFrameCount() == 0) |
| return; |
| |
| |
| TLevel::Iterator frameIt = level->begin(); |
| if (frameIt == level->end()) |
| return; |
| TImageP img = lr->getFrameReader(frameIt->first)->load(); |
| |
| |
| const QSize &qChipSize = m_manager->getChipSize(); |
| TDimension chipSize(qChipSize.width(), qChipSize.height()); |
| |
| TVectorImageP vimg = img; |
| TRasterImageP rimg = img; |
| |
| TRaster32P ras; |
| if (vimg) { |
| assert(level->getPalette()); |
| TPalette *vPalette = level->getPalette(); |
| assert(vPalette); |
| vimg->setPalette(vPalette); |
| |
| TOfflineGL *glContext = 0; |
| glContext = TOfflineGL::getStock(chipSize); |
| |
| glContext->clear(TPixel32::White); |
| TRectD bbox = img->getBBox(); |
| double scx = 0.8 * chipSize.lx / bbox.getLx(); |
| double scy = 0.8 * chipSize.ly / bbox.getLy(); |
| double sc = tmin(scx, scy); |
| double dx = 0.5 * chipSize.lx; |
| double dy = 0.5 * chipSize.ly; |
| |
| TAffine aff = TTranslation(dx, dy) * TScale(sc) * |
| TTranslation(-0.5 * (bbox.x0 + bbox.x1), -0.5 * (bbox.y0 + bbox.y1)); |
| TVectorRenderData rd(aff, chipSize, vPalette, 0, true); |
| |
| glContext->draw(img, rd); |
| |
| |
| ras = glContext->getRaster(); |
| } else if (rimg) { |
| TDimension size = rimg->getRaster()->getSize(); |
| if (size == chipSize) |
| ras = rimg->getRaster()->clone(); |
| else { |
| TRaster32P rout(chipSize); |
| |
| TRop::resample(rout, rimg->getRaster(), |
| TScale((double)chipSize.lx / size.lx, (double)chipSize.ly / size.ly)); |
| |
| TRop::addBackground(rout, TPixel::White); |
| ras = rout; |
| } |
| } else |
| assert(!"unsupported type for custom styles!"); |
| |
| QImage *image = new QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32); |
| convertRaster32ToImage(ras, image); |
| |
| m_data.m_patternName = m_fp.getName(); |
| m_data.m_isVector = (m_fp.getType() == "pli" || m_fp.getType() == "svg"); |
| m_data.m_image = image; |
| } catch (...) { |
| } |
| } |
| |
| |
| |
| void CustomStyleManager::StyleLoaderTask::onFinished(TThread::RunnableP sender) |
| { |
| |
| if (m_data.m_image) |
| { |
| m_manager->m_patterns.push_back(m_data); |
| emit m_manager->patternAdded(); |
| } |
| } |
| |
| |
| |
| |
| |
| CustomStyleManager::CustomStyleManager( |
| const TFilePath &stylesFolder, QString filters, QSize chipSize) |
| : m_stylesFolder(stylesFolder), m_filters(filters), m_chipSize(chipSize) |
| { |
| m_executor.setMaxActiveTasks(1); |
| } |
| |
| |
| |
| int CustomStyleManager::getPatternCount() |
| { |
| return m_patterns.size(); |
| } |
| |
| |
| |
| CustomStyleManager::PatternData CustomStyleManager::getPattern(int index) |
| { |
| return (index < 0 || index >= m_patterns.size()) ? PatternData() : m_patterns[index]; |
| } |
| |
| |
| |
| TFilePath CustomStyleManager::getRootPath() |
| { |
| return ::rootPath; |
| } |
| |
| |
| |
| void CustomStyleManager::setRootPath(const TFilePath &rootPath) |
| { |
| ::rootPath = rootPath; |
| } |
| |
| |
| |
| void CustomStyleManager::loadItems() |
| { |
| |
| const TFilePath &rootFP(getRootPath()); |
| |
| assert(rootFP != TFilePath()); |
| if (rootFP == TFilePath()) |
| return; |
| |
| QDir patternDir(QString::fromStdWString((rootFP + m_stylesFolder).getWideString())); |
| patternDir.setNameFilters(m_filters.split(' ')); |
| |
| |
| TFilePathSet fps; |
| try { |
| TSystem::readDirectory(fps, patternDir); |
| } catch (...) { |
| return; |
| } |
| |
| |
| TFilePathSet newFps; |
| TFilePathSet::iterator it; |
| int i; |
| for (i = 0; i < m_patterns.size(); i++) { |
| PatternData data = m_patterns.at(i); |
| for (it = fps.begin(); it != fps.end(); ++it) { |
| if (data.m_patternName == it->getName() && data.m_isVector == (it->getType() == "pli")) |
| break; |
| } |
| |
| if (it == fps.end()) { |
| m_patterns.removeAt(i); |
| i--; |
| } else |
| fps.erase(it); |
| } |
| |
| |
| for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++) |
| m_executor.addTask(new StyleLoaderTask(this, *it)); |
| } |
| |