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; }