QRect KisPixelSelection::selectedExactRect() const { if (*(m_datamanager->defaultPixel()) == MIN_SELECTED) { if (m_d->parentPaintDevice) { // The selected exact rect is the area of this selection that overlaps // with the parent paint device. return m_d->parentPaintDevice->exactBounds().intersected(exactBounds()); } else { return exactBounds(); } } else { if (m_d->parentPaintDevice) { // By default all pixels are selected, to the size of the parent paint device. return m_d->parentPaintDevice->exactBounds(); } else { // By default all pixels are selected; no matter how many pixels are // marked as deselected, there are always by-default-selected pixels // around the deselected pixels. return QRect(0, 0, qint32_MAX, qint32_MAX); } } }
QVector<QPolygon> KisPixelSelection::outline() { quint8 defaultPixel = *(m_datamanager->defaultPixel()); QRect selectionExtent = exactBounds(); qint32 xOffset = selectionExtent.x(); qint32 yOffset = selectionExtent.y(); qint32 width = selectionExtent.width(); qint32 height = selectionExtent.height(); quint8* buffer = new quint8[width*height]; quint8* marks = new quint8[width*height]; for (int i = 0; i < width*height; i++) { marks[i] = 0; } QVector<QPolygon> paths; readBytes(buffer, xOffset, yOffset, width, height); int nodes = 0; for (qint32 y = 0; y < height; y++) { for (qint32 x = 0; x < width; x++) { if (buffer[y*width+x] == defaultPixel) continue; EdgeType startEdge = TopEdge; EdgeType edge = startEdge; while (edge != NoEdge && (marks[y*width+x] & (1 << edge) || !isOutlineEdge(edge, x, y, buffer, width, height))) { edge = nextEdge(edge); if (edge == startEdge) edge = NoEdge; } if (edge != NoEdge) { QPolygon path; path << QPoint(x + xOffset, y + yOffset); // XXX: Unused? (BSAR) // bool clockwise = edge == BottomEdge; qint32 row = y, col = x; EdgeType currentEdge = edge; EdgeType lastEdge = currentEdge; do { //While following a strait line no points nead to be added if (lastEdge != currentEdge) { appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge); nodes++; lastEdge = currentEdge; } marks[row*width+col] |= 1 << currentEdge; nextOutlineEdge(¤tEdge, &row, &col, buffer, width, height); } while (row != y || col != x || currentEdge != edge); paths.push_back(path); } } } delete[] buffer; delete[] marks; return paths; }
QRect KisPixelSelection::selectedExactRect() const { return exactBounds(); }