Beispiel #1
0
bool kpToolAutoCrop (kpMainWindow *mainWindow)
{
#if DEBUG_KP_TOOL_AUTO_CROP
    kdDebug () << "kpToolAutoCrop() CALLED!" << endl;
#endif

    if (!mainWindow)
    {
        kdError () << "kpToolAutoCrop() passed NULL mainWindow" << endl;
        return false;
    }

    kpDocument *doc = mainWindow->document ();
    if (!doc)
    {
        kdError () << "kpToolAutoCrop() passed NULL document" << endl;
        return false;
    }

    // OPT: if already pulled selection pixmap, no need to do it again here
    QPixmap pixmap = doc->selection () ? doc->getSelectedPixmap () : *doc->pixmap ();
    if (pixmap.isNull ())
    {
        kdError () << "kptoolAutoCrop() pased NULL pixmap" << endl;
        return false;
    }

    kpViewManager *vm = mainWindow->viewManager ();
    if (!vm)
    {
        kdError () << "kpToolAutoCrop() passed NULL vm" << endl;
        return false;
    }

    int processedColorSimilarity = mainWindow->colorToolBar ()->processedColorSimilarity ();
    kpToolAutoCropBorder leftBorder (&pixmap, processedColorSimilarity),
                         rightBorder (&pixmap, processedColorSimilarity),
                         topBorder (&pixmap, processedColorSimilarity),
                         botBorder (&pixmap, processedColorSimilarity);


    kpSetOverrideCursorSaver cursorSaver (Qt::waitCursor);

    // TODO: With Colour Similarity, a lot of weird (and wonderful) things can
    //       happen resulting in a huge number of code paths.  Needs refactoring
    //       and regression testing.
    //
    // TODO: e.g. When the top fills entire rect but bot doesn't we could
    //       invalidate top and continue autocrop.
    int numRegions = 0;
    if (!leftBorder.calculate (true/*x*/, +1/*going right*/) ||
            leftBorder.fillsEntirePixmap () ||
            !rightBorder.calculate (true/*x*/, -1/*going left*/) ||
            rightBorder.fillsEntirePixmap () ||
            !topBorder.calculate (false/*y*/, +1/*going down*/) ||
            topBorder.fillsEntirePixmap () ||
            !botBorder.calculate (false/*y*/, -1/*going up*/) ||
            botBorder.fillsEntirePixmap () ||
            ((numRegions = leftBorder.exists () +
                           rightBorder.exists () +
                           topBorder.exists () +
                           botBorder.exists ()) == 0))
    {
#if DEBUG_KP_TOOL_AUTO_CROP
        kdDebug () << "\tcan't find border; leftBorder.rect=" << leftBorder.rect ()
                   << " rightBorder.rect=" << rightBorder.rect ()
                   << " topBorder.rect=" << topBorder.rect ()
                   << " botBorder.rect=" << botBorder.rect ()
                   << endl;
#endif
        ::showNothingToAutocropMessage (mainWindow, (bool) doc->selection ());
        return false;
    }

#if DEBUG_KP_TOOL_AUTO_CROP
    kdDebug () << "\tnumRegions=" << numRegions << endl;
    kdDebug () << "\t\tleft=" << leftBorder.rect ()
               << " refCol=" << (leftBorder.exists () ? (int *) leftBorder.referenceColor ().toQRgb () : 0)
               << " avgCol=" << (leftBorder.exists () ? (int *) leftBorder.averageColor ().toQRgb () : 0)
               << endl;
    kdDebug () << "\t\tright=" << rightBorder.rect ()
               << " refCol=" << (rightBorder.exists () ? (int *) rightBorder.referenceColor ().toQRgb () : 0)
               << " avgCol=" << (rightBorder.exists () ? (int *) rightBorder.averageColor ().toQRgb () : 0)
               << endl;
    kdDebug () << "\t\ttop=" << topBorder.rect ()
               << " refCol=" << (topBorder.exists () ? (int *) topBorder.referenceColor ().toQRgb () : 0)
               << " avgCol=" << (topBorder.exists () ? (int *) topBorder.averageColor ().toQRgb () : 0)
               << endl;
    kdDebug () << "\t\tbot=" << botBorder.rect ()
               << " refCol=" << (botBorder.exists () ? (int *) botBorder.referenceColor ().toQRgb () : 0)
               << " avgCol=" << (botBorder.exists () ? (int *) botBorder.averageColor ().toQRgb () : 0)
               << endl;
#endif


    // In case e.g. the user pastes a solid, coloured-in rectangle,
    // we favour killing the bottom and right regions
    // (these regions probably contain the unwanted whitespace due
    //  to the doc being bigger than the pasted selection to start with).
    //
    // We also kill if they kiss or even overlap.

    if (leftBorder.exists () && rightBorder.exists ())
    {
        const kpColor leftCol = leftBorder.averageColor ();
        const kpColor rightCol = rightBorder.averageColor ();

        if ((numRegions == 2 && !leftCol.isSimilarTo (rightCol, processedColorSimilarity)) ||
                leftBorder.right () >= rightBorder.left () - 1)  // kissing or overlapping
        {
#if DEBUG_KP_TOOL_AUTO_CROP
            kdDebug () << "\tignoring left border" << endl;
#endif
            leftBorder.invalidate ();
        }
    }

    if (topBorder.exists () && botBorder.exists ())
    {
        const kpColor topCol = topBorder.averageColor ();
        const kpColor botCol = botBorder.averageColor ();

        if ((numRegions == 2 && !topCol.isSimilarTo (botCol, processedColorSimilarity)) ||
                topBorder.bottom () >= botBorder.top () - 1)  // kissing or overlapping
        {
#if DEBUG_KP_TOOL_AUTO_CROP
            kdDebug () << "\tignoring top border" << endl;
#endif
            topBorder.invalidate ();
        }
    }


    mainWindow->addImageOrSelectionCommand (
        new kpToolAutoCropCommand (
            (bool) doc->selection (),
            leftBorder, rightBorder,
            topBorder, botBorder,
            mainWindow));


    return true;
}
std::string MapEditor::blockType(Terrain* terrain){

	bool leftOccupied(false);
	bool rightOccupied(false);
	bool topOccupied(false);
	bool botOccupied(false);
	bool topLeftOccupied(true);
	bool topRightOccupied(true);
	bool botLeftOccupied(true);
	bool botRightOccupied(true);

	sf::Vector2f thisPos(terrain->getPos());
	std::string returnString;

	Terrains relevantTerrains;
	for (Terrains::size_type i = 0; i < mTerrains.size(); i++){
		if (mTerrains[i]->getPos().x < thisPos.x + 200 && mTerrains[i]->getPos().x > thisPos.x - 200)
			if(mTerrains[i]->getType() == Terrain::BLOCK0 || 
				mTerrains[i]->getType() == Terrain::BLOCK0ICY || 
				mTerrains[i]->getType() == Terrain::BLOCK0WALLJUMP)
			relevantTerrains.push_back(mTerrains[i]);
	}

	
	sf::Vector2f leftBorder(thisPos.x - 1, 
		thisPos.y + (terrain->getHeight()/ 2));
	sf::Vector2f rightBorder(thisPos.x + terrain->getWidth() + 1, 
		thisPos.y + (terrain->getHeight() / 2));
	sf::Vector2f topBorder(thisPos.x + (terrain->getWidth() / 2), 
		thisPos.y - 1);
	sf::Vector2f botBorder(thisPos.x + (terrain->getWidth() / 2), 
		thisPos.y + (terrain->getHeight() + 1));
	sf::Vector2f topLeftBorder(terrain->getPos());
	topLeftBorder.x -= 1;
	topLeftBorder.y -= 1;
	sf::Vector2f topRightBorder(terrain->getPos());
	topRightBorder.x += terrain->getWidth() + 1;
	topRightBorder.y -= 1;
	sf::Vector2f botLeftBorder(terrain->getPos());
	botLeftBorder.x -= 1;
	botLeftBorder.y += terrain->getHeight() + 1;
	sf::Vector2f botRightBorder(terrain->getPos());
	botRightBorder.x += terrain->getWidth() + 1;
	botRightBorder.y += terrain->getHeight() + 1;

	for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++){
		if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &leftBorder))
			leftOccupied = true;
		if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &rightBorder))
			rightOccupied = true;
		if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topBorder))
			topOccupied = true;
		if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botBorder))
			botOccupied = true;
	}

	if (leftOccupied && rightOccupied && topOccupied && botOccupied)
		returnString.push_back('a');
	if (leftOccupied && rightOccupied && topOccupied && !botOccupied)
		returnString.push_back('b');
	if (leftOccupied && rightOccupied && !topOccupied && botOccupied)
		returnString.push_back('c');
	if (leftOccupied && !rightOccupied && topOccupied && botOccupied)
		returnString.push_back('d');
	if (!leftOccupied && rightOccupied && topOccupied && botOccupied)
		returnString.push_back('e');
	if (leftOccupied && rightOccupied && !topOccupied && !botOccupied)
		returnString.push_back('f');
	if (leftOccupied && !rightOccupied && topOccupied && !botOccupied)
		returnString.push_back('g');
	if (!leftOccupied && rightOccupied && topOccupied && !botOccupied)
		returnString.push_back('h');
	if (leftOccupied && !rightOccupied && !topOccupied && botOccupied)
		returnString.push_back('i');
	if (!leftOccupied && rightOccupied && !topOccupied && botOccupied)
		returnString.push_back('j');
	if (!leftOccupied && !rightOccupied && topOccupied && botOccupied)
		returnString.push_back('k');
	if (leftOccupied && !rightOccupied && !topOccupied && !botOccupied)
		returnString.push_back('l');
	if (!leftOccupied && rightOccupied && !topOccupied && !botOccupied)
		returnString.push_back('m');
	if (!leftOccupied && !rightOccupied && topOccupied && !botOccupied)
		returnString.push_back('n');
	if (!leftOccupied && !rightOccupied && !topOccupied && botOccupied)
		returnString.push_back('o');
	if (!leftOccupied && !rightOccupied && !topOccupied && !botOccupied)
		returnString.push_back('p');

	bool tileDecNeeded(false);

	if (returnString[0] == 'a') {
		topLeftOccupied = false;
		topRightOccupied = false;
		botLeftOccupied = false;
		botRightOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
		
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topLeftBorder))
				topLeftOccupied = true;
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topRightBorder))
				topRightOccupied = true;
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botLeftBorder))
				botLeftOccupied = true;
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botRightBorder))
				botRightOccupied = true;

		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'b') {
		topLeftOccupied = false;
		topRightOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {

			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topLeftBorder))
				topLeftOccupied = true;
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topRightBorder))
				topRightOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'c') {
		botLeftOccupied = false;
		botRightOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botLeftBorder))
				botLeftOccupied = true;
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botRightBorder))
				botRightOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'd') {
		topLeftOccupied = false;
		botLeftOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topLeftBorder))
				topLeftOccupied = true;
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botLeftBorder))
				botLeftOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'e') {
		topRightOccupied = false;
		botRightOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topRightBorder))
				topRightOccupied = true;
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botRightBorder))
				botRightOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'g') {
		topLeftOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topLeftBorder))
				topLeftOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'h') {
		topRightOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &topRightBorder))
				topRightOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'i') {
		botLeftOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botLeftBorder))
				botLeftOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (returnString[0] == 'j') {
		botRightOccupied = false;
		for (Terrains::size_type i = 0; i < relevantTerrains.size(); i++) {
			if (MapEditor::isSpriteClicked(relevantTerrains[i]->getSprite(), &botRightBorder))
				botRightOccupied = true;
		}
		tileDecNeeded = true;
	}
	if (tileDecNeeded) {
		if (!topLeftOccupied && !topRightOccupied && !botRightOccupied && !botLeftOccupied)
			returnString.push_back('a');
		if (topLeftOccupied && topRightOccupied && !botRightOccupied && !botLeftOccupied)
			returnString.push_back('b');
		if (!topLeftOccupied && topRightOccupied && botRightOccupied && !botLeftOccupied)
			returnString.push_back('c');
		if (topLeftOccupied && !topRightOccupied && !botRightOccupied && botLeftOccupied)
			returnString.push_back('d');
		if (!topLeftOccupied && !topRightOccupied && botRightOccupied && botLeftOccupied)
			returnString.push_back('e');
		if (!topLeftOccupied && topRightOccupied && botRightOccupied && botLeftOccupied)
			returnString.push_back('f');
		if (topLeftOccupied && !topRightOccupied && botRightOccupied && botLeftOccupied)
			returnString.push_back('g');
		if (topLeftOccupied && topRightOccupied && !botRightOccupied && botLeftOccupied)
			returnString.push_back('h');
		if (topLeftOccupied && topRightOccupied && botRightOccupied && !botLeftOccupied)
			returnString.push_back('i');
		if (topLeftOccupied && !topRightOccupied && !botRightOccupied && !botLeftOccupied)
			returnString.push_back('j');
		if (!topLeftOccupied && topRightOccupied && !botRightOccupied && !botLeftOccupied)
			returnString.push_back('k');
		if (!topLeftOccupied && !topRightOccupied && botRightOccupied && !botLeftOccupied)
			returnString.push_back('l');
		if (!topLeftOccupied && !topRightOccupied && !botRightOccupied && botLeftOccupied)
			returnString.push_back('m');	
	}

	return returnString;
}