Layer* read_layer(std::istream& is, LayerSubObjectsSerializer* subObjects, Sprite* sprite) { uint16_t name_length = read16(is); // Name length std::vector<char> name(name_length+1); if (name_length > 0) { is.read(&name[0], name_length); // Name name[name_length] = 0; } else name[0] = 0; uint32_t flags = read32(is); // Flags uint16_t layer_type = read16(is); // Type base::UniquePtr<Layer> layer; switch (static_cast<ObjectType>(layer_type)) { case ObjectType::LayerImage: { // Create layer layer.reset(new LayerImage(sprite)); // Read cels int cels = read16(is); // Number of cels for (int c=0; c<cels; ++c) { // Read the cel Cel* cel = subObjects->read_cel(is); // Add the cel in the layer static_cast<LayerImage*>(layer.get())->addCel(cel); // Read the cel's image Image* image = subObjects->read_image(is); sprite->stock()->replaceImage(cel->imageIndex(), image); } break; } case ObjectType::LayerFolder: { // Create the layer set layer.reset(new LayerFolder(sprite)); // Number of sub-layers int layers = read16(is); for (int c=0; c<layers; c++) { Layer* child = subObjects->read_layer(is); if (child) static_cast<LayerFolder*>(layer.get())->addLayer(child); else break; } break; } default: throw InvalidLayerType("Invalid layer type found in stream"); } if (layer != NULL) { layer->setName(&name[0]); layer->setFlags(flags); } return layer.release(); }
/** * [working thread] */ virtual void onJob() { UndoTransaction undoTransaction(m_writer.context(), "Sprite Size"); DocumentApi api = m_writer.document()->getApi(); // Get all sprite cels CelList cels; m_sprite->getCels(cels); // For each cel... int progress = 0; for (CelIterator it = cels.begin(); it != cels.end(); ++it, ++progress) { Cel* cel = *it; // Change its location api.setCelPosition(m_sprite, cel, scale_x(cel->x()), scale_y(cel->y())); // Get cel's image Image* image = cel->image(); if (!image) continue; // Resize the image int w = scale_x(image->width()); int h = scale_y(image->height()); Image* new_image = Image::create(image->pixelFormat(), MAX(1, w), MAX(1, h)); doc::algorithm::fixup_image_transparent_colors(image); doc::algorithm::resize_image(image, new_image, m_resize_method, m_sprite->getPalette(cel->frame()), m_sprite->getRgbMap(cel->frame())); api.replaceStockImage(m_sprite, cel->imageIndex(), new_image); jobProgress((float)progress / cels.size()); // cancel all the operation? if (isCanceled()) return; // UndoTransaction destructor will undo all operations } // Resize mask if (m_document->isMaskVisible()) { base::UniquePtr<Image> old_bitmap (crop_image(m_document->mask()->bitmap(), -1, -1, m_document->mask()->bitmap()->width()+2, m_document->mask()->bitmap()->height()+2, 0)); int w = scale_x(old_bitmap->width()); int h = scale_y(old_bitmap->height()); base::UniquePtr<Mask> new_mask(new Mask); new_mask->replace(scale_x(m_document->mask()->bounds().x-1), scale_y(m_document->mask()->bounds().y-1), MAX(1, w), MAX(1, h)); algorithm::resize_image(old_bitmap, new_mask->bitmap(), m_resize_method, m_sprite->getPalette(FrameNumber(0)), // Ignored m_sprite->getRgbMap(FrameNumber(0))); // Ignored // Reshrink new_mask->intersect(new_mask->bounds()); // Copy new mask api.copyToCurrentMask(new_mask); // Regenerate mask m_document->resetTransformation(); m_document->generateMaskBoundaries(); } // resize sprite api.setSpriteSize(m_sprite, m_new_width, m_new_height); // commit changes undoTransaction.commit(); }