本文整理汇总了C++中QPainterPath::simplified方法的典型用法代码示例。如果您正苦于以下问题:C++ QPainterPath::simplified方法的具体用法?C++ QPainterPath::simplified怎么用?C++ QPainterPath::simplified使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QPainterPath
的用法示例。
在下文中一共展示了QPainterPath::simplified方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: path
QPainterPath CPcbCircle::path()
{
QPainterPath ppath;
QPoint topLeft(-radius(),-radius());
QPoint bottomRight(radius(),radius());
ppath.addEllipse(QRectF(topLeft,bottomRight));
return ppath.simplified();
}
示例2: paintEvent
void BalloonTip::paintEvent(QPaintEvent * /*ev*/)
{
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
painter.setBrush(Qt::white);
painter.setPen(QColor(0, 0, 0, 130));
painter.setFont(this->font());
QRect popupRect = relativePopupRect();
QRect textRect = relativeTextRect();
QPainterPath path;
QPolygon arrowTriangle;
switch (my_arrowPos) {
case BottomLeft:
arrowTriangle << QPoint(30, popupRect.height() + 60) << QPoint(60, popupRect.height() + 30)
<< QPoint(90, popupRect.height() + 30);
break;
case TopLeft:
arrowTriangle << QPoint(30, 0) << QPoint(60, 15) << QPoint(90, 15);
break;
case BottomRight:
arrowTriangle << QPoint(popupRect.width() - 30, popupRect.height() + 60)
<< QPoint(popupRect.width() - 60, popupRect.height() + 30)
<< QPoint(popupRect.width() - 90, popupRect.height() + 30);
break;
case TopRight:
arrowTriangle << QPoint(popupRect.width() - 30, 0) << QPoint(popupRect.width() - 60, 30)
<< QPoint(popupRect.width() - 90, 30);
break;
case LeftTop:
arrowTriangle << QPoint(popupRect.left() - 10, popupRect.height() * 0.6)
<< QPoint(popupRect.left(), popupRect.height() * 0.6 + 5)
<< QPoint(popupRect.left(), popupRect.height() * 0.6 - 5);
break;
}
path.addPolygon(arrowTriangle);
path.addRoundedRect(popupRect, 1, 1);
path = path.simplified();
painter.drawPath(path);
painter.setPen(QColor(20, 20, 20));
painter.drawText(textRect, my_text);
QFont font = this->font();
font.setBold(true);
font.setPixelSize(12);
painter.setFont(font);
painter.setPen(QColor(48, 159, 220));
if (!my_icon.isNull()) {
painter.drawText(textRect.topLeft() + QPoint(20, -10), my_title);
painter.drawPixmap(textRect.topLeft() + QPoint(0, -22), my_icon);
} else {
painter.drawText(textRect.topLeft() + QPoint(5, -10), my_title);
}
}
示例3: testSplitDisjointPaths
void KisGradientPainterTest::testSplitDisjointPaths()
{
QPainterPath path;
// small bug: the smaller rect is also merged
path.addRect(QRectF(323, 123, 4, 4));
path.addRect(QRectF(300, 100, 50, 50));
path.addRect(QRectF(320, 120, 10, 10));
path.addRect(QRectF(200, 100, 50, 50));
path.addRect(QRectF(240, 120, 70, 10));
path.addRect(QRectF(100, 100, 50, 50));
path.addRect(QRectF(120, 120, 10, 10));
path = path.simplified();
{
QImage srcImage(450, 250, QImage::Format_ARGB32);
srcImage.fill(0);
QPainter gc(&srcImage);
gc.fillPath(path, Qt::red);
//srcImage.save("src_disjoint_paths.png");
}
QList<QPainterPath> result = KritaUtils::splitDisjointPaths(path);
{
QImage dstImage(450, 250, QImage::Format_ARGB32);
dstImage.fill(0);
QPainter gc(&dstImage);
QVector<QBrush> brushes;
brushes << Qt::red;
brushes << Qt::green;
brushes << Qt::blue;
brushes << Qt::cyan;
brushes << Qt::magenta;
brushes << Qt::yellow;
brushes << Qt::black;
brushes << Qt::white;
int index = 0;
Q_FOREACH (const QPainterPath &p, result) {
gc.fillPath(p, brushes[index]);
index = (index + 1) % brushes.size();
}
TestUtil::checkQImageExternal(dstImage,
"shaped_gradient",
"test",
"disjoint_paths");
}
示例4: paint
void Callout::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* w)
{
Q_UNUSED(option);
Q_UNUSED(w);
QPainterPath path;
path.addRoundedRect(rect, 5, 5);
auto anchor = mapFromParent(chart->mapToPosition(this->anchor));
if (!rect.contains(anchor))
{
QPointF point1, point2;
// establish the position of the anchor point in relation to rect
auto above = anchor.y() <= rect.top();
auto aboveCenter = anchor.y() > rect.top() && anchor.y() <= rect.center().y();
auto belowCenter = anchor.y() > rect.center().y() && anchor.y() <= rect.bottom();
auto below = anchor.y() > rect.bottom();
auto onLeft = anchor.x() <= rect.left();
auto leftOfCenter = anchor.x() > rect.left() && anchor.x() <= rect.center().x();
auto rightOfCenter = anchor.x() > rect.center().x() && anchor.x() <= rect.right();
auto onRight = anchor.x() > rect.right();
// get the nearest rect corner.
auto x = (onRight + rightOfCenter) * rect.width();
auto y = (below + belowCenter) * rect.height();
auto cornerCase = (above && onLeft) || (above && onRight) || (below && onLeft) || (below && onRight);
auto vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y);
auto x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * !vertical * (onLeft * 10 - onRight * 20);
auto y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (above * 10 - below * 20);;
point1.setX(x1);
point1.setY(y1);
auto x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * !vertical * (onLeft * 20 - onRight * 10);;
auto y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (above * 20 - below * 10);;
point2.setX(x2);
point2.setY(y2);
path.moveTo(point1);
path.lineTo(anchor);
path.lineTo(point2);
path = path.simplified();
}
painter->setBrush(QColor(255, 255, 255));
painter->drawPath(path);
painter->drawText(textRect, text);
}
示例5: paintEvent
void TitleBar::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.setBrush(_background);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.setFillRule(Qt::WindingFill);
path.addRoundedRect(QRect(0, 0, width(), height()), _radius, _radius);
//bottomRight
path.addRect(QRect(width() - _radius, height() - _radius, _radius, _radius));
//bottomLeft
path.addRect(QRect(0, height() - _radius, _radius, _radius));
painter.drawPath(path.simplified());
}
示例6: paintEvent
void Window::paintEvent(QPaintEvent *) {
QPainter painter(this);
if (_hasShadow) {
drawShadow(painter, _borderWidth, _radius, QColor(120, 120, 120, 32), QColor(255, 255, 255, 0), 0.0, 1.0, 0.6, width(), height());
} else {
painter.setBrush(QColor("#FFFFFF"));
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
path.setFillRule(Qt::WindingFill);
path.addRoundedRect(QRect(0, 0, width(), height()), _radius, _radius);
painter.drawPath(path.simplified());
}
}
示例7: getPainterPath
QPainterPath XYTempWindows::getPainterPath(const QRect &rect, XYTempWindows::DIRECTION direction)
{
QPainterPath path;
int arrow_h = 5;
switch (direction)
{
case TOP:
arrow_h = rect.height() * 0.1;
textRect = QRect(rect.x() + 1, rect.y() + arrow_h + 1,
rect.width() - 2, rect.height() - arrow_h - 2);
path.addRoundedRect(textRect, 4, 4);
path.moveTo(rect.x() + rect.width() / 2 - arrow_h / 2, rect.y() + arrow_h + 1);
path.lineTo(rect.x() + rect.width() / 2, rect.y());
path.lineTo(rect.x() + rect.width() / 2 + arrow_h / 2, rect.y() + arrow_h + 1);
break;
case BOTTOM:
arrow_h = rect.height() * 0.1;
textRect = QRect(rect.x() + 1, rect.y() + 1,
rect.width() - 2, rect.height() - arrow_h - 1);
path.addRoundedRect(textRect, 4, 4);
path.moveTo(rect.x() + rect.width() / 2 - arrow_h / 2, rect.y() + rect.height() - arrow_h);
path.lineTo(rect.x() + rect.width() / 2, rect.y() + rect.height());
path.lineTo(rect.x() + rect.width() / 2 + arrow_h / 2, rect.y() + rect.height() - arrow_h);
break;
case LEFT:
arrow_h = rect.height() * 0.1;
textRect = QRect(rect.x() + arrow_h, rect.y() + 1,
rect.width() - arrow_h - 2, rect.height() - 2);
path.addRoundedRect(textRect, 4, 4);
path.moveTo(rect.x() + arrow_h, rect.y() + rect.height() / 2 - arrow_h / 2);
path.lineTo(rect.x() - 2, rect.y() + rect.height() / 2);
path.lineTo(rect.x() + arrow_h, rect.y() + rect.height() / 2 + arrow_h / 2);
break;
case RIGHT:
arrow_h = rect.height() * 0.1;
textRect = QRect(rect.x() + 1, rect.y() + 1,
rect.width() - arrow_h - 2, rect.height() - 2);
path.addRoundedRect(textRect, 4, 4);
path.moveTo(rect.x() - 1 + rect.width() - arrow_h, rect.y() + rect.height() / 2 - arrow_h / 2);
path.lineTo(rect.x() - 1 + rect.width(), rect.y() + rect.height() / 2);
path.lineTo(rect.x() - 1 + rect.width() - arrow_h, rect.y() + rect.height() / 2 + arrow_h / 2);
break;
default:
break;
}
return path.simplified();
}
示例8: textPath
QPainterPath EvButton::textPath() const
{
QPainterPath path;
path.setFillRule( Qt::WindingFill);
QRect rect = textRect();
if(m_rounded){
float roundness = this->roundness();
path.addRoundRect( rect, roundness );
path.addRect( QRect(rect.x(),0, roundness,roundness ) );
path.addRect( QRect( rect.x(),rect.y() , roundness,roundness ) );
}
else{
path.addRect(rect);
}
return path.simplified();
}
示例9: outline
QPolygonF Carton::outline() const
{
#if QT_VERSION >= 0x040400
QPainterPath painterPath;
if (isFaceVisibleFromFront(Top))
painterPath.addPolygon(face2d(Top));
if (isFaceVisibleFromFront(Left))
painterPath.addPolygon(face2d(Left));
else if (isFaceVisibleFromFront(Right))
painterPath.addPolygon(face2d(Right));
if (isFaceVisibleFromFront(Front))
painterPath.addPolygon(face2d(Front));
else if (isFaceVisibleFromFront(Back))
painterPath.addPolygon(face2d(Back));
return painterPath.simplified().toFillPolygon();
#else
return QPolygonF();
#endif
}
示例10: shape
/*!
\fn QPainterPath NmHsWidget::shape()
Called by home screen fw to check widget boundaries, needed to draw
outside widget boundingRect.
/return QPainterPath path describing actual boundaries of widget
including child items
*/
QPainterPath NmHsWidget::shape() const
{
NM_FUNCTION;
QPainterPath path;
path.setFillRule(Qt::WindingFill);
if (mWidgetContainer){
//add mWidgetContainer using geometry to get
//correct point for top-left-corner
QRectF widgetRect = mWidgetContainer->geometry();
path.addRect(widgetRect);
//then fetch shape from title row
QPainterPath titlepath;
titlepath.addPath(mTitleRow->shape());
//translate it's location to be inside mWidgetContainer
titlepath.translate(widgetRect.topLeft());
//and finally add it to path
path.addPath(titlepath);
}
//simplified path, i.e. only outlines
return path.simplified();
}
示例11: qwtCombinePathList
//.........这里部分代码省略.........
const QRectF br = pathList[i].controlPointRect();
if ( br.center().x() < rect.center().x() )
{
if ( br.center().y() < rect.center().y() )
{
if ( qAbs( br.top() - rect.top() ) <
qAbs( br.left() - rect.left() ) )
{
index = 1;
}
else
{
index = 0;
}
}
else
{
if ( qAbs( br.bottom() - rect.bottom() ) <
qAbs( br.left() - rect.left() ) )
{
index = 6;
}
else
{
index = 7;
}
}
if ( subPath.currentPosition().y() > br.center().y() )
qwtRevertPath( subPath );
}
else
{
if ( br.center().y() < rect.center().y() )
{
if ( qAbs( br.top() - rect.top() ) <
qAbs( br.right() - rect.right() ) )
{
index = 2;
}
else
{
index = 3;
}
}
else
{
if ( qAbs( br.bottom() - rect.bottom() ) <
qAbs( br.right() - rect.right() ) )
{
index = 5;
}
else
{
index = 4;
}
}
if ( subPath.currentPosition().y() < br.center().y() )
qwtRevertPath( subPath );
}
ordered[index] = subPath;
}
for ( int i = 0; i < 4; i++ )
{
if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() )
{
// we don't accept incomplete rounded borders
return QPainterPath();
}
}
const QPolygonF corners( rect );
QPainterPath path;
//path.moveTo( rect.topLeft() );
for ( int i = 0; i < 4; i++ )
{
if ( ordered[2 * i].isEmpty() )
{
path.lineTo( corners[i] );
}
else
{
path.connectPath( ordered[2 * i] );
path.connectPath( ordered[2 * i + 1] );
}
}
path.closeSubpath();
#if 0
return path.simplified();
#else
return path;
#endif
}
示例12: paint
void QWaylandMaterialDecoration::paint(QPaintDevice *device)
{
QRect surfaceRect(QPoint(), window()->frameGeometry().size());
QRect top(QPoint(), QSize(window()->frameGeometry().width(), margins().top()));
QPainter p(device);
p.setRenderHint(QPainter::Antialiasing);
// Title bar
int radius = waylandWindow()->isMaximized() ? 0 : dp(3);
QPainterPath roundedRect;
roundedRect.addRoundedRect(0, 0, window()->frameGeometry().width(), margins().top() * 1.5,
radius, radius);
p.fillPath(roundedRect.simplified(), m_backgroundColor);
// Window icon
QIcon icon = waylandWindow()->windowIcon();
if (!icon.isNull()) {
QPixmap pixmap = icon.pixmap(QSize(128, 128));
QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
QRectF iconRect(0, 0, 22, 22);
p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
margins().left() + BUTTON_SPACING, 4),
scaled, iconRect);
}
// Window title
QString windowTitleText = window()->title();
if (!windowTitleText.isEmpty()) {
if (m_windowTitle.text() != windowTitleText) {
m_windowTitle.setText(windowTitleText);
m_windowTitle.prepare();
}
QRect titleBar = top;
titleBar.setLeft(margins().left() + BUTTON_SPACING +
(icon.isNull() ? 0 : 22 + BUTTON_SPACING));
titleBar.setRight(minimizeButtonRect().left() - BUTTON_SPACING);
p.save();
p.setClipRect(titleBar);
p.setPen(m_textColor);
QSizeF size = m_windowTitle.size();
int dx = (top.width() - size.width()) / 2;
int dy = (top.height() - size.height()) / 2;
QFont font = p.font();
font.setBold(true);
font.setFamily("Roboto");
p.setFont(font);
QPoint windowTitlePoint(top.topLeft().x() + dx, top.topLeft().y() + dy);
p.drawStaticText(windowTitlePoint, m_windowTitle);
p.restore();
}
p.save();
p.setPen(m_iconColor);
// Close button
QBitmap closeIcon = buttonIcon("window-close");
p.drawPixmap(closeButtonRect(), closeIcon, closeIcon.rect());
// Maximize button
QBitmap maximizeIcon =
buttonIcon(waylandWindow()->isMaximized() ? "window-restore" : "window-maximize");
p.drawPixmap(maximizeButtonRect(), maximizeIcon, maximizeIcon.rect());
// Minimize button
QBitmap minimizeIcon = buttonIcon("window-minimize");
p.drawPixmap(minimizeButtonRect(), minimizeIcon, minimizeIcon.rect());
p.restore();
}
示例13: drawComplexControl
void QRibbonComboBoxStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
{
QProxyStyle::drawComplexControl(control, option, painter, widget);
int rightButtonWidth = 18;
int x = option->rect.x();
int y = option->rect.y();
int cbWidth = option->rect.width();
int cbHeight = option->rect.height();
float arrowX = cbWidth - arrowWidth - (rightButtonWidth - arrowWidth) / 2.0;
float arrowY = (cbHeight - arrowHeight) / 2.0;
QPainterPath* painterPath = new QPainterPath();
// Erase the old border
QRect* borderErased = new QRect(1, 1, cbWidth - 2, cbHeight - 2);
painterPath->addRoundedRect(*borderErased, 0, 0);
painter->strokePath(painterPath->simplified(), QPen(Qt::white, 2));
QDELETE(borderErased);
QDELETE(painterPath);
// Erase the right button part
QRect* rightPartErased = new QRect(0, 0, rightButtonWidth, cbHeight);
rightPartErased->moveLeft(cbWidth - rightButtonWidth);
painter->fillRect(*rightPartErased, Qt::white);
QDELETE(rightPartErased);
// Paint the border of button
painterPath = new QPainterPath();
QRect* border = new QRect(0, 0, cbWidth - 1, cbHeight - 1);
painterPath->addRoundedRect(*border, 0, 0);
bool isHovered = option->state & State_MouseOver;
bool isOpened = option->state & (State_On | State_Sunken);
if (isOpened == true)
{
painter->strokePath(painterPath->simplified(), QPen(QColor("#0078d7"), 1));
}
else
{
painter->strokePath(painterPath->simplified(), QPen(QColor("#5c5c5c"), 1));
}
QDELETE(border);
QDELETE(painterPath);
QPoint globalCursorPos = QCursor::pos();
QPoint widgetPos = widget->mapFromGlobal(globalCursorPos);
// Paint the right part of combobox
if ((isHovered == true || isOpened == true) && widgetPos.x() >= (cbWidth - rightButtonWidth) && widgetPos.x() <= cbWidth)
{
QColor hoveredColor(Qt::green);
QRect* hoverRightPart = new QRect(0, 0, rightButtonWidth, cbHeight);
hoverRightPart->moveLeft(cbWidth - rightButtonWidth);
painter->fillRect(*hoverRightPart, hoveredColor);
QDELETE(hoverRightPart);
// Draw right button border
painterPath = new QPainterPath();
QRect* rightButtonBorder = new QRect(cbWidth - rightButtonWidth, 0, rightButtonWidth - 1, cbHeight - 1);
painterPath->addRoundedRect(*rightButtonBorder, 0, 0);
painter->strokePath(painterPath->simplified(), QPen(QColor("#0078d7"), 1));
QDELETE(rightButtonBorder);
QDELETE(painterPath);
}
// Draw the down arrow
painter->setPen(QPen(QColor("#5c5c5c"), 2));
QLineF arrowDown(QPointF(arrowX, arrowY), QPointF(arrowX + arrowHeight, arrowY + arrowHeight));
painter->drawLine(arrowDown);
arrowDown.setLine(arrowX + arrowHeight, arrowY + arrowHeight, arrowX + arrowWidth, arrowY);
painter->drawLine(arrowDown);
}
示例14: recreateTexture
void TextLayer::recreateTexture(VidgfxContext *gfx)
{
if(!m_isTexDirty)
return; // Don't waste any time if it hasn't changed
m_isTexDirty = false;
// Delete existing texture if one exists
if(m_texture != NULL)
vidgfx_context_destroy_tex(gfx, m_texture);
m_texture = NULL;
// Determine texture size. We need to keep in mind that the text in the
// document might extend outside of the layer's bounds.
m_document.setTextWidth(m_rect.width());
QSize size(
(int)ceilf(m_document.size().width()),
(int)ceilf(m_document.size().height()));
if(m_document.isEmpty() || size.isEmpty()) {
// Nothing to display
return;
}
// Create temporary canvas. We need to be careful here as text is rendered
// differently on premultiplied vs non-premultiplied pixel formats. On a
// premultiplied format text is rendered with subpixel rendering enabled
// while on a non-premultiplied format it is not. As we don't want subpixel
// rendering we use the standard ARGB32 format.
QSize imgSize(
size.width() + m_strokeSize * 2, size.height() + m_strokeSize * 2);
QImage img(imgSize, QImage::Format_ARGB32);
img.fill(Qt::transparent);
QPainter p(&img);
p.setRenderHint(QPainter::Antialiasing, true);
// Render text
//m_document.drawContents(&p);
// Render stroke
if(m_strokeSize > 0) {
#define STROKE_TECHNIQUE 0
#if STROKE_TECHNIQUE == 0
// Technique 0: Use QTextDocument's built-in text outliner
//quint64 timeStart = App->getUsecSinceExec();
QTextDocument *outlineDoc = m_document.clone(this);
QTextCharFormat format;
QPen pen(m_strokeColor, (double)(m_strokeSize * 2));
pen.setJoinStyle(Qt::RoundJoin);
format.setTextOutline(pen);
QTextCursor cursor(outlineDoc);
cursor.select(QTextCursor::Document);
cursor.mergeCharFormat(format);
// Take into account the stroke offset
p.translate(m_strokeSize, m_strokeSize);
//quint64 timePath = App->getUsecSinceExec();
outlineDoc->drawContents(&p);
delete outlineDoc;
//quint64 timeEnd = App->getUsecSinceExec();
//appLog() << "Path time = " << (timePath - timeStart) << " usec";
//appLog() << "Render time = " << (timeEnd - timePath) << " usec";
//appLog() << "Full time = " << (timeEnd - timeStart) << " usec";
#elif STROKE_TECHNIQUE == 1
// Technique 1: Create a text QPainterPath and stroke it
quint64 timeStart = App->getUsecSinceExec();
// Create the path for the text's stroke
QPainterPath path;
QTextBlock &block = m_document.firstBlock();
int numBlocks = m_document.blockCount();
for(int i = 0; i < numBlocks; i++) {
QTextLayout *layout = block.layout();
for(int j = 0; j < layout->lineCount(); j++) {
QTextLine &line = layout->lineAt(j);
const QString text = block.text().mid(
line.textStart(), line.textLength());
QPointF pos = layout->position() + line.position();
pos.ry() += line.ascent();
//appLog() << pos << ": " << text;
path.addText(pos, block.charFormat().font(), text);
}
block = block.next();
}
quint64 timePath = App->getUsecSinceExec();
path = path.simplified(); // Fixes gaps with large stroke sizes
quint64 timeSimplify = App->getUsecSinceExec();
// Render the path
//p.strokePath(path, QPen(m_strokeColor, m_strokeSize));
// Convert it to a stroke
QPainterPathStroker stroker;
stroker.setWidth(m_strokeSize);
//stroker.setCurveThreshold(2.0);
stroker.setJoinStyle(Qt::RoundJoin);
//.........这里部分代码省略.........
示例15: createPuzzleShape
// This function generates puzzle piece shapes.
// ----------
// unit - the size of the rectangular base of the puzzle piece
// status - flags of TabStatus values that describe the shape of this puzzle piece
// tabFull - the full size of tabs including stroke, offset, tolerance
// tabSize - size of tabs
// tabOffset - offset of tabs (meaning: how far away they are from the edge of the piece)
// tabTolerance - extra size to the tabs (so that merging works flawlessly, without visual artifacts)
// blankSize - size of blanks
// blankOffset - offset of blanks (meaning: how far away they are from the edge of the piece)
// ----------
static QPainterPath createPuzzleShape(QSize unit, int status, qreal tabFull, qreal tabSize, qreal tabOffset, qreal tabTolerance, qreal blankSize, qreal blankOffset)
{
QPainterPath rectClip;
rectClip.addRect(tabFull - 1, tabFull - 1, unit.width() + 1, unit.height() + 1);
QPainterPath clip = rectClip;
// Left
if (status & Puzzle::Creation::LeftBlank)
{
QPainterPath leftBlank;
leftBlank.addEllipse(QPointF(tabFull + blankOffset, tabFull + unit.height() / 2.0), blankSize, blankSize);
clip = clip.subtracted(leftBlank);
}
else if (status & Puzzle::Creation::LeftTab)
{
QPainterPath leftTab;
leftTab.addEllipse(QPointF(tabSize + tabTolerance, tabFull + unit.height() / 2.0), tabSize + tabTolerance, tabSize + tabTolerance);
clip = clip.united(leftTab);
}
// Top
if (status & Puzzle::Creation::TopBlank)
{
QPainterPath topBlank;
topBlank.addEllipse(QPointF(tabFull + unit.width() / 2.0, tabFull + blankOffset), blankSize, blankSize);
clip = clip.subtracted(topBlank);
}
else if (status & Puzzle::Creation::TopTab)
{
QPainterPath topTab;
topTab.addEllipse(QPointF(tabFull + unit.width() / 2.0, tabSize + tabTolerance), tabSize + tabTolerance, tabSize + tabTolerance);
clip = clip.united(topTab);
}
// Right
if (status & Puzzle::Creation::RightTab)
{
QPainterPath rightTab;
rightTab.addEllipse(QPointF(tabFull + unit.width() + tabOffset, tabFull + unit.height() / 2.0), tabSize + tabTolerance, tabSize + tabTolerance);
clip = clip.united(rightTab);
}
else if (status & Puzzle::Creation::RightBlank)
{
QPainterPath rightBlank;
rightBlank.addEllipse(QPointF(tabFull + unit.width() - blankOffset, tabFull + unit.height() / 2.0), blankSize, blankSize);
clip = clip.subtracted(rightBlank);
}
// Bottom
if (status & Puzzle::Creation::BottomTab)
{
QPainterPath bottomTab;
bottomTab.addEllipse(QPointF(tabFull + unit.width() / 2.0, tabFull + unit.height() + tabOffset), tabSize + tabTolerance, tabSize + tabTolerance);
clip = clip.united(bottomTab);
}
else if (status & Puzzle::Creation::BottomBlank)
{
QPainterPath bottomBlank;
bottomBlank.addEllipse(QPointF(tabFull + unit.width() / 2.0, tabFull + unit.height() - blankOffset), blankSize, blankSize);
clip = clip.subtracted(bottomBlank);
}
clip = clip.simplified();
return clip;
}