Beispiel #1
0
void Sprite::render(Image* image, int x, int y, FrameNumber frame) const
{
  fill_rect(image, x, y, x+m_width-1, y+m_height-1,
            (m_format == IMAGE_INDEXED ? getTransparentColor(): 0));

  layer_render(getFolder(), image, x, y, frame);
}
Beispiel #2
0
/**
 * Returns a new layer (flat_layer) with all "layer" rendered frame by
 * frame from "frmin" to "frmax" (inclusive).  "layer" can be a set of
 * layers, so the routine flattens all children to an unique output
 * layer.
 *
 * @param dst_sprite The sprite where to put the new flattened layer.
 * @param src_layer Generally a set of layers to be flattened.
 */
LayerImage* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer,
				   int x, int y, int w, int h, int frmin, int frmax)
{
  UniquePtr<LayerImage> flatLayer(new LayerImage(dst_sprite));

  for (int frame=frmin; frame<=frmax; frame++) {
    // Does this frame have cels to render?
    if (has_cels(src_layer, frame)) {
      // Create a new image
      Image* image = image_new(flatLayer->getSprite()->getImgType(), w, h);

      try {
	// Create the new cel for the output layer (add the image to stock too).
	Cel* cel = new Cel(frame, flatLayer->getSprite()->getStock()->addImage(image));
	cel->setPosition(x, y);

	// Clear the image and render this frame.
	image_clear(image, 0);
	layer_render(src_layer, image, -x, -y, frame);
	flatLayer->addCel(cel);
      }
      catch (...) {
	delete image;
	throw;
      }
    }
  }

  return flatLayer.release();
}
Beispiel #3
0
void layer_render(const Layer* layer, Image* image, int x, int y, FrameNumber frame)
{
  if (!layer->isVisible())
    return;

  switch (layer->type()) {

    case ObjectType::LayerImage: {
      const Cel* cel = static_cast<const LayerImage*>(layer)->getCel(frame);
      Image* src_image;

      if (cel) {
        ASSERT((cel->imageIndex() >= 0) &&
               (cel->imageIndex() < layer->sprite()->stock()->size()));

        src_image = cel->image();
        ASSERT(src_image != NULL);

        ASSERT(src_image->maskColor() == layer->sprite()->transparentColor());

        composite_image(image, src_image,
          cel->x() + x,
          cel->y() + y,
          MID(0, cel->opacity(), 255),
          static_cast<const LayerImage*>(layer)->getBlendMode());
      }
      break;
    }

    case ObjectType::LayerFolder: {
      LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin();
      LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd();

      for (; it != end; ++it)
        layer_render(*it, image, x, y, frame);

      break;
    }

  }
}
Beispiel #4
0
void layer_render(const Layer* layer, Image* image, int x, int y, FrameNumber frame)
{
  if (!layer->isReadable())
    return;

  switch (layer->getType()) {

    case GFXOBJ_LAYER_IMAGE: {
      const Cel* cel = static_cast<const LayerImage*>(layer)->getCel(frame);
      Image* src_image;

      if (cel) {
        ASSERT((cel->getImage() >= 0) &&
               (cel->getImage() < layer->getSprite()->getStock()->size()));

        src_image = layer->getSprite()->getStock()->getImage(cel->getImage());
        ASSERT(src_image != NULL);

        src_image->mask_color = layer->getSprite()->getTransparentColor();

        image_merge(image, src_image,
                    cel->getX() + x,
                    cel->getY() + y,
                    MID (0, cel->getOpacity(), 255),
                    static_cast<const LayerImage*>(layer)->getBlendMode());
      }
      break;
    }

    case GFXOBJ_LAYER_FOLDER: {
      LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin();
      LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd();

      for (; it != end; ++it)
        layer_render(*it, image, x, y, frame);

      break;
    }

  }
}
Beispiel #5
0
/** Render a diagram.
 * @param data The diagram to render.
 * @param renderer The renderer to render on.
 * @param update The area that needs updating.
 * @param obj_renderer If non-NULL, an alternative renderer of objects.
 * @param gdata User data passed on to inner calls.
 * @bug Describe obj_renderer better.
 */
