/** * The purpose of this function is to make sure that widgets are not laid out outside its layout. * E.g. the layoutItemRect margins are only meant to take of the surrounding margins/spacings. * However, if the margin is 0, it can easily cover the area of a widget above it. */ void QBoxLayoutPrivate::effectiveMargins(int *left, int *top, int *right, int *bottom) const { int l = leftMargin; int t = topMargin; int r = rightMargin; int b = bottomMargin; #ifdef Q_WS_MAC Q_Q(const QBoxLayout); if (horz(dir)) { QBoxLayoutItem *leftBox = 0; QBoxLayoutItem *rightBox = 0; if (left || right) { leftBox = list.value(0); rightBox = list.value(list.count() - 1); if (dir == QBoxLayout::RightToLeft) qSwap(leftBox, rightBox); int leftDelta = 0; int rightDelta = 0; if (leftBox) { QLayoutItem *itm = leftBox->item; if (QWidget *w = itm->widget()) leftDelta = itm->geometry().left() - w->geometry().left(); } if (rightBox) { QLayoutItem *itm = rightBox->item; if (QWidget *w = itm->widget()) rightDelta = w->geometry().right() - itm->geometry().right(); } QWidget *w = q->parentWidget(); Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QApplication::layoutDirection(); if (layoutDirection == Qt::RightToLeft) qSwap(leftDelta, rightDelta); l = qMax(l, leftDelta); r = qMax(r, rightDelta); } int count = top || bottom ? list.count() : 0; for (int i = 0; i < count; ++i) { QBoxLayoutItem *box = list.at(i); QLayoutItem *itm = box->item; QWidget *w = itm->widget(); if (w) { QRect lir = itm->geometry(); QRect wr = w->geometry(); if (top) t = qMax(t, lir.top() - wr.top()); if (bottom) b = qMax(b, wr.bottom() - lir.bottom()); } } } else { // vertical layout QBoxLayoutItem *topBox = 0; QBoxLayoutItem *bottomBox = 0; if (top || bottom) { topBox = list.value(0); bottomBox = list.value(list.count() - 1); if (dir == QBoxLayout::BottomToTop) { qSwap(topBox, bottomBox); } if (top && topBox) { QLayoutItem *itm = topBox->item; QWidget *w = itm->widget(); if (w) t = qMax(t, itm->geometry().top() - w->geometry().top()); } if (bottom && bottomBox) { QLayoutItem *itm = bottomBox->item; QWidget *w = itm->widget(); if (w) b = qMax(b, w->geometry().bottom() - itm->geometry().bottom()); } } int count = left || right ? list.count() : 0; for (int i = 0; i < count; ++i) { QBoxLayoutItem *box = list.at(i); QLayoutItem *itm = box->item; QWidget *w = itm->widget(); if (w) { QRect lir = itm->geometry(); QRect wr = w->geometry(); if (left) l = qMax(l, lir.left() - wr.left()); if (right) r = qMax(r, wr.right() - lir.right()); } } } #endif if (left) *left = l; if (top) *top = t; if (right) *right = r; if (bottom) *bottom = b; }
/* Parse all the date formats that Firefox can. The official format is: expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT But browsers have been supporting a very wide range of date strings. To work on many sites we need to support more then just the official date format. For reference see Firefox's PR_ParseTimeStringToExplodedTime in prtime.c. The Firefox date parser is coded in a very complex way and is slightly over ~700 lines long. While this implementation will be slightly slower for the non standard dates it is smaller, more readable, and maintainable. Or in their own words: "} // else what the hell is this." */ static QDateTime parseDateString(const QByteArray &dateString) { QTime time; // placeholders for values when we are not sure it is a year, month or day int unknown[3] = {-1, -1, -1}; int month = -1; int day = -1; int year = -1; int zoneOffset = -1; // hour:minute:second.ms pm QRegExp timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)")); int at = 0; while (at < dateString.length()) { #ifdef PARSEDATESTRINGDEBUG qDebug() << dateString.mid(at); #endif bool isNum = isNumber(dateString[at]); // Month if (!isNum && checkStaticArray(month, dateString, at, months, sizeof(months)- 1)) { ++month; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Month:" << month; #endif at += 3; continue; } // Zone if (!isNum && zoneOffset == -1 && checkStaticArray(zoneOffset, dateString, at, zones, sizeof(zones)- 1)) { int sign = (at >= 0 && dateString[at - 1] == '-') ? -1 : 1; zoneOffset = sign * zoneOffsets[zoneOffset] * 60 * 60; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Zone:" << month; #endif at += 3; continue; } // Zone offset if (!isNum && (zoneOffset == -1 || zoneOffset == 0) // Can only go after gmt && (dateString[at] == '+' || dateString[at] == '-') && (at == 0 || isWhitespace(dateString[at - 1]) || dateString[at - 1] == ',' || (at >= 3 && (dateString[at - 3] == 'g') && (dateString[at - 2] == 'm') && (dateString[at - 1] == 't')))) { int end = 1; while (end < 5 && dateString.length() > at+end && dateString[at + end] >= '0' && dateString[at + end] <= '9') ++end; int minutes = 0; int hours = 0; switch (end - 1) { case 4: minutes = atoi(dateString.mid(at + 3, 2).constData()); // fall through case 2: hours = atoi(dateString.mid(at + 1, 2).constData()); break; case 1: hours = atoi(dateString.mid(at + 1, 1).constData()); break; default: at += end; continue; } if (end != 1) { int sign = dateString[at] == '-' ? -1 : 1; zoneOffset = sign * ((minutes * 60) + (hours * 60 * 60)); #ifdef PARSEDATESTRINGDEBUG qDebug() << "Zone offset:" << zoneOffset << hours << minutes; #endif at += end; continue; } } // Time if (isNum && time.isNull() && dateString.length() >= at + 3 && (dateString[at + 2] == ':' || dateString[at + 1] == ':')) { // While the date can be found all over the string the format // for the time is set and a nice regexp can be used. int pos = timeRx.indexIn(QLatin1String(dateString), at); if (pos != -1) { QStringList list = timeRx.capturedTexts(); int h = atoi(list.at(1).toLatin1().constData()); int m = atoi(list.at(2).toLatin1().constData()); int s = atoi(list.at(4).toLatin1().constData()); int ms = atoi(list.at(6).toLatin1().constData()); if (h < 12 && !list.at(9).isEmpty()) if (list.at(9) == QLatin1String("pm")) h += 12; time = QTime(h, m, s, ms); #ifdef PARSEDATESTRINGDEBUG qDebug() << "Time:" << list << timeRx.matchedLength(); #endif at += timeRx.matchedLength(); continue; } } // 4 digit Year if (isNum && year == -1 && dateString.length() >= at + 3) { if (isNumber(dateString[at + 1]) && isNumber(dateString[at + 2]) && isNumber(dateString[at + 3])) { year = atoi(dateString.mid(at, 4).constData()); at += 4; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Year:" << year; #endif continue; } } // a one or two digit number // Could be month, day or year if (isNum) { int length = 1; if (dateString.length() > at + 1 && isNumber(dateString[at + 1])) ++length; int x = atoi(dateString.mid(at, length).constData()); if (year == -1 && (x > 31 || x == 0)) { year = x; } else { if (unknown[0] == -1) unknown[0] = x; else if (unknown[1] == -1) unknown[1] = x; else if (unknown[2] == -1) unknown[2] = x; } at += length; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Saving" << x; #endif continue; } // Unknown character, typically a weekday such as 'Mon' ++at; } // Once we are done parsing the string take the digits in unknown // and determine which is the unknown year/month/day int couldBe[3] = { 0, 0, 0 }; int unknownCount = 3; for (int i = 0; i < unknownCount; ++i) { if (unknown[i] == -1) { couldBe[i] = ADAY | AYEAR | AMONTH; unknownCount = i; continue; } if (unknown[i] >= 1) couldBe[i] = ADAY; if (month == -1 && unknown[i] >= 1 && unknown[i] <= 12) couldBe[i] |= AMONTH; if (year == -1) couldBe[i] |= AYEAR; } // For any possible day make sure one of the values that could be a month // can contain that day. // For any possible month make sure one of the values that can be a // day that month can have. // Example: 31 11 06 // 31 can't be a day because 11 and 6 don't have 31 days for (int i = 0; i < unknownCount; ++i) { int currentValue = unknown[i]; bool findMatchingMonth = couldBe[i] & ADAY && currentValue >= 29; bool findMatchingDay = couldBe[i] & AMONTH; if (!findMatchingMonth || !findMatchingDay) continue; for (int j = 0; j < 3; ++j) { if (j == i) continue; for (int k = 0; k < 2; ++k) { if (k == 0 && !(findMatchingMonth && (couldBe[j] & AMONTH))) continue; else if (k == 1 && !(findMatchingDay && (couldBe[j] & ADAY))) continue; int m = currentValue; int d = unknown[j]; if (k == 0) qSwap(m, d); if (m == -1) m = month; bool found = true; switch(m) { case 2: // When we get 29 and the year ends up having only 28 // See date.isValid below // Example: 29 23 Feb if (d <= 29) found = false; break; case 4: case 6: case 9: case 11: if (d <= 30) found = false; break; default: if (d > 0 && d <= 31) found = false; } if (k == 0) findMatchingMonth = found; else if (k == 1) findMatchingDay = found; } } if (findMatchingMonth) couldBe[i] &= ~ADAY; if (findMatchingDay) couldBe[i] &= ~AMONTH; } // First set the year/month/day that have been deduced // and reduce the set as we go along to deduce more for (int i = 0; i < unknownCount; ++i) { int unset = 0; for (int j = 0; j < 3; ++j) { if (couldBe[j] == ADAY && day == -1) { day = unknown[j]; unset |= ADAY; } else if (couldBe[j] == AMONTH && month == -1) { month = unknown[j]; unset |= AMONTH; } else if (couldBe[j] == AYEAR && year == -1) { year = unknown[j]; unset |= AYEAR; } else { // common case break; } couldBe[j] &= ~unset; } } // Now fallback to a standardized order to fill in the rest with for (int i = 0; i < unknownCount; ++i) { if (couldBe[i] & AMONTH && month == -1) month = unknown[i]; else if (couldBe[i] & ADAY && day == -1) day = unknown[i]; else if (couldBe[i] & AYEAR && year == -1) year = unknown[i]; } #ifdef PARSEDATESTRINGDEBUG qDebug() << "Final set" << year << month << day; #endif if (year == -1 || month == -1 || day == -1) { #ifdef PARSEDATESTRINGDEBUG qDebug() << "Parser failure" << year << month << day; #endif return QDateTime(); } // Y2k behavior int y2k = 0; if (year < 70) y2k = 2000; else if (year < 100) y2k = 1900; QDate date(year + y2k, month, day); // When we were given a bad cookie that when parsed // set the day to 29 and the year to one that doesn't // have the 29th of Feb rather then adding the extra // complicated checking earlier just swap here. // Example: 29 23 Feb if (!date.isValid()) date = QDate(day + y2k, month, year); QDateTime dateTime(date, time, Qt::UTC); if (zoneOffset != -1) { dateTime = dateTime.addSecs(zoneOffset); } if (!dateTime.isValid()) return QDateTime(); return dateTime; }
void Stack::swap(Stack &other) { qSwap(d, other.d); }
void QgsRendererCategoryV2::swap( QgsRendererCategoryV2 & cat ) { qSwap( mValue, cat.mValue ); qSwap( mSymbol, cat.mSymbol ); qSwap( mLabel, cat.mLabel ); }
DataFormMedia::Ptr create() { DataFormMedia::Ptr result; qSwap(result, m_media); return result; }
/*! \internal */ QWebSocketFrame &QWebSocketFrame::operator =(QWebSocketFrame &&other) { qSwap(m_closeCode, other.m_closeCode); qSwap(m_closeReason, other.m_closeReason); qSwap(m_isFinalFrame, other.m_isFinalFrame); qSwap(m_mask, other.m_mask); qSwap(m_rsv1, other.m_rsv1); qSwap(m_rsv2, other.m_rsv2); qSwap(m_rsv3, other.m_rsv3); qSwap(m_opCode, other.m_opCode); qSwap(m_length, other.m_length); qSwap(m_payload, other.m_payload); qSwap(m_isValid, other.m_isValid); return *this; }
/*! Draw a rectangular frame \param painter Painter \param rect Frame rectangle \param palette Palette \param foregroundRole Foreground role used for QFrame::Plain \param frameWidth Frame width \param midLineWidth Used for QFrame::Box \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow */ void QwtPainter::drawFrame( QPainter *painter, const QRectF &rect, const QPalette &palette, QPalette::ColorRole foregroundRole, int frameWidth, int midLineWidth, int frameStyle ) { if ( frameWidth <= 0 || rect.isEmpty() ) return; const int shadow = frameStyle & QFrame::Shadow_Mask; painter->save(); if ( shadow == QFrame::Plain ) { const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); const QRectF innerRect = outerRect.adjusted( frameWidth, frameWidth, -frameWidth, -frameWidth ); QPainterPath path; path.addRect( outerRect ); path.addRect( innerRect ); painter->setPen( Qt::NoPen ); painter->setBrush( palette.color( foregroundRole ) ); painter->drawPath( path ); } else { const int shape = frameStyle & QFrame::Shape_Mask; if ( shape == QFrame::Box ) { const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); const QRectF midRect1 = outerRect.adjusted( frameWidth, frameWidth, -frameWidth, -frameWidth ); const QRectF midRect2 = midRect1.adjusted( midLineWidth, midLineWidth, -midLineWidth, -midLineWidth ); const QRectF innerRect = midRect2.adjusted( frameWidth, frameWidth, -frameWidth, -frameWidth ); QPainterPath path1; path1.moveTo( outerRect.bottomLeft() ); path1.lineTo( outerRect.topLeft() ); path1.lineTo( outerRect.topRight() ); path1.lineTo( midRect1.topRight() ); path1.lineTo( midRect1.topLeft() ); path1.lineTo( midRect1.bottomLeft() ); QPainterPath path2; path2.moveTo( outerRect.bottomLeft() ); path2.lineTo( outerRect.bottomRight() ); path2.lineTo( outerRect.topRight() ); path2.lineTo( midRect1.topRight() ); path2.lineTo( midRect1.bottomRight() ); path2.lineTo( midRect1.bottomLeft() ); QPainterPath path3; path3.moveTo( midRect2.bottomLeft() ); path3.lineTo( midRect2.topLeft() ); path3.lineTo( midRect2.topRight() ); path3.lineTo( innerRect.topRight() ); path3.lineTo( innerRect.topLeft() ); path3.lineTo( innerRect.bottomLeft() ); QPainterPath path4; path4.moveTo( midRect2.bottomLeft() ); path4.lineTo( midRect2.bottomRight() ); path4.lineTo( midRect2.topRight() ); path4.lineTo( innerRect.topRight() ); path4.lineTo( innerRect.bottomRight() ); path4.lineTo( innerRect.bottomLeft() ); QPainterPath path5; path5.addRect( midRect1 ); path5.addRect( midRect2 ); painter->setPen( Qt::NoPen ); QBrush brush1 = palette.dark().color(); QBrush brush2 = palette.light().color(); if ( shadow == QFrame::Raised ) qSwap( brush1, brush2 ); painter->setBrush( brush1 ); painter->drawPath( path1 ); painter->drawPath( path4 ); painter->setBrush( brush2 ); painter->drawPath( path2 ); painter->drawPath( path3 ); painter->setBrush( palette.mid() ); painter->drawPath( path5 ); } #if 0 // qDrawWinPanel doesn't result in something nice // on a scalable document like PDF. Better draw a // Panel. else if ( shape == QFrame::WinPanel ) { painter->setRenderHint( QPainter::NonCosmeticDefaultPen, true ); qDrawWinPanel ( painter, rect.toRect(), palette, frameStyle & QFrame::Sunken ); } else if ( shape == QFrame::StyledPanel ) { } #endif else { const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 ); const QRectF innerRect = outerRect.adjusted( frameWidth - 1.0, frameWidth - 1.0, -( frameWidth - 1.0 ), -( frameWidth - 1.0 ) ); QPainterPath path1; path1.moveTo( outerRect.bottomLeft() ); path1.lineTo( outerRect.topLeft() ); path1.lineTo( outerRect.topRight() ); path1.lineTo( innerRect.topRight() ); path1.lineTo( innerRect.topLeft() ); path1.lineTo( innerRect.bottomLeft() ); QPainterPath path2; path2.moveTo( outerRect.bottomLeft() ); path2.lineTo( outerRect.bottomRight() ); path2.lineTo( outerRect.topRight() ); path2.lineTo( innerRect.topRight() ); path2.lineTo( innerRect.bottomRight() ); path2.lineTo( innerRect.bottomLeft() ); painter->setPen( Qt::NoPen ); QBrush brush1 = palette.dark().color(); QBrush brush2 = palette.light().color(); if ( shadow == QFrame::Raised ) qSwap( brush1, brush2 ); painter->setBrush( brush1 ); painter->drawPath( path1 ); painter->setBrush( brush2 ); painter->drawPath( path2 ); } } painter->restore(); }
void ScoreWidget::showPlayerScore (int i, const QString scoreBullet, const QString scoreMountain, const QString scoreLeftWhist, const QString scoreRightWhist, const int scoreTotal) { const int PoolWidth = 60; const int Pool2Width = 85; int PaperWidth = width(); int PaperHeight = height(); QPainter p(this); if (m_landscape) { p.translate(PaperWidth, 0); p.rotate(90); qSwap(PaperWidth, PaperHeight); } QPoint center(PaperWidth/2, PaperHeight-PaperWidth/2); p.setPen(qRgb(0, 0, 0)); QFont fnt(p.font()); QRect r1 = p.boundingRect(rect(), Qt::AlignHCenter, QString::number(scoreTotal)); switch (i) { case 1: // Bullet p.setPen(qRgb(0, 128, 0)); p.drawText(PoolWidth+r1.height()+4, PaperHeight-PoolWidth-4, scoreBullet); // Mountain p.setPen(qRgb(235, 0, 0)); p.drawText(Pool2Width+r1.height()+4, PaperHeight-Pool2Width-4, scoreMountain); // Whists p.setPen(qRgb(0, 0, 0)); p.drawText(r1.height()+4, PaperHeight-4, scoreLeftWhist); p.drawText(center.x()+4, PaperHeight-4, scoreRightWhist); // Total score if (scoreTotal >= 0) p.setPen(qRgb(0, 0, 235)); else p.setPen(qRgb(235, 0, 0)); fnt.setBold(true); p.setFont(fnt); p.drawText(center.x()-r1.width()/2, center.y()+100, QString::number(scoreTotal)); break; case 2: // Bullet p.setPen(qRgb(0, 128, 0)); drawRotatedText(p, PoolWidth+4, 4, 90, scoreBullet); // Mountain p.setPen(qRgb(235, 0, 0)); drawRotatedText(p, Pool2Width+4, 4, 90, scoreMountain); // Whists p.setPen(qRgb(0, 0, 0)); drawRotatedText(p, 4, 4, 90, scoreLeftWhist); drawRotatedText(p, 4, (PaperHeight-PoolWidth)/2+4, 90, scoreRightWhist); // Total score if (scoreTotal >= 0) p.setPen(qRgb(0, 0, 235)); else p.setPen(qRgb(235, 0, 0)); fnt.setBold(true); p.setFont(fnt); if(!m_landscape) { drawRotatedText(p, center.x() - 60, (PaperHeight - Pool2Width - r1.width())/2, 90, QString::number(scoreTotal)); } else { drawRotatedText(p, center.x() - 60, (PaperHeight - Pool2Width + r1.width())/2, -90, QString::number(scoreTotal)); } break; case 3: // Bullet p.setPen(qRgb(0, 128, 0)); drawRotatedText(p, PaperWidth-PoolWidth-4, PaperHeight-PoolWidth-r1.height(), -90, scoreBullet); // Mountain p.setPen(qRgb(235, 0, 0)); drawRotatedText(p, PaperWidth-Pool2Width-4, PaperHeight-Pool2Width-r1.height(), -90, scoreMountain); // Whists p.setPen(qRgb(0, 0, 0)); drawRotatedText(p, PaperWidth-4, PaperHeight-r1.height()-4, -90, scoreLeftWhist); drawRotatedText(p, PaperWidth-4, (PaperHeight-PoolWidth)/2-4, -90, scoreRightWhist); // Total score if (scoreTotal >= 0) p.setPen(qRgb(0, 0, 235)); else p.setPen(qRgb(235, 0, 0)); fnt.setBold(true); p.setFont(fnt); drawRotatedText(p, center.x() + 80, (PaperHeight - Pool2Width + r1.width())/2, -90, QString::number(scoreTotal)); break; default: ; } fnt.setBold(false); p.setFont(fnt); p.end(); }
void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const FloatPoint& point, int from, int to) const { if (to < 0) to = run.length(); QPainter *p = ctx->platformContext(); if (ctx->textDrawingMode() & cTextFill) { if (ctx->fillGradient()) { QBrush brush(*ctx->fillGradient()->platformGradient()); brush.setTransform(ctx->fillGradient()->gradientSpaceTransform()); p->setPen(QPen(brush, 0)); } else if (ctx->fillPattern()) { TransformationMatrix affine; p->setPen(QPen(QBrush(ctx->fillPattern()->createPlatformPattern(affine)), 0)); } else p->setPen(QColor(ctx->fillColor())); } if (ctx->textDrawingMode() & cTextStroke) { if (ctx->strokeGradient()) { QBrush brush(*ctx->strokeGradient()->platformGradient()); brush.setTransform(ctx->strokeGradient()->gradientSpaceTransform()); p->setPen(QPen(brush, ctx->strokeThickness())); } else if (ctx->strokePattern()) { TransformationMatrix affine; p->setPen(QPen(QBrush(ctx->strokePattern()->createPlatformPattern(affine)), ctx->strokeThickness())); } else p->setPen(QPen(QColor(ctx->strokeColor()), ctx->strokeThickness())); } const QString string = fixSpacing(qstring(run)); // text shadow IntSize shadowSize; int shadowBlur; Color shadowColor; bool hasShadow = ctx->textDrawingMode() == cTextFill && ctx->getShadow(shadowSize, shadowBlur, shadowColor); if (from > 0 || to < run.length()) { QTextLayout layout(string, font()); QTextLine line = setupLayout(&layout, run); float x1 = line.cursorToX(from); float x2 = line.cursorToX(to); if (x2 < x1) qSwap(x1, x2); QFontMetrics fm(font()); int ascent = fm.ascent(); QRectF clip(point.x() + x1, point.y() - ascent, x2 - x1, fm.height()); if (hasShadow) { // TODO: when blur support is added, the clip will need to account // for the blur radius qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0; if (shadowSize.width() > 0) dx2 = shadowSize.width(); else dx1 = -shadowSize.width(); if (shadowSize.height() > 0) dy2 = shadowSize.height(); else dy1 = -shadowSize.height(); // expand the clip rect to include the text shadow as well clip.adjust(dx1, dx2, dy1, dy2); } p->save(); p->setClipRect(clip.toRect()); QPointF pt(point.x(), point.y() - ascent); if (hasShadow) { p->save(); p->setPen(QColor(shadowColor)); p->translate(shadowSize.width(), shadowSize.height()); line.draw(p, pt); p->restore(); } line.draw(p, pt); p->restore(); return; } p->setFont(font()); QPointF pt(point.x(), point.y()); int flags = run.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight; if (hasShadow) { // TODO: text shadow blur support p->save(); p->setPen(QColor(shadowColor)); p->translate(shadowSize.width(), shadowSize.height()); p->drawText(pt, string, flags, run.padding()); p->restore(); } if (ctx->textDrawingMode() & cTextStroke) { QPainterPath path; path.addText(pt, font(), string); p->strokePath(path, p->pen()); } if (ctx->textDrawingMode() & cTextFill) p->drawText(pt, string, flags, run.padding()); }
void old_tesselate_polygon(QVector<XTrapezoid> *traps, const QPointF *pg, int pgSize, bool winding) { QVector<QEdge> edges; edges.reserve(128); qreal ymin(INT_MAX/256); qreal ymax(INT_MIN/256); //painter.begin(pg, pgSize); if (pg[0] != pg[pgSize-1]) qWarning() << Q_FUNC_INFO << "Malformed polygon (first and last points must be identical)"; // generate edge table // qDebug() << "POINTS:"; for (int x = 0; x < pgSize-1; ++x) { QEdge edge; QPointF p1(Q27Dot5ToDouble(FloatToQ27Dot5(pg[x].x())), Q27Dot5ToDouble(FloatToQ27Dot5(pg[x].y()))); QPointF p2(Q27Dot5ToDouble(FloatToQ27Dot5(pg[x+1].x())), Q27Dot5ToDouble(FloatToQ27Dot5(pg[x+1].y()))); // qDebug() << " " // << p1; edge.winding = p1.y() > p2.y() ? 1 : -1; if (edge.winding > 0) qSwap(p1, p2); edge.p1.x = XDoubleToFixed(p1.x()); edge.p1.y = XDoubleToFixed(p1.y()); edge.p2.x = XDoubleToFixed(p2.x()); edge.p2.y = XDoubleToFixed(p2.y()); edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // line derivative edge.b = p1.y() - edge.m * p1.x(); // intersection with y axis edge.m = edge.m != 0.0 ? 1.0 / edge.m : 0.0; // inverted derivative edges.append(edge); ymin = qMin(ymin, qreal(XFixedToDouble(edge.p1.y))); ymax = qMax(ymax, qreal(XFixedToDouble(edge.p2.y))); } QList<const QEdge *> et; // edge list for (int i = 0; i < edges.size(); ++i) et.append(&edges.at(i)); // sort edge table by min y value qSort(et.begin(), et.end(), compareEdges); // eliminate shared edges for (int i = 0; i < et.size(); ++i) { for (int k = i+1; k < et.size(); ++k) { const QEdge *edgeI = et.at(i); const QEdge *edgeK = et.at(k); if (edgeK->p1.y > edgeI->p1.y) break; if (edgeI->winding != edgeK->winding && isEqual(edgeI->p1, edgeK->p1) && isEqual(edgeI->p2, edgeK->p2) ) { et.removeAt(k); et.removeAt(i); --i; break; } } } if (ymax <= ymin) return; QList<const QEdge *> aet; // edges that intersects the current scanline // if (ymin < 0) // ymin = 0; // if (paintEventClipRegion) // don't scan more lines than we have to // ymax = paintEventClipRegion->boundingRect().height(); #ifdef QT_DEBUG_TESSELATOR qDebug("==> ymin = %f, ymax = %f", ymin, ymax); #endif // QT_DEBUG_TESSELATOR currentY = ymin; // used by the less than op for (qreal y = ymin; y < ymax;) { // fill active edge table with edges that intersect the current line for (int i = 0; i < et.size(); ++i) { const QEdge *edge = et.at(i); if (edge->p1.y > XDoubleToFixed(y)) break; aet.append(edge); et.removeAt(i); --i; } // remove processed edges from active edge table for (int i = 0; i < aet.size(); ++i) { if (aet.at(i)->p2.y <= XDoubleToFixed(y)) { aet.removeAt(i); --i; } } if (aet.size()%2 != 0) { #ifndef QT_NO_DEBUG qWarning("QX11PaintEngine: aet out of sync - this should not happen."); #endif return; } // done? if (!aet.size()) { if (!et.size()) { break; } else { y = currentY = XFixedToDouble(et.at(0)->p1.y); continue; } } // calculate the next y where we have to start a new set of trapezoids qreal next_y(INT_MAX/256); for (int i = 0; i < aet.size(); ++i) { const QEdge *edge = aet.at(i); if (XFixedToDouble(edge->p2.y) < next_y) next_y = XFixedToDouble(edge->p2.y); } if (et.size() && next_y > XFixedToDouble(et.at(0)->p1.y)) next_y = XFixedToDouble(et.at(0)->p1.y); int aetSize = aet.size(); for (int i = 0; i < aetSize; ++i) { for (int k = i+1; k < aetSize; ++k) { const QEdge *edgeI = aet.at(i); const QEdge *edgeK = aet.at(k); qreal m1 = edgeI->m; qreal b1 = edgeI->b; qreal m2 = edgeK->m; qreal b2 = edgeK->b; if (qAbs(m1 - m2) < 0.001) continue; // ### intersect is not calculated correctly when optimized with -O2 (gcc) volatile qreal intersect = 0; if (!qIsFinite(b1)) intersect = (1.f / m2) * XFixedToDouble(edgeI->p1.x) + b2; else if (!qIsFinite(b2)) intersect = (1.f / m1) * XFixedToDouble(edgeK->p1.x) + b1; else intersect = (b1*m1 - b2*m2) / (m1 - m2); if (intersect > y && intersect < next_y) next_y = intersect; } } XFixed yf, next_yf; yf = qrealToXFixed(y); next_yf = qrealToXFixed(next_y); if (yf == next_yf) { y = currentY = next_y; continue; } #ifdef QT_DEBUG_TESSELATOR qDebug("###> y = %f, next_y = %f, %d active edges", y, next_y, aet.size()); qDebug("===> edges"); dump_edges(et); qDebug("===> active edges"); dump_edges(aet); #endif // calc intersection points QVarLengthArray<QIntersectionPoint> isects(aet.size()+1); for (int i = 0; i < isects.size()-1; ++i) { const QEdge *edge = aet.at(i); isects[i].x = (edge->p1.x != edge->p2.x) ? ((y - edge->b)*edge->m) : XFixedToDouble(edge->p1.x); isects[i].edge = edge; } if (isects.size()%2 != 1) qFatal("%s: number of intersection points must be odd", Q_FUNC_INFO); // sort intersection points qSort(&isects[0], &isects[isects.size()-1], compareIntersections); // qDebug() << "INTERSECTION_POINTS:"; // for (int i = 0; i < isects.size(); ++i) // qDebug() << isects[i].edge << isects[i].x; if (winding) { // winding fill rule for (int i = 0; i < isects.size()-1;) { int winding = 0; const QEdge *left = isects[i].edge; const QEdge *right = 0; winding += isects[i].edge->winding; for (++i; i < isects.size()-1 && winding != 0; ++i) { winding += isects[i].edge->winding; right = isects[i].edge; } if (!left || !right) break; //painter.addTrapezoid(&toXTrapezoid(yf, next_yf, *left, *right)); traps->append(toXTrapezoid(yf, next_yf, *left, *right)); } } else { // odd-even fill rule for (int i = 0; i < isects.size()-2; i += 2) { //painter.addTrapezoid(&toXTrapezoid(yf, next_yf, *isects[i].edge, *isects[i+1].edge)); traps->append(toXTrapezoid(yf, next_yf, *isects[i].edge, *isects[i+1].edge)); } } y = currentY = next_y; } #ifdef QT_DEBUG_TESSELATOR qDebug("==> number of trapezoids: %d - edge table size: %d\n", traps->size(), et.size()); for (int i = 0; i < traps->size(); ++i) dump_trap(traps->at(i)); #endif // optimize by unifying trapezoids that share left/right lines // and have a common top/bottom edge // for (int i = 0; i < tps.size(); ++i) { // for (int k = i+1; k < tps.size(); ++k) { // if (i != k && tps.at(i).right == tps.at(k).right // && tps.at(i).left == tps.at(k).left // && (tps.at(i).top == tps.at(k).bottom // || tps.at(i).bottom == tps.at(k).top)) // { // tps[i].bottom = tps.at(k).bottom; // tps.removeAt(k); // i = 0; // break; // } // } // } //static int i = 0; //QImage img = painter.end(); //img.save(QString("res%1.png").arg(i++), "PNG"); }
void ScoreWidget::paintBlankPaper () { int PaperWidth = m_paperBmp->width(); int PaperHeight = m_paperBmp->height(); const int PoolWidth = 60; const int Pool2Width = 85; const int maxPoolRadius = 20; QPainter p(m_paperBmp); if (m_landscape) { p.translate(PaperWidth, 0); p.rotate(90); qSwap(PaperWidth, PaperHeight); } p.setRenderHints(QPainter::Antialiasing); QRect NewRect = QRect(0, 0, PaperWidth, PaperHeight); QImage img(QString(":/pics/scorepaper.png")); p.drawImage(0, 0, img); p.setPen(Qt::black); // Draw borders of paper p.drawRect(NewRect); QPoint center(PaperWidth/2, PaperHeight-PaperWidth/2); // Diagonal lines from bottom corners to circle p.drawLine(NewRect.bottomLeft(), center); p.drawLine(NewRect.bottomRight(), center); // Central vertical line p.drawLine( center.x(), 0, center.x(), center.y() ); // External border of pool p.drawRect(PoolWidth, 0, PaperWidth-2*PoolWidth, PaperHeight-PoolWidth); // Border of mountain p.drawRect(Pool2Width, 0, PaperWidth-2*Pool2Width, PaperHeight-Pool2Width); // Player lines p.drawLine(0, (PaperHeight-PoolWidth)/2, PoolWidth, (PaperHeight-PoolWidth)/2); p.drawLine(PaperWidth, (PaperHeight-PoolWidth)/2, PaperWidth-PoolWidth, (PaperHeight-PoolWidth)/2); p.drawLine(PaperWidth/2, PaperHeight, PaperWidth/2, PaperHeight-PoolWidth); // Circle with MaxPool value QRadialGradient g(center, maxPoolRadius, center+QPoint(-maxPoolRadius/2,-maxPoolRadius/2)); g.setColorAt(0, Qt::white); g.setColorAt(1, qRgb(250, 250, 0)); QBrush b1(g); p.setBrush(b1); p.drawEllipse(center, maxPoolRadius, maxPoolRadius); // Draw text // MaxPool QFont fnt(p.font()); fnt.setBold(true); p.setFont(fnt); p.drawText(QRect(center.x() - maxPoolRadius, center.y() - maxPoolRadius, maxPoolRadius*2, maxPoolRadius*2), QString::number(m_model->optMaxPool), QTextOption(Qt::AlignCenter)); fnt.setBold(false); p.setFont(fnt); // Players' names QBrush brush(qRgb(255, 255, 255)); p.setBrush(brush); const QRect r1 = p.boundingRect(NewRect, Qt::AlignHCenter, m_model->player(1)->nick()); const QRect r2 = p.boundingRect(NewRect, Qt::AlignHCenter, m_model->player(2)->nick()); const QRect r3 = p.boundingRect(NewRect, Qt::AlignHCenter, m_model->player(3)->nick()); p.drawText(QRect(center.x()-r1.width()/2, center.y()+55, r1.width(), r1.height()), m_model->player(1)->nick(), QTextOption(Qt::AlignHCenter)); drawRotatedText(p, center.x() - 30, (PaperHeight - Pool2Width + (m_landscape ? 1 : -1) * r2.width())/2, r2.width(), r2.height(), m_landscape ? -90 : 90, m_model->player(2)->nick()); drawRotatedText(p, center.x() + 30, (PaperHeight - Pool2Width + r3.width())/2, r3.width(), r3.height(), -90, m_model->player(3)->nick()); p.end(); }
void SSGQuickLayer::grab() { if (!m_item || m_size.isNull()) { delete m_fbo; delete m_secondaryFbo; m_fbo = m_secondaryFbo = 0; m_depthStencilBuffer.clear(); m_dirtyTexture = false; return; } QSGNode *root = m_item; while (root->firstChild() && root->type() != QSGNode::RootNodeType) root = root->firstChild(); if (root->type() != QSGNode::RootNodeType) return; if (!m_renderer) { m_renderer = m_context->createRenderer(); connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture())); } m_renderer->setDevicePixelRatio(m_device_pixel_ratio); m_renderer->setRootNode(static_cast<QSGRootNode *>(root)); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); bool deleteFboLater = false; if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format || (!m_fbo->format().mipmap() && m_mipmap)) { if (!m_multisamplingChecked) { if (m_context->openglContext()->format().samples() <= 1) { m_multisampling = false; } else { const QSet<QByteArray> extensions = m_context->openglContext()->extensions(); m_multisampling = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample")) && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit")); } m_multisamplingChecked = true; } if (m_multisampling) { // Don't delete the FBO right away in case it is used recursively. deleteFboLater = true; delete m_secondaryFbo; QOpenGLFramebufferObjectFormat format; format.setInternalTextureFormat(m_format); format.setSamples(m_context->openglContext()->format().samples()); m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo); } else { QOpenGLFramebufferObjectFormat format; format.setInternalTextureFormat(m_format); format.setMipmap(m_mipmap); if (m_recursive) { deleteFboLater = true; delete m_secondaryFbo; m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format); funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture()); updateBindOptions(true); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo); } else { delete m_fbo; delete m_secondaryFbo; m_fbo = new QOpenGLFramebufferObject(m_size, format); m_secondaryFbo = 0; funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); updateBindOptions(true); m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_fbo); } } } if (m_recursive && !m_secondaryFbo) { // m_fbo already created, m_recursive was just set. Q_ASSERT(m_fbo); Q_ASSERT(!m_multisampling); m_secondaryFbo = new QOpenGLFramebufferObject(m_size, m_fbo->format()); funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture()); updateBindOptions(true); } // Render texture. root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update. m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update. #ifdef QSG_DEBUG_FBO_OVERLAY if (qmlFboOverlay()) { if (!m_debugOverlay) m_debugOverlay = new QSGSimpleRectNode(); m_debugOverlay->setRect(QRectF(0, 0, m_size.width(), m_size.height())); m_debugOverlay->setColor(QColor(0xff, 0x00, 0x80, 0x40)); root->appendChildNode(m_debugOverlay); } #endif m_dirtyTexture = false; m_renderer->setDeviceRect(m_size); m_renderer->setViewportRect(m_size); QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(), m_mirrorVertical ? m_rect.bottom() : m_rect.top(), m_mirrorHorizontal ? -m_rect.width() : m_rect.width(), m_mirrorVertical ? -m_rect.height() : m_rect.height()); m_renderer->setProjectionMatrixToRect(mirrored); m_renderer->setClearColor(Qt::transparent); if (m_multisampling) { m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data())); if (deleteFboLater) { delete m_fbo; QOpenGLFramebufferObjectFormat format; format.setInternalTextureFormat(m_format); format.setAttachment(QOpenGLFramebufferObject::NoAttachment); format.setMipmap(m_mipmap); format.setSamples(0); m_fbo = new QOpenGLFramebufferObject(m_size, format); funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); updateBindOptions(true); } QRect r(QPoint(), m_size); QOpenGLFramebufferObject::blitFramebuffer(m_fbo, r, m_secondaryFbo, r); } else { if (m_recursive) { m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data())); if (deleteFboLater) { delete m_fbo; QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(m_format); format.setMipmap(m_mipmap); m_fbo = new QOpenGLFramebufferObject(m_size, format); funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); updateBindOptions(true); } qSwap(m_fbo, m_secondaryFbo); } else { m_renderer->renderScene(BindableFbo(m_fbo, m_depthStencilBuffer.data())); } } if (m_mipmap) { funcs->glBindTexture(GL_TEXTURE_2D, textureId()); funcs->glGenerateMipmap(GL_TEXTURE_2D); } root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update. #ifdef QSG_DEBUG_FBO_OVERLAY if (qmlFboOverlay()) root->removeChildNode(m_debugOverlay); #endif if (m_recursive) markDirtyTexture(); // Continuously update if 'live' and 'recursive'. }
void AnnounceThread::swap(AnnounceThread &other) { qSwap(d, other.d); }
/* Initializes the data structure needed by qGeomCalc and recalculates max/min and size hint. */ void QBoxLayoutPrivate::setupGeom() { if (!dirty) return; Q_Q(QBoxLayout); int maxw = horz(dir) ? 0 : QLAYOUTSIZE_MAX; int maxh = horz(dir) ? QLAYOUTSIZE_MAX : 0; int minw = 0; int minh = 0; int hintw = 0; int hinth = 0; bool horexp = false; bool verexp = false; hasHfw = false; int n = list.count(); geomArray.clear(); QVector<QLayoutStruct> a(n); QSizePolicy::ControlTypes controlTypes1; QSizePolicy::ControlTypes controlTypes2; int fixedSpacing = q->spacing(); int previousNonEmptyIndex = -1; QStyle *style = 0; if (fixedSpacing < 0) { if (QWidget *parentWidget = q->parentWidget()) style = parentWidget->style(); } for (int i = 0; i < n; i++) { QBoxLayoutItem *box = list.at(i); QSize max = box->item->maximumSize(); QSize min = box->item->minimumSize(); QSize hint = box->item->sizeHint(); Qt::Orientations exp = box->item->expandingDirections(); bool empty = box->item->isEmpty(); int spacing = 0; if (!empty) { if (fixedSpacing >= 0) { spacing = (previousNonEmptyIndex >= 0) ? fixedSpacing : 0; #ifdef Q_WS_MAC if (!horz(dir) && previousNonEmptyIndex >= 0) { QBoxLayoutItem *sibling = (dir == QBoxLayout::TopToBottom ? box : list.at(previousNonEmptyIndex)); if (sibling) { QWidget *wid = sibling->item->widget(); if (wid) spacing = qMax(spacing, sibling->item->geometry().top() - wid->geometry().top()); } } #endif } else { controlTypes1 = controlTypes2; controlTypes2 = box->item->controlTypes(); if (previousNonEmptyIndex >= 0) { QSizePolicy::ControlTypes actual1 = controlTypes1; QSizePolicy::ControlTypes actual2 = controlTypes2; if (dir == QBoxLayout::RightToLeft || dir == QBoxLayout::BottomToTop) qSwap(actual1, actual2); if (style) { spacing = style->combinedLayoutSpacing(actual1, actual2, horz(dir) ? Qt::Horizontal : Qt::Vertical, 0, q->parentWidget()); if (spacing < 0) spacing = 0; } } } if (previousNonEmptyIndex >= 0) a[previousNonEmptyIndex].spacing = spacing; previousNonEmptyIndex = i; } bool ignore = empty && box->item->widget(); // ignore hidden widgets bool dummy = true; if (horz(dir)) { bool expand = (exp & Qt::Horizontal || box->stretch > 0); horexp = horexp || expand; maxw += spacing + max.width(); minw += spacing + min.width(); hintw += spacing + hint.width(); if (!ignore) qMaxExpCalc(maxh, verexp, dummy, max.height(), exp & Qt::Vertical, box->item->isEmpty()); minh = qMax(minh, min.height()); hinth = qMax(hinth, hint.height()); a[i].sizeHint = hint.width(); a[i].maximumSize = max.width(); a[i].minimumSize = min.width(); a[i].expansive = expand; a[i].stretch = box->stretch ? box->stretch : box->hStretch(); } else { bool expand = (exp & Qt::Vertical || box->stretch > 0); verexp = verexp || expand; maxh += spacing + max.height(); minh += spacing + min.height(); hinth += spacing + hint.height(); if (!ignore) qMaxExpCalc(maxw, horexp, dummy, max.width(), exp & Qt::Horizontal, box->item->isEmpty()); minw = qMax(minw, min.width()); hintw = qMax(hintw, hint.width()); a[i].sizeHint = hint.height(); a[i].maximumSize = max.height(); a[i].minimumSize = min.height(); a[i].expansive = expand; a[i].stretch = box->stretch ? box->stretch : box->vStretch(); } a[i].empty = empty; a[i].spacing = 0; // might be be initialized with a non-zero value in a later iteration hasHfw = hasHfw || box->item->hasHeightForWidth(); } geomArray = a; expanding = (Qt::Orientations) ((horexp ? Qt::Horizontal : 0) | (verexp ? Qt::Vertical : 0)); minSize = QSize(minw, minh); maxSize = QSize(maxw, maxh).expandedTo(minSize); sizeHint = QSize(hintw, hinth).expandedTo(minSize).boundedTo(maxSize); q->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); int left, top, right, bottom; effectiveMargins(&left, &top, &right, &bottom); QSize extra(left + right, top + bottom); minSize += extra; maxSize += extra; sizeHint += extra; dirty = false; }
//------------------------------------------------------------------------------ // Name: swap //------------------------------------------------------------------------------ void BasicBlock::swap(BasicBlock &other) { qSwap(instructions_, other.instructions_); }
/*! Update the axes scales \param intervals Scale intervals */ void QwtPlotRescaler::updateScales( QwtInterval intervals[QwtPlot::axisCnt] ) const { if ( d_data->inReplot >= 5 ) { return; } QwtPlot *plt = const_cast<QwtPlot *>( plot() ); const bool doReplot = plt->autoReplot(); plt->setAutoReplot( false ); for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( axis == referenceAxis() || aspectRatio( axis ) > 0.0 ) { double v1 = intervals[axis].minValue(); double v2 = intervals[axis].maxValue(); if ( !plt->axisScaleDiv( axis ).isIncreasing() ) qSwap( v1, v2 ); if ( d_data->inReplot >= 1 ) d_data->axisData[axis].scaleDiv = plt->axisScaleDiv( axis ); if ( d_data->inReplot >= 2 ) { QList<double> ticks[QwtScaleDiv::NTickTypes]; for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ ) ticks[i] = d_data->axisData[axis].scaleDiv.ticks( i ); plt->setAxisScaleDiv( axis, QwtScaleDiv( v1, v2, ticks ) ); } else { plt->setAxisScale( axis, v1, v2 ); } } } QwtPlotCanvas *canvas = qobject_cast<QwtPlotCanvas *>( plt->canvas() ); bool immediatePaint = false; if ( canvas ) { immediatePaint = canvas->testPaintAttribute( QwtPlotCanvas::ImmediatePaint ); canvas->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, false ); } plt->setAutoReplot( doReplot ); d_data->inReplot++; plt->replot(); d_data->inReplot--; if ( canvas && immediatePaint ) { canvas->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, true ); } }
QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); primaryFBO->release(); glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); QOpenGLFramebufferObject* destFBO = toTexture ? Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject() : NULL; if (_isEmpty && _renderMode != DIFFUSE_ADD_MODE) { // copy the primary to the screen if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { QOpenGLFramebufferObject::blitFramebuffer(destFBO, primaryFBO); } else { maybeBind(destFBO); glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glColor3f(1.0f, 1.0f, 1.0f); renderFullscreenQuad(); glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); maybeRelease(destFBO); } } else if (_renderMode == ADD_MODE) { maybeBind(destFBO); _addProgram->bind(); renderFullscreenQuad(); _addProgram->release(); maybeRelease(destFBO); } else if (_renderMode == DIFFUSE_ADD_MODE) { // diffuse into the secondary/tertiary (alternating between frames) QOpenGLFramebufferObject* oldDiffusedFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); QOpenGLFramebufferObject* newDiffusedFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); if (_isOddFrame) { qSwap(oldDiffusedFBO, newDiffusedFBO); } newDiffusedFBO->bind(); if (_isFirstFrame) { glClear(GL_COLOR_BUFFER_BIT); } else { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture()); _diffuseProgram->bind(); QSize size = Application::getInstance()->getGLWidget()->size(); _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height()); renderFullscreenQuad(); _diffuseProgram->release(); } newDiffusedFBO->release(); // add diffused texture to the primary glBindTexture(GL_TEXTURE_2D, newDiffusedFBO->texture()); if (toTexture) { destFBO = oldDiffusedFBO; } maybeBind(destFBO); _addSeparateProgram->bind(); renderFullscreenQuad(); _addSeparateProgram->release(); maybeRelease(destFBO); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); } else { // _renderMode == BLUR_ADD_MODE || _renderMode == BLUR_PERSIST_ADD_MODE // render the primary to the secondary with the horizontal blur QOpenGLFramebufferObject* secondaryFBO = Application::getInstance()->getTextureCache()->getSecondaryFramebufferObject(); secondaryFBO->bind(); _horizontalBlurProgram->bind(); renderFullscreenQuad(); _horizontalBlurProgram->release(); secondaryFBO->release(); if (_renderMode == BLUR_ADD_MODE) { // render the secondary to the screen with the vertical blur glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); if (toTexture) { destFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); } maybeBind(destFBO); _verticalBlurAddProgram->bind(); renderFullscreenQuad(); _verticalBlurAddProgram->release(); maybeRelease(destFBO); } else { // _renderMode == BLUR_PERSIST_ADD_MODE // render the secondary to the tertiary with vertical blur and persistence QOpenGLFramebufferObject* tertiaryFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); tertiaryFBO->bind(); glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_CONSTANT_ALPHA, GL_CONSTANT_ALPHA); const float PERSISTENCE_SMOOTHING = 0.9f; glBlendColor(0.0f, 0.0f, 0.0f, _isFirstFrame ? 0.0f : PERSISTENCE_SMOOTHING); glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); _verticalBlurProgram->bind(); renderFullscreenQuad(); _verticalBlurProgram->release(); glBlendColor(0.0f, 0.0f, 0.0f, 0.0f); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glDisable(GL_BLEND); // now add the tertiary to the primary buffer tertiaryFBO->release(); glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tertiaryFBO->texture()); maybeBind(destFBO); _addSeparateProgram->bind(); renderFullscreenQuad(); _addSeparateProgram->release(); maybeRelease(destFBO); } glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); } glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glEnable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glBindTexture(GL_TEXTURE_2D, 0); _isFirstFrame = false; return destFBO; }
void KinectHelper::consume_depth(VideoFrameRef frame){ /// Get depth data from the frame just fetched const openni::DepthPixel* pDepth = (const openni::DepthPixel*)frame.getData(); // for point cloud const openni::DepthPixel* iDepth = (const openni::DepthPixel*)frame.getData(); // for depth image /// Depth Image (*depth_back_buffer) = QImage(frame.getWidth(), frame.getHeight(), QImage::Format_RGB32); for (unsigned nY=0; nY<frame.getHeight(); nY++) { uchar *imageptr = (*depth_back_buffer).scanLine(nY); for (unsigned nX=0; nX < frame.getWidth(); nX++) { unsigned depth = *iDepth; unsigned maxdist=10000; if(depth>maxdist) depth=maxdist; if(depth) { depth = (depth*255)/maxdist; //depth = (maxdist-depth)*255/maxdist+1; } // depth: 0: invalid // depth: 255: closest // depth: 1: furtherst (maxdist distance) // Here we could do depth*color, to show the colored depth imageptr[0] = depth; imageptr[1] = depth; imageptr[2] = depth; imageptr[3] = 0xff; iDepth++; imageptr+=4; } } _mutex.lock(); qSwap(depth_front_buffer, depth_back_buffer); _mutex.unlock(); /// Point Cloud float wx,wy,wz; /// NaN values must be handled well and not displayed by OpenGL for (int y = 0; y<frame.getHeight(); ++y){ for(int x = 0; x<frame.getWidth(); ++x){ DepthPixel d = *pDepth; pDepth++; /// Convert depth coordinates to world coordinates to remove camera intrinsics CoordinateConverter::convertDepthToWorld(depth, x, y, d, &wx, &wy, &wz); /// Change the coordinates of the vertices in the model (*points_back_buffer)(y,x) = Vector3(wx,wy,wz); } } /// Now swap front and back buffers _mutex.lock(); qSwap(points_front_buffer, points_back_buffer); _mutex.unlock(); }
/*! \internal */ void QWebSocketFrame::swap(QWebSocketFrame &other) { if (&other != this) { qSwap(m_closeCode, other.m_closeCode); qSwap(m_closeReason, other.m_closeReason); qSwap(m_isFinalFrame, other.m_isFinalFrame); qSwap(m_mask, other.m_mask); qSwap(m_rsv1, other.m_rsv1); qSwap(m_rsv2, other.m_rsv2); qSwap(m_rsv3, other.m_rsv3); qSwap(m_opCode, other.m_opCode); qSwap(m_length, other.m_length); qSwap(m_payload, other.m_payload); qSwap(m_isValid, other.m_isValid); } }
void CurveDrawer::drawLine(QPointF p0, QPointF p1, qreal thickness) { //draw line with thickness and squared ends struct DrawHelper { QPointF p0; QPointF p1; QPointF dp; qreal ed; DrawHelper(const QPointF& p0, const QPointF& p1) { this->p0 = p0; this->p1 = p1; dp = p1 - p0; ed = Utils::norm(dp); } double dist(const QPointF& p) { return qAbs((p.x() - p0.x()) * dp.y() - (p.y() - p0.y()) * dp.x()) / ed; } bool inside(const QPointF& p) { qreal v = (p.y() - p0.x()) * dp.y() + (p.x() - p1.y()) * dp.x(); return v + (p1.y() - p0.x()) * dp.x() + (p0.x() - p0.y()) * dp.y() >= 0 && v + (p1.y() - p1.x()) * dp.x() + (p0.x() - p1.y()) * dp.y() <= 0; } static QPointF makePoint(const QPointF& p) { return p; } static QPointF makePointSwap(const QPointF& p) { return QPointF(p.y(), p.x()); } } drawHelper(p0, p1); QPointF (*pointMaker)(const QPointF& p) = DrawHelper::makePoint; if (qAbs(drawHelper.dp.y()) > qAbs(drawHelper.dp.x())) { p0 = DrawHelper::makePointSwap(p0); p1 = DrawHelper::makePointSwap(p1); pointMaker = DrawHelper::makePointSwap; } if (p1.x() < p0.x()) { qSwap(p0, p1); qSwap(drawHelper.p0, drawHelper.p1); drawHelper.dp *= -1; } qreal xOffset = thickness * qAbs(p0.y() - p1.y()) / drawHelper.ed; QPointF dStep(1, (p1.y() - p0.y()) / (p1.x() - p0.x())); for (QPointF p(p0 - xOffset * dStep); p.x() <= p1.x() + xOffset; p += dStep) { for (int sy = -1; sy <= 1; sy += 2) { qreal dist; for (QPoint pp(Utils::roundPoint(p)); (dist = drawHelper.dist(pointMaker(pp))) <= thickness; pp.ry() += sy) { if (drawHelper.inside(pointMaker(pp))) { setPixel(Utils::roundPoint(pointMaker(pp)), pixelColor(dist, thickness)); } } } } }
void QwtPainter::drawRoundedFrame( QPainter *painter, const QRectF &rect, double xRadius, double yRadius, const QPalette &palette, int lineWidth, int frameStyle ) { painter->save(); painter->setRenderHint( QPainter::Antialiasing, true ); painter->setBrush( Qt::NoBrush ); double lw2 = lineWidth * 0.5; QRectF r = rect.adjusted( lw2, lw2, -lw2, -lw2 ); QPainterPath path; path.addRoundedRect( r, xRadius, yRadius ); enum Style { Plain, Sunken, Raised }; Style style = Plain; if ( (frameStyle & QFrame::Sunken) == QFrame::Sunken ) style = Sunken; else if ( (frameStyle & QFrame::Raised) == QFrame::Raised ) style = Raised; if ( style != Plain && path.elementCount() == 17 ) { // move + 4 * ( cubicTo + lineTo ) QPainterPath pathList[8]; for ( int i = 0; i < 4; i++ ) { const int j = i * 4 + 1; pathList[ 2 * i ].moveTo( path.elementAt(j - 1).x, path.elementAt( j - 1 ).y ); pathList[ 2 * i ].cubicTo( path.elementAt(j + 0).x, path.elementAt(j + 0).y, path.elementAt(j + 1).x, path.elementAt(j + 1).y, path.elementAt(j + 2).x, path.elementAt(j + 2).y ); pathList[ 2 * i + 1 ].moveTo( path.elementAt(j + 2).x, path.elementAt(j + 2).y ); pathList[ 2 * i + 1 ].lineTo( path.elementAt(j + 3).x, path.elementAt(j + 3).y ); } QColor c1( palette.color( QPalette::Dark ) ); QColor c2( palette.color( QPalette::Light ) ); if ( style == Raised ) qSwap( c1, c2 ); for ( int i = 0; i < 4; i++ ) { QRectF r = pathList[2 * i].controlPointRect(); QPen arcPen; arcPen.setCapStyle( Qt::FlatCap ); arcPen.setWidth( lineWidth ); QPen linePen; linePen.setCapStyle( Qt::FlatCap ); linePen.setWidth( lineWidth ); switch( i ) { case 0: { arcPen.setColor( c1 ); linePen.setColor( c1 ); break; } case 1: { QLinearGradient gradient; gradient.setStart( r.topLeft() ); gradient.setFinalStop( r.bottomRight() ); gradient.setColorAt( 0.0, c1 ); gradient.setColorAt( 1.0, c2 ); arcPen.setBrush( gradient ); linePen.setColor( c2 ); break; } case 2: { arcPen.setColor( c2 ); linePen.setColor( c2 ); break; } case 3: { QLinearGradient gradient; gradient.setStart( r.bottomRight() ); gradient.setFinalStop( r.topLeft() ); gradient.setColorAt( 0.0, c2 ); gradient.setColorAt( 1.0, c1 ); arcPen.setBrush( gradient ); linePen.setColor( c1 ); break; } } painter->setPen( arcPen ); painter->drawPath( pathList[ 2 * i] ); painter->setPen( linePen ); painter->drawPath( pathList[ 2 * i + 1] ); } } else { QPen pen( palette.color( QPalette::WindowText ), lineWidth ); painter->setPen( pen ); painter->drawPath( path ); } painter->restore(); }
void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { switch (element) { case PE_PanelButtonCommand: { int delta = (option->state & State_MouseOver) ? 64 : 0; QColor slightOpaqueBlack(0, 0, 0, 63); QColor semiTransparentWhite(255, 255, 255, 127 + delta); QColor semiTransparentBlack(0, 0, 0, 127 - delta); int x, y, width, height; option->rect.getRect(&x, &y, &width, &height); QPainterPath roundRect = roundRectPath(option->rect); int radius = qMin(width, height) / 2; QBrush brush; bool darker; const QStyleOptionButton *buttonOption = qstyleoption_cast<const QStyleOptionButton *>(option); if (buttonOption && (buttonOption->features & QStyleOptionButton::Flat)) { brush = option->palette.background(); darker = (option->state & (State_Sunken | State_On)); } else { if (option->state & (State_Sunken | State_On)) { brush = option->palette.mid(); darker = !(option->state & State_Sunken); } else { brush = option->palette.button(); darker = false; } } painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->fillPath(roundRect, brush); if (darker) { QColor slightlyOpaqueBlack(0, 0, 0, 63); painter->fillPath(roundRect, slightlyOpaqueBlack); } int penWidth; if (radius < 10) { penWidth = 3; } else if (radius < 20) { penWidth = 5; } else { penWidth = 7; } QPen topPen(semiTransparentWhite, penWidth); QPen bottomPen(semiTransparentBlack, penWidth); if (option->state & (State_Sunken | State_On)) { qSwap(topPen, bottomPen); } int x1 = x; int x2 = x + radius; int x3 = x + width - radius; int x4 = x + width; if (option->direction == Qt::RightToLeft) { qSwap(x1, x4); qSwap(x2, x3); } QPolygon topHalf; topHalf << QPoint(x1, y) << QPoint(x4, y) << QPoint(x3, y + radius) << QPoint(x2, y + height - radius) << QPoint(x4, y + height); painter->setClipPath(roundRect); painter->setClipRegion(topHalf, Qt::IntersectClip); painter->setPen(topPen); painter->drawPath(roundRect); QPolygon bottomHalf = topHalf; bottomHalf[0] = QPoint(x4, y + height); painter->setClipPath(roundRect); painter->setClipRegion(bottomHalf, Qt::IntersectClip); painter->setPen(bottomPen); painter->drawPath(roundRect); painter->setPen(option->palette.foreground().color()); painter->setClipping(false); painter->drawPath(roundRect); painter->restore(); } break; default: QMotifStyle::drawPrimitive(element, option, painter, widget); } }
QQuickTransition *QQuickStateGroupPrivate::findTransition(const QString &from, const QString &to) { QQuickTransition *highest = 0; int score = 0; bool reversed = false; bool done = false; for (int ii = 0; !done && ii < transitions.count(); ++ii) { QQuickTransition *t = transitions.at(ii); if (!t->enabled()) continue; for (int ii = 0; ii < 2; ++ii) { if (ii && (!t->reversible() || (t->fromState() == QLatin1String("*") && t->toState() == QLatin1String("*")))) break; QStringList fromState; QStringList toState; fromState = t->fromState().split(QLatin1Char(',')); for (int jj = 0; jj < fromState.count(); ++jj) fromState[jj] = fromState.at(jj).trimmed(); toState = t->toState().split(QLatin1Char(',')); for (int jj = 0; jj < toState.count(); ++jj) toState[jj] = toState.at(jj).trimmed(); if (ii == 1) qSwap(fromState, toState); int tScore = 0; if (fromState.contains(from)) tScore += 2; else if (fromState.contains(QLatin1String("*"))) tScore += 1; else continue; if (toState.contains(to)) tScore += 2; else if (toState.contains(QLatin1String("*"))) tScore += 1; else continue; if (ii == 1) reversed = true; else reversed = false; if (tScore == 4) { highest = t; done = true; break; } else if (tScore > score) { score = tScore; highest = t; } } } if (highest) highest->setReversed(reversed); return highest; }
void QTessellatorPrivate::addIntersection(const Edge *e1, const Edge *e2) { const IntersectionLink emptyLink = {-1, -1}; int next = vertices.nextPos(vertices[e1->edge]); if (e2->edge == next) return; int prev = vertices.prevPos(vertices[e1->edge]); if (e2->edge == prev) return; Q27Dot5 yi; bool det_positive; bool isect = e1->intersect(*e2, &yi, &det_positive); QDEBUG("checking edges %d and %d", e1->edge, e2->edge); if (!isect) { QDEBUG() << " no intersection"; return; } // don't emit an intersection if it's at the start of a line segment or above us if (yi <= y) { if (!det_positive) return; QDEBUG() << " ----->>>>>> WRONG ORDER!"; yi = y; } QDEBUG() << " between edges " << e1->edge << "and" << e2->edge << "at point (" << Q27Dot5ToDouble(yi) << ')'; Intersection i1; i1.y = yi; i1.edge = e1->edge; IntersectionLink link1 = intersections.value(i1, emptyLink); Intersection i2; i2.y = yi; i2.edge = e2->edge; IntersectionLink link2 = intersections.value(i2, emptyLink); // new pair of edges if (link1.next == -1 && link2.next == -1) { link1.next = link1.prev = i2.edge; link2.next = link2.prev = i1.edge; } else if (link1.next == i2.edge || link1.prev == i2.edge || link2.next == i1.edge || link2.prev == i1.edge) { #ifdef DEBUG checkLinkChain(intersections, i1); checkLinkChain(intersections, i2); Q_ASSERT(edgeInChain(i1, i2.edge)); #endif return; } else if (link1.next == -1 || link2.next == -1) { if (link2.next == -1) { qSwap(i1, i2); qSwap(link1, link2); } Q_ASSERT(link1.next == -1); #ifdef DEBUG checkLinkChain(intersections, i2); #endif // only i2 in list link1.next = i2.edge; link1.prev = link2.prev; link2.prev = i1.edge; Intersection other; other.y = yi; other.edge = link1.prev; IntersectionLink link = intersections.value(other, emptyLink); Q_ASSERT(link.next == i2.edge); Q_ASSERT(link.prev != -1); link.next = i1.edge; intersections.insert(other, link); } else { bool connected = edgeInChain(i1, i2.edge); if (connected) return; #ifdef DEBUG checkLinkChain(intersections, i1); checkLinkChain(intersections, i2); #endif // both already in some list. Have to make sure they are connected // this can be done by cutting open the ring(s) after the two eges and // connecting them again Intersection other1; other1.y = yi; other1.edge = link1.next; IntersectionLink linko1 = intersections.value(other1, emptyLink); Intersection other2; other2.y = yi; other2.edge = link2.next; IntersectionLink linko2 = intersections.value(other2, emptyLink); linko1.prev = i2.edge; link2.next = other1.edge; linko2.prev = i1.edge; link1.next = other2.edge; intersections.insert(other1, linko1); intersections.insert(other2, linko2); } intersections.insert(i1, link1); intersections.insert(i2, link2); #ifdef DEBUG checkLinkChain(intersections, i1); checkLinkChain(intersections, i2); Q_ASSERT(edgeInChain(i1, i2.edge)); #endif return; }
GLuint GLWidget::makeGear(const GLfloat *reflectance, GLdouble innerRadius, GLdouble outerRadius, GLdouble thickness, GLdouble toothSize, GLint toothCount) { const double Pi = 3.14159265358979323846; GLuint list = glGenLists(1); glNewList(list, GL_COMPILE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, reflectance); GLdouble r0 = innerRadius; GLdouble r1 = outerRadius - toothSize / 2.0; GLdouble r2 = outerRadius + toothSize / 2.0; GLdouble delta = (2.0 * Pi / toothCount) / 4.0; GLdouble z = thickness / 2.0; int i, j; glShadeModel(GL_FLAT); for (i = 0; i < 2; ++i) { GLdouble sign = (i == 0) ? +1.0 : -1.0; glNormal3d(0.0, 0.0, sign); glBegin(GL_QUAD_STRIP); for (j = 0; j <= toothCount; ++j) { GLdouble angle = 2.0 * Pi * j / toothCount; glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z); glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z); glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z); glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta), sign * z); } glEnd(); glBegin(GL_QUADS); for (j = 0; j < toothCount; ++j) { GLdouble angle = 2.0 * Pi * j / toothCount; glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z); glVertex3d(r2 * cos(angle + delta), r2 * sin(angle + delta), sign * z); glVertex3d(r2 * cos(angle + 2 * delta), r2 * sin(angle + 2 * delta), sign * z); glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta), sign * z); } glEnd(); } glBegin(GL_QUAD_STRIP); for (i = 0; i < toothCount; ++i) { for (j = 0; j < 2; ++j) { GLdouble angle = 2.0 * Pi * (i + (j / 2.0)) / toothCount; GLdouble s1 = r1; GLdouble s2 = r2; if (j == 1) qSwap(s1, s2); glNormal3d(cos(angle), sin(angle), 0.0); glVertex3d(s1 * cos(angle), s1 * sin(angle), +z); glVertex3d(s1 * cos(angle), s1 * sin(angle), -z); glNormal3d(s2 * sin(angle + delta) - s1 * sin(angle), s1 * cos(angle) - s2 * cos(angle + delta), 0.0); glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), +z); glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), -z); } } glVertex3d(r1, 0.0, +z); glVertex3d(r1, 0.0, -z); glEnd(); glShadeModel(GL_SMOOTH); glBegin(GL_QUAD_STRIP); for (i = 0; i <= toothCount; ++i) { GLdouble angle = i * 2.0 * Pi / toothCount; glNormal3d(-cos(angle), -sin(angle), 0.0); glVertex3d(r0 * cos(angle), r0 * sin(angle), +z); glVertex3d(r0 * cos(angle), r0 * sin(angle), -z); } glEnd(); glEndList(); return list; }
// tessellates the given convex polygon void QTessellator::tessellateConvex(const QPointF *points, int nPoints) { Q_ASSERT(points[0] == points[nPoints-1]); --nPoints; d->vertices.nPoints = nPoints; d->vertices.init(nPoints); for (int i = 0; i < nPoints; ++i) { d->vertices[i]->x = FloatToQ27Dot5(points[i].x()); d->vertices[i]->y = FloatToQ27Dot5(points[i].y()); } int left = 0, right = 0; int top = 0; for (int i = 1; i < nPoints; ++i) { if (d->vertices[i]->y < d->vertices[top]->y) top = i; } left = (top + nPoints - 1) % nPoints; right = (top + 1) % nPoints; while (d->vertices[left]->x == d->vertices[top]->x && d->vertices[left]->y == d->vertices[top]->y && left != right) left = (left + nPoints - 1) % nPoints; while (d->vertices[right]->x == d->vertices[top]->x && d->vertices[right]->y == d->vertices[top]->y && left != right) right = (right + 1) % nPoints; if (left == right) return; int dir = 1; Vertex dLeft = { d->vertices[top]->x - d->vertices[left]->x, d->vertices[top]->y - d->vertices[left]->y }; Vertex dRight = { d->vertices[right]->x - d->vertices[top]->x, d->vertices[right]->y - d->vertices[top]->y }; Q27Dot5 cross = dLeft.x * dRight.y - dLeft.y * dRight.x; // flip direction if polygon is clockwise if (cross < 0 || (cross == 0 && dLeft.x > 0)) { qSwap(left, right); dir = -1; } Vertex *lastLeft = d->vertices[top]; Vertex *lastRight = d->vertices[top]; QTessellator::Trapezoid trap; while (lastLeft->y == d->vertices[left]->y && left != right) { lastLeft = d->vertices[left]; left = (left + nPoints - dir) % nPoints; } while (lastRight->y == d->vertices[right]->y && left != right) { lastRight = d->vertices[right]; right = (right + nPoints + dir) % nPoints; } while (true) { trap.top = qMax(lastRight->y, lastLeft->y); trap.bottom = qMin(d->vertices[left]->y, d->vertices[right]->y); trap.topLeft = lastLeft; trap.topRight = lastRight; trap.bottomLeft = d->vertices[left]; trap.bottomRight = d->vertices[right]; if (trap.bottom > trap.top) addTrap(trap); if (left == right) break; if (d->vertices[right]->y < d->vertices[left]->y) { do { lastRight = d->vertices[right]; right = (right + nPoints + dir) % nPoints; } while (lastRight->y == d->vertices[right]->y && left != right); } else { do { lastLeft = d->vertices[left]; left = (left + nPoints - dir) % nPoints; } while (lastLeft->y == d->vertices[left]->y && left != right); } } }
/*! \brief Draw the marker at the knob's front \param painter Painter \param rect Bounding rectangle of the knob without scale \param angle Angle of the marker in degrees ( clockwise, 0 at the 12 o'clock position ) */ void QwtKnob::drawMarker( QPainter *painter, const QRectF &rect, double angle ) const { if ( d_data->markerStyle == NoMarker || !isValid() ) return; const double radians = qwtRadians( angle ); const double sinA = -qFastSin( radians ); const double cosA = qFastCos( radians ); const double xm = rect.center().x(); const double ym = rect.center().y(); const double margin = 4.0; double radius = 0.5 * ( rect.width() - d_data->borderWidth ) - margin; if ( radius < 1.0 ) radius = 1.0; int markerSize = d_data->markerSize; if ( markerSize <= 0 ) markerSize = qRound( 0.4 * radius ); switch ( d_data->markerStyle ) { case Notch: case Nub: { const double dotWidth = qMin( double( markerSize ), radius); const double dotCenterDist = radius - 0.5 * dotWidth; if ( dotCenterDist > 0.0 ) { const QPointF center( xm - sinA * dotCenterDist, ym - cosA * dotCenterDist ); QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth ); ellipse.moveCenter( center ); QColor c1 = palette().color( QPalette::Light ); QColor c2 = palette().color( QPalette::Mid ); if ( d_data->markerStyle == Notch ) qSwap( c1, c2 ); QLinearGradient gradient( ellipse.topLeft(), ellipse.bottomRight() ); gradient.setColorAt( 0.0, c1 ); gradient.setColorAt( 1.0, c2 ); painter->setPen( Qt::NoPen ); painter->setBrush( gradient ); painter->drawEllipse( ellipse ); } break; } case Dot: { const double dotWidth = qMin( double( markerSize ), radius); const double dotCenterDist = radius - 0.5 * dotWidth; if ( dotCenterDist > 0.0 ) { const QPointF center( xm - sinA * dotCenterDist, ym - cosA * dotCenterDist ); QRectF ellipse( 0.0, 0.0, dotWidth, dotWidth ); ellipse.moveCenter( center ); painter->setPen( Qt::NoPen ); painter->setBrush( palette().color( QPalette::ButtonText ) ); painter->drawEllipse( ellipse ); } break; } case Tick: { const double rb = qMax( radius - markerSize, 1.0 ); const double re = radius; const QLineF line( xm - sinA * rb, ym - cosA * rb, xm - sinA * re, ym - cosA * re ); QPen pen( palette().color( QPalette::ButtonText ), 0 ); pen.setCapStyle( Qt::FlatCap ); painter->setPen( pen ); painter->drawLine ( line ); break; } case Triangle: { const double rb = qMax( radius - markerSize, 1.0 ); const double re = radius; painter->translate( rect.center() ); painter->rotate( angle - 90.0 ); QPolygonF polygon; polygon += QPointF( re, 0.0 ); polygon += QPointF( rb, 0.5 * ( re - rb ) ); polygon += QPointF( rb, -0.5 * ( re - rb ) ); painter->setPen( Qt::NoPen ); painter->setBrush( palette().color( QPalette::ButtonText ) ); painter->drawPolygon( polygon ); painter->resetTransform(); break; } default: break; } }
// tessellates the stroke of the line from a_ to b_ with the given width and a flat cap void QTessellator::tessellateRect(const QPointF &a_, const QPointF &b_, qreal width) { Vertex a = { FloatToQ27Dot5(a_.x()), FloatToQ27Dot5(a_.y()) }; Vertex b = { FloatToQ27Dot5(b_.x()), FloatToQ27Dot5(b_.y()) }; QPointF pa = a_, pb = b_; if (a.y > b.y) { qSwap(a, b); qSwap(pa, pb); } Vertex delta = { b.x - a.x, b.y - a.y }; if (delta.x == 0 && delta.y == 0) return; qreal hw = 0.5 * width; if (delta.x == 0) { Q27Dot5 halfWidth = FloatToQ27Dot5(hw); if (halfWidth == 0) return; Vertex topLeft = { a.x - halfWidth, a.y }; Vertex topRight = { a.x + halfWidth, a.y }; Vertex bottomLeft = { a.x - halfWidth, b.y }; Vertex bottomRight = { a.x + halfWidth, b.y }; QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight }; addTrap(trap); } else if (delta.y == 0) { Q27Dot5 halfWidth = FloatToQ27Dot5(hw); if (halfWidth == 0) return; if (a.x > b.x) qSwap(a.x, b.x); Vertex topLeft = { a.x, a.y - halfWidth }; Vertex topRight = { b.x, a.y - halfWidth }; Vertex bottomLeft = { a.x, a.y + halfWidth }; Vertex bottomRight = { b.x, a.y + halfWidth }; QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight }; addTrap(trap); } else { QPointF perp(pb.y() - pa.y(), pa.x() - pb.x()); qreal length = qSqrt(perp.x() * perp.x() + perp.y() * perp.y()); if (qFuzzyIsNull(length)) return; // need the half of the width perp *= hw / length; QPointF pta = pa + perp; QPointF ptb = pa - perp; QPointF ptc = pb - perp; QPointF ptd = pb + perp; Vertex ta = { FloatToQ27Dot5(pta.x()), FloatToQ27Dot5(pta.y()) }; Vertex tb = { FloatToQ27Dot5(ptb.x()), FloatToQ27Dot5(ptb.y()) }; Vertex tc = { FloatToQ27Dot5(ptc.x()), FloatToQ27Dot5(ptc.y()) }; Vertex td = { FloatToQ27Dot5(ptd.x()), FloatToQ27Dot5(ptd.y()) }; if (ta.y < tb.y) { if (tb.y < td.y) { QTessellator::Trapezoid top = { ta.y, tb.y, &ta, &tb, &ta, &td }; QTessellator::Trapezoid bottom = { td.y, tc.y, &tb, &tc, &td, &tc }; addTrap(top); addTrap(bottom); QTessellator::Trapezoid middle = { tb.y, td.y, &tb, &tc, &ta, &td }; addTrap(middle); } else { QTessellator::Trapezoid top = { ta.y, td.y, &ta, &tb, &ta, &td }; QTessellator::Trapezoid bottom = { tb.y, tc.y, &tb, &tc, &td, &tc }; addTrap(top); addTrap(bottom); if (tb.y != td.y) { QTessellator::Trapezoid middle = { td.y, tb.y, &ta, &tb, &td, &tc }; addTrap(middle); } } } else { if (ta.y < tc.y) { QTessellator::Trapezoid top = { tb.y, ta.y, &tb, &tc, &tb, &ta }; QTessellator::Trapezoid bottom = { tc.y, td.y, &tc, &td, &ta, &td }; addTrap(top); addTrap(bottom); QTessellator::Trapezoid middle = { ta.y, tc.y, &tb, &tc, &ta, &td }; addTrap(middle); } else { QTessellator::Trapezoid top = { tb.y, tc.y, &tb, &tc, &tb, &ta }; QTessellator::Trapezoid bottom = { ta.y, td.y, &tc, &td, &ta, &td }; addTrap(top); addTrap(bottom); if (ta.y != tc.y) { QTessellator::Trapezoid middle = { tc.y, ta.y, &tc, &td, &tb, &ta }; addTrap(middle); } } } } }
void HistogramItem::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &) const { const QwtIntervalData &iData = d_data->data; painter->setPen(QPen(d_data->color)); const int x0 = xMap.transform(baseline()); const int y0 = yMap.transform(baseline()); for ( int i = 0; i < (int)iData.size(); i++ ) { if ( d_data->attributes & HistogramItem::Xfy ) { const int x2 = xMap.transform(iData.value(i)); if ( x2 == x0 ) continue; int y1 = yMap.transform( iData.interval(i).minValue()); int y2 = yMap.transform( iData.interval(i).maxValue()); if ( y1 > y2 ) qSwap(y1, y2); if ( i < (int)iData.size() - 2 ) { const int yy1 = yMap.transform(iData.interval(i+1).minValue()); const int yy2 = yMap.transform(iData.interval(i+1).maxValue()); if ( y2 == qwtMin(yy1, yy2) ) { const int xx2 = xMap.transform( iData.interval(i+1).minValue()); if ( xx2 != x0 && ( (xx2 < x0 && x2 < x0) || (xx2 > x0 && x2 > x0) ) ) { // One pixel distance between neighboured bars y2++; } } } drawBar(painter, Qt::Horizontal, QRect(x0, y1, x2 - x0, y2 - y1)); } else // this is used { const int y2 = yMap.transform(iData.value(i)); if ( y2 == y0 ) continue; int x1 = xMap.transform(iData.interval(i).minValue()); int x2 = xMap.transform(iData.interval(i).maxValue()); if ( x1 > x2 ) qSwap(x1, x2); if ( i < (int)iData.size() - 2 ) { const int xx1 = xMap.transform(iData.interval(i+1).minValue()); const int xx2 = xMap.transform(iData.interval(i+1).maxValue()); if ( x2 == qwtMin(xx1, xx2) ) { const int yy2 = yMap.transform(iData.value(i+1)); if ( yy2 != y0 && ( (yy2 < y0 && y2 < y0) || (yy2 > y0 && y2 > y0) ) ) { // One pixel distance between neighboured bars x2--; } } } drawBar(painter, Qt::Vertical, QRect(x1, y0, x2 - x1, y2 - y0) ); } } }
void JCurveGroupWidget::updateCurve(JCurveWidget *curveView) { if (!curveView) { return; } // 清空旧数据 curveView->clearCurve(); // 获取横、纵坐标信号量 const QString suffix = curveView->property("suffix").toString().replace('-', '_'); const QString nameX = curveView->property("nameX").toString(); const QString nameY = curveView->property("nameY").toString(); QString sectionX = nameX.section(" (", 0, 0); QString sectionY = nameY.section(" (", 0, 0); // QString legendTitle = nameY % " (" % suffix % ")"; JCurveWidget::AxisXYType axisXYType = curveView->axisXYType(); // 获取M-H信号名称 QString machSection, heightSection; if (!JFlyRecord::instance()->readSignalMHSection( JSqlDataMgr::instance()->signalTableNamePrefix().append(suffix), machSection, heightSection)) { return; } // 生成数据表名称 const QString recordTableName = JSqlDataMgr::instance()->recordTableNamePrefix().append(suffix); // if (axisXYType == JCurveWidget::AxisXY_Value_Value) { // 获取记录数据 QVector<QPointF> data; QListIterator<QRectF> citerSiftAreas(q_siftAreas); while (citerSiftAreas.hasNext()) { const QRectF &range = citerSiftAreas.next(); // QVector<QPointF> tempData; if (JSqlDataMgr::instance()->readRecordDataV(recordTableName, sectionX, sectionY, machSection, heightSection, range, tempData)) { data << tempData; } } // 检测是否有数据需要处理 if (data.isEmpty()) { return; // 无数据需要绘制 } // curveView->updateData(curveView->addCurve(legendTitle), data); } else { // 获取记录数据 if (axisXYType == JCurveWidget::AxisXY_Value_Time) { qSwap(sectionX, sectionY); } // QList<QPair<QTime, qreal> > data; QListIterator<QRectF> citerSiftAreas(q_siftAreas); while (citerSiftAreas.hasNext()) { const QRectF &range = citerSiftAreas.next(); // QList<QPair<QTime, qreal> > tempData; if (JSqlDataMgr::instance()->readRecordDataV(recordTableName, sectionX, sectionY, machSection, heightSection, range, tempData)) { data.append(tempData); } } // 检测是否有数据需要处理 if (data.isEmpty()) { return; // 无数据需要绘制 } // curveView->updateData(curveView->addCurve(legendTitle), data); } }