TEST(File, SeveralSizes) { she::ScopedHandle<she::System> system(she::CreateSystem()); // Register all possible image formats. FileFormatsManager::instance().registerAllFormats(); std::vector<char> fn(256); for (int w=10; w<=10+503*2; w+=503) { for (int h=10; h<=10+503*2; h+=503) { //std::sprintf(&fn[0], "test_%dx%d.ase", w, h); std::sprintf(&fn[0], "test.ase"); { UniquePtr<Document> doc(Document::createBasicDocument(IMAGE_INDEXED, w, h, 256)); doc->setFilename(&fn[0]); // Random pixels LayerImage* layer = dynamic_cast<LayerImage*>(doc->getSprite()->getFolder()->getFirstLayer()); ASSERT_TRUE(layer != NULL); Image* image = doc->getSprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage()); std::srand(w*h); int c = std::rand()%256; for (int y=0; y<h; y++) { for (int x=0; x<w; x++) { image_putpixel_fast<IndexedTraits>(image, x, y, c); if ((std::rand()&4) == 0) c = std::rand()%256; } } save_document(doc); } { UniquePtr<Document> doc(load_document(&fn[0])); ASSERT_EQ(w, doc->getSprite()->getWidth()); ASSERT_EQ(h, doc->getSprite()->getHeight()); // Same random pixels (see the seed) LayerImage* layer = dynamic_cast<LayerImage*>(doc->getSprite()->getFolder()->getFirstLayer()); ASSERT_TRUE(layer != NULL); Image* image = doc->getSprite()->getStock()->getImage(layer->getCel(FrameNumber(0))->getImage()); std::srand(w*h); int c = std::rand()%256; for (int y=0; y<h; y++) { for (int x=0; x<w; x++) { ASSERT_EQ(c, image_getpixel_fast<IndexedTraits>(image, x, y)); if ((std::rand()&4) == 0) c = std::rand()%256; } } } } } }
bool save_palette(const char *filename, Palette* pal) { std::string ext = base::string_to_lower(base::get_file_extension(filename)); bool success = false; if (ext == "col") { success = doc::file::save_col_file(pal, filename); } else if (ext == "gpl") { success = doc::file::save_gpl_file(pal, filename); } else { FileFormat* ff = FileFormatsManager::instance()->getFileFormatByExtension(ext.c_str()); if (ff->support(FILE_SUPPORT_SAVE)) { app::Context tmpContext; doc::Document* doc = tmpContext.documents().add( 16, 16, doc::ColorMode::INDEXED, Palette::MaxColors); Sprite* sprite = doc->sprite(); doc->sprite()->setPalette(pal, false); LayerImage* layer = dynamic_cast<LayerImage*>(sprite->folder()->getFirstLayer()); Image* image = layer->getCel(FrameNumber(0))->image(); int x, y, c; for (y=c=0; y<16; y++) for (x=0; x<16; x++) image->putPixel(x, y, c++); doc->setFilename(filename); success = (save_document(&tmpContext, doc) == 0); doc->close(); delete doc; } } return success; }
// TODO the DocumentRange should be "iteratable" to replace this function CelList get_cels_in_range(Sprite* sprite, const DocumentRange& range) { CelList cels; for (LayerIndex layerIdx = range.layerBegin(); layerIdx <= range.layerEnd(); ++layerIdx) { Layer* layer = sprite->indexToLayer(layerIdx); if (!layer->isImage()) continue; LayerImage* layerImage = static_cast<LayerImage*>(layer); for (FrameNumber frame = range.frameEnd(), begin = range.frameBegin().previous(); frame != begin; frame = frame.previous()) { Cel* cel = layerImage->getCel(frame); if (cel) cels.push_back(cel); } } return cels; }
// Gives to the user the possibility to move the sprite's layer in the // current editor, returns true if the position was changed. int interactive_move_layer(int mode, bool use_undo, int (*callback)()) { Editor* editor = current_editor; Document* document = editor->getDocument(); undo::UndoHistory* undo = document->getUndoHistory(); Sprite* sprite = document->getSprite(); ASSERT(sprite->getCurrentLayer()->is_image()); LayerImage* layer = static_cast<LayerImage*>(sprite->getCurrentLayer()); Cel *cel = layer->getCel(sprite->getCurrentFrame()); int start_x, new_x; int start_y, new_y; int start_b; int ret; int update = false; int quiet_clock = -1; int first_time = true; int begin_x; int begin_y; if (!cel) return false; begin_x = cel->getX(); begin_y = cel->getY(); editor->hideDrawingCursor(); jmouse_set_cursor(JI_CURSOR_MOVE); editor->editor_click_start(mode, &start_x, &start_y, &start_b); do { if (update) { cel->setPosition(begin_x - start_x + new_x, begin_y - start_y + new_y); // Update layer-bounds. editor->invalidate(); // Update status bar. app_get_statusbar()->setStatusText (0, "Pos %3d %3d Offset %3d %3d", (int)cel->getX(), (int)cel->getY(), (int)(cel->getX() - begin_x), (int)(cel->getY() - begin_y)); /* update clock */ quiet_clock = ji_clock; first_time = false; } /* call the user's routine */ if (callback) (*callback)(); /* redraw dirty widgets */ jwidget_flush_redraw(ji_get_default_manager()); jmanager_dispatch_messages(ji_get_default_manager()); gui_feedback(); } while (editor->editor_click(&new_x, &new_y, &update, NULL)); new_x = cel->getX(); new_y = cel->getY(); cel->setPosition(begin_x, begin_y); /* the position was changed */ if (!editor->editor_click_cancel()) { if (use_undo && undo->isEnabled()) { undo->setLabel("Cel Movement"); undo->setModification(undo::ModifyDocument); undo->pushUndoer(new undoers::SetCelPosition(undo->getObjects(), cel)); } cel->setPosition(new_x, new_y); ret = true; } /* the position wasn't changed */ else { ret = false; } /* redraw the sprite in all editors */ update_screen_for_document(document); /* restore the cursor */ editor->showDrawingCursor(); editor->editor_click_done(); return ret; }
void UndoTransaction::flattenLayers(int bgcolor) { Image* cel_image; Cel* cel; int frame; // create a temporary image UniquePtr<Image> image_wrap(Image::create(m_sprite->getPixelFormat(), m_sprite->getWidth(), m_sprite->getHeight())); Image* image = image_wrap.get(); /* get the background layer from the sprite */ LayerImage* background = m_sprite->getBackgroundLayer(); if (!background) { /* if there aren't a background layer we must to create the background */ background = new LayerImage(m_sprite); if (isEnabled()) m_undoHistory->pushUndoer(new undoers::AddLayer(m_undoHistory->getObjects(), m_sprite->getFolder(), background)); m_sprite->getFolder()->add_layer(background); if (isEnabled()) m_undoHistory->pushUndoer(new undoers::MoveLayer(m_undoHistory->getObjects(), background)); background->configureAsBackground(); } /* copy all frames to the background */ for (frame=0; frame<m_sprite->getTotalFrames(); frame++) { /* clear the image and render this frame */ image_clear(image, bgcolor); layer_render(m_sprite->getFolder(), image, 0, 0, frame); cel = background->getCel(frame); if (cel) { cel_image = m_sprite->getStock()->getImage(cel->getImage()); ASSERT(cel_image != NULL); /* we have to save the current state of `cel_image' in the undo */ if (isEnabled()) { Dirty* dirty = new Dirty(cel_image, image); dirty->saveImagePixels(cel_image); m_undoHistory->pushUndoer(new undoers::DirtyArea( m_undoHistory->getObjects(), cel_image, dirty)); delete dirty; } } else { /* if there aren't a cel in this frame in the background, we have to create a copy of the image for the new cel */ cel_image = Image::createCopy(image); /* TODO error handling: if (!cel_image) { ... } */ /* here we create the new cel (with the new image `cel_image') */ cel = new Cel(frame, m_sprite->getStock()->addImage(cel_image)); /* TODO error handling: if (!cel) { ... } */ /* and finally we add the cel in the background */ background->addCel(cel); } image_copy(cel_image, image, 0, 0); } /* select the background */ if (m_sprite->getCurrentLayer() != background) { if (isEnabled()) m_undoHistory->pushUndoer(new undoers::SetCurrentLayer( m_undoHistory->getObjects(), m_sprite)); m_sprite->setCurrentLayer(background); } // Remove old layers. LayerList layers = m_sprite->getFolder()->get_layers_list(); LayerIterator it = layers.begin(); LayerIterator end = layers.end(); for (; it != end; ++it) { if (*it != background) { Layer* old_layer = *it; // Remove the layer if (isEnabled()) m_undoHistory->pushUndoer(new undoers::RemoveLayer(m_undoHistory->getObjects(), old_layer)); m_sprite->getFolder()->remove_layer(old_layer); // Destroy the layer delete old_layer; } } }
void DocumentApi::flattenLayers(Sprite* sprite, int bgcolor) { Image* cel_image; Cel* cel; DocumentUndo* undo = m_document->getUndo(); // Create a temporary image. UniquePtr<Image> image_wrap(Image::create(sprite->getPixelFormat(), sprite->getWidth(), sprite->getHeight())); Image* image = image_wrap.get(); // Get the background layer from the sprite. LayerImage* background = sprite->getBackgroundLayer(); if (!background) { // If there aren't a background layer we must to create the background. background = new LayerImage(sprite); addLayer(sprite->getFolder(), background, NULL); configureLayerAsBackground(background); } // Copy all frames to the background. for (FrameNumber frame(0); frame<sprite->getTotalFrames(); ++frame) { // Clear the image and render this frame. image_clear(image, bgcolor); layer_render(sprite->getFolder(), image, 0, 0, frame); cel = background->getCel(frame); if (cel) { cel_image = sprite->getStock()->getImage(cel->getImage()); ASSERT(cel_image != NULL); // We have to save the current state of `cel_image' in the undo. if (undo->isEnabled()) { Dirty* dirty = new Dirty(cel_image, image); dirty->saveImagePixels(cel_image); m_undoers->pushUndoer(new undoers::DirtyArea( getObjects(), cel_image, dirty)); delete dirty; } } else { // If there aren't a cel in this frame in the background, we // have to create a copy of the image for the new cel. cel_image = Image::createCopy(image); // TODO error handling: if createCopy throws // Here we create the new cel (with the new image `cel_image'). cel = new Cel(frame, sprite->getStock()->addImage(cel_image)); // TODO error handling: if new Cel throws // And finally we add the cel in the background. background->addCel(cel); } image_copy(cel_image, image, 0, 0); } // Delete old layers. LayerList layers = sprite->getFolder()->getLayersList(); LayerIterator it = layers.begin(); LayerIterator end = layers.end(); for (; it != end; ++it) if (*it != background) removeLayer(*it); }