|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Toonz includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tlevel_io.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tofflinegl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tropcm.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorrenderdata.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
shun-iwasawa |
c96e49 |
#include "tvectorgl.h"
|
|
justburner |
981d46 |
#include "tcolorstyles.h"
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
// TnzCore includes
|
|
justburner |
981d46 |
#include "tfiletype.h"
|
|
justburner |
981d46 |
#include "tvectorbrushstyle.h"
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
// TnzLib includes
|
|
justburner |
981d46 |
#include "toonz/imagestyles.h"
|
|
justburner |
981d46 |
#include "toonz/toonzfolders.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qdir></qdir>
|
|
Toshihiro Shimizu |
890ddd |
#include <qimage></qimage>
|
|
shun-iwasawa |
c96e49 |
#include <qoffscreensurface></qoffscreensurface>
|
|
shun-iwasawa |
c96e49 |
#include <qthread></qthread>
|
|
shun-iwasawa |
c96e49 |
#include <qguiapplication></qguiapplication>
|
|
shun-iwasawa |
c96e49 |
#include <qopenglcontext></qopenglcontext>
|
|
shun-iwasawa |
c96e49 |
#include <qopenglframebufferobject></qopenglframebufferobject>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stylemanager.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
#include <qvector></qvector>
|
|
justburner |
981d46 |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace stuff
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void convertRaster32ToImage(TRaster32P ras, QImage *image) {
|
|
Shinya Kitaoka |
120a6e |
int lx = ras->getLx();
|
|
Shinya Kitaoka |
120a6e |
int ly = ras->getLy();
|
|
Shinya Kitaoka |
120a6e |
int i, j;
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < lx; i++)
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < ly; j++) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 pix = ras->pixels(ly - 1 - j)[i];
|
|
Shinya Kitaoka |
120a6e |
QRgb value;
|
|
Shinya Kitaoka |
120a6e |
value = qRgba(pix.r, pix.g, pix.b, pix.m);
|
|
Shinya Kitaoka |
120a6e |
image->setPixel(i, j, value);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
QImage rasterToQImage(const TRasterP &ras, bool premultiplied = true,
|
|
justburner |
981d46 |
bool mirrored = true) {
|
|
justburner |
981d46 |
if (TRaster32P ras32 = ras) {
|
|
justburner |
981d46 |
QImage image(ras->getRawData(), ras->getLx(), ras->getLy(),
|
|
justburner |
981d46 |
premultiplied ? QImage::Format_ARGB32_Premultiplied
|
|
justburner |
981d46 |
: QImage::Format_ARGB32);
|
|
justburner |
981d46 |
if (mirrored) return image.mirrored();
|
|
justburner |
981d46 |
return image;
|
|
justburner |
981d46 |
} else if (TRasterGR8P ras8 = ras) {
|
|
justburner |
981d46 |
QImage image(ras->getRawData(), ras->getLx(), ras->getLy(), ras->getWrap(),
|
|
justburner |
981d46 |
QImage::Format_Indexed8);
|
|
justburner |
981d46 |
static QVector<qrgb> colorTable;</qrgb>
|
|
justburner |
981d46 |
if (colorTable.size() == 0) {
|
|
justburner |
981d46 |
int i;
|
|
justburner |
981d46 |
for (i = 0; i < 256; i++) colorTable.append(QColor(i, i, i).rgb());
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
image.setColorTable(colorTable);
|
|
justburner |
981d46 |
if (mirrored) return image.mirrored();
|
|
justburner |
981d46 |
return image;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
return QImage();
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
justburner |
981d46 |
// FavoritesManager implementation
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
FavoritesManager::FavoritesManager() {
|
|
justburner |
981d46 |
m_fpPinsToTop = ToonzFolder::getMyModuleDir() + "pintotopbrushes.txt";
|
|
justburner |
981d46 |
m_xxPinsToTop = false;
|
|
justburner |
981d46 |
loadPinsToTop();
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
FavoritesManager *FavoritesManager::instance() {
|
|
justburner |
981d46 |
static FavoritesManager _instance;
|
|
justburner |
981d46 |
return &_instance;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
bool FavoritesManager::loadPinsToTop() {
|
|
justburner |
981d46 |
if (!TFileStatus(m_fpPinsToTop).doesExist()) return false;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TIStream is(m_fpPinsToTop);
|
|
justburner |
981d46 |
if (!is) throw TException("Can't read XML");
|
|
justburner |
981d46 |
std::string tagName;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
if (!is.matchTag(tagName) || tagName != "PinsToTop") return false;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
m_pinsToTop.clear();
|
|
justburner |
981d46 |
while (!is.matchEndTag()) {
|
|
justburner |
981d46 |
if (!is.matchTag(tagName)) throw TException("Expected tag");
|
|
justburner |
981d46 |
if (tagName == "BrushIdName") {
|
|
justburner |
981d46 |
std::string brushname;
|
|
justburner |
981d46 |
is >> brushname;
|
|
justburner |
981d46 |
m_pinsToTop.push_back(brushname);
|
|
justburner |
981d46 |
if (!is.matchEndTag()) throw TException("Expected end tag");
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
m_xxPinsToTop = false;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
return true;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void FavoritesManager::savePinsToTop() {
|
|
justburner |
981d46 |
if (!m_xxPinsToTop) return;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TOStream os(m_fpPinsToTop);
|
|
justburner |
981d46 |
if (!os) throw TException("Can't write XML");
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
os.openChild("PinsToTop");
|
|
justburner |
981d46 |
for (auto &idname : m_pinsToTop) {
|
|
justburner |
981d46 |
os.openChild("BrushIdName", {});
|
|
justburner |
981d46 |
os << idname;
|
|
justburner |
981d46 |
os.closeChild();
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
os.closeChild();
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
bool FavoritesManager::getPinToTop(std::string idname) const {
|
|
justburner |
981d46 |
return m_pinsToTop.contains(idname);
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void FavoritesManager::setPinToTop(std::string idname, bool state) {
|
|
justburner |
981d46 |
int index = m_pinsToTop.indexOf(idname);
|
|
justburner |
981d46 |
if (state && index == -1) {
|
|
justburner |
981d46 |
m_xxPinsToTop = true;
|
|
justburner |
981d46 |
m_pinsToTop.append(idname);
|
|
justburner |
981d46 |
} else if (!state && index != -1) {
|
|
justburner |
981d46 |
m_xxPinsToTop = true;
|
|
justburner |
981d46 |
m_pinsToTop.removeAll(idname);
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void FavoritesManager::togglePinToTop(std::string idname) {
|
|
justburner |
981d46 |
int index = m_pinsToTop.indexOf(idname);
|
|
justburner |
981d46 |
if (index != -1)
|
|
justburner |
981d46 |
m_pinsToTop.removeAt(index);
|
|
justburner |
981d46 |
else
|
|
justburner |
981d46 |
m_pinsToTop.append(idname);
|
|
justburner |
981d46 |
m_xxPinsToTop = true;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
// BaseStyleManager implementation
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TFilePath BaseStyleManager::s_rootPath;
|
|
justburner |
981d46 |
BaseStyleManager::ChipData BaseStyleManager::s_emptyChipData;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
BaseStyleManager::BaseStyleManager(const TFilePath &stylesFolder,
|
|
justburner |
981d46 |
QString filters, QSize chipSize)
|
|
justburner |
981d46 |
: m_stylesFolder(stylesFolder)
|
|
justburner |
981d46 |
, m_filters(filters)
|
|
justburner |
981d46 |
, m_chipSize(chipSize)
|
|
justburner |
981d46 |
, m_loaded(false)
|
|
justburner |
981d46 |
, m_isIndexed(false) {}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
const BaseStyleManager::ChipData &BaseStyleManager::getData(int index) const {
|
|
justburner |
981d46 |
if (m_isIndexed) {
|
|
justburner |
981d46 |
return (index < 0 || index >= m_indexes.count())
|
|
justburner |
981d46 |
? s_emptyChipData
|
|
justburner |
981d46 |
: m_chips[m_indexes[index]];
|
|
justburner |
981d46 |
} else {
|
|
justburner |
981d46 |
return (index < 0 || index >= m_chips.count()) ? s_emptyChipData
|
|
justburner |
981d46 |
: m_chips[index];
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void BaseStyleManager::applyFilter() {
|
|
justburner |
981d46 |
FavoritesManager *favMan = FavoritesManager::instance();
|
|
justburner |
981d46 |
QList<int> indexes;</int>
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
m_indexes.clear();
|
|
justburner |
981d46 |
int len = m_chips.count();
|
|
justburner |
981d46 |
for (int i = 0; i < len; i++) {
|
|
justburner |
981d46 |
auto &chip = m_chips[i];
|
|
justburner |
981d46 |
if (chip.desc.indexOf(m_searchText, 0, Qt::CaseInsensitive) >= 0) {
|
|
justburner |
981d46 |
if (favMan->getPinToTop(chip.idname)) {
|
|
justburner |
981d46 |
chip.markPinToTop = true;
|
|
justburner |
981d46 |
m_indexes.append(i);
|
|
justburner |
981d46 |
} else {
|
|
justburner |
981d46 |
chip.markPinToTop = false;
|
|
justburner |
981d46 |
indexes.append(i);
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
bool hasPinsToTop = m_indexes.count() > 0;
|
|
justburner |
981d46 |
m_indexes.append(indexes);
|
|
justburner |
981d46 |
m_isIndexed = (m_indexes.count() != len) || hasPinsToTop;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TFilePath BaseStyleManager::getRootPath() { return s_rootPath; }
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void BaseStyleManager::setRootPath(const TFilePath &rootPath) {
|
|
justburner |
981d46 |
s_rootPath = rootPath;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// StyleLoaderTask definition
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class CustomStyleManager::StyleLoaderTask final : public TThread::Runnable {
|
|
Shinya Kitaoka |
120a6e |
CustomStyleManager *m_manager;
|
|
Shinya Kitaoka |
120a6e |
TFilePath m_fp;
|
|
justburner |
981d46 |
ChipData m_data;
|
|
shun-iwasawa |
c96e49 |
std::shared_ptr<qoffscreensurface> m_offScreenSurface;</qoffscreensurface>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
StyleLoaderTask(CustomStyleManager *manager, const TFilePath &fp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void run() override;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void onFinished(TThread::RunnableP sender) override;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
CustomStyleManager::StyleLoaderTask::StyleLoaderTask(
|
|
Shinya Kitaoka |
120a6e |
CustomStyleManager *manager, const TFilePath &fp)
|
|
Shinya Kitaoka |
120a6e |
: m_manager(manager), m_fp(fp) {
|
|
Shinya Kitaoka |
120a6e |
connect(this, SIGNAL(finished(TThread::RunnableP)), this,
|
|
Shinya Kitaoka |
120a6e |
SLOT(onFinished(TThread::RunnableP)));
|
|
shun-iwasawa |
c96e49 |
|
|
shun-iwasawa |
c96e49 |
if (QThread::currentThread() == qGuiApp->thread()) {
|
|
shun-iwasawa |
c96e49 |
m_offScreenSurface.reset(new QOffscreenSurface());
|
|
shun-iwasawa |
c96e49 |
m_offScreenSurface->setFormat(QSurfaceFormat::defaultFormat());
|
|
shun-iwasawa |
c96e49 |
m_offScreenSurface->create();
|
|
shun-iwasawa |
c96e49 |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CustomStyleManager::StyleLoaderTask::run() {
|
|
justburner |
981d46 |
m_data = m_manager->createPattern(m_fp, m_offScreenSurface);
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void CustomStyleManager::StyleLoaderTask::onFinished(
|
|
justburner |
981d46 |
TThread::RunnableP sender) {
|
|
justburner |
981d46 |
// On the main thread...
|
|
justburner |
981d46 |
if (!m_data.image.isNull()) // Everything went ok
|
|
justburner |
981d46 |
{
|
|
justburner |
981d46 |
m_manager->m_chips.append(m_data);
|
|
justburner |
981d46 |
emit m_manager->patternAdded();
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
// CustomStyleManager implementation
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
CustomStyleManager::CustomStyleManager(std::string rasterIdName,
|
|
justburner |
981d46 |
std::string vectorIdName,
|
|
justburner |
981d46 |
const TFilePath &stylesFolder,
|
|
justburner |
981d46 |
QString filters, QSize chipSize)
|
|
justburner |
981d46 |
: BaseStyleManager(stylesFolder, filters, chipSize)
|
|
justburner |
981d46 |
, m_started(false)
|
|
justburner |
981d46 |
, m_rasterIdName(rasterIdName)
|
|
justburner |
981d46 |
, m_vectorIdName(vectorIdName) {
|
|
justburner |
981d46 |
m_executor.setMaxActiveTasks(1);
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void CustomStyleManager::loadItems() {
|
|
justburner |
981d46 |
// Build the folder to be read
|
|
justburner |
981d46 |
const TFilePath &rootFP(getRootPath());
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
assert(rootFP != TFilePath());
|
|
justburner |
981d46 |
if (rootFP == TFilePath()) return;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
QDir patternDir(
|
|
justburner |
981d46 |
QString::fromStdWString((rootFP + m_stylesFolder).getWideString()));
|
|
justburner |
981d46 |
patternDir.setNameFilters(m_filters.split(' '));
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
// Read the said folder
|
|
justburner |
981d46 |
TFilePathSet fps;
|
|
justburner |
981d46 |
try {
|
|
justburner |
981d46 |
TSystem::readDirectory(fps, patternDir);
|
|
justburner |
981d46 |
} catch (...) {
|
|
justburner |
981d46 |
return;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
// Delete patterns no longer in the folder
|
|
justburner |
981d46 |
TFilePathSet newFps;
|
|
justburner |
981d46 |
TFilePathSet::iterator it;
|
|
justburner |
981d46 |
int i;
|
|
justburner |
981d46 |
for (i = 0; i < m_chips.size(); i++) {
|
|
justburner |
981d46 |
ChipData data = m_chips.at(i);
|
|
justburner |
981d46 |
for (it = fps.begin(); it != fps.end(); ++it) {
|
|
shun-iwasawa |
443318 |
bool isVector = (it->getType() == "pli");
|
|
shun-iwasawa |
443318 |
QString name = QString::fromStdWString(it->getWideName());
|
|
justburner |
981d46 |
if (data.name == name && data.isVector == isVector) break;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
if (it == fps.end()) {
|
|
justburner |
981d46 |
m_chips.removeAt(i);
|
|
justburner |
981d46 |
i--;
|
|
justburner |
981d46 |
} else
|
|
justburner |
981d46 |
fps.erase(it); // The style is not new, so don't generate tasks for it
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
// For each (now new) file entry, generate a fetching task
|
|
justburner |
981d46 |
for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++)
|
|
justburner |
981d46 |
m_executor.addTask(new StyleLoaderTask(this, *it));
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
QImage CustomStyleManager::makeIcon(
|
|
justburner |
981d46 |
const TFilePath &path, const QSize &qChipSize,
|
|
justburner |
981d46 |
std::shared_ptr<qoffscreensurface> offsurf) {</qoffscreensurface>
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
// Fetch the level
|
|
justburner |
981d46 |
TLevelReaderP lr(path);
|
|
Shinya Kitaoka |
120a6e |
TLevelP level = lr->loadInfo();
|
|
justburner |
981d46 |
if (!level || level->getFrameCount() == 0) return QImage();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Fetch the image of the first frame in the level
|
|
Shinya Kitaoka |
120a6e |
TLevel::Iterator frameIt = level->begin();
|
|
justburner |
981d46 |
if (frameIt == level->end()) return QImage();
|
|
Shinya Kitaoka |
120a6e |
TImageP img = lr->getFrameReader(frameIt->first)->load();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Process the image
|
|
Shinya Kitaoka |
120a6e |
TDimension chipSize(qChipSize.width(), qChipSize.height());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP vimg = img;
|
|
Shinya Kitaoka |
120a6e |
TRasterImageP rimg = img;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras;
|
|
shun-iwasawa |
c96e49 |
|
|
justburner |
981d46 |
QImage image;
|
|
shun-iwasawa |
c96e49 |
|
|
Shinya Kitaoka |
120a6e |
if (vimg) {
|
|
Shinya Kitaoka |
120a6e |
assert(level->getPalette());
|
|
Shinya Kitaoka |
120a6e |
TPalette *vPalette = level->getPalette();
|
|
Shinya Kitaoka |
120a6e |
assert(vPalette);
|
|
Shinya Kitaoka |
120a6e |
vimg->setPalette(vPalette);
|
|
Shinya Kitaoka |
120a6e |
|
|
manongjohn |
829232 |
#ifdef LINUX
|
|
shun-iwasawa |
84ffc5 |
TOfflineGL *glContext = 0;
|
|
shun-iwasawa |
84ffc5 |
glContext = TOfflineGL::getStock(chipSize);
|
|
shun-iwasawa |
84ffc5 |
glContext->clear(TPixel32::White);
|
|
manongjohn |
829232 |
#else
|
|
shun-iwasawa |
c96e49 |
QOpenGLContext *glContext = new QOpenGLContext();
|
|
shun-iwasawa |
c96e49 |
if (QOpenGLContext::currentContext())
|
|
shun-iwasawa |
c96e49 |
glContext->setShareContext(QOpenGLContext::currentContext());
|
|
shun-iwasawa |
c96e49 |
glContext->setFormat(QSurfaceFormat::defaultFormat());
|
|
shun-iwasawa |
c96e49 |
glContext->create();
|
|
justburner |
981d46 |
glContext->makeCurrent(offsurf.get());
|
|
shun-iwasawa |
c96e49 |
// attaching stencil buffer here as some styles use it
|
|
shun-iwasawa |
c96e49 |
QOpenGLFramebufferObject fb(
|
|
shun-iwasawa |
c96e49 |
chipSize.lx, chipSize.ly,
|
|
shun-iwasawa |
c96e49 |
QOpenGLFramebufferObject::CombinedDepthStencil);
|
|
shun-iwasawa |
c96e49 |
|
|
shun-iwasawa |
c96e49 |
fb.bind();
|
|
shun-iwasawa |
c96e49 |
// Draw
|
|
shun-iwasawa |
c96e49 |
glViewport(0, 0, chipSize.lx, chipSize.ly);
|
|
shun-iwasawa |
c96e49 |
glClearColor(1.0, 1.0, 1.0, 1.0); // clear with white color
|
|
shun-iwasawa |
c96e49 |
glClear(GL_COLOR_BUFFER_BIT);
|
|
shun-iwasawa |
c96e49 |
|
|
shun-iwasawa |
c96e49 |
glMatrixMode(GL_PROJECTION);
|
|
shun-iwasawa |
c96e49 |
glLoadIdentity();
|
|
shun-iwasawa |
c96e49 |
gluOrtho2D(0, chipSize.lx, 0, chipSize.ly);
|
|
shun-iwasawa |
c96e49 |
|
|
shun-iwasawa |
c96e49 |
glMatrixMode(GL_MODELVIEW);
|
|
shun-iwasawa |
c96e49 |
glLoadIdentity();
|
|
manongjohn |
829232 |
#endif
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox = img->getBBox();
|
|
Shinya Kitaoka |
120a6e |
double scx = 0.8 * chipSize.lx / bbox.getLx();
|
|
Shinya Kitaoka |
120a6e |
double scy = 0.8 * chipSize.ly / bbox.getLy();
|
|
Shinya Kitaoka |
120a6e |
double sc = std::min(scx, scy);
|
|
Shinya Kitaoka |
120a6e |
double dx = 0.5 * chipSize.lx;
|
|
Shinya Kitaoka |
120a6e |
double dy = 0.5 * chipSize.ly;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine aff =
|
|
Shinya Kitaoka |
120a6e |
TTranslation(dx, dy) * TScale(sc) *
|
|
Shinya Kitaoka |
120a6e |
TTranslation(-0.5 * (bbox.x0 + bbox.x1), -0.5 * (bbox.y0 + bbox.y1));
|
|
Shinya Kitaoka |
120a6e |
TVectorRenderData rd(aff, chipSize, vPalette, 0, true);
|
|
Shinya Kitaoka |
120a6e |
|
|
manongjohn |
829232 |
#ifdef LINUX
|
|
shun-iwasawa |
84ffc5 |
glContext->draw(img, rd);
|
|
shun-iwasawa |
84ffc5 |
// No need to clone! The received raster already is a copy of the
|
|
shun-iwasawa |
84ffc5 |
// context's buffer
|
|
shun-iwasawa |
84ffc5 |
ras = glContext->getRaster(); //->clone();
|
|
manongjohn |
829232 |
#else
|
|
shun-iwasawa |
c96e49 |
tglDraw(rd, vimg.getPointer());
|
|
shun-iwasawa |
c96e49 |
|
|
justburner |
981d46 |
image = QImage(fb.toImage().scaled(QSize(chipSize.lx, chipSize.ly),
|
|
justburner |
981d46 |
Qt::IgnoreAspectRatio,
|
|
justburner |
981d46 |
Qt::SmoothTransformation));
|
|
shun-iwasawa |
c96e49 |
fb.release();
|
|
shun-iwasawa |
c96e49 |
glContext->deleteLater();
|
|
manongjohn |
829232 |
#endif
|
|
Shinya Kitaoka |
120a6e |
} else if (rimg) {
|
|
Shinya Kitaoka |
120a6e |
TDimension size = rimg->getRaster()->getSize();
|
|
Shinya Kitaoka |
120a6e |
if (size == chipSize)
|
|
Shinya Kitaoka |
120a6e |
ras = rimg->getRaster()->clone(); // Yep, this may be necessary
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TRaster32P rout(chipSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRop::resample(rout, rimg->getRaster(),
|
|
Shinya Kitaoka |
120a6e |
TScale((double)chipSize.lx / size.lx,
|
|
Shinya Kitaoka |
120a6e |
(double)chipSize.ly / size.ly));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRop::addBackground(rout, TPixel::White);
|
|
Shinya Kitaoka |
120a6e |
ras = rout;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
manongjohn |
829232 |
#ifndef LINUX
|
|
justburner |
981d46 |
// image = QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32);
|
|
justburner |
981d46 |
// convertRaster32ToImage(ras, &image);
|
|
justburner |
981d46 |
image = rasterToQImage(ras);
|
|
manongjohn |
829232 |
#endif
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(!"unsupported type for custom styles!");
|
|
Shinya Kitaoka |
120a6e |
|
|
manongjohn |
829232 |
#ifdef LINUX
|
|
justburner |
981d46 |
// image = QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32);
|
|
justburner |
981d46 |
// convertRaster32ToImage(ras, &image);
|
|
justburner |
981d46 |
image = rasterToQImage(ras);
|
|
manongjohn |
829232 |
#endif
|
|
manongjohn |
829232 |
|
|
justburner |
981d46 |
return image;
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
return QImage();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
CustomStyleManager::ChipData CustomStyleManager::createPattern(
|
|
justburner |
981d46 |
const TFilePath &path, std::shared_ptr<qoffscreensurface> offsurf) {</qoffscreensurface>
|
|
justburner |
981d46 |
ChipData data;
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
bool isVector = (path.getType() == "pli" || path.getType() == "svg");
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
// Generate preview
|
|
justburner |
981d46 |
try {
|
|
justburner |
981d46 |
data.image = makeIcon(path, getChipSize(), offsurf);
|
|
justburner |
981d46 |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
if (!data.image.isNull()) {
|
|
justburner |
981d46 |
data.name = QString::fromStdWString(path.getWideName());
|
|
justburner |
981d46 |
data.desc = data.name;
|
|
justburner |
981d46 |
data.isVector = isVector;
|
|
justburner |
981d46 |
if (isVector)
|
|
justburner |
981d46 |
data.idname = m_vectorIdName + data.name.toStdString();
|
|
justburner |
981d46 |
else
|
|
justburner |
981d46 |
data.idname = m_rasterIdName + data.name.toStdString();
|
|
justburner |
981d46 |
data.hash = TColorStyle::generateHash(data.idname);
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
return data;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
justburner |
981d46 |
// TextureStyleManager implementation
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
TextureStyleManager::TextureStyleManager(const TFilePath &stylesFolder,
|
|
justburner |
981d46 |
QSize chipSize)
|
|
justburner |
981d46 |
: BaseStyleManager(stylesFolder, QString(), chipSize) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
void TextureStyleManager::loadTexture(const TFilePath &fp) {
|
|
justburner |
981d46 |
if (fp == TFilePath()) {
|
|
justburner |
981d46 |
TRaster32P ras(25, 25);
|
|
justburner |
981d46 |
TTextureStyle::fillCustomTextureIcon(ras);
|
|
justburner |
981d46 |
// ras->fill(TPixel::Blue);
|
|
justburner |
981d46 |
ChipData customText(
|
|
justburner |
981d46 |
QString(""), QObject::tr("Custom Texture", "TextureStyleChooserPage"),
|
|
justburner |
981d46 |
rasterToQImage(ras), 4, false, ras,
|
|
justburner |
981d46 |
TTextureStyle::staticBrushIdName(L""));
|
|
justburner |
981d46 |
customText.hash = TTextureStyle::generateHash(customText.idname);
|
|
justburner |
981d46 |
m_chips.append(customText);
|
|
justburner |
981d46 |
return;
|
|
justburner |
981d46 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
TRasterP ras;
|
|
justburner |
981d46 |
TImageReader::load(fp, ras);
|
|
justburner |
981d46 |
if (!ras || ras->getLx() < 2 || ras->getLy() < 2) return;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TRaster32P ras32 = ras;
|
|
justburner |
981d46 |
if (!ras32) return;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TDimension d(2, 2);
|
|
justburner |
981d46 |
while (d.lx < 256 && d.lx * 2 <= ras32->getLx()) d.lx *= 2;
|
|
justburner |
981d46 |
while (d.ly < 256 && d.ly * 2 <= ras32->getLy()) d.ly *= 2;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TRaster32P texture;
|
|
justburner |
981d46 |
if (d == ras32->getSize())
|
|
justburner |
981d46 |
texture = ras32;
|
|
justburner |
981d46 |
else {
|
|
justburner |
981d46 |
texture = TRaster32P(d);
|
|
justburner |
981d46 |
TScale sc((double)texture->getLx() / ras32->getLx(),
|
|
justburner |
981d46 |
(double)texture->getLy() / ras32->getLy());
|
|
justburner |
981d46 |
TRop::resample(texture, ras32, sc);
|
|
justburner |
981d46 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
QString name = QString::fromStdWString(fp.getLevelNameW());
|
|
justburner |
981d46 |
ChipData text(name, name, rasterToQImage(ras), 4, false, texture,
|
|
justburner |
981d46 |
TTextureStyle::staticBrushIdName(fp.getLevelNameW()));
|
|
justburner |
981d46 |
text.hash = TTextureStyle::generateHash(text.idname);
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
m_chips.append(text);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
void TextureStyleManager::loadItems() {
|
|
justburner |
981d46 |
m_chips.clear();
|
|
justburner |
981d46 |
if (getRootPath() == TFilePath()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
TFilePath texturePath = getRootPath() + "textures";
|
|
justburner |
981d46 |
TFilePathSet fps;
|
|
justburner |
981d46 |
try {
|
|
justburner |
981d46 |
fps = TSystem::readDirectory(texturePath);
|
|
justburner |
981d46 |
} catch (...) {
|
|
justburner |
981d46 |
return;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
if (fps.empty()) return;
|
|
justburner |
981d46 |
int count = 0;
|
|
justburner |
981d46 |
for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++)
|
|
justburner |
981d46 |
if (TFileType::getInfo(*it) == TFileType::RASTER_IMAGE) {
|
|
justburner |
981d46 |
try {
|
|
justburner |
981d46 |
loadTexture(*it);
|
|
justburner |
981d46 |
++count;
|
|
justburner |
981d46 |
} catch (...) {
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
loadTexture(TFilePath()); // custom texture
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
m_loaded = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
// MyPaintBrushStyleManager implementation
|
|
justburner |
981d46 |
//********************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
981d46 |
MyPaintBrushStyleManager::MyPaintBrushStyleManager(QSize chipSize)
|
|
justburner |
981d46 |
: BaseStyleManager(TFilePath(), QString(), chipSize) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
981d46 |
void MyPaintBrushStyleManager::loadItems() {
|
|
justburner |
981d46 |
m_brushes.clear();
|
|
justburner |
981d46 |
m_chips.clear();
|
|
justburner |
981d46 |
std::set<tfilepath> brushFiles;</tfilepath>
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TFilePathSet dirs = TMyPaintBrushStyle::getBrushesDirs();
|
|
justburner |
981d46 |
for (TFilePathSet::iterator i = dirs.begin(); i != dirs.end(); ++i) {
|
|
justburner |
981d46 |
TFileStatus fs(*i);
|
|
justburner |
981d46 |
if (fs.doesExist() && fs.isDirectory()) {
|
|
justburner |
981d46 |
TFilePathSet files = TSystem::readDirectoryTree(*i, false, true);
|
|
justburner |
981d46 |
for (TFilePathSet::iterator j = files.begin(); j != files.end(); ++j)
|
|
justburner |
981d46 |
if (j->getType() == TMyPaintBrushStyle::getBrushType())
|
|
justburner |
981d46 |
brushFiles.insert(*j - *i);
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
981d46 |
// reserve memory to avoid reallocation
|
|
justburner |
981d46 |
m_brushes.reserve(brushFiles.size());
|
|
justburner |
981d46 |
for (std::set<tfilepath>::iterator i = brushFiles.begin();</tfilepath>
|
|
justburner |
981d46 |
i != brushFiles.end(); ++i) {
|
|
justburner |
981d46 |
TMyPaintBrushStyle style = TMyPaintBrushStyle(*i);
|
|
justburner |
981d46 |
m_brushes.push_back(style);
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
// Generate a QImage preview to draw the chip faster at cost of few memory
|
|
justburner |
981d46 |
QImage previewQImage = rasterToQImage(style.getPreview());
|
|
justburner |
981d46 |
QString stylePath = style.getPath().getQString();
|
|
justburner |
981d46 |
m_chips.append(ChipData(stylePath, stylePath, previewQImage, 4001, false,
|
|
justburner |
981d46 |
TRasterP(), style.getBrushIdName(),
|
|
justburner |
981d46 |
style.getBrushIdHash()));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
981d46 |
m_loaded = true;
|
|
justburner |
981d46 |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
// SpecialStyleManager implementation
|
|
justburner |
981d46 |
//********************************************************************************
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
SpecialStyleManager::SpecialStyleManager(QSize chipSize)
|
|
justburner |
981d46 |
: BaseStyleManager(TFilePath(), QString(), chipSize) {}
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
//-----------------------------------------------------------------------------
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
void SpecialStyleManager::loadItems() {
|
|
justburner |
981d46 |
m_chips.clear();
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
std::vector<int> tags;</int>
|
|
justburner |
981d46 |
TColorStyle::getAllTags(tags);
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
int chipCount = 0;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
for (int j = 0; j < (int)tags.size(); j++) {
|
|
justburner |
981d46 |
int tagId = tags[j];
|
|
justburner |
981d46 |
if (tagId == 3 || // solid color
|
|
justburner |
981d46 |
tagId == 4 || // texture
|
|
justburner |
981d46 |
tagId == 100 || // obsolete imagepattern id
|
|
justburner |
981d46 |
tagId == 2000 || // imagepattern
|
|
justburner |
981d46 |
tagId == 2800 || // imagepattern
|
|
justburner |
981d46 |
tagId == 2001 || // cleanup
|
|
justburner |
981d46 |
tagId == 2002 || // black cleanup
|
|
justburner |
981d46 |
tagId == 3000 || // vector brush
|
|
justburner |
981d46 |
tagId == 4001 // mypaint brush
|
|
justburner |
981d46 |
)
|
|
justburner |
981d46 |
continue;
|
|
justburner |
981d46 |
|
|
justburner |
981d46 |
TColorStyle *style = TColorStyle::create(tagId);
|
|
justburner |
981d46 |
if (style->isRasterStyle()) {
|
|
justburner |
981d46 |
delete style;
|
|
justburner |
981d46 |
continue;
|
|
justburner |
981d46 |
}
|
|
justburner |
981d46 |
TDimension chipSize(getChipSize().width(), getChipSize().height());
|
|
justburner |
981d46 |
// QImage *image = new QImage(chipSize.lx, chipSize.ly,
|
|
justburner |
981d46 |
// QImage::Format_RGB32); convertRaster32ToImage(style->getIcon(chipSize),
|
|
justburner |
981d46 |
// image);
|
|
justburner |
981d46 |
TRaster32P raster = style->getIcon(chipSize);
|
|
justburner |
981d46 |
ChipData chip(style->getDescription(), style->getDescription(),
|
|
justburner |
981d46 |
rasterToQImage(raster), tagId, true, raster,
|
|
justburner |
981d46 |
style->getBrushIdName(), style->getBrushIdHash());
|
|
justburner |
981d46 |
m_chips.append(chip);
|
|
justburner |
981d46 |
delete style;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
981d46 |
m_loaded = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|