void
data_render(DiagramData *data, DiaRenderer *renderer, Rectangle *update,
	    ObjectRenderer obj_renderer,
	    gpointer gdata)
{
  Layer *layer;
  guint i, active_layer;

  if (!renderer->is_interactive) 
    (DIA_RENDERER_GET_CLASS(renderer)->begin_render)(renderer);
  
  for (i=0; i<data->layers->len; i++) {
    layer = (Layer *) g_ptr_array_index(data->layers, i);
    active_layer = (layer == data->active_layer);
    if (layer->visible)
      layer_render(layer, renderer, update, obj_renderer, gdata, active_layer);
  }
  
  if (!renderer->is_interactive) 
    (DIA_RENDERER_GET_CLASS(renderer)->end_render)(renderer);
}
Beispiel #6
0
bool FliFormat::onSave(FileOp* fop)
{
  Sprite* sprite = fop->document->getSprite();
  unsigned char cmap[768];
  unsigned char omap[768];
  s_fli_header fli_header;
  int c, times;
  Image *bmp, *old;
  Palette *pal;

  /* prepare fli header */
  fli_header.filesize = 0;
  fli_header.frames = 0;
  fli_header.width = sprite->getWidth();
  fli_header.height = sprite->getHeight();

  if ((fli_header.width == 320) && (fli_header.height == 200))
    fli_header.magic = HEADER_FLI;
  else
    fli_header.magic = HEADER_FLC;

  fli_header.depth = 8;
  fli_header.flags = 3;
  fli_header.speed = get_time_precision(sprite);
  fli_header.created = 0;
  fli_header.updated = 0;
  fli_header.aspect_x = 1;
  fli_header.aspect_y = 1;
  fli_header.oframe1 = fli_header.oframe2 = 0;

  /* open the file to write in binary mode */
  FileHandle f(fop->filename.c_str(), "wb");

  fseek(f, 128, SEEK_SET);

  /* create the bitmaps */
  bmp = Image::create(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight());
  old = Image::create(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight());
  if ((!bmp) || (!old)) {
    fop_error(fop, "Not enough memory for temporary bitmaps.\n");
    if (bmp) image_free(bmp);
    if (old) image_free(old);
    return false;
  }

  /* write frame by frame */
  for (FrameNumber frpos(0);
       frpos < sprite->getTotalFrames();
       ++frpos) {
    /* get color map */
    pal = sprite->getPalette(frpos);
    for (c=0; c<256; c++) {
      cmap[3*c  ] = _rgba_getr(pal->getEntry(c));
      cmap[3*c+1] = _rgba_getg(pal->getEntry(c));
      cmap[3*c+2] = _rgba_getb(pal->getEntry(c));
    }

    /* render the frame in the bitmap */
    image_clear(bmp, 0);
    layer_render(sprite->getFolder(), bmp, 0, 0, frpos);

    /* how many times this frame should be written to get the same
       time that it has in the sprite */
    times = sprite->getFrameDuration(frpos) / fli_header.speed;

    for (c=0; c<times; c++) {
      /* write this frame */
      if (frpos == 0 && c == 0)
        fli_write_frame(f, &fli_header, NULL, NULL,
                        (unsigned char *)bmp->dat, cmap, W_ALL);
      else
        fli_write_frame(f, &fli_header,
                        (unsigned char *)old->dat, omap,
                        (unsigned char *)bmp->dat, cmap, W_ALL);

      /* update the old image and color-map to the new ones to compare later */
      image_copy(old, bmp, 0, 0);
      memcpy(omap, cmap, 768);
    }

    /* update progress */
    fop_progress(fop, (float)(frpos.next()) / (float)(sprite->getTotalFrames()));
  }

  /* write the header and close the file */
  fli_write_header(f, &fli_header);

  /* destroy the bitmaps */
  image_free(bmp);
  image_free(old);

  return true;
}
Beispiel #7
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 #8
0
static gboolean
export_dxf(DiagramData *data, DiaContext *ctx,
	   const gchar *filename, const gchar *diafilename,
           void* user_data)
{
    DxfRenderer *renderer;
    FILE *file;
    int i;
    Layer *layer;
    gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
    gchar buf2[G_ASCII_DTOSTR_BUF_SIZE];

    file = g_fopen(filename, "w");

    if (file == NULL) {
	dia_context_add_message_with_errno (ctx, errno, _("Can't open output file %s"),
					    dia_context_get_filename(ctx));
	return FALSE;
    }

    renderer = g_object_new(DXF_TYPE_RENDERER, NULL);

    renderer->file = file;

    /* drawing limits */
    fprintf(file, "  0\nSECTION\n  2\nHEADER\n");
    fprintf(file, "  9\n$EXTMIN\n 10\n%s\n 20\n%s\n",
      g_ascii_formatd (buf, sizeof(buf), "%g", data->extents.left),
      g_ascii_formatd (buf2, sizeof(buf2), "%g", -data->extents.bottom));
    fprintf(file, "  9\n$EXTMAX\n 10\n%s\n 20\n%s\n",
      g_ascii_formatd (buf, sizeof(buf), "%g", data->extents.right),
      g_ascii_formatd (buf2, sizeof(buf2), "%g", -data->extents.top));
    fprintf(file, "  0\nENDSEC\n");

    /* write layer description */
    fprintf(file,"  0\nSECTION\n  2\nTABLES\n  0\nTABLE\n");
    /* some dummy entry to make it work for more DXF viewers */
    fprintf(file,"  2\nLAYER\n 70\n255\n");

    for (i=0; i<data->layers->len; i++) {
      layer = (Layer *) g_ptr_array_index(data->layers, i);
      fprintf(file,"  0\nLAYER\n  2\n%s\n",layer->name);
      if(layer->visible)
	fprintf(file," 62\n%d\n",i+1);
      else
        fprintf(file," 62\n%d\n",(-1)*(i+1));
    }
    fprintf(file, "  0\nENDTAB\n  0\nENDSEC\n");

    /* write graphics */
    fprintf(file,"  0\nSECTION\n  2\nENTITIES\n");

    init_attributes(renderer);

    DIA_RENDERER_GET_CLASS(renderer)->begin_render(DIA_RENDERER(renderer), NULL);

    for (i=0; i<data->layers->len; i++) {
        layer = (Layer *) g_ptr_array_index(data->layers, i);
	    renderer->layername = layer->name;
        layer_render(layer, DIA_RENDERER(renderer), NULL, NULL, data, 0);
    }

    DIA_RENDERER_GET_CLASS(renderer)->end_render(DIA_RENDERER(renderer));

    g_object_unref(renderer);

    return TRUE;
}
Beispiel #9
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);
}