Beispiel #1
0
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;
}
Beispiel #4
0
// 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;
}
Beispiel #5
0
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;
    }
  }
}
Beispiel #6
0
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);
}