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); }
/** * 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(); }
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; } } }
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; } } }
/** 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); }
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; }
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; } } }
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; }
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); }