From 377482929e4ba78788e7500c0d85142585a01883 Mon Sep 17 00:00:00 2001 From: shun-iwasawa Date: Oct 19 2020 09:01:29 +0000 Subject: fix crash on drawing absent level --- diff --git a/toonz/sources/include/toonz/txshsimplelevel.h b/toonz/sources/include/toonz/txshsimplelevel.h index d502ddb..555099a 100644 --- a/toonz/sources/include/toonz/txshsimplelevel.h +++ b/toonz/sources/include/toonz/txshsimplelevel.h @@ -243,6 +243,10 @@ Editable range is contained in \b m_editableRange. //! and assigns the specified level path. TImageP createEmptyFrame(); + void initializePalette(); + void initializeResolutionAndDpi(const TDimension &dim = TDimension(), + double dpi = 0); + TDimension getResolution(); TPointD getImageDpi(const TFrameId &fid = TFrameId::NO_FRAME, diff --git a/toonz/sources/toonzlib/toonzscene.cpp b/toonz/sources/toonzlib/toonzscene.cpp index 6f66006..3bc0d96 100644 --- a/toonz/sources/toonzlib/toonzscene.cpp +++ b/toonz/sources/toonzlib/toonzscene.cpp @@ -615,7 +615,7 @@ void ToonzScene::save(const TFilePath &fp, TXsheet *subxsh) { if (!os.checkStatus()) throw TException("Could not open temporary save file"); - TXsheet *xsh = subxsh; + TXsheet *xsh = subxsh; if (xsh == 0) xsh = m_childStack->getTopXsheet(); std::map attr; @@ -873,7 +873,7 @@ TXshLevel *ToonzScene::createNewLevel(int type, std::wstring levelName, /*-- LevelSetの中に同じファイルパスのLevelがあるかをチェック --*/ if (type != CHILD_XSHLEVEL && type != PLT_XSHLEVEL) { if (fp.isEmpty()) fp = getDefaultLevelPath(type, levelName); - TFilePath actualFp = decodeFilePath(fp); + TFilePath actualFp = decodeFilePath(fp); if (TSystem::doesExistFileOrLevel( actualFp)) // if(TFileStatus(actualFp).doesExist()) continue; @@ -928,46 +928,8 @@ TXshLevel *ToonzScene::createNewLevel(int type, std::wstring levelName, sl->setPath(fp); sl->setDirtyFlag(true); - if (type == TZP_XSHLEVEL || type == PLI_XSHLEVEL) - sl->setPalette(new TPalette()); - - if (type == OVL_XSHLEVEL) - sl->setPalette(FullColorPalette::instance()->getPalette(this)); - - TPalette *palette = sl->getPalette(); - if (palette && type != OVL_XSHLEVEL) { - palette->setPaletteName(sl->getName()); - palette->setDirtyFlag(true); - } - - if (type == TZP_XSHLEVEL || type == OVL_XSHLEVEL) { - double dpiY = dpi; - sl->getProperties()->setDpiPolicy(LevelProperties::DP_ImageDpi); - if (dim == TDimension()) { - double w, h; - Preferences *pref = Preferences::instance(); - if (pref->isNewLevelSizeToCameraSizeEnabled()) { - TDimensionD camSize = getCurrentCamera()->getSize(); - w = camSize.lx; - h = camSize.ly; - sl->getProperties()->setDpiPolicy(LevelProperties::DP_CustomDpi); - dpi = getCurrentCamera()->getDpi().x; - dpiY = getCurrentCamera()->getDpi().y; - } else { - w = pref->getDefLevelWidth(); - h = pref->getDefLevelHeight(); - dpi = pref->getDefLevelDpi(); - dpiY = dpi; - } - - sl->getProperties()->setImageRes( - TDimension(tround(w * dpi), tround(h * dpiY))); - } else - sl->getProperties()->setImageRes(dim); - - sl->getProperties()->setImageDpi(TPointD(dpi, dpiY)); - sl->getProperties()->setDpi(dpi); - } + sl->initializePalette(); + sl->initializeResolutionAndDpi(); xl = sl; } @@ -1163,7 +1125,7 @@ TXshLevel *ToonzScene::loadLevel(const TFilePath &actualPath, } NameModifier nm(levelName); - levelName = nm.getNext(); + levelName = nm.getNext(); while (m_levelSet->hasLevel(levelName)) levelName = nm.getNext(); // Discriminate sound levels @@ -1213,7 +1175,7 @@ TXshLevel *ToonzScene::loadLevel(const TFilePath &actualPath, const Preferences &prefs = *Preferences::instance(); int formatIdx = prefs.matchLevelFormat( levelPath); // Should I use actualPath here? It's mostly - // irrelevant anyway, it's for old tzp/tzu... + // irrelevant anyway, it's for old tzp/tzu... if (formatIdx >= 0) lp->options() = prefs.levelFormat(formatIdx).m_options; else { @@ -1285,8 +1247,8 @@ TFilePath ToonzScene::decodeFilePath(const TFilePath &path) const { return dir + tail; } if (project) { - h = ::to_string(head.substr(1)); - TFilePath f = project->getFolder(h); + h = ::to_string(head.substr(1)); + TFilePath f = project->getFolder(h); if (f != TFilePath()) s = f.getWideString(); } } @@ -1418,9 +1380,8 @@ TFilePath ToonzScene::getDefaultLevelPath(int levelType, levelPath = TFilePath(levelName + L"..png"); } - if (!isUntitled() && - Preferences::instance()->getPathAliasPriority() == - Preferences::SceneFolderAlias) + if (!isUntitled() && Preferences::instance()->getPathAliasPriority() == + Preferences::SceneFolderAlias) return TFilePath("$scenefolder") + levelPath; std::string folderName = getFolderName(levelType); diff --git a/toonz/sources/toonzlib/txshsimplelevel.cpp b/toonz/sources/toonzlib/txshsimplelevel.cpp index dee5221..6bc50d5 100644 --- a/toonz/sources/toonzlib/txshsimplelevel.cpp +++ b/toonz/sources/toonzlib/txshsimplelevel.cpp @@ -14,6 +14,7 @@ #include "toonz/stage.h" #include "toonz/textureutils.h" #include "toonz/levelset.h" +#include "toonz/tcamera.h" // TnzBase includes #include "tenv.h" @@ -1903,9 +1904,69 @@ void TXshSimpleLevel::invalidateFrame(const TFrameId &fid) { } //----------------------------------------------------------------------------- +// note that the palette will always be replaced by the new one. +void TXshSimpleLevel::initializePalette() { + assert(getScene()); + int type = getType(); + if (type == TZP_XSHLEVEL || type == PLI_XSHLEVEL) setPalette(new TPalette()); + if (type == OVL_XSHLEVEL) + setPalette(FullColorPalette::instance()->getPalette(getScene())); + TPalette *palette = getPalette(); + if (palette && type != OVL_XSHLEVEL) { + palette->setPaletteName(getName()); + palette->setDirtyFlag(true); + } +} + +//----------------------------------------------------------------------------- + +void TXshSimpleLevel::initializeResolutionAndDpi(const TDimension &dim, + double dpi) { + assert(getScene()); + if (getProperties()->getImageRes() != TDimension() && + getProperties()->getDpi() != TPointD()) + return; + + double dpiY = dpi; + getProperties()->setDpiPolicy(LevelProperties::DP_ImageDpi); + if (dim == TDimension()) { + double w, h; + Preferences *pref = Preferences::instance(); + if (pref->isNewLevelSizeToCameraSizeEnabled()) { + TDimensionD camSize = getScene()->getCurrentCamera()->getSize(); + w = camSize.lx; + h = camSize.ly; + getProperties()->setDpiPolicy(LevelProperties::DP_CustomDpi); + dpi = getScene()->getCurrentCamera()->getDpi().x; + dpiY = getScene()->getCurrentCamera()->getDpi().y; + } else { + w = pref->getDefLevelWidth(); + h = pref->getDefLevelHeight(); + dpi = pref->getDefLevelDpi(); + dpiY = dpi; + } + + getProperties()->setImageRes(TDimension(tround(w * dpi), tround(h * dpiY))); + } else + getProperties()->setImageRes(dim); + + getProperties()->setImageDpi(TPointD(dpi, dpiY)); + getProperties()->setDpi(dpi); +} + +//----------------------------------------------------------------------------- // crea un frame con tipo, dimensioni, dpi, ecc. compatibili con il livello TImageP TXshSimpleLevel::createEmptyFrame() { + // In case this is the first frame to be created in this level (i.e. the level + // file was missing when loading resources) initialize the level in the same + // manner as createNewLevel() in order to avoid crash. This can be happened if + // the level was not saved after creating and being placed in the xsheet. + if (isEmpty()) { + initializePalette(); + initializeResolutionAndDpi(); + } + TImageP result; switch (m_type) {