本文整理汇总了C++中DocumentApi类的典型用法代码示例。如果您正苦于以下问题:C++ DocumentApi类的具体用法?C++ DocumentApi怎么用?C++ DocumentApi使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了DocumentApi类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: writer
void RemoveFrameCommand::onExecute(Context* context)
{
ContextWriter writer(context);
Document* document(writer.document());
Sprite* sprite(writer.sprite());
{
Transaction transaction(writer.context(), "Remove Frame");
DocumentApi api = document->getApi(transaction);
// TODO the range of selected frames should be in doc::Site.
auto range = App::instance()->timeline()->range();
if (range.enabled()) {
for (frame_t frame = range.frameEnd(),
begin = range.frameBegin()-1;
frame != begin;
--frame) {
api.removeFrame(sprite, frame);
}
}
else {
api.removeFrame(sprite, writer.frame());
}
transaction.commit();
}
update_screen_for_document(document);
}
示例2: reader
void CanvasSizeCommand::onExecute(Context* context)
{
const ContextReader reader(context);
const Sprite* sprite(reader.sprite());
if (context->isUiAvailable()) {
// load the window widget
base::UniquePtr<CanvasSizeWindow> window(new CanvasSizeWindow(0, 0, 0, 0));
window->remapWindow();
window->centerWindow();
load_window_pos(window, "CanvasSize");
window->setVisible(true);
window->openWindowInForeground();
save_window_pos(window, "CanvasSize");
if (!window->pressedOk())
return;
m_left = window->getLeft();
m_right = window->getRight();
m_top = window->getTop();
m_bottom = window->getBottom();
}
// Resize canvas
int x1 = -m_left;
int y1 = -m_top;
int x2 = sprite->width() + m_right;
int y2 = sprite->height() + m_bottom;
if (x2 <= x1) x2 = x1+1;
if (y2 <= y1) y2 = y1+1;
{
ContextWriter writer(reader);
Document* document = writer.document();
Sprite* sprite = writer.sprite();
UndoTransaction undoTransaction(writer.context(), "Canvas Size");
DocumentApi api = document->getApi();
raster::color_t bgcolor = color_utils::color_for_target(
context->settings()->getBgColor(),
ColorTarget(
ColorTarget::BackgroundLayer,
sprite->pixelFormat(),
sprite->transparentColor()));
api.cropSprite(sprite, gfx::Rect(x1, y1, x2-x1, y2-y1), bgcolor);
undoTransaction.commit();
document->generateMaskBoundaries();
update_screen_for_document(document);
}
}
示例3: reverse_frames
void reverse_frames(Document* doc, const DocumentRange& range)
{
const app::Context* context = static_cast<app::Context*>(doc->context());
const ContextReader reader(context);
ContextWriter writer(reader);
Transaction transaction(writer.context(), "Reverse Frames");
DocumentApi api = doc->getApi(transaction);
Sprite* sprite = doc->sprite();
frame_t frameBegin, frameEnd;
int layerBegin, layerEnd;
bool moveFrames = false;
switch (range.type()) {
case DocumentRange::kCels:
frameBegin = range.frameBegin();
frameEnd = range.frameEnd();
layerBegin = range.layerBegin();
layerEnd = range.layerEnd() + 1;
break;
case DocumentRange::kFrames:
frameBegin = range.frameBegin();
frameEnd = range.frameEnd();
moveFrames = true;
break;
case DocumentRange::kLayers:
frameBegin = frame_t(0);
frameEnd = sprite->totalFrames()-1;
layerBegin = range.layerBegin();
layerEnd = range.layerEnd() + 1;
break;
}
if (moveFrames) {
for (frame_t frameRev = frameEnd+1;
frameRev > frameBegin;
--frameRev) {
api.moveFrame(sprite, frameBegin, frameRev);
}
}
else {
std::vector<Layer*> layers;
sprite->getLayersList(layers);
for (int layerIdx = layerBegin; layerIdx != layerEnd; ++layerIdx) {
for (frame_t frame = frameBegin,
frameRev = frameEnd;
frame != (frameBegin+frameEnd)/2+1;
++frame, --frameRev) {
LayerImage* layer = static_cast<LayerImage*>(layers[layerIdx]);
api.swapCel(layer, frame, frameRev);
}
}
}
transaction.commit();
}
示例4: writer
bool MovingCelState::onMouseUp(Editor* editor, MouseMessage* msg)
{
Document* document = editor->document();
// Here we put back the cel into its original coordinate (so we can
// add an undoer before).
if (m_celOffset != gfx::Point(0, 0)) {
// Put the cels in the original position.
for (size_t i=0; i<m_celList.size(); ++i) {
Cel* cel = m_celList[i];
const gfx::Point& celStart = m_celStarts[i];
cel->setPosition(celStart);
}
// If the user didn't cancel the operation...
if (!m_canceled) {
ContextWriter writer(UIContext::instance(), 500);
Transaction transaction(writer.context(), "Cel Movement", ModifyDocument);
DocumentApi api = document->getApi(transaction);
// And now we move the cel (or all selected range) to the new position.
for (Cel* cel : m_celList) {
api.setCelPosition(writer.sprite(), cel,
cel->x() + m_celOffset.x,
cel->y() + m_celOffset.y);
}
// Move selection if it was visible
if (m_maskVisible)
api.setMaskPosition(document->mask()->bounds().x + m_celOffset.x,
document->mask()->bounds().y + m_celOffset.y);
transaction.commit();
}
// Redraw all editors. We've to notify all views about this
// general update because MovingCelState::onMouseMove() redraws
// only the cels in the current editor. And at this point we'd
// like to update all the editors.
document->notifyGeneralUpdate();
}
// Restore the mask visibility.
if (m_maskVisible) {
document->setMaskVisible(m_maskVisible);
document->generateMaskBoundaries();
}
editor->backToPreviousState();
editor->releaseMouse();
return true;
}
示例5: writer
void RemoveLayerCommand::onExecute(Context* context)
{
std::string layerName;
ContextWriter writer(context);
Document* document(writer.document());
Sprite* sprite(writer.sprite());
{
Transaction transaction(writer.context(), "Remove Layer");
DocumentApi api = document->getApi(transaction);
const Site* site = writer.site();
if (site->inTimeline() &&
!site->selectedLayers().empty()) {
SelectedLayers selLayers = site->selectedLayers();
selLayers.removeChildrenIfParentIsSelected();
layer_t deletedTopLevelLayers = 0;
for (Layer* layer : selLayers) {
if (layer->parent() == sprite->root())
++deletedTopLevelLayers;
}
if (deletedTopLevelLayers == sprite->root()->layersCount()) {
ui::Alert::show("Error<<You cannot delete all layers.||&OK");
return;
}
for (Layer* layer : selLayers) {
api.removeLayer(layer);
}
}
else {
if (sprite->allLayersCount() == 1) {
ui::Alert::show("Error<<You cannot delete the last layer.||&OK");
return;
}
Layer* layer = writer.layer();
layerName = layer->name();
api.removeLayer(layer);
}
transaction.commit();
}
update_screen_for_document(document);
StatusBar::instance()->invalidate();
if (!layerName.empty())
StatusBar::instance()->showTip(1000, "Layer '%s' removed", layerName.c_str());
else
StatusBar::instance()->showTip(1000, "Layers removed");
}
示例6: writer
void NewLayerCommand::onExecute(Context* context)
{
ContextWriter writer(context);
Document* document(writer.document());
Sprite* sprite(writer.sprite());
std::string name;
// Default name (m_name is a name specified in params)
if (!m_name.empty())
name = m_name;
else
name = get_unique_layer_name(sprite);
// If params specify to ask the user about the name...
if (m_ask) {
// We open the window to ask the name
base::UniquePtr<Window> window(app::load_widget<Window>("new_layer.xml", "new_layer"));
Widget* name_widget = app::find_widget<Widget>(window, "name");
name_widget->setText(name.c_str());
name_widget->setMinSize(gfx::Size(128, 0));
window->openWindowInForeground();
if (window->closer() != window->findChild("ok"))
return;
name = window->findChild("name")->text();
}
Layer* activeLayer = writer.layer();
Layer* layer;
{
Transaction transaction(writer.context(), "New Layer");
DocumentApi api = document->getApi(transaction);
layer = api.newLayer(sprite, name);
// If "top" parameter is false, create the layer above the active
// one.
if (activeLayer && !m_top)
api.restackLayerAfter(layer, activeLayer);
transaction.commit();
}
update_screen_for_document(document);
StatusBar::instance()->invalidate();
StatusBar::instance()->showTip(1000, "Layer `%s' created", name.c_str());
App::instance()->getMainWindow()->popTimeline();
}
示例7: onJob
/**
* [working thread]
*/
virtual void onJob()
{
UndoTransaction undoTransaction(m_writer.context(), "Rotate Canvas");
DocumentApi api = m_document->getApi();
// get all sprite cels
CelList cels;
m_sprite->getCels(cels);
// for each cel...
for (CelIterator it = cels.begin(); it != cels.end(); ++it) {
Cel* cel = *it;
Image* image = m_sprite->getStock()->getImage(cel->getImage());
// change it location
switch (m_angle) {
case 180:
api.setCelPosition(m_sprite, cel,
m_sprite->getWidth() - cel->getX() - image->getWidth(),
m_sprite->getHeight() - cel->getY() - image->getHeight());
break;
case 90:
api.setCelPosition(m_sprite, cel,
m_sprite->getHeight() - cel->getY() - image->getHeight(),
cel->getX());
break;
case -90:
api.setCelPosition(m_sprite, cel,
cel->getY(),
m_sprite->getWidth() - cel->getX() - image->getWidth());
break;
}
}
// for each stock's image
for (int i=0; i<m_sprite->getStock()->size(); ++i) {
Image* image = m_sprite->getStock()->getImage(i);
if (!image)
continue;
// rotate the image
Image* new_image = Image::create(image->getPixelFormat(),
m_angle == 180 ? image->getWidth(): image->getHeight(),
m_angle == 180 ? image->getHeight(): image->getWidth());
raster::rotate_image(image, new_image, m_angle);
api.replaceStockImage(m_sprite, i, new_image);
jobProgress((float)i / m_sprite->getStock()->size());
// cancel all the operation?
if (isCanceled())
return; // UndoTransaction destructor will undo all operations
}
// rotate mask
if (m_document->isMaskVisible()) {
Mask* origMask = m_document->getMask();
base::UniquePtr<Mask> new_mask(new Mask());
const gfx::Rect& origBounds = origMask->getBounds();
int x = 0, y = 0;
switch (m_angle) {
case 180:
x = m_sprite->getWidth() - origBounds.x - origBounds.w;
y = m_sprite->getHeight() - origBounds.y - origBounds.h;
break;
case 90:
x = m_sprite->getHeight() - origBounds.y - origBounds.h;
y = origBounds.x;
break;
case -90:
x = origBounds.y;
y = m_sprite->getWidth() - origBounds.x - origBounds.w;
break;
}
// create the new rotated mask
new_mask->replace(x, y,
m_angle == 180 ? origBounds.w: origBounds.h,
m_angle == 180 ? origBounds.h: origBounds.w);
raster::rotate_image(origMask->getBitmap(), new_mask->getBitmap(), m_angle);
// Copy new mask
api.copyToCurrentMask(new_mask);
// Regenerate mask
m_document->resetTransformation();
m_document->generateMaskBoundaries();
}
// change the sprite's size
if (m_angle != 180)
api.setSpriteSize(m_sprite, m_sprite->getHeight(), m_sprite->getWidth());
// commit changes
undoTransaction.commit();
//.........这里部分代码省略.........
示例8: reader
void SpritePropertiesCommand::onExecute(Context* context)
{
std::string imgtype_text;
char buf[256];
ColorButton* color_button = NULL;
// Load the window widget
app::gen::SpriteProperties window;
// Get sprite properties and fill frame fields
{
const ContextReader reader(context);
const Document* document(reader.document());
const Sprite* sprite(reader.sprite());
// Update widgets values
switch (sprite->pixelFormat()) {
case IMAGE_RGB:
imgtype_text = "RGB";
break;
case IMAGE_GRAYSCALE:
imgtype_text = "Grayscale";
break;
case IMAGE_INDEXED:
std::sprintf(buf, "Indexed (%d colors)", sprite->palette(0)->size());
imgtype_text = buf;
break;
default:
ASSERT(false);
imgtype_text = "Unknown";
break;
}
// Filename
window.name()->setText(document->filename());
// Color mode
window.type()->setText(imgtype_text.c_str());
// Sprite size (width and height)
window.size()->setTextf(
"%dx%d (%s)",
sprite->width(),
sprite->height(),
base::get_pretty_memory_size(sprite->getMemSize()).c_str());
// How many frames
window.frames()->setTextf("%d", (int)sprite->totalFrames());
if (sprite->pixelFormat() == IMAGE_INDEXED) {
color_button = new ColorButton(app::Color::fromIndex(sprite->transparentColor()),
IMAGE_INDEXED);
window.transparentColorPlaceholder()->addChild(color_button);
}
else {
window.transparentColorPlaceholder()->addChild(new Label("(only for indexed images)"));
}
}
window.remapWindow();
window.centerWindow();
load_window_pos(&window, "SpriteProperties");
window.setVisible(true);
window.openWindowInForeground();
if (window.closer() == window.ok()) {
if (color_button) {
ContextWriter writer(context);
Sprite* sprite(writer.sprite());
// If the transparent color index has changed, we update the
// property in the sprite.
int index = color_button->getColor().getIndex();
if (color_t(index) != sprite->transparentColor()) {
Transaction transaction(writer.context(), "Set Transparent Color");
DocumentApi api = writer.document()->getApi(transaction);
api.setSpriteTransparentColor(sprite, index);
transaction.commit();
update_screen_for_document(writer.document());
}
}
}
save_window_pos(&window, "SpriteProperties");
}
示例9: drop_range_op
static DocumentRange drop_range_op(
Document* doc, Op op, const DocumentRange& from,
DocumentRangePlace place, const DocumentRange& to)
{
if (place != kDocumentRangeBefore &&
place != kDocumentRangeAfter) {
ASSERT(false);
throw std::invalid_argument("Invalid 'place' argument");
}
Sprite* sprite = doc->sprite();
// Check noop/trivial/do nothing cases, i.e., move a range to the same place.
// Also check invalid cases, like moving a Background layer.
switch (from.type()) {
case DocumentRange::kCels:
if (from == to)
return from;
break;
case DocumentRange::kFrames:
if (op == Move) {
if ((to.frameBegin() >= from.frameBegin() && to.frameEnd() <= from.frameEnd()) ||
(place == kDocumentRangeBefore && to.frameBegin() == from.frameEnd()+1) ||
(place == kDocumentRangeAfter && to.frameEnd() == from.frameBegin()-1))
return from;
}
break;
case DocumentRange::kLayers:
if (op == Move) {
if ((to.layerBegin() >= from.layerBegin() && to.layerEnd() <= from.layerEnd()) ||
(place == kDocumentRangeBefore && to.layerBegin() == from.layerEnd()+1) ||
(place == kDocumentRangeAfter && to.layerEnd() == from.layerBegin()-1))
return from;
// We cannot move the background
for (LayerIndex i = from.layerBegin(); i <= from.layerEnd(); ++i)
if (sprite->indexToLayer(i)->isBackground())
throw std::runtime_error("The background layer cannot be moved");
// Before background
if (place == kDocumentRangeBefore) {
Layer* background = sprite->indexToLayer(to.layerBegin());
if (background && background->isBackground())
throw std::runtime_error("You cannot move something below the background layer");
}
}
break;
}
const char* undoLabel = NULL;
switch (op) {
case Move: undoLabel = "Move Range"; break;
case Copy: undoLabel = "Copy Range"; break;
default:
ASSERT(false);
throw std::invalid_argument("Invalid 'op' argument");
}
DocumentRange resultRange;
{
const app::Context* context = static_cast<app::Context*>(doc->context());
const ContextReader reader(context);
ContextWriter writer(reader);
Transaction transaction(writer.context(), undoLabel, ModifyDocument);
DocumentApi api = doc->getApi(transaction);
// TODO Try to add the range with just one call to DocumentApi
// methods, to avoid generating a lot of SetCelFrame undoers (see
// DocumentApi::setCelFramePosition).
switch (from.type()) {
case DocumentRange::kCels:
{
std::vector<Layer*> layers;
sprite->getLayersList(layers);
int srcLayerBegin, srcLayerStep, srcLayerEnd;
int dstLayerBegin, dstLayerStep;
frame_t srcFrameBegin, srcFrameStep, srcFrameEnd;
frame_t dstFrameBegin, dstFrameStep;
if (to.layerBegin() <= from.layerBegin()) {
srcLayerBegin = from.layerBegin();
srcLayerStep = 1;
srcLayerEnd = from.layerEnd()+1;
dstLayerBegin = to.layerBegin();
dstLayerStep = 1;
}
else {
srcLayerBegin = from.layerEnd();
srcLayerStep = -1;
srcLayerEnd = from.layerBegin()-1;
dstLayerBegin = to.layerEnd();
dstLayerStep = -1;
}
if (to.frameBegin() <= from.frameBegin()) {
srcFrameBegin = from.frameBegin();
srcFrameStep = frame_t(1);
//.........这里部分代码省略.........
示例10: onJob
// [working thread]
void onJob() override {
DocumentApi api = writer().document()->getApi(transaction());
int cels_count = 0;
for (Cel* cel : sprite()->uniqueCels()) { // TODO add size() member function to CelsRange
(void)cel;
++cels_count;
}
// For each cel...
int progress = 0;
for (Cel* cel : sprite()->uniqueCels()) {
// Get cel's image
Image* image = cel->image();
if (image && !cel->link()) {
// Resize the cel bounds only if it's from a reference layer
if (cel->layer()->isReference()) {
gfx::RectF newBounds = scale_rect<double>(cel->boundsF());
transaction().execute(new cmd::SetCelBoundsF(cel, newBounds));
}
else {
// Change its location
api.setCelPosition(sprite(), cel, scale_x(cel->x()), scale_y(cel->y()));
// Resize the image
int w = scale_x(image->width());
int h = scale_y(image->height());
ImageRef new_image(Image::create(image->pixelFormat(), MAX(1, w), MAX(1, h)));
new_image->setMaskColor(image->maskColor());
doc::algorithm::fixup_image_transparent_colors(image);
doc::algorithm::resize_image(
image, new_image.get(),
m_resize_method,
sprite()->palette(cel->frame()),
sprite()->rgbMap(cel->frame()),
(cel->layer()->isBackground() ? -1: sprite()->transparentColor()));
api.replaceImage(sprite(), cel->imageRef(), new_image);
}
}
jobProgress((float)progress / cels_count);
++progress;
// Cancel all the operation?
if (isCanceled())
return; // Transaction destructor will undo all operations
}
// Resize mask
if (document()->isMaskVisible()) {
ImageRef old_bitmap
(crop_image(document()->mask()->bitmap(), -1, -1,
document()->mask()->bitmap()->width()+2,
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(
gfx::Rect(
scale_x(document()->mask()->bounds().x-1),
scale_y(document()->mask()->bounds().y-1), MAX(1, w), MAX(1, h)));
algorithm::resize_image(
old_bitmap.get(), new_mask->bitmap(),
m_resize_method,
sprite()->palette(0), // Ignored
sprite()->rgbMap(0), // Ignored
-1); // Ignored
// Reshrink
new_mask->intersect(new_mask->bounds());
// Copy new mask
api.copyToCurrentMask(new_mask);
// Regenerate mask
document()->resetTransformation();
document()->generateMaskBoundaries();
}
// Resize slices
for (auto& slice : sprite()->slices()) {
for (auto& k : *slice) {
const SliceKey& key = *k.value();
if (key.isEmpty())
continue;
SliceKey newKey = key;
newKey.setBounds(scale_rect(newKey.bounds()));
if (newKey.hasCenter())
newKey.setCenter(scale_rect(newKey.center()));
if (newKey.hasPivot())
newKey.setPivot(gfx::Point(scale_x(newKey.pivot().x),
scale_y(newKey.pivot().y)));
//.........这里部分代码省略.........
示例11: window
void ImportSpriteSheetCommand::onExecute(Context* context)
{
ImportSpriteSheetWindow window(context);
retry:;
window.openWindowInForeground();
if (!window.ok())
return;
Document* document = window.document();
DocumentPreferences* docPref = window.docPref();
gfx::Rect frameBounds = window.frameBounds();
// The user don't select a sheet yet.
if (!document) {
Alert::show("Import Sprite Sheet<<Select a sprite first.||&Close");
goto retry;
}
// The list of frames imported from the sheet
std::vector<ImageRef> animation;
try {
Sprite* sprite = document->sprite();
frame_t currentFrame = context->activeSite().frame();
render::Render render;
// As first step, we cut each tile and add them into "animation" list.
for (int y=frameBounds.y; y<sprite->height(); y += frameBounds.h) {
for (int x=frameBounds.x; x<sprite->width(); x += frameBounds.w) {
ImageRef resultImage(
Image::create(sprite->pixelFormat(), frameBounds.w, frameBounds.h));
// Render the portion of sheet.
render.renderSprite(resultImage.get(), sprite, currentFrame,
gfx::Clip(0, 0, x, y, frameBounds.w, frameBounds.h));
animation.push_back(resultImage);
}
}
if (animation.size() == 0) {
Alert::show("Import Sprite Sheet"
"<<The specified rectangle does not create any tile."
"<<Select a rectangle inside the sprite region."
"||&OK");
return;
}
// The following steps modify the sprite, so we wrap all
// operations in a undo-transaction.
ContextWriter writer(context);
Transaction transaction(writer.context(), "Import Sprite Sheet", ModifyDocument);
DocumentApi api = document->getApi(transaction);
// Add the layer in the sprite.
LayerImage* resultLayer = api.newLayer(sprite);
// Add all frames+cels to the new layer
for (size_t i=0; i<animation.size(); ++i) {
// Create the cel.
base::UniquePtr<Cel> resultCel(new Cel(frame_t(i), animation[i]));
// Add the cel in the layer.
api.addCel(resultLayer, resultCel);
resultCel.release();
}
// Copy the list of layers (because we will modify it in the iteration).
LayerList layers = sprite->folder()->getLayersList();
// Remove all other layers
for (LayerIterator it=layers.begin(), end=layers.end(); it!=end; ++it) {
if (*it != resultLayer)
api.removeLayer(*it);
}
// Change the number of frames
api.setTotalFrames(sprite, frame_t(animation.size()));
// Set the size of the sprite to the tile size.
api.setSpriteSize(sprite, frameBounds.w, frameBounds.h);
transaction.commit();
ASSERT(docPref);
if (docPref)
docPref->importSpriteSheet.bounds(frameBounds);
}
catch (...) {
throw;
}
update_screen_for_document(document);
}
示例12: onJob
/**
* [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();
}
示例13: onJob
// [working thread]
virtual void onJob()
{
Transaction transaction(m_writer.context(), "Rotate Canvas");
DocumentApi api = m_document->getApi(transaction);
// 1) Rotate cel positions
for (Cel* cel : m_cels) {
Image* image = cel->image();
if (!image)
continue;
switch (m_angle) {
case 180:
api.setCelPosition(m_sprite, cel,
m_sprite->width() - cel->x() - image->width(),
m_sprite->height() - cel->y() - image->height());
break;
case 90:
api.setCelPosition(m_sprite, cel,
m_sprite->height() - cel->y() - image->height(),
cel->x());
break;
case -90:
api.setCelPosition(m_sprite, cel,
cel->y(),
m_sprite->width() - cel->x() - image->width());
break;
}
}
// 2) Rotate images
int i = 0;
for (Cel* cel : m_cels) {
Image* image = cel->image();
if (image) {
ImageRef new_image(Image::create(image->pixelFormat(),
m_angle == 180 ? image->width(): image->height(),
m_angle == 180 ? image->height(): image->width()));
doc::rotate_image(image, new_image.get(), m_angle);
api.replaceImage(m_sprite, cel->imageRef(), new_image);
}
jobProgress((float)i / m_cels.size());
++i;
// cancel all the operation?
if (isCanceled())
return; // Transaction destructor will undo all operations
}
// rotate mask
if (m_document->isMaskVisible()) {
Mask* origMask = m_document->mask();
base::UniquePtr<Mask> new_mask(new Mask());
const gfx::Rect& origBounds = origMask->bounds();
int x = 0, y = 0;
switch (m_angle) {
case 180:
x = m_sprite->width() - origBounds.x - origBounds.w;
y = m_sprite->height() - origBounds.y - origBounds.h;
break;
case 90:
x = m_sprite->height() - origBounds.y - origBounds.h;
y = origBounds.x;
break;
case -90:
x = origBounds.y;
y = m_sprite->width() - origBounds.x - origBounds.w;
break;
}
// create the new rotated mask
new_mask->replace(
gfx::Rect(x, y,
m_angle == 180 ? origBounds.w: origBounds.h,
m_angle == 180 ? origBounds.h: origBounds.w));
doc::rotate_image(origMask->bitmap(), new_mask->bitmap(), m_angle);
// Copy new mask
api.copyToCurrentMask(new_mask);
// Regenerate mask
m_document->resetTransformation();
m_document->generateMaskBoundaries();
}
// change the sprite's size
if (m_rotateSprite && m_angle != 180)
api.setSpriteSize(m_sprite, m_sprite->height(), m_sprite->width());
// commit changes
transaction.commit();
}
示例14: onImport
void onImport()
{
// The user don't select a sheet yet.
if (!m_document) {
Alert::show("Import Sprite Sheet<<Select a sprite first.||&Close");
return;
}
// The list of frames imported from the sheet
std::vector<Image*> animation;
try {
Sprite* sprite = m_document->getSprite();
FrameNumber currentFrame = m_context->getActiveLocation().frame();
// As first step, we cut each tile and add them into "animation" list.
for (int y=m_rect.y; y<sprite->getHeight(); y += m_rect.h) {
for (int x=m_rect.x; x<sprite->getWidth(); x += m_rect.w) {
base::UniquePtr<Image> resultImage(Image::create(sprite->getPixelFormat(), m_rect.w, m_rect.h));
// Clear the image with mask color.
image_clear(resultImage, 0);
// Render the portion of sheet.
sprite->render(resultImage, -x, -y, currentFrame);
animation.push_back(resultImage);
resultImage.release();
}
}
if (animation.size() == 0) {
Alert::show("Import Sprite Sheet"
"<<The specified rectangle does not create any tile."
"<<Select a rectangle inside the sprite region."
"||&OK");
return;
}
// The following steps modify the sprite, so we wrap all
// operations in a undo-transaction.
ContextWriter writer(m_context);
UndoTransaction undoTransaction(writer.context(), "Import Sprite Sheet", undo::ModifyDocument);
DocumentApi api = m_document->getApi();
// Add the layer in the sprite.
LayerImage* resultLayer = api.newLayer(sprite);
// Add all frames+cels to the new layer
for (size_t i=0; i<animation.size(); ++i) {
int indexInStock;
// Add the image into the sprite's stock
indexInStock = api.addImageInStock(sprite, animation[i]);
animation[i] = NULL;
// Create the cel.
base::UniquePtr<Cel> resultCel(new Cel(FrameNumber(i), indexInStock));
// Add the cel in the layer.
api.addCel(resultLayer, resultCel);
resultCel.release();
}
// Copy the list of layers (because we will modify it in the iteration).
LayerList layers = sprite->getFolder()->getLayersList();
// Remove all other layers
for (LayerIterator it=layers.begin(), end=layers.end(); it!=end; ++it) {
if (*it != resultLayer)
api.removeLayer(*it);
}
// Change the number of frames
api.setTotalFrames(sprite, FrameNumber(animation.size()));
// Set the size of the sprite to the tile size.
api.setSpriteSize(sprite, m_rect.w, m_rect.h);
undoTransaction.commit();
}
catch (...) {
for (size_t i=0; i<animation.size(); ++i)
delete animation[i];
throw;
}
update_screen_for_document(m_document);
closeWindow(NULL);
}
示例15: writer
void FlipCommand::onExecute(Context* context)
{
ContextWriter writer(context);
Document* document = writer.document();
Sprite* sprite = writer.sprite();
DocumentApi api = document->getApi();
{
UndoTransaction undoTransaction(writer.context(),
m_flipMask ?
(m_flipType == raster::algorithm::FlipHorizontal ?
"Flip Horizontal":
"Flip Vertical"):
(m_flipType == raster::algorithm::FlipHorizontal ?
"Flip Canvas Horizontal":
"Flip Canvas Vertical"));
if (m_flipMask) {
int x, y;
Image* image = writer.image(&x, &y);
if (!image)
return;
Mask* mask = NULL;
bool alreadyFlipped = false;
// This variable will be the area to be flipped inside the image.
gfx::Rect bounds(image->getBounds());
// If there is some portion of sprite selected, we flip the
// selected region only. If the mask isn't visible, we flip the
// whole image.
if (document->isMaskVisible()) {
mask = document->getMask();
// Intersect the full area of the image with the mask's
// bounds, so we don't request to flip an area outside the
// image's bounds.
bounds = bounds.createIntersect(gfx::Rect(mask->getBounds()).offset(-x, -y));
// If the mask isn't a rectangular area, we've to flip the mask too.
if (mask->getBitmap() != NULL && !mask->isRectangular()) {
int bgcolor = app_get_color_to_clear_layer(writer.layer());
// Flip the portion of image specified by the mask.
mask->offsetOrigin(-x, -y);
api.flipImageWithMask(image, mask, m_flipType, bgcolor);
mask->offsetOrigin(x, y);
alreadyFlipped = true;
// Flip the mask.
Image* maskBitmap = mask->getBitmap();
if (maskBitmap != NULL) {
// Create a flipped copy of the current mask.
base::UniquePtr<Mask> newMask(new Mask(*mask));
newMask->freeze();
raster::algorithm::flip_image(newMask->getBitmap(),
maskBitmap->getBounds(), m_flipType);
newMask->unfreeze();
// Change the current mask and generate the new boundaries.
api.copyToCurrentMask(newMask);
document->generateMaskBoundaries();
}
}
}
// Flip the portion of image specified by "bounds" variable.
if (!alreadyFlipped) {
api.flipImage(image, bounds, m_flipType);
}
}
else {
// get all sprite cels
CelList cels;
sprite->getCels(cels);
// for each cel...
for (CelIterator it = cels.begin(); it != cels.end(); ++it) {
Cel* cel = *it;
Image* image = sprite->getStock()->getImage(cel->getImage());
api.setCelPosition
(sprite, cel,
(m_flipType == raster::algorithm::FlipHorizontal ?
sprite->getWidth() - image->getWidth() - cel->getX():
cel->getX()),
(m_flipType == raster::algorithm::FlipVertical ?
sprite->getHeight() - image->getHeight() - cel->getY():
cel->getY()));
api.flipImage(image, image->getBounds(), m_flipType);
}
}
undoTransaction.commit();
}
update_screen_for_document(document);
//.........这里部分代码省略.........