Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/rasterselection.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tpaletteutil.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/rasterimagedata.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/strokesdata.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/selectioncommandids.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/dvdialog.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/palettecontroller.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcamera.h"
Toshihiro Shimizu 890ddd
#include "toonz/trasterimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qapplication></qapplication>
Toshihiro Shimizu 890ddd
#include <qclipboard></qclipboard>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRasterP getRaster(const TImageP image)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (TToonzImageP ti = (TToonzImageP)(image))
Toshihiro Shimizu 890ddd
		return ti->getRaster();
Toshihiro Shimizu 890ddd
	if (TRasterImageP ri = (TRasterImageP)(image))
Toshihiro Shimizu 890ddd
		return ri->getRaster();
Toshihiro Shimizu 890ddd
	return (TRasterP)(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRect convertWorldToRaster(const TRectD area, const TRasterP ras)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (area.isEmpty())
Toshihiro Shimizu 890ddd
		return TRect();
Toshihiro Shimizu 890ddd
	if (!ras)
Toshihiro Shimizu 890ddd
		return TRect(tfloor(area.x0), tfloor(area.y0), tfloor(area.x1) - 1, tfloor(area.y1) - 1);
Toshihiro Shimizu 890ddd
	TRectD rect(area + ras->getCenterD());
Toshihiro Shimizu 890ddd
	return TRect(tfloor(rect.x0), tfloor(rect.y0), tceil(rect.x1) - 1, tceil(rect.y1) - 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRect convertWorldToRaster(const TRectD area, const TImageP image)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterImageP ri(image);
Toshihiro Shimizu 890ddd
	TToonzImageP ti(image);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Watch out! TToonzImage::getRaster() returns a TRasterCM32P, while
Toshihiro Shimizu 890ddd
	//TRasterImage::getRaster() returns a TRasterP!
Toshihiro Shimizu 890ddd
	TRasterP ras = (ri) ? ri->getRaster() : (TRasterP)ti->getRaster();
Toshihiro Shimizu 890ddd
	return convertWorldToRaster(area, ras);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD convertRasterToWorld(const TRect area, const TImageP image)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TToonzImageP ti(image);
Toshihiro Shimizu 890ddd
	if (ti)
Toshihiro Shimizu 890ddd
		return ToonzImageUtils::convertRasterToWorld(area, image);
Toshihiro Shimizu 890ddd
	return TRasterImageUtils::convertRasterToWorld(area, image);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD intersection(const TRectD &area, const TImageP image)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TToonzImageP ti(image);
Toshihiro Shimizu 890ddd
	if (ti)
Toshihiro Shimizu 890ddd
		return area * ToonzImageUtils::convertRasterToWorld(ti->getRaster()->getBounds(), image);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterImageP ri(image);
Toshihiro Shimizu 890ddd
	if (ri)
Toshihiro Shimizu 890ddd
		return area * TRasterImageUtils::convertRasterToWorld(ri->getRaster()->getBounds(), ri);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return area;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//The stroke is in raster coordinates
Toshihiro Shimizu 890ddd
template <class class="" pixel1,="" pixel2=""></class>
Toshihiro Shimizu 890ddd
TRasterPT<pixel1> getImageFromStroke(TRasterPT<pixel2> ras, const TStroke &stroke)</pixel2></pixel1>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRectD regionsBoxD = stroke.getBBox();
Toshihiro Shimizu 890ddd
	//E' volutamente allargato di un pixel!
Toshihiro Shimizu 890ddd
	TRect regionsBox(tfloor(regionsBoxD.x0), tfloor(regionsBoxD.y0), tceil(regionsBoxD.x1), tceil(regionsBoxD.y1));
Toshihiro Shimizu 890ddd
	regionsBox *= ras->getBounds();
Toshihiro Shimizu 890ddd
	if (regionsBox.isEmpty())
Toshihiro Shimizu 890ddd
		return (TRasterPT<pixel1>)0;</pixel1>
Toshihiro Shimizu 890ddd
	TRasterPT<pixel1> buffer(regionsBox.getSize());</pixel1>
Toshihiro Shimizu 890ddd
	buffer->clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Compute regions created by the vector
Toshihiro Shimizu 890ddd
	TVectorImage app;
Toshihiro Shimizu 890ddd
	app.addStroke(new TStroke(stroke));
Toshihiro Shimizu 890ddd
	app.findRegions();
Toshihiro Shimizu 890ddd
	int reg, j, k, y;
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
	for (reg = 0; reg < (int)app.getRegionCount(); reg++) {
Toshihiro Shimizu 890ddd
		//For each region, pixels inside the region are copied in buffer!
Toshihiro Shimizu 890ddd
		TRectD bBoxD = stroke.getBBox();
Toshihiro Shimizu 890ddd
		TRect bBox(tfloor(bBoxD.x0), tfloor(bBoxD.y0), tceil(bBoxD.x1) - 1, tceil(bBoxD.y1) - 1);
Toshihiro Shimizu 890ddd
		bBox *= ras->getBounds();
Toshihiro Shimizu 890ddd
		for (y = bBox.y0; y <= bBox.y1; y++) {
Toshihiro Shimizu 890ddd
			PIXEL2 *selectedLine = ras->pixels(y);
Toshihiro Shimizu 890ddd
			int startY = y - regionsBox.y0;
Toshihiro Shimizu 890ddd
			PIXEL1 *bufferLine = buffer->pixels(startY >= 0 ? startY : 0);
Toshihiro Shimizu 890ddd
			vector<double> intersections;</double>
Toshihiro Shimizu 890ddd
			app.getRegion(reg)->computeScanlineIntersections(y, intersections);
Toshihiro Shimizu 890ddd
			if (intersections.empty())
Toshihiro Shimizu 890ddd
				app.getRegion(reg)->computeScanlineIntersections(y + 0.9, intersections);
Toshihiro Shimizu 890ddd
			for (j = 0; j < (int)intersections.size(); j += 2) {
Toshihiro Shimizu 890ddd
				if (intersections[j] == intersections[j + 1])
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
				int from = tmax(tfloor(intersections[j]), bBox.x0);
Toshihiro Shimizu 890ddd
				int to = tmin(tceil(intersections[j + 1]), bBox.x1);
Toshihiro Shimizu 890ddd
				for (k = from; k <= to; k++) {
Toshihiro Shimizu 890ddd
					TRasterCM32P bufferCM(buffer);
Toshihiro Shimizu 890ddd
					TRaster32P buffer32(buffer);
Toshihiro Shimizu 890ddd
					TRasterCM32P rasCM(ras);
Toshihiro Shimizu 890ddd
					TRaster32P ras32(ras);
Toshihiro Shimizu 890ddd
					TRasterGR8P rasGR8(ras);
Toshihiro Shimizu 890ddd
					if (bufferCM && rasCM) {
Toshihiro Shimizu 890ddd
						TPixelCM32 *bottomPix = (TPixelCM32 *)bufferLine + k - regionsBox.x0;
Toshihiro Shimizu 890ddd
						TPixelCM32 *topPix = (TPixelCM32 *)selectedLine + k;
Toshihiro Shimizu 890ddd
						*bottomPix = *topPix;
Toshihiro Shimizu 890ddd
					} else if (buffer32 && ras32) {
Toshihiro Shimizu 890ddd
						TPixel32 *bottomPix = (TPixel32 *)bufferLine + k - regionsBox.x0;
Toshihiro Shimizu 890ddd
						TPixel32 *topPix = (TPixel32 *)selectedLine + k;
Toshihiro Shimizu 890ddd
						*bottomPix = *topPix;
Toshihiro Shimizu 890ddd
					} else if (buffer32 && rasGR8) {
Toshihiro Shimizu 890ddd
						TPixel32 *bottomPix = (TPixel32 *)bufferLine + k - regionsBox.x0;
Toshihiro Shimizu 890ddd
						TPixelGR8 *topPix = (TPixelGR8 *)selectedLine + k;
Toshihiro Shimizu 890ddd
						*bottomPix = TPixel32(topPix->value, topPix->value, topPix->value, 255);
Toshihiro Shimizu 890ddd
					} else
Toshihiro Shimizu 890ddd
						assert(0);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	ras->unlock();
Toshihiro Shimizu 890ddd
	return buffer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class class="" pixel1,="" pixel2=""></class>
Toshihiro Shimizu 890ddd
TRasterPT<pixel1> getImageFromSelection(TRasterPT<pixel2> &ras, RasterSelection &selection)</pixel2></pixel1>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (selection.isEmpty())
Toshihiro Shimizu 890ddd
		return (TRasterPT<pixel1>)0;</pixel1>
Toshihiro Shimizu 890ddd
	TRectD wSelectionBound = selection.getSelectionBbox();
Toshihiro Shimizu 890ddd
	TRect rSelectionBound = convertWorldToRaster(wSelectionBound, ras);
Toshihiro Shimizu 890ddd
	rSelectionBound *= ras->getBounds();
Toshihiro Shimizu 890ddd
	TRasterPT<pixel1> selectedRaster(rSelectionBound.getSize());</pixel1>
Toshihiro Shimizu 890ddd
	selectedRaster->clear();
Toshihiro Shimizu 890ddd
	vector<tstroke> strokes = selection.getStrokes();</tstroke>
Toshihiro Shimizu 890ddd
	TPoint startPosition = rSelectionBound.getP00();
Toshihiro Shimizu 890ddd
	unsigned int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < strokes.size(); i++) {
Toshihiro Shimizu 890ddd
		TStroke stroke = strokes[i];
Toshihiro Shimizu 890ddd
		stroke.transform(TTranslation(ras->getCenterD()));
Toshihiro Shimizu 890ddd
		TRasterPT<pixel1> app = getImageFromStroke<pixel1, pixel2="">(ras, stroke);</pixel1,></pixel1>
Toshihiro Shimizu 890ddd
		if (!app)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		TRectD strokeRectD = stroke.getBBox();
Toshihiro Shimizu 890ddd
		TRect strokeRect(tfloor(strokeRectD.x0), tfloor(strokeRectD.y0), tceil(strokeRectD.x1) - 1, tceil(strokeRectD.y1) - 1);
Toshihiro Shimizu 890ddd
		TPoint offset((strokeRect * rSelectionBound).getP00() - rSelectionBound.getP00());
Toshihiro Shimizu 890ddd
		TPoint startP = rSelectionBound.getP00() + offset;
Toshihiro Shimizu 890ddd
		startPosition = TPoint(tmin(startPosition.x, startP.x), tmin(startPosition.y, startP.y));
Toshihiro Shimizu 890ddd
		TRop::over(selectedRaster, app, offset);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	selection.setStartPosition(startPosition);
Toshihiro Shimizu 890ddd
	return selectedRaster;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRasterP getImageFromSelection(const TImageP &image, RasterSelection &selection)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (TToonzImageP toonzImage = (TToonzImageP)image) {
Toshihiro Shimizu 890ddd
		TRasterPT<tpixelcm32> ras = toonzImage->getRaster();</tpixelcm32>
Toshihiro Shimizu 890ddd
		return getImageFromSelection<tpixelcm32, tpixelcm32="">(ras, selection);</tpixelcm32,>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (TRasterImageP rasterImage = (TRasterImageP)image) {
Toshihiro Shimizu 890ddd
		TRasterP ras = rasterImage->getRaster();
Toshihiro Shimizu 890ddd
		if (TRaster32P ras32 = (TRaster32P)ras)
Toshihiro Shimizu 890ddd
			return getImageFromSelection<tpixel32, tpixel32="">(ras32, selection);</tpixel32,>
Toshihiro Shimizu 890ddd
		if (TRasterGR8P rasGR8 = (TRasterGR8P)ras)
Toshihiro Shimizu 890ddd
			return getImageFromSelection<tpixel32, tpixelgr8="">(rasGR8, selection);</tpixel32,>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return (TRasterP)0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixel=""></typename>
Toshihiro Shimizu 890ddd
void deleteSelectionWithoutUndo(TRasterPT<pixel> &ras, const vector<tstroke> &strokes, PIXEL emptyValue)</tstroke></pixel>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!ras)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	unsigned int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < strokes.size(); i++) {
Toshihiro Shimizu 890ddd
		TStroke s = strokes[i];
Toshihiro Shimizu 890ddd
		s.transform(TTranslation(ras->getCenterD()));
Toshihiro Shimizu 890ddd
		TRectD strokeRectD = s.getBBox();
Toshihiro Shimizu 890ddd
		//E' volutamente allargato di un pixel!
Toshihiro Shimizu 890ddd
		TRect strokeRect(tfloor(strokeRectD.x0), tfloor(strokeRectD.y0), tceil(strokeRectD.x1), tceil(strokeRectD.y1));
Toshihiro Shimizu 890ddd
		if (!strokeRect.overlaps(ras->getBounds()))
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Compute regions created by the vector
Toshihiro Shimizu 890ddd
		TVectorImage app;
Toshihiro Shimizu 890ddd
		app.addStroke(new TStroke(s));
Toshihiro Shimizu 890ddd
		app.findRegions();
Toshihiro Shimizu 890ddd
		int reg, j, k, y;
Toshihiro Shimizu 890ddd
		ras->lock();
Toshihiro Shimizu 890ddd
		TRect rasRect(ras->getBounds());
Toshihiro Shimizu 890ddd
		for (reg = 0; reg < (int)app.getRegionCount(); reg++) {
Toshihiro Shimizu 890ddd
			//For each region, pixels inside the region are erased!
Toshihiro Shimizu 890ddd
			TRectD bBoxD = app.getRegion(reg)->getBBox();
Toshihiro Shimizu 890ddd
			TRect bBox(tfloor(bBoxD.x0), tfloor(bBoxD.y0), tceil(bBoxD.x1) - 1, tceil(bBoxD.y1) - 1);
Toshihiro Shimizu 890ddd
			bBox *= rasRect;
Toshihiro Shimizu 890ddd
			for (y = bBox.y0; y <= bBox.y1; y++) {
Toshihiro Shimizu 890ddd
				PIXEL *selectedLine = ras->pixels(y);
Toshihiro Shimizu 890ddd
				int startY = y - strokeRect.y0;
Toshihiro Shimizu 890ddd
				vector<double> intersections;</double>
Toshihiro Shimizu 890ddd
				app.getRegion(reg)->computeScanlineIntersections(y, intersections);
Toshihiro Shimizu 890ddd
				if (intersections.empty())
Toshihiro Shimizu 890ddd
					app.getRegion(reg)->computeScanlineIntersections(y + 0.9, intersections);
Toshihiro Shimizu 890ddd
				for (j = 0; j < (int)intersections.size(); j += 2) {
Toshihiro Shimizu 890ddd
					if (intersections[j] == intersections[j + 1])
Toshihiro Shimizu 890ddd
						continue;
Toshihiro Shimizu 890ddd
					int from = tmax(tfloor(intersections[j]), bBox.x0);
Toshihiro Shimizu 890ddd
					int to = tmin(tceil(intersections[j + 1]), bBox.x1);
Toshihiro Shimizu 890ddd
					for (k = from; k <= to; k++)
Toshihiro Shimizu 890ddd
						*(selectedLine + k) = emptyValue;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		ras->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void deleteSelectionWithoutUndo(const TImageP &image, const vector<tstroke> &strokes)</tstroke>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (TToonzImageP toonzImage = (TToonzImageP)image) {
Toshihiro Shimizu 890ddd
		TRasterPT<tpixelcm32> ras = toonzImage->getRaster();</tpixelcm32>
Toshihiro Shimizu 890ddd
		deleteSelectionWithoutUndo<tpixelcm32>(ras, strokes, TPixelCM32());</tpixelcm32>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (TRasterImageP rasterImage = (TRasterImageP)image) {
Toshihiro Shimizu 890ddd
		TRasterP ras = rasterImage->getRaster();
Toshihiro Shimizu 890ddd
		if (TRaster32P ras32 = (TRaster32P)ras)
Toshihiro Shimizu 890ddd
			deleteSelectionWithoutUndo<tpixel32>(ras32, strokes, TPixel32::Transparent);</tpixel32>
Toshihiro Shimizu 890ddd
		if (TRasterGR8P rasGR8 = (TRasterGR8P)ras)
Toshihiro Shimizu 890ddd
			deleteSelectionWithoutUndo<tpixelgr8>(rasGR8, strokes, TPixelGR8::White);</tpixelgr8>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void pasteFloatingSelectionWithoutUndo(const TImageP &image, const TRasterP &floatingSelection,
Toshihiro Shimizu 890ddd
									   const TAffine &transformation, const TRectD &wSelectionBound,
Toshihiro Shimizu 890ddd
									   bool noAntialiasing)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterImageP ri = (TRasterImageP)image;
Toshihiro Shimizu 890ddd
	TToonzImageP ti = (TToonzImageP)image;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterP targetRaster = (ri) ? ri->getRaster() : (TRasterP)ti->getRaster();
Toshihiro Shimizu 890ddd
	if (!targetRaster || !floatingSelection)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRect rSelectionBound = convertWorldToRaster(wSelectionBound, targetRaster);
Toshihiro Shimizu 890ddd
	TRop::over(targetRaster, floatingSelection, rSelectionBound.getP00(), transformation,
Toshihiro Shimizu 890ddd
			   noAntialiasing ? TRop::ClosestPixel : TRop::Triangle);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// UndoDeleteSelection
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class UndoDeleteSelection : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	static int m_id;
Toshihiro Shimizu 890ddd
	TXshSimpleLevelP m_level;
Toshihiro Shimizu 890ddd
	TFrameId m_frameId;
Toshihiro Shimizu 890ddd
	string m_erasedImageId;
Toshihiro Shimizu 890ddd
	TPoint m_erasePoint;
Toshihiro Shimizu 890ddd
	vector<tstroke> m_strokes;</tstroke>
Toshihiro Shimizu 890ddd
	TTool *m_tool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	UndoDeleteSelection(RasterSelection *selection, TXshSimpleLevel *level)
Toshihiro Shimizu 890ddd
		: TUndo(), m_level(level), m_frameId(selection->getFrameId()), m_strokes(selection->getOriginalStrokes())
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		m_erasedImageId = "UndoDeleteSelection" + toString(m_id++);
Toshihiro Shimizu 890ddd
		TRasterP ras = getRaster(image);
Toshihiro Shimizu 890ddd
		TRasterP erasedRas;
Toshihiro Shimizu 890ddd
		if (!selection->isFloating())
Toshihiro Shimizu 890ddd
			erasedRas = TRasterP(getImageFromSelection(image, *selection));
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			erasedRas = TRasterP(selection->getOriginalFloatingSelection());
Toshihiro Shimizu 890ddd
		TImageP erasedImage;
Toshihiro Shimizu 890ddd
		if (TRasterCM32P toonzRas = (TRasterCM32P)(erasedRas))
Toshihiro Shimizu 890ddd
			erasedImage = TToonzImageP(toonzRas, toonzRas->getBounds());
Toshihiro Shimizu 890ddd
		else if (TRaster32P fullColorRas = (TRaster32P)(erasedRas))
Toshihiro Shimizu 890ddd
			erasedImage = TRasterImageP(fullColorRas);
Toshihiro Shimizu 890ddd
		TImageCache::instance()->add(m_erasedImageId, erasedImage, false);
Toshihiro Shimizu 890ddd
		m_erasePoint = selection->getStartPosition();
Toshihiro Shimizu 890ddd
		m_tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~UndoDeleteSelection()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (TImageCache::instance()->isCached(m_erasedImageId))
Toshihiro Shimizu 890ddd
			TImageCache::instance()->remove(m_erasedImageId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		if (!image)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TRasterP ras = getRaster(image);
Toshihiro Shimizu 890ddd
		if (!ras)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TImageP erasedImage = TImageCache::instance()->get(m_erasedImageId, false);
Toshihiro Shimizu 890ddd
		if (!erasedImage)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TRasterP erasedRaster = getRaster(erasedImage);
Toshihiro Shimizu 890ddd
		TRop::over(ras, erasedRaster, m_erasePoint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ToolUtils::updateSaveBox(m_level, m_frameId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!m_tool)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_tool->notifyImageChanged(m_frameId);
Toshihiro Shimizu 890ddd
		m_tool->invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		TImageP erasedImage = TImageCache::instance()->get(m_erasedImageId, false);
Toshihiro Shimizu 890ddd
		if (!erasedImage)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		deleteSelectionWithoutUndo(image, m_strokes);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ToolUtils::updateSaveBox(m_level, m_frameId);
Toshihiro Shimizu 890ddd
		if (!m_tool)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_tool->notifyImageChanged(m_frameId);
Toshihiro Shimizu 890ddd
		m_tool->invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int UndoDeleteSelection::m_id = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// UndoPasteSelection
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class UndoPasteSelection : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	RasterSelection *m_currentSelection, m_newSelection;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	UndoPasteSelection(RasterSelection *currentSelection)
Toshihiro Shimizu 890ddd
		: TUndo(), m_currentSelection(currentSelection), m_newSelection(*currentSelection)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~UndoPasteSelection()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_currentSelection->setFloatingSeletion(TRasterP());
Toshihiro Shimizu 890ddd
		m_currentSelection->selectNone();
Toshihiro Shimizu 890ddd
		m_currentSelection->notify();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		*m_currentSelection = m_newSelection;
Toshihiro Shimizu 890ddd
		m_currentSelection->notify();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QString getHistoryString()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return QObject::tr("Paste");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// UndoPasteFloatingSelection
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class UndoPasteFloatingSelection : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	static int m_id;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell m_imageCell; //!< Level/frame pair to the pasted-to image
Toshihiro Shimizu 890ddd
						  //!< (seemingly cached as m_imageId)
Toshihiro Shimizu 890ddd
	TPaletteP m_oldPalette, m_newPalette;
Toshihiro Shimizu 890ddd
	string m_imageId, m_floatingImageId, m_undoImageId, m_oldFloatingImageId;
Toshihiro Shimizu 890ddd
	vector<tstroke> m_strokes;</tstroke>
Toshihiro Shimizu 890ddd
	TRectD m_selectionRect;
Toshihiro Shimizu 890ddd
	TAffine m_transformation;
Toshihiro Shimizu 890ddd
	TPoint m_startPos;
Toshihiro Shimizu 890ddd
	bool m_isPastedSelection;
Toshihiro Shimizu 890ddd
	bool m_noAntialiasing;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool *m_tool;
Toshihiro Shimizu 890ddd
	TFrameId m_frameId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	UndoPasteFloatingSelection(RasterSelection *currentSelection, TPalette *oldPalette, bool noAntialiasing)
Toshihiro Shimizu 890ddd
		: TUndo(), m_imageCell(currentSelection->getCurrentImageCell()), m_oldPalette(oldPalette ? oldPalette->clone() : 0), m_strokes(currentSelection->getOriginalStrokes()), m_selectionRect(currentSelection->getSelectionBbox()), m_transformation(currentSelection->getTransformation()), m_isPastedSelection(currentSelection->isPastedSelection()), m_noAntialiasing(noAntialiasing), m_undoImageId(""), m_frameId(currentSelection->getFrameId())
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageP image(currentSelection->getCurrentImage());
Toshihiro Shimizu 890ddd
		if (!image)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_imageId = "UndoPasteImage_" + toString(m_id);
Toshihiro Shimizu 890ddd
		TImageCache::instance()->add(m_imageId, image, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_floatingImageId = "UndoPasteFloatingSelection_floating_" + toString(m_id);
Toshihiro Shimizu 890ddd
		TRasterP floatingRas = currentSelection->getFloatingSelection();
Toshihiro Shimizu 890ddd
		TImageP floatingImage;
Toshihiro Shimizu 890ddd
		if (TRasterCM32P toonzRas = (TRasterCM32P)(floatingRas))
Toshihiro Shimizu 890ddd
			floatingImage = TToonzImageP(toonzRas, toonzRas->getBounds());
Toshihiro Shimizu 890ddd
		else if (TRaster32P fullColorRas = (TRaster32P)(floatingRas))
Toshihiro Shimizu 890ddd
			floatingImage = TRasterImageP(fullColorRas);
Toshihiro Shimizu 890ddd
		else if (TRasterGR8P grRas = (TRasterGR8P)(floatingRas))
Toshihiro Shimizu 890ddd
			floatingImage = TRasterImageP(grRas);
Toshihiro Shimizu 890ddd
		TImageCache::instance()->add(m_floatingImageId, floatingImage, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_oldFloatingImageId = "UndoPasteFloatingSelection_oldFloating_" + toString(m_id);
Toshihiro Shimizu 890ddd
		TRasterP oldFloatingRas = currentSelection->getOriginalFloatingSelection();
Toshihiro Shimizu 890ddd
		TImageP olfFloatingImage;
Toshihiro Shimizu 890ddd
		if (TRasterCM32P toonzRas = (TRasterCM32P)(oldFloatingRas))
Toshihiro Shimizu 890ddd
			olfFloatingImage = TToonzImageP(toonzRas, toonzRas->getBounds());
Toshihiro Shimizu 890ddd
		else if (TRaster32P fullColorRas = (TRaster32P)(oldFloatingRas))
Toshihiro Shimizu 890ddd
			olfFloatingImage = TRasterImageP(fullColorRas);
Toshihiro Shimizu 890ddd
		else if (TRasterGR8P grRas = (TRasterGR8P)(oldFloatingRas))
Toshihiro Shimizu 890ddd
			olfFloatingImage = TRasterImageP(grRas);
Toshihiro Shimizu 890ddd
		TImageCache::instance()->add(m_oldFloatingImageId, olfFloatingImage, false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPaletteP imgPalette = image->getPalette();
Toshihiro Shimizu 890ddd
		m_newPalette = imgPalette ? imgPalette->clone() : 0;
Toshihiro Shimizu 890ddd
		TRasterP rasImage = getRaster(image);
Toshihiro Shimizu 890ddd
		TRectD wRect = m_selectionRect.enlarge(2);
Toshihiro Shimizu 890ddd
		TRect rRect = convertWorldToRaster(wRect, image);
Toshihiro Shimizu 890ddd
		rRect *= rasImage->getBounds();
Toshihiro Shimizu 890ddd
		if (!rRect.isEmpty()) {
Toshihiro Shimizu 890ddd
			m_undoImageId = "UndoPasteFloatingSelection_undo" + toString(m_id);
Toshihiro Shimizu 890ddd
			TRasterP undoRas = rasImage->extract(rRect)->clone();
Toshihiro Shimizu 890ddd
			TImageP undoImage;
Toshihiro Shimizu 890ddd
			if (TRasterCM32P toonzRas = (TRasterCM32P)(undoRas))
Toshihiro Shimizu 890ddd
				undoImage = TToonzImageP(toonzRas, toonzRas->getBounds());
Toshihiro Shimizu 890ddd
			else if (TRaster32P fullColorRas = (TRaster32P)(undoRas))
Toshihiro Shimizu 890ddd
				undoImage = TRasterImageP(fullColorRas);
Toshihiro Shimizu 890ddd
			else if (TRasterGR8P grRas = (TRasterGR8P)(undoRas))
Toshihiro Shimizu 890ddd
				undoImage = TRasterImageP(grRas);
Toshihiro Shimizu 890ddd
			TImageCache::instance()->add(m_undoImageId, undoImage, false);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		m_startPos = currentSelection->getStartPosition();
Toshihiro Shimizu 890ddd
		m_id++;
Toshihiro Shimizu 890ddd
		m_tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~UndoPasteFloatingSelection()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (TImageCache::instance()->isCached(m_imageId))
Toshihiro Shimizu 890ddd
			TImageCache::instance()->remove(m_imageId);
Toshihiro Shimizu 890ddd
		if (TImageCache::instance()->isCached(m_floatingImageId))
Toshihiro Shimizu 890ddd
			TImageCache::instance()->remove(m_floatingImageId);
Toshihiro Shimizu 890ddd
		if (TImageCache::instance()->isCached(m_undoImageId))
Toshihiro Shimizu 890ddd
			TImageCache::instance()->remove(m_undoImageId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageP image = TImageCache::instance()->get(m_imageId, false);
Toshihiro Shimizu 890ddd
		if (!image)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TRasterP rasImage = getRaster(image);
Toshihiro Shimizu 890ddd
		TRectD wRect = m_selectionRect.enlarge(2);
Toshihiro Shimizu 890ddd
		TRect rRect = convertWorldToRaster(wRect, image);
Toshihiro Shimizu 890ddd
		rRect *= rasImage->getBounds();
Toshihiro Shimizu 890ddd
		if (!m_undoImageId.empty()) {
Toshihiro Shimizu 890ddd
			TImageP undoImage = TImageCache::instance()->get(m_undoImageId, false);
Toshihiro Shimizu 890ddd
			if (!undoImage)
Toshihiro Shimizu 890ddd
				return;
Toshihiro Shimizu 890ddd
			rasImage->copy(getRaster(undoImage), rRect.getP00());
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TXshSimpleLevelP sl(m_imageCell.getSimpleLevel());
Toshihiro Shimizu 890ddd
		const TFrameId &fid = m_imageCell.m_frameId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!m_isPastedSelection) {
Toshihiro Shimizu 890ddd
			TImageP floatingImage = TImageCache::instance()->get(m_oldFloatingImageId, false);
Toshihiro Shimizu 890ddd
			if (!floatingImage)
Toshihiro Shimizu 890ddd
				return;
Toshihiro Shimizu 890ddd
			TRasterP floatingRaster = getRaster(floatingImage);
Toshihiro Shimizu 890ddd
			TRop::over(rasImage, floatingRaster, m_startPos);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ToolUtils::updateSaveBox(sl, fid);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_oldPalette)
Toshihiro Shimizu 890ddd
			image->getPalette()->assign(m_oldPalette->clone());
Toshihiro Shimizu 890ddd
		TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
		app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
		if (!m_tool)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_tool->notifyImageChanged(m_frameId);
Toshihiro Shimizu 890ddd
		m_tool->invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TImageP image = TImageCache::instance()->get(m_imageId, false);
Toshihiro Shimizu 890ddd
		TImageP floatingImage = TImageCache::instance()->get(m_floatingImageId, false);
Toshihiro Shimizu 890ddd
		if (!floatingImage || !image)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TRasterP floatingRas = getRaster(floatingImage);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TXshSimpleLevelP sl(m_imageCell.getSimpleLevel());
Toshihiro Shimizu 890ddd
		const TFrameId &fid = m_imageCell.m_frameId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!m_isPastedSelection)
Toshihiro Shimizu 890ddd
			deleteSelectionWithoutUndo(image, m_strokes);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRasterP ras = getRaster(image);
Toshihiro Shimizu 890ddd
		pasteFloatingSelectionWithoutUndo(image, floatingRas, m_transformation, m_selectionRect, m_noAntialiasing);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ToolUtils::updateSaveBox(sl, fid);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_newPalette)
Toshihiro Shimizu 890ddd
			image->getPalette()->assign(m_newPalette->clone());
Toshihiro Shimizu 890ddd
		TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
		app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
		if (!m_tool)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_tool->notifyImageChanged(m_frameId);
Toshihiro Shimizu 890ddd
		m_tool->invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QString getHistoryString()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return QObject::tr("Paste");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int UndoPasteFloatingSelection::m_id = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Next methods are used to compute intersection between selected stroke and image box
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Help function.*/
Toshihiro Shimizu 890ddd
TSegment getSegmentByIndex(TRectD rect, int index)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (index == 0)
Toshihiro Shimizu 890ddd
		return TSegment(rect.getP00(), rect.getP01());
Toshihiro Shimizu 890ddd
	if (index == 1)
Toshihiro Shimizu 890ddd
		return TSegment(rect.getP01(), rect.getP11());
Toshihiro Shimizu 890ddd
	if (index == 2)
Toshihiro Shimizu 890ddd
		return TSegment(rect.getP11(), rect.getP10());
Toshihiro Shimizu 890ddd
	if (index == 3)
Toshihiro Shimizu 890ddd
		return TSegment(rect.getP10(), rect.getP00());
Toshihiro Shimizu 890ddd
	return TSegment();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Help function. precPoint -> point */
Toshihiro Shimizu 890ddd
bool isClockwise(TRectD bbox, int segmentIndex, TThickPoint precPoint, TThickPoint point)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (segmentIndex == 0)
Toshihiro Shimizu 890ddd
		return precPoint.y > point.y;
Toshihiro Shimizu 890ddd
	if (segmentIndex == 1)
Toshihiro Shimizu 890ddd
		return precPoint.x > point.x;
Toshihiro Shimizu 890ddd
	if (segmentIndex == 2)
Toshihiro Shimizu 890ddd
		return precPoint.y < point.y;
Toshihiro Shimizu 890ddd
	if (segmentIndex == 3)
Toshihiro Shimizu 890ddd
		return precPoint.x < point.x;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Help function.*/
Toshihiro Shimizu 890ddd
void addPointToVector(TThickPoint point, std::vector<tthickpoint> &points, bool insertMiddlePoint)</tthickpoint>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (insertMiddlePoint)
Toshihiro Shimizu 890ddd
		points.push_back((points[points.size() - 1] + point) * 0.5);
Toshihiro Shimizu 890ddd
	points.push_back(point);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Return intersection between \b bbox and \b chuck;
Toshihiro Shimizu 890ddd
    set segmentIndex to index of segment that contains intersection. */
Toshihiro Shimizu 890ddd
TThickPoint getIntersectionPoint(TRectD bbox, const TThickQuadratic *chunk,
Toshihiro Shimizu 890ddd
								 int &segmentIndex, bool secondChunkIntersection)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TStroke stroke;
Toshihiro Shimizu 890ddd
	std::vector<tthickpoint> points;</tthickpoint>
Toshihiro Shimizu 890ddd
	points.push_back(chunk->getThickP0());
Toshihiro Shimizu 890ddd
	points.push_back(chunk->getThickP1());
Toshihiro Shimizu 890ddd
	points.push_back(chunk->getThickP2());
Toshihiro Shimizu 890ddd
	stroke.reshape(&points[0], points.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<doublepair> intersectionInfo;</doublepair>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<doublepair> intersections;</doublepair>
Toshihiro Shimizu 890ddd
	TSegment segment0(bbox.getP00(), bbox.getP01());
Toshihiro Shimizu 890ddd
	int count0 = intersect(stroke, segment0, intersections);
Toshihiro Shimizu 890ddd
	if (count0 > 0) {
Toshihiro Shimizu 890ddd
		DoublePair pair;
Toshihiro Shimizu 890ddd
		pair.first = intersections[0].first;
Toshihiro Shimizu 890ddd
		pair.second = 0;
Toshihiro Shimizu 890ddd
		intersectionInfo.push_back(pair);
Toshihiro Shimizu 890ddd
		intersections.clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TSegment segment1(bbox.getP01(), bbox.getP11());
Toshihiro Shimizu 890ddd
	int count1 = intersect(stroke, segment1, intersections);
Toshihiro Shimizu 890ddd
	if (count1 > 0) {
Toshihiro Shimizu 890ddd
		DoublePair pair;
Toshihiro Shimizu 890ddd
		pair.first = intersections[0].first;
Toshihiro Shimizu 890ddd
		pair.second = 1;
Toshihiro Shimizu 890ddd
		intersectionInfo.push_back(pair);
Toshihiro Shimizu 890ddd
		intersections.clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TSegment segment2(bbox.getP11(), bbox.getP10());
Toshihiro Shimizu 890ddd
	int count2 = intersect(stroke, segment2, intersections);
Toshihiro Shimizu 890ddd
	if (count2 > 0) {
Toshihiro Shimizu 890ddd
		DoublePair pair;
Toshihiro Shimizu 890ddd
		pair.first = intersections[0].first;
Toshihiro Shimizu 890ddd
		pair.second = 2;
Toshihiro Shimizu 890ddd
		intersectionInfo.push_back(pair);
Toshihiro Shimizu 890ddd
		intersections.clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TSegment segment3(bbox.getP10(), bbox.getP00());
Toshihiro Shimizu 890ddd
	int count3 = intersect(stroke, segment3, intersections);
Toshihiro Shimizu 890ddd
	if (count3 > 0) {
Toshihiro Shimizu 890ddd
		DoublePair pair;
Toshihiro Shimizu 890ddd
		pair.first = intersections[0].first;
Toshihiro Shimizu 890ddd
		pair.second = 3;
Toshihiro Shimizu 890ddd
		intersectionInfo.push_back(pair);
Toshihiro Shimizu 890ddd
		intersections.clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	int infoSize = intersectionInfo.size();
Toshihiro Shimizu 890ddd
	assert(infoSize <= 2);
Toshihiro Shimizu 890ddd
	if (infoSize == 1) {
Toshihiro Shimizu 890ddd
		segmentIndex = intersectionInfo[0].second;
Toshihiro Shimizu 890ddd
		return stroke.getPoint(intersectionInfo[0].first);
Toshihiro Shimizu 890ddd
	} else if (infoSize == 2) {
Toshihiro Shimizu 890ddd
		double firstT = intersectionInfo[0].first;
Toshihiro Shimizu 890ddd
		double secondT = intersectionInfo[1].first;
Toshihiro Shimizu 890ddd
		if (!secondChunkIntersection) {
Toshihiro Shimizu 890ddd
			if (firstT < secondT) {
Toshihiro Shimizu 890ddd
				segmentIndex = intersectionInfo[0].second;
Toshihiro Shimizu 890ddd
				return stroke.getPoint(intersectionInfo[0].first);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				segmentIndex = intersectionInfo[1].second;
Toshihiro Shimizu 890ddd
				return stroke.getPoint(intersectionInfo[1].first);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			if (firstT > secondT) {
Toshihiro Shimizu 890ddd
				segmentIndex = intersectionInfo[0].second;
Toshihiro Shimizu 890ddd
				return stroke.getPoint(intersectionInfo[0].first);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				segmentIndex = intersectionInfo[1].second;
Toshihiro Shimizu 890ddd
				return stroke.getPoint(intersectionInfo[1].first);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	segmentIndex = -1;
Toshihiro Shimizu 890ddd
	return TThickPoint();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Insert \b bbox corners in \b points if \b bbox corners are contained in \b outPoints stroke. */
Toshihiro Shimizu 890ddd
void insertBoxCorners(TRectD bbox, std::vector<tthickpoint> &points, std::vector<tthickpoint> outPoints,</tthickpoint></tthickpoint>
Toshihiro Shimizu 890ddd
					  int currentSegmentIndex, int precSegmentIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (outPoints[0] != outPoints[(int)outPoints.size() - 1])
Toshihiro Shimizu 890ddd
		addPointToVector(outPoints[0], outPoints, true);
Toshihiro Shimizu 890ddd
	assert((int)outPoints.size() % 2 == 1);
Toshihiro Shimizu 890ddd
	TStroke *outPointsStroke = new TStroke();
Toshihiro Shimizu 890ddd
	outPointsStroke->reshape(&(outPoints[0]), outPoints.size());
Toshihiro Shimizu 890ddd
	TVectorImageP vi(new TVectorImage());
Toshihiro Shimizu 890ddd
	vi->addStroke(outPointsStroke);
Toshihiro Shimizu 890ddd
	vi->findRegions();
Toshihiro Shimizu 890ddd
	assert((int)vi->getRegionCount() > 0);
Toshihiro Shimizu 890ddd
	bool sameIndex = (precSegmentIndex == currentSegmentIndex);
Toshihiro Shimizu 890ddd
	if (currentSegmentIndex == -1)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	int j;
Toshihiro Shimizu 890ddd
	for (j = sameIndex ? 1 : 0; j < 2; j++) {
Toshihiro Shimizu 890ddd
		bool clockwise = j;
Toshihiro Shimizu 890ddd
		if (sameIndex)
Toshihiro Shimizu 890ddd
			clockwise = isClockwise(bbox, currentSegmentIndex, outPoints[outPoints.size() - 2], outPoints[outPoints.size() - 1]);
Toshihiro Shimizu 890ddd
		int segmentIndex = precSegmentIndex;
Toshihiro Shimizu 890ddd
		if (sameIndex)
Toshihiro Shimizu 890ddd
			segmentIndex = clockwise ? currentSegmentIndex - 1 : currentSegmentIndex + 1;
Toshihiro Shimizu 890ddd
		if (segmentIndex < 0)
Toshihiro Shimizu 890ddd
			segmentIndex = 3;
Toshihiro Shimizu 890ddd
		if (segmentIndex > 3)
Toshihiro Shimizu 890ddd
			segmentIndex = 0;
Toshihiro Shimizu 890ddd
		while (segmentIndex != currentSegmentIndex) {
Toshihiro Shimizu 890ddd
			if (sameIndex) //controllo anche il segmento di partenza.
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				segmentIndex = currentSegmentIndex;
Toshihiro Shimizu 890ddd
				sameIndex = false;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			TSegment s = getSegmentByIndex(bbox, segmentIndex);
Toshihiro Shimizu 890ddd
			TThickPoint corner = clockwise ? s.getP0() : s.getP1();
Toshihiro Shimizu 890ddd
			int i;
Toshihiro Shimizu 890ddd
			for (i = 0; i < (int)vi->getRegionCount(); i++)
Toshihiro Shimizu 890ddd
				if (vi->getRegion(i)->contains(corner)) {
Toshihiro Shimizu 890ddd
					if ((int)points.size() % 2 == 1)
Toshihiro Shimizu 890ddd
						points.push_back((points[points.size() - 1] + corner) * 0.5);
Toshihiro Shimizu 890ddd
					points.push_back(corner);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			segmentIndex = clockwise ? segmentIndex - 1 : segmentIndex + 1;
Toshihiro Shimizu 890ddd
			if (segmentIndex < 0)
Toshihiro Shimizu 890ddd
				segmentIndex = 3;
Toshihiro Shimizu 890ddd
			if (segmentIndex > 3)
Toshihiro Shimizu 890ddd
				segmentIndex = 0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke getStrokeByRect(TRectD r)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TStroke stroke;
Toshihiro Shimizu 890ddd
	if (r.isEmpty())
Toshihiro Shimizu 890ddd
		return stroke;
Toshihiro Shimizu 890ddd
	vector<tthickpoint> points;</tthickpoint>
Toshihiro Shimizu 890ddd
	points.push_back(r.getP00());
Toshihiro Shimizu 890ddd
	points.push_back((r.getP00() + r.getP01()) * 0.5);
Toshihiro Shimizu 890ddd
	points.push_back(r.getP01());
Toshihiro Shimizu 890ddd
	points.push_back((r.getP01() + r.getP11()) * 0.5);
Toshihiro Shimizu 890ddd
	points.push_back(r.getP11());
Toshihiro Shimizu 890ddd
	points.push_back((r.getP11() + r.getP10()) * 0.5);
Toshihiro Shimizu 890ddd
	points.push_back(r.getP10());
Toshihiro Shimizu 890ddd
	points.push_back((r.getP10() + r.getP00()) * 0.5);
Toshihiro Shimizu 890ddd
	points.push_back(r.getP00());
Toshihiro Shimizu 890ddd
	stroke.reshape(&(points[0]), points.size());
Toshihiro Shimizu 890ddd
	stroke.setSelfLoop(true);
Toshihiro Shimizu 890ddd
	return stroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TStroke getIntersectedStroke(TStroke &stroke, TRectD bbox)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int cpCount = stroke.getControlPointCount();
Toshihiro Shimizu 890ddd
	if (cpCount == 0)
Toshihiro Shimizu 890ddd
		return stroke;
Toshihiro Shimizu 890ddd
	//isFirstTime, startSegmentIndex e startOutPoints sono usati nel il caso in cui lo stroke inizia fuori dalla bbox.
Toshihiro Shimizu 890ddd
	bool isFirstTime = true;
Toshihiro Shimizu 890ddd
	std::vector<tthickpoint> points, outPoints, startOutPoints;</tthickpoint>
Toshihiro Shimizu 890ddd
	TThickPoint precPoint = stroke.getControlPoint(0);
Toshihiro Shimizu 890ddd
	bool isPrecPointInternal = bbox.contains(precPoint);
Toshihiro Shimizu 890ddd
	if (isPrecPointInternal)
Toshihiro Shimizu 890ddd
		points.push_back(precPoint);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		outPoints.push_back(precPoint);
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	int precSegmentIndex, currentSegmentIndex, startSegmentIndex, precChunkIndex = -1;
Toshihiro Shimizu 890ddd
	for (i = 1; i < stroke.getControlPointCount(); i++) {
Toshihiro Shimizu 890ddd
		TThickPoint point = stroke.getControlPoint(i);
Toshihiro Shimizu 890ddd
		bool isPointInternal = bbox.contains(point);
Toshihiro Shimizu 890ddd
		if (isPointInternal && isPrecPointInternal)
Toshihiro Shimizu 890ddd
			addPointToVector(point, points, (int)points.size() % 2 != i % 2);
Toshihiro Shimizu 890ddd
		if (!isPointInternal && !isPrecPointInternal)
Toshihiro Shimizu 890ddd
			addPointToVector(point, outPoints, (int)outPoints.size() > 0 && (int)outPoints.size() % 2 != i % 2);
Toshihiro Shimizu 890ddd
		if (isPointInternal != isPrecPointInternal) {
Toshihiro Shimizu 890ddd
			//Devo trovare l'intersezione
Toshihiro Shimizu 890ddd
			int chunkIndex = (i % 2 == 0) ? (i * 0.5) - 1 : i * 0.5;
Toshihiro Shimizu 890ddd
			TThickPoint p = getIntersectionPoint(bbox, stroke.getChunk(chunkIndex), currentSegmentIndex, chunkIndex == precChunkIndex);
Toshihiro Shimizu 890ddd
			precChunkIndex = chunkIndex;
Toshihiro Shimizu 890ddd
			addPointToVector(p, outPoints, (int)outPoints.size() % 2 == 1);
Toshihiro Shimizu 890ddd
			if (!isPrecPointInternal && points.size() > 0 && outPoints.size() > 0) {
Toshihiro Shimizu 890ddd
				insertBoxCorners(bbox, points, outPoints, currentSegmentIndex, precSegmentIndex);
Toshihiro Shimizu 890ddd
				outPoints.clear();
Toshihiro Shimizu 890ddd
			} else if (outPoints.size() > 0 && isFirstTime) {
Toshihiro Shimizu 890ddd
				startSegmentIndex = currentSegmentIndex;
Toshihiro Shimizu 890ddd
				startOutPoints = outPoints;
Toshihiro Shimizu 890ddd
				outPoints.clear();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			isFirstTime = false;
Toshihiro Shimizu 890ddd
			precSegmentIndex = currentSegmentIndex;
Toshihiro Shimizu 890ddd
			addPointToVector(p, points, (int)points.size() % 2 == 1);
Toshihiro Shimizu 890ddd
			addPointToVector(p, outPoints, (int)outPoints.size() % 2 == 1);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (isPointInternal && !isPrecPointInternal)
Toshihiro Shimizu 890ddd
			addPointToVector(point, points, (int)points.size() % 2 != i % 2);
Toshihiro Shimizu 890ddd
		if (!isPointInternal && isPrecPointInternal)
Toshihiro Shimizu 890ddd
			addPointToVector(point, outPoints, (int)outPoints.size() > 0 && (int)outPoints.size() % 2 != i % 2);
Toshihiro Shimizu 890ddd
		isPrecPointInternal = isPointInternal;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//Caso in cui lo stroke aveva il primo punto fuori dalla bbox
Toshihiro Shimizu 890ddd
	if (!isPrecPointInternal && points.size() > 0 && outPoints.size() > 0) {
Toshihiro Shimizu 890ddd
		int t;
Toshihiro Shimizu 890ddd
		for (t = 0; t < (int)outPoints.size(); t++)
Toshihiro Shimizu 890ddd
			addPointToVector(outPoints[t], startOutPoints, (int)startOutPoints.size() % 2 != 2);
Toshihiro Shimizu 890ddd
		insertBoxCorners(bbox, points, startOutPoints, startSegmentIndex, currentSegmentIndex);
Toshihiro Shimizu 890ddd
		outPoints.clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Caso particolare in cui lo stroke non ha intersezione con la bbox
Toshihiro Shimizu 890ddd
	if (points.size() == 0) { //Lo stroke e' completamente contenuto nella bbox
Toshihiro Shimizu 890ddd
		if (bbox.contains(precPoint))
Toshihiro Shimizu 890ddd
			return stroke;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			return getStrokeByRect(bbox);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (points[0] != points[(int)points.size() - 1])
Toshihiro Shimizu 890ddd
		addPointToVector(points[0], points, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert((int)points.size() % 2 == 1);
Toshihiro Shimizu 890ddd
	TStroke intersectedStroke;
Toshihiro Shimizu 890ddd
	intersectedStroke.reshape(&(points[0]), points.size());
Toshihiro Shimizu 890ddd
	intersectedStroke.setSelfLoop(true);
Toshihiro Shimizu 890ddd
	return intersectedStroke;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// RasterSelection
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RasterSelection::RasterSelection()
Toshihiro Shimizu 890ddd
	: TSelection(), m_currentImage(), m_oldPalette(0), m_selectionBbox(), m_affine(), m_startPosition(), m_floatingSelection(), m_originalfloatingSelection(), m_fid(), m_transformationCount(0), m_isPastedSelection(false), m_noAntialiasing(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_strokes.clear();
Toshihiro Shimizu 890ddd
	m_originalStrokes.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RasterSelection::RasterSelection(const RasterSelection &src)
Toshihiro Shimizu 890ddd
	: TSelection(), m_currentImage(src.m_currentImage), m_oldPalette(src.m_oldPalette), m_selectionBbox(src.m_selectionBbox), m_strokes(src.m_strokes), m_originalStrokes(src.m_originalStrokes), m_affine(src.m_affine), m_startPosition(src.m_startPosition), m_fid(src.m_fid), m_transformationCount(src.m_transformationCount), m_isPastedSelection(src.m_isPastedSelection), m_noAntialiasing(src.m_noAntialiasing)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setView(src.getView());
Toshihiro Shimizu 890ddd
	if (src.isFloating()) {
Toshihiro Shimizu 890ddd
		m_floatingSelection = src.m_floatingSelection->clone();
Toshihiro Shimizu 890ddd
		if (src.m_originalfloatingSelection)
Toshihiro Shimizu 890ddd
			m_originalfloatingSelection = src.m_originalfloatingSelection->clone();
Toshihiro Shimizu 890ddd
		assert(isFloating());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Returns the clone of this selection
Toshihiro Shimizu 890ddd
TSelection *RasterSelection::clone() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	RasterSelection *rs = new RasterSelection(*this);
Toshihiro Shimizu 890ddd
	return rs;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Notify to the viewer that the selection is changed.
Toshihiro Shimizu 890ddd
void RasterSelection::notify()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	RasterSelection *selection = dynamic_cast<rasterselection *="">(TTool::getApplication()->getCurrentSelection()->getSelection());</rasterselection>
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->notifyView();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Empty the selection.
Toshihiro Shimizu 890ddd
//! If the selection is floating, the floating image is pasted using the current tranformation.
Toshihiro Shimizu 890ddd
void RasterSelection::selectNone()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (isFloating()) {
Toshihiro Shimizu 890ddd
		pasteFloatingSelection();
Toshihiro Shimizu 890ddd
		notify();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	m_selectionBbox = TRectD();
Toshihiro Shimizu 890ddd
	m_strokes.clear();
Toshihiro Shimizu 890ddd
	m_originalStrokes.clear();
Toshihiro Shimizu 890ddd
	m_affine = TAffine();
Toshihiro Shimizu 890ddd
	m_startPosition = TPoint();
Toshihiro Shimizu 890ddd
	m_floatingSelection = TRasterP();
Toshihiro Shimizu 890ddd
	m_originalfloatingSelection = TRasterP();
Toshihiro Shimizu 890ddd
	m_transformationCount = 0;
Toshihiro Shimizu 890ddd
	m_isPastedSelection = false;
Toshihiro Shimizu 890ddd
	m_oldPalette = 0;
Toshihiro Shimizu 890ddd
	notify();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::select(TStroke &stroke)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRect box = getRaster(m_currentImage)->getBounds();
Toshihiro Shimizu 890ddd
	TRectD rasterBbox = convertRasterToWorld(box, m_currentImage);
Toshihiro Shimizu 890ddd
	TStroke intersectedStroke = getIntersectedStroke(stroke, rasterBbox);
Toshihiro Shimizu 890ddd
	if ((int)intersectedStroke.getControlPointCount() == 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_strokes.push_back(intersectedStroke);
Toshihiro Shimizu 890ddd
	m_originalStrokes.push_back(intersectedStroke);
Toshihiro Shimizu 890ddd
	notify();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::select(const TRectD &rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!!m_currentImage);
Toshihiro Shimizu 890ddd
	TRectD r = rect;
Toshihiro Shimizu 890ddd
	TRect box = getRaster(m_currentImage)->getBounds();
Toshihiro Shimizu 890ddd
	r *= convertRasterToWorld(box, m_currentImage);
Toshihiro Shimizu 890ddd
	if (!r.isEmpty()) {
Toshihiro Shimizu 890ddd
		TStroke stroke = getStrokeByRect(r);
Toshihiro Shimizu 890ddd
		if ((int)stroke.getControlPointCount() == 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_strokes.push_back(stroke);
Toshihiro Shimizu 890ddd
		m_originalStrokes.push_back(stroke);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	notify();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::selectAll()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_currentImage)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	selectNone();
Toshihiro Shimizu 890ddd
	TRectD wRect = convertRasterToWorld(getRaster(m_currentImage)->getBounds(), m_currentImage);
Toshihiro Shimizu 890ddd
	select(wRect);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool RasterSelection::isEmpty() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getStrokesBound(m_strokes).isEmpty();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::enableCommands()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Clear, &RasterSelection::deleteSelection);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Cut, &RasterSelection::cutSelection);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Copy, &RasterSelection::copySelection);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Paste, &RasterSelection::pasteSelection);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_SelectAll, &RasterSelection::selectAll);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool RasterSelection::isFloating() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_floatingSelection;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::transform(const TAffine &affine)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_affine = affine * m_affine;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::makeFloating()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (isEmpty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (!m_currentImage)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	m_floatingSelection = getImageFromSelection(m_currentImage, *this);
Toshihiro Shimizu 890ddd
	m_originalfloatingSelection = m_floatingSelection->clone();
Toshihiro Shimizu 890ddd
	deleteSelectionWithoutUndo(m_currentImage, m_strokes);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToolUtils::updateSaveBox();
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	tool->notifyImageChanged(m_fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::pasteFloatingSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!isFloating())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(m_transformationCount != -1 && m_transformationCount != -2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_isPastedSelection)
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->popUndo(m_transformationCount + 1);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->popUndo(m_transformationCount);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_transformationCount > 0 || m_isPastedSelection)
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->add(new UndoPasteFloatingSelection(
Toshihiro Shimizu 890ddd
			this, m_oldPalette.getPointer(), m_noAntialiasing));
Toshihiro Shimizu 890ddd
	else if (m_transformationCount == 0)
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->popUndo(-1, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRectD wRect = getSelectionBbox();
Toshihiro Shimizu 890ddd
	pasteFloatingSelectionWithoutUndo(m_currentImage, m_floatingSelection, m_affine, wRect, m_noAntialiasing);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToolUtils::updateSaveBox(m_currentImageCell.getSimpleLevel(),
Toshihiro Shimizu 890ddd
							 m_currentImageCell.getFrameId());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	setFloatingSeletion(TRasterP());
Toshihiro Shimizu 890ddd
	selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	tool->notifyImageChanged(m_fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::deleteSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_currentImage)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
	// we have to remove all undo transformation and the undo for the makeFloating operation!
Toshihiro Shimizu 890ddd
	if (isFloating()) {
Toshihiro Shimizu 890ddd
		assert(m_transformationCount != -1 && m_transformationCount != -2);
Toshihiro Shimizu 890ddd
		if (m_isPastedSelection)
Toshihiro Shimizu 890ddd
			TUndoManager::manager()->popUndo(m_transformationCount + 1);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			TUndoManager::manager()->popUndo(m_transformationCount);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!isPastedSelection() && !isEmpty())
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->add(new UndoDeleteSelection(this, level));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!isFloating())
Toshihiro Shimizu 890ddd
		deleteSelectionWithoutUndo(m_currentImage, m_strokes);
Toshihiro Shimizu 890ddd
	else if (m_oldPalette)
Toshihiro Shimizu 890ddd
		m_currentImage->getPalette()->assign(m_oldPalette.getPointer());
Toshihiro Shimizu 890ddd
	m_floatingSelection = TRasterP();
Toshihiro Shimizu 890ddd
	m_originalfloatingSelection = TRasterP();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ToolUtils::updateSaveBox();
Toshihiro Shimizu 890ddd
	selectNone();
Toshihiro Shimizu 890ddd
	app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
	TTool *tool = app->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	tool->notifyImageChanged(m_fid);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::copySelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (isEmpty() || !m_currentImage)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	if (!isFloating())
Toshihiro Shimizu 890ddd
		ras = getImageFromSelection(m_currentImage, *this);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		ras = m_floatingSelection;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double dpix, dpiy;
Toshihiro Shimizu 890ddd
	std::vector<trectd> rect;</trectd>
Toshihiro Shimizu 890ddd
	if (TToonzImageP ti = (TToonzImageP)(m_currentImage)) {
Toshihiro Shimizu 890ddd
		ToonzImageData *data = new ToonzImageData();
Toshihiro Shimizu 890ddd
		ti->getDpi(dpix, dpiy);
Toshihiro Shimizu 890ddd
		data->setData(ras, ti->getPalette(), dpix, dpiy, ti->getSize(), rect, m_strokes, m_originalStrokes, m_affine);
Toshihiro Shimizu 890ddd
		QApplication::clipboard()->setMimeData(cloneData(data));
Toshihiro Shimizu 890ddd
	} else if (TRasterImageP ri = (TRasterImageP)(m_currentImage)) {
Toshihiro Shimizu 890ddd
		FullColorImageData *data = new FullColorImageData();
Toshihiro Shimizu 890ddd
		ri->getDpi(dpix, dpiy);
Toshihiro Shimizu 890ddd
		data->setData(ras, ri->getPalette(), dpix, dpiy, ri->getRaster()->getSize(), rect, m_strokes, m_originalStrokes, m_affine);
Toshihiro Shimizu 890ddd
		QApplication::clipboard()->setMimeData(cloneData(data));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::cutSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	copySelection();
Toshihiro Shimizu 890ddd
	deleteSelection();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::pasteSelection(const RasterImageData *riData)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::vector<trectd> rect;</trectd>
Toshihiro Shimizu 890ddd
	double currentDpiX, currentDpiY;
Toshihiro Shimizu 890ddd
	double dpiX, dpiY;
Toshihiro Shimizu 890ddd
	const ToonzImageData *toonzImageData = dynamic_cast<const *="" toonzimagedata="">(riData);</const>
Toshihiro Shimizu 890ddd
	const FullColorImageData *fullColorData = dynamic_cast<const *="" fullcolorimagedata="">(riData);</const>
Toshihiro Shimizu 890ddd
	if (TToonzImageP ti = (TToonzImageP)m_currentImage) {
Toshihiro Shimizu 890ddd
		ti->getDpi(currentDpiX, currentDpiY);
Toshihiro Shimizu 890ddd
		TRasterP cmRas;
Toshihiro Shimizu 890ddd
		if (fullColorData) {
Toshihiro Shimizu 890ddd
			DVGui::error(QObject::tr("The copied selection cannot be pasted in the current drawing."));
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		riData->getData(cmRas, dpiX, dpiY, rect, m_strokes, m_originalStrokes, m_affine, m_currentImage->getPalette());
Toshihiro Shimizu 890ddd
		if (!cmRas)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		m_floatingSelection = cmRas;
Toshihiro Shimizu 890ddd
	} else if (TRasterImageP ri = (TRasterImageP)m_currentImage) {
Toshihiro Shimizu 890ddd
		ri->getDpi(currentDpiX, currentDpiY);
Toshihiro Shimizu 890ddd
		TRasterP ras;
Toshihiro Shimizu 890ddd
		riData->getData(ras, dpiX, dpiY, rect, m_strokes, m_originalStrokes, m_affine, ri->getPalette());
Toshihiro Shimizu 890ddd
		if (!ras)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		if (TRasterCM32P rasCM = ras) {
Toshihiro Shimizu 890ddd
			TDimension dim = rasCM->getSize();
Toshihiro Shimizu 890ddd
			TRaster32P app = TRaster32P(dim.lx, dim.ly);
Toshihiro Shimizu 890ddd
			TRop::convert(app, rasCM, ri->getPalette());
Toshihiro Shimizu 890ddd
			ras = app;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		m_floatingSelection = ras;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_floatingSelection)
Toshihiro Shimizu 890ddd
		m_originalfloatingSelection = m_floatingSelection->clone();
Toshihiro Shimizu 890ddd
	TScale sc;
Toshihiro Shimizu 890ddd
	if (dpiX != 0 && dpiY != 0 && currentDpiX != 0 && currentDpiY != 0)
Toshihiro Shimizu 890ddd
		sc = TScale(currentDpiX / dpiX, currentDpiY / dpiY);
Toshihiro Shimizu 890ddd
	m_affine = m_affine * sc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::pasteSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	TTool *tool = app->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	TImageP image = tool->getImage(true);
Toshihiro Shimizu 890ddd
	m_currentImage = image;
Toshihiro Shimizu 890ddd
	m_fid = tool->getCurrentFid();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
	const RasterImageData *riData = dynamic_cast<const *="" rasterimagedata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
	const StrokesData *stData = dynamic_cast<const *="" strokesdata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
	if (!riData && !stData)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (isFloating())
Toshihiro Shimizu 890ddd
		pasteFloatingSelection();
Toshihiro Shimizu 890ddd
	selectNone();
Toshihiro Shimizu 890ddd
	m_isPastedSelection = true;
Toshihiro Shimizu 890ddd
	m_oldPalette = m_currentImage->getPalette()->clone();
Toshihiro Shimizu 890ddd
	if (stData) {
Toshihiro Shimizu 890ddd
		if (TToonzImageP ti = m_currentImage)
Toshihiro Shimizu 890ddd
			riData = stData->toToonzImageData(ti);
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			TRasterImageP ri = m_currentImage;
Toshihiro Shimizu 890ddd
			assert(ri);
Toshihiro Shimizu 890ddd
			double dpix, dpiy;
Toshihiro Shimizu 890ddd
			ri->getDpi(dpix, dpiy);
Toshihiro Shimizu 890ddd
			if (dpix == 0 || dpiy == 0) {
Toshihiro Shimizu 890ddd
				TPointD dpi = tool->getXsheet()->getScene()->getCurrentCamera()->getDpi();
Toshihiro Shimizu 890ddd
				dpix = dpi.x;
Toshihiro Shimizu 890ddd
				dpiy = dpi.y;
Toshihiro Shimizu 890ddd
				ri->setDpi(dpix, dpiy);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			riData = stData->toFullColorImageData(ri);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!riData)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	pasteSelection(riData);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	app->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
	notify();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(new UndoPasteSelection(this));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool RasterSelection::isTransformed()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return !m_affine.isIdentity();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD RasterSelection::getStrokesBound(std::vector<tstroke> strokes) const</tstroke>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	TRectD box = TRectD();
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)strokes.size(); i++)
Toshihiro Shimizu 890ddd
		box += strokes[i].getBBox();
Toshihiro Shimizu 890ddd
	return box;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD RasterSelection::getSelectionBound() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_strokes.size() == 0)
Toshihiro Shimizu 890ddd
		return TRectD();
Toshihiro Shimizu 890ddd
	TRectD selectionBox = getStrokesBound(m_strokes);
Toshihiro Shimizu 890ddd
	if (isFloating())
Toshihiro Shimizu 890ddd
		selectionBox = m_affine * selectionBox;
Toshihiro Shimizu 890ddd
	return selectionBox;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD RasterSelection::getOriginalSelectionBound() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_originalStrokes.size() == 0)
Toshihiro Shimizu 890ddd
		return TRectD();
Toshihiro Shimizu 890ddd
	return getStrokesBound(m_originalStrokes);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRectD RasterSelection::getSelectionBbox() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRectD rect = m_selectionBbox;
Toshihiro Shimizu 890ddd
	if (isFloating())
Toshihiro Shimizu 890ddd
		rect = m_affine * m_selectionBbox;
Toshihiro Shimizu 890ddd
	return rect;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void RasterSelection::setSelectionBbox(const TRectD &rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_selectionBbox = rect;
Toshihiro Shimizu 890ddd
	if (m_currentImage)
Toshihiro Shimizu 890ddd
		m_selectionBbox = intersection(m_selectionBbox, m_currentImage);
Toshihiro Shimizu 890ddd
}