void ImageLoader::buildAllIconsAndPutInCache(TXshSimpleLevel *level, std::vector<TFrameId> fids, std::vector<std::string> iconIds, bool cacheImagesAsWell) { if (m_path.getType() != "tlv") return; if (fids.empty() || iconIds.empty()) return; /*- fidとアイコンidの数は同じはず -*/ if ((int)fids.size() != (int)iconIds.size()) return; try { TLevelReaderP lr(m_path); if (!lr) return; for (int i = 0; i < (int)fids.size(); i++) { lr->doReadPalette(false); TImageReaderP ir = lr->getFrameReader(fids[i]); lr->doReadPalette(true); TImageInfo info; TPalette *palette = level->getPalette(); std::string fullImgId = level->getImageId(fids[i]); /*- 画像データも一緒にキャッシュする場合 -*/ if (cacheImagesAsWell) { ir->enable16BitRead(m_64bitCompatible); ir->setShrink(1); TImageP fullImg = ir->load(); if (fullImg) { if (palette) fullImg->setPalette(palette); TImageCache::instance()->add(fullImgId, fullImg, true); setImageInfo(info, fullImg.getPointer()); } } /*- アイコンのロード -*/ TImageP img = ir->loadIcon(); ir->enable16BitRead(false); if (img) { if (palette) img->setPalette(palette); TImageCache::instance()->add(iconIds[i], img, true); } } } catch (...) { return; } }
static void setFrame(QScriptEngine *engine, QScriptValue &level, const TFrameId &fid, const TImageP &drawing) { QScriptValueList args; args << QString::fromStdString(fid.expand()) << Wrapper::create(engine, new Image(drawing.getPointer())); level.property("setFrame").call(level, args); }
void ImagePainter::paintImage(const TImageP &image, const TDimension &imageSize, const TDimension &viewerSize, const TAffine &aff, const VisualSettings &visualSettings, const CompareSettings &compareSettings, const TRect &loadbox) { glDisable(GL_DEPTH_TEST); if (visualSettings.m_drawExternalBG) { glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); } GLenum error = glGetError(); // assert(error==GL_NO_ERROR); if (error != GL_NO_ERROR) { printf("ImagePainter::paintImage() gl_error:%d\n", error); } if (!image) return; TRasterImageP rimg = (TRasterImageP)image; TVectorImageP vimg = (TVectorImageP)image; TToonzImageP timg = (TToonzImageP)image; TRect clipRect(viewerSize); clipRect -= TPoint(viewerSize.lx * 0.5, viewerSize.ly * 0.5); Painter painter(viewerSize, imageSize, aff, image->getPalette(), visualSettings); if (rimg) painter.onRasterImage(rimg.getPointer()); else if (vimg) painter.onVectorImage(vimg.getPointer()); else if (timg) painter.onToonzImage(timg.getPointer()); if (visualSettings.m_blankColor != TPixel::Transparent) { painter.drawBlank(); return; } // if I have a color filter applied using a glmask, , drawing of images must // be done on black bg! if (!vimg) painter.flushRasterImages( loadbox, visualSettings.m_doCompare ? compareSettings.m_compareX : DefaultCompareValue, visualSettings.m_doCompare ? compareSettings.m_compareY : DefaultCompareValue, compareSettings.m_swapCompared); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); if (visualSettings.m_doCompare) drawCompareLines(viewerSize, compareSettings.m_compareX, compareSettings.m_compareY); }
void RasterSelectionTool::draw() { TImageP image = getImage(false); TToonzImageP ti = (TToonzImageP)image; TRasterImageP ri = (TRasterImageP)image; if (!ti && !ri) return; if (m_setSaveboxTool && m_modifySavebox.getValue()) { m_setSaveboxTool->draw(); return; } glPushMatrix(); /*-- フローティング画像の描画 --*/ drawFloatingSelection(); if (m_strokeSelectionType.getValue() == POLYLINE_SELECTION && !m_rasterSelection.isFloating()) drawPolylineSelection(); if (m_rasterSelection.isEmpty()) m_bboxs.clear(); /*-- 選択範囲の変形ハンドルの描画 --*/ if (getBBoxsCount() > 0) drawCommandHandle(image.getPointer()); /*-- 選択範囲の四角形の描画 --*/ if (m_selecting && !m_selectingRect.isEmpty()) drawRectSelection(image.getPointer()); /*-- バウンディングボックスの描画 --*/ /* if(ti) { TRectD saveBox = ToonzImageUtils::convertRasterToWorld(ti->getSavebox(), ti); drawRect(saveBox.enlarge(0.5)*ti->getSubsampling(), TPixel32::Black, 0x5555, true); } */ glPopMatrix(); }
/*-- Paste後のフローティング状態の画像の描画 --*/ void RasterSelectionTool::drawFloatingSelection() { double pixelSize = TTool::getApplication()->getCurrentTool()->getTool()->getPixelSize(); TAffine aff = m_rasterSelection.getTransformation(); glPushMatrix(); tglMultMatrix(aff); //draw m_floatingSelection if (isFloating()) { TRasterP floatingSelection = m_rasterSelection.getFloatingSelection(); TImageP app; if (TRasterCM32P toonzRas = (TRasterCM32P)(floatingSelection)) app = TToonzImageP(toonzRas, toonzRas->getBounds()); if (TRaster32P fullColorRas = (TRaster32P)(floatingSelection)) app = TRasterImageP(fullColorRas); if (TRasterGR8P grRas = (TRasterGR8P)(floatingSelection)) app = TRasterImageP(grRas); app->setPalette(m_rasterSelection.getCurrentImage()->getPalette()); FourPoints points = getBBox() * aff.inv(); TRectD bbox = points.getBox(); TPointD center((bbox.getP00() + bbox.getP11()) * 0.5); if (TToonzImageP ti = (TToonzImageP)app) GLRasterPainter::drawRaster(TTranslation(center), ti, false); if (TRasterImageP ri = (TRasterImageP)app) GLRasterPainter::drawRaster(TTranslation(center), ri, true); } std::vector<TStroke> strokes = m_rasterSelection.getStrokes(); int i; for (i = 0; i < (int)strokes.size(); i++) { TStroke stroke = strokes[i]; glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0xF0F0); tglColor(TPixel32::Black); drawStrokeCenterline(stroke, pixelSize); glDisable(GL_LINE_STIPPLE); } glPopMatrix(); }
void redo() const { TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); TXshCell cell = xsheet->getCell(m_r, m_c); TImageP image = (TRasterImageP)cell.getImage(true); if (!image) return; TRasterP ras = image->raster(); if (!ras) return; onChange(ras, m_threshold, m_softness); TXshSimpleLevel *simpleLevel = cell.getSimpleLevel(); assert(simpleLevel); simpleLevel->touchFrame(cell.getFrameId()); simpleLevel->setDirtyFlag(false); IconGenerator::instance()->invalidate(simpleLevel, cell.getFrameId()); if (m_isLastInBlock) { TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); } }
void undo() const { std::map<TFrameId, QString>::const_iterator it = m_images.begin(); TPalette *palette = m_palette->clone(); m_level->setPalette(palette); vector<TFrameId> fids; for (; it != m_images.end(); ++it) //, ++mit) { QString id = "MergeCmappedUndo" + QString::number(m_mergeCmappedSessionId) + "-" + QString::number(it->first.getNumber()); TImageP img = TImageCache::instance()->get(id, false)->cloneImage(); img->setPalette(palette); m_level->setFrame(it->first, img); fids.push_back(it->first); } removeLevel(m_xl); TApp::instance()->getPaletteController()->getCurrentLevelPalette()->setPalette(palette); m_level->setDirtyFlag(true); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); }
void AntialiasPopup::setCurrentSampleRaster() { TRasterP sampleRas; m_startRas = TRasterP(); TSelection *selection = TApp::instance()->getCurrentSelection()->getSelection(); TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(selection); TFilmstripSelection *filmstripSelection = dynamic_cast<TFilmstripSelection *>(selection); TImageP image; if (cellSelection) { TApp *app = TApp::instance(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TXshCell cell = xsh->getCell(app->getCurrentFrame()->getFrameIndex(), app->getCurrentColumn()->getColumnIndex()); TImageP aux = cell.getImage(true); if (aux) image = aux->cloneImage(); } else if (filmstripSelection) { TApp *app = TApp::instance(); TXshSimpleLevel *simpleLevel = app->getCurrentLevel()->getSimpleLevel(); if (simpleLevel) { TImageP imageAux = simpleLevel->getFrame(app->getCurrentFrame()->getFid(), true); if (imageAux) image = imageAux->cloneImage(); } } if (!image || !(sampleRas = image->raster())) { m_viewer->setImage(TImageP()); m_viewer->update(); m_okBtn->setEnabled(false); return; } m_okBtn->setEnabled(true); m_startRas = sampleRas->clone(); onChange(m_startRas, sampleRas, m_thresholdField->getValue(), m_softnessField->getValue()); m_viewer->setImage(image); m_viewer->update(); }
TRasterP getRaster() const { return m_img->raster(); }
void AntialiasPopup::apply() { TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(TSelection::getCurrent()); int threshold = m_thresholdField->getValue(); int softness = m_softnessField->getValue(); if (cellSelection) { std::set<TImage *> images; int r0, c0, r1, c1; cellSelection->getSelectedCells(r0, c0, r1, c1); TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); bool oneImageChanged = false; int c, r; TUndoManager::manager()->beginBlock(); for (c = c0; c <= c1; c++) for (r = r0; r <= r1; r++) { TXshCell cell = xsheet->getCell(r, c); TImageP image = cell.getImage(true); if (!image) continue; if (images.find(image.getPointer()) != images.end()) continue; TRasterP ras = image->raster(); if (!ras) continue; images.insert(image.getPointer()); oneImageChanged = true; TUndoManager::manager()->add(new TRasterAntialiasUndo(threshold, softness, r, c, ras->clone())); onChange(ras, threshold, softness); TXshSimpleLevel *simpleLevel = cell.getSimpleLevel(); assert(simpleLevel); simpleLevel->touchFrame(cell.getFrameId()); simpleLevel->setDirtyFlag(true); IconGenerator::instance()->invalidate(simpleLevel, cell.getFrameId()); } TUndoManager::manager()->endBlock(); if (oneImageChanged) { close(); return; } } TFilmstripSelection *filmstripSelection = dynamic_cast<TFilmstripSelection *>(TSelection::getCurrent()); if (filmstripSelection) { TXshSimpleLevel *simpleLevel = TApp::instance()->getCurrentLevel()->getSimpleLevel(); if (simpleLevel) { std::set<TFrameId> fids = filmstripSelection->getSelectedFids(); std::set<TFrameId>::iterator it = fids.begin(); bool oneImageChanged = false; for (it; it != fids.end(); it++) { TImageP image = simpleLevel->getFrame(*it, true); if (!image) continue; TRasterP ras = image->raster(); if (!ras) continue; oneImageChanged = true; onChange(ras, threshold, softness); simpleLevel->touchFrame(*it); simpleLevel->setDirtyFlag(true); IconGenerator::instance()->invalidate(simpleLevel, *it); } if (oneImageChanged) { close(); return; } } } DVGui::error(QObject::tr("The current selection is invalid.")); return; }
StylePicker::StylePicker(const TImageP &image) : m_image(image), m_palette(image->getPalette()) { }
QString ImageBuilder::add(const TImageP &img, const TAffine &aff) { if (fabs(aff.det()) < 0.001) return ""; if (m_img && (m_img->getType() != img->getType())) return "Image type mismatch"; if (!m_img && img->getType() != TImage::VECTOR && m_width > 0 && m_height > 0) { TRasterP ras = img->raster()->create(m_width, m_height); if (img->getType() == TImage::RASTER) m_img = TRasterImageP(ras); else if (img->getType() == TImage::TOONZ_RASTER) { m_img = TToonzImageP(ras, ras->getBounds()); m_img->setPalette(img->getPalette()); } else return "Bad image type"; } if (!m_img && aff.isIdentity()) { m_img = img->cloneImage(); } else if (img->getType() == TImage::VECTOR) { // vector image if (!m_img) { // transform TVectorImageP vi = img->cloneImage(); vi->transform(aff); m_img = vi; } else { // merge TVectorImageP up = img; TVectorImageP dn = m_img; dn->mergeImage(up, aff); } } else { if (img->getType() != TImage::TOONZ_RASTER && img->getType() != TImage::RASTER) { // this should not ever happen return "Bad image type"; } TRasterP up = img->raster(); if (!m_img) { // create an empty bg TRasterP ras = up->create(); ras->clear(); if (img->getType() == TImage::TOONZ_RASTER) { TRasterCM32P rasCm = ras; m_img = TToonzImageP(rasCm, TRect(0, 0, ras->getLx() - 1, ras->getLy() - 1)); m_img->setPalette(img->getPalette()); } else { m_img = TRasterImageP(ras); } } TRasterP dn = m_img->raster(); if (aff.isTranslation() && aff.a13 == floor(aff.a13) && aff.a23 == floor(aff.a23)) { // just a integer coord translation TPoint delta = -up->getCenter() + dn->getCenter() + TPoint((int)aff.a13, (int)aff.a23); TRop::over(dn, up, delta); } else { TAffine aff1 = TTranslation(dn->getCenterD()) * aff * TTranslation(-up->getCenterD()); TRop::over(dn, up, aff1, TRop::Mitchell); } } return ""; }
TImageP ImageLoader::build(int imFlags, void *extData) { assert(extData); // Extract external data BuildExtData *data = static_cast<BuildExtData *>(extData); int subsampling = buildSubsampling(imFlags, data); try { // Initialize level reader TLevelReaderP lr(m_path); if (!lr) return TImageP(); // Load info in cases where it's required first lr->doReadPalette(false); if ((m_path.getType() == "pli") || (m_path.getType() == "svg") || (m_path.getType() == "psd")) lr->loadInfo(); lr->doReadPalette(true); // Allow palette loading TImageReaderP ir = lr->getFrameReader(m_fid); bool enable64bit = (imFlags & ImageManager::is64bitEnabled); ir->enable16BitRead(enable64bit); // Set 64-bit loading if required // Load the image TImageP img; if (data->m_icon && m_path.getType() == "tlv") img = ir->loadIcon(); // TODO: Why just in the tlv case?? else { ir->setShrink(subsampling); img = ir->load(); } ir->enable16BitRead(false); if (!img) return img; // There was an error loading the image. TPalette *palette = data->m_sl->getPalette(); if (palette) img->setPalette(palette); if (subsampling > 1) { // Store the subsampling info in the image if (TRasterImageP ri = img) ri->setSubsampling(subsampling); else if (TToonzImageP ti = img) ti->setSubsampling(subsampling); } // In case the image will be cached, store its subsampling and 64 bit compatibility if (!(imFlags & ImageManager::dontPutInCache)) { m_subsampling = subsampling; m_64bitCompatible = data->m_sl->is16BitChannelLevel() ? enable64bit : true; } return img; } catch (...) { return TImageP(); } }
TImage *TTool::touchImage() { if (!m_application) return 0; m_cellsData.clear(); m_isLevelCreated = false; m_isFrameCreated = false; Preferences *pref = Preferences::instance(); bool isAutoCreateEnabled = pref->isAutoCreateEnabled(); bool animationSheetEnabled = pref->isAnimationSheetEnabled(); bool isAutoStretchEnabled = pref->isAutoStretchEnabled(); TFrameHandle *currentFrame = m_application->getCurrentFrame(); TXshLevelHandle *currentLevel = m_application->getCurrentLevel(); if (currentFrame->isEditingLevel()) { // Editing level // no level => return 0 TXshLevel *xl = currentLevel->getLevel(); if (!xl) return 0; TXshSimpleLevel *sl = xl->getSimpleLevel(); if (!sl || sl->isEmpty()) return 0; TFrameId fid = currentFrame->getFid(); TImageP img = sl->getFrame(fid, true); if (!img) { // no drawing found if (sl->isSubsequence() || sl->isReadOnly() || !isAutoCreateEnabled) return 0; // create a new drawing img = sl->createEmptyFrame(); sl->setFrame(fid, img); currentLevel->notifyLevelChange(); m_isFrameCreated = true; } return img.getPointer(); } else { // editing xsheet if (m_application->getCurrentObject()->isSpline()) return 0; TSceneHandle *currentScene = m_application->getCurrentScene(); ToonzScene *scene = currentScene->getScene(); int row = currentFrame->getFrame(); int col = m_application->getCurrentColumn()->getColumnIndex(); if (col < 0) return 0; TXsheetHandle *currentXsheet = m_application->getCurrentXsheet(); TXsheet *xsh = currentXsheet->getXsheet(); if (!xsh) return 0; TXshCell cell = xsh->getCell(row, col); TXshSimpleLevel *sl = cell.getSimpleLevel(); if (sl != 0) { // current cell is not empty if (isAutoCreateEnabled && animationSheetEnabled && row > 0 && xsh->getCell(row - 1, col) == xsh->getCell(row, col)) { // animationSheet is enabled and the current cell is a "hold". We must // create a new drawing. // measure the hold length (starting from the current row) : r0-r1 int r0 = row, r1 = row; if (isAutoStretchEnabled) while (xsh->getCell(r1 + 1, col) == cell) r1++; // find the proper frameid (possibly addisng suffix, in order to avoid a // fid already used) TFrameId fid = getNewFrameId(sl, row); // create the new drawing TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; // insert the drawing in the level sl->setFrame(fid, img); // update the cell cell = TXshCell(sl, fid); // update the xsheet (change the current cell and possibly all the // following "hold") for (int r = r0; r <= r1; r++) xsh->setCell(r, col, cell); // notify currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); m_cellsData.push_back(r0); m_cellsData.push_back(r1); m_cellsData.push_back(0); } // we've found the image. return it. return cell.getImage(true).getPointer(); } // current cell is empty. if (!isAutoCreateEnabled) return 0; // get the column range int r0, r1; xsh->getCellRange(col, r0, r1); if (animationSheetEnabled && r0 <= r1) { // animation sheet enabled and not empty column. We must create a new // drawing in the column level and possibly add "holds" // find the last not-empty cell before the current one (a) and the first // after (b) int a = row - 1, b = row + 1; while (a >= r0 && xsh->getCell(a, col).isEmpty()) a--; while (b <= r1 && xsh->getCell(b, col).isEmpty()) b++; // find the level we must attach to if (a >= r0) { // there is a not-emtpy cell before the current one sl = xsh->getCell(a, col).getSimpleLevel(); } else if (b <= r1) { sl = xsh->getCell(b, col).getSimpleLevel(); } if (sl) { // note: sl should be always !=0 (the column is not empty) // if - for some reason - it is ==0 then we skip to the standard (i.e. // !animationSheetEnabled) beahviour // create the drawing // find the proper frameid (possibly addisng suffix, in order to avoid a // fid already used) TFrameId fid = getNewFrameId(sl, row); // create the new drawing TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; // insert the drawing in the level sl->setFrame(fid, img); // update the cell cell = TXshCell(sl, fid); xsh->setCell(row, col, cell); // create holds if (!isAutoStretchEnabled) { m_cellsData.push_back(row); m_cellsData.push_back(row); m_cellsData.push_back(2); // vuoto => nuovo } else { if (a >= r0) { // create a hold before : [a+1, row-1] TXshCell aCell = xsh->getCell(a, col); for (int i = a + 1; i < row; i++) xsh->setCell(i, col, aCell); m_cellsData.push_back(a + 1); m_cellsData.push_back(row - 1); m_cellsData.push_back(1); // vuoto => vecchio if (b <= r1 && xsh->getCell(b, col).getSimpleLevel() == sl) { // create also a hold after for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell); m_cellsData.push_back(row); m_cellsData.push_back(b - 1); m_cellsData.push_back(2); // vuoto => nuovo } else { m_cellsData.push_back(row); m_cellsData.push_back(row); m_cellsData.push_back(2); // vuoto => nuovo } } else if (b <= r1) { // create a hold after for (int i = row + 1; i < b; i++) xsh->setCell(i, col, cell); m_cellsData.push_back(row); m_cellsData.push_back(b - 1); m_cellsData.push_back(2); // vuoto => nuovo } } } // notify & return currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); return cell.getImage(true).getPointer(); } if (row > 0 && xsh->getCell(row - 1, col).getSimpleLevel() != 0 && !animationSheetEnabled) { sl = xsh->getCell(row - 1, col).getSimpleLevel(); if (sl->getType() != OVL_XSHLEVEL || sl->getPath().getFrame() != TFrameId::NO_FRAME) { // la cella precedente contiene un drawing di un livello. animationSheet // e' disabilitato // creo un nuovo frame currentLevel->setLevel(sl); if (sl->isSubsequence() || sl->isReadOnly()) return 0; TFrameId fid = sl->index2fid(sl->getFrameCount()); TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; sl->setFrame(fid, img); cell = TXshCell(sl, fid); xsh->setCell(row, col, cell); currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); return img.getPointer(); } } // animation sheet disabled or empty column. autoCreate is enabled: we must // create a new level int levelType = pref->getDefLevelType(); TXshLevel *xl = scene->createNewLevel(levelType); sl = xl->getSimpleLevel(); m_isLevelCreated = true; // create the drawing TFrameId fid = animationSheetEnabled ? getNewFrameId(sl, row) : TFrameId(1); TImageP img = sl->createEmptyFrame(); m_isFrameCreated = true; sl->setFrame(fid, img); cell = TXshCell(sl, fid); xsh->setCell(row, col, cell); if (animationSheetEnabled) { m_cellsData.push_back(row); m_cellsData.push_back(row); m_cellsData.push_back(2); // vuoto => nuovo } currentXsheet->notifyXsheetChanged(); currentScene->notifyCastChange(); currentLevel->notifyLevelChange(); return img.getPointer(); } }