void hist_impl::render(const void* pWnd, int pX, int pY, int pVPW, int pVPH) { float w = float(pVPW - (leftMargin()+rightMargin()+tickSize())); float h = float(pVPH - (bottomMargin()+topMargin()+tickSize())); float offset_x = (2.0f * (leftMargin()+tickSize()) + (w - pVPW)) / pVPW; float offset_y = (2.0f * (bottomMargin()+tickSize()) + (h - pVPH)) / pVPH; float scale_x = w / pVPW; float scale_y = h / pVPH; CheckGL("Begin Histogram::render"); /* Enavle scissor test to discard anything drawn beyond viewport. * Set scissor rectangle to clip fragments outside of viewport */ glScissor(pX+leftMargin()+tickSize(), pY+bottomMargin()+tickSize(), pVPW - (leftMargin()+rightMargin()+tickSize()), pVPH - (bottomMargin()+topMargin()+tickSize())); glEnable(GL_SCISSOR_TEST); glm::mat4 trans = glm::translate(glm::scale(glm::mat4(1), glm::vec3(scale_x, scale_y, 1)), glm::vec3(offset_x, offset_y, 0)); glUseProgram(mHistBarProgram); glUniformMatrix4fv(mHistBarMatIndex, 1, GL_FALSE, glm::value_ptr(trans)); glUniform4fv(mHistBarColorIndex, 1, mBarColor); glUniform1f(mHistBarNBinsIndex, (GLfloat)mNBins); glUniform1f(mHistBarYMaxIndex, ymax()); /* render a rectangle for each bin. Same * rectangle is scaled and translated accordingly * for each bin. This is done by OpenGL feature of * instanced rendering */ bindResources(pWnd); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, mNBins); unbindResources(); glUseProgram(0); /* Stop clipping */ glDisable(GL_SCISSOR_TEST); renderChart(pWnd, pX, pY, pVPW, pVPH); CheckGL("End Histogram::render"); }
double height() const { return ymax() - ymin(); };
nervana::boundingbox::box unnormalize(float width, float height) { return nervana::boundingbox::box( xmin() * width, ymin() * height, xmax() * width - 1, ymax() * height - 1); }
QRectF QTessellatorPrivate::collectAndSortVertices(const QPointF *points, int *maxActiveEdges) { *maxActiveEdges = 0; Vertex *v = vertices.storage; Vertex **vv = vertices.sorted; qreal xmin(points[0].x()); qreal xmax(points[0].x()); qreal ymin(points[0].y()); qreal ymax(points[0].y()); // collect vertex data Q27Dot5 y_prev = FloatToQ27Dot5(points[vertices.nPoints-1].y()); Q27Dot5 x_next = FloatToQ27Dot5(points[0].x()); Q27Dot5 y_next = FloatToQ27Dot5(points[0].y()); int j = 0; int i = 0; while (i < vertices.nPoints) { Q27Dot5 y_curr = y_next; *vv = v; v->x = x_next; v->y = y_next; v->flags = 0; next_point: xmin = qMin(xmin, points[i+1].x()); xmax = qMax(xmax, points[i+1].x()); ymin = qMin(ymin, points[i+1].y()); ymax = qMax(ymax, points[i+1].y()); y_next = FloatToQ27Dot5(points[i+1].y()); x_next = FloatToQ27Dot5(points[i+1].x()); // skip vertices on top of each other if (v->x == x_next && v->y == y_next) { ++i; if (i < vertices.nPoints) goto next_point; Vertex *v0 = vertices.storage; v0->flags &= ~(LineBeforeStarts|LineBeforeEnds|LineBeforeHorizontal); if (y_prev < y_curr) v0->flags |= LineBeforeEnds; else if (y_prev > y_curr) v0->flags |= LineBeforeStarts; else v0->flags |= LineBeforeHorizontal; if ((v0->flags & (LineBeforeStarts|LineAfterStarts)) && !(v0->flags & (LineAfterEnds|LineBeforeEnds))) *maxActiveEdges += 2; break; } if (y_prev < y_curr) v->flags |= LineBeforeEnds; else if (y_prev > y_curr) v->flags |= LineBeforeStarts; else v->flags |= LineBeforeHorizontal; if (y_curr < y_next) v->flags |= LineAfterStarts; else if (y_curr > y_next) v->flags |= LineAfterEnds; else v->flags |= LineAfterHorizontal; // ### could probably get better limit by looping over sorted list and counting down on ending edges if ((v->flags & (LineBeforeStarts|LineAfterStarts)) && !(v->flags & (LineAfterEnds|LineBeforeEnds))) *maxActiveEdges += 2; y_prev = y_curr; ++v; ++vv; ++j; ++i; } vertices.nPoints = j; QDEBUG() << "maxActiveEdges=" << *maxActiveEdges; vv = vertices.sorted; qSort(vv, vv + vertices.nPoints, compareVertex); return QRectF(xmin, ymin, xmax-xmin, ymax-ymin); }
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"); }
int QDeclarativePinch::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { if (_id < 11) qt_static_metacall(this, _c, _id, _a); _id -= 11; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< QGraphicsObject**>(_v) = target(); break; case 1: *reinterpret_cast< qreal*>(_v) = minimumScale(); break; case 2: *reinterpret_cast< qreal*>(_v) = maximumScale(); break; case 3: *reinterpret_cast< qreal*>(_v) = minimumRotation(); break; case 4: *reinterpret_cast< qreal*>(_v) = maximumRotation(); break; case 5: *reinterpret_cast< Axis*>(_v) = axis(); break; case 6: *reinterpret_cast< qreal*>(_v) = xmin(); break; case 7: *reinterpret_cast< qreal*>(_v) = xmax(); break; case 8: *reinterpret_cast< qreal*>(_v) = ymin(); break; case 9: *reinterpret_cast< qreal*>(_v) = ymax(); break; case 10: *reinterpret_cast< bool*>(_v) = active(); break; } _id -= 11; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 0: setTarget(*reinterpret_cast< QGraphicsObject**>(_v)); break; case 1: setMinimumScale(*reinterpret_cast< qreal*>(_v)); break; case 2: setMaximumScale(*reinterpret_cast< qreal*>(_v)); break; case 3: setMinimumRotation(*reinterpret_cast< qreal*>(_v)); break; case 4: setMaximumRotation(*reinterpret_cast< qreal*>(_v)); break; case 5: setAxis(*reinterpret_cast< Axis*>(_v)); break; case 6: setXmin(*reinterpret_cast< qreal*>(_v)); break; case 7: setXmax(*reinterpret_cast< qreal*>(_v)); break; case 8: setYmin(*reinterpret_cast< qreal*>(_v)); break; case 9: setYmax(*reinterpret_cast< qreal*>(_v)); break; } _id -= 11; } else if (_c == QMetaObject::ResetProperty) { switch (_id) { case 0: resetTarget(); break; } _id -= 11; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 11; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 11; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 11; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 11; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 11; } #endif // QT_NO_PROPERTIES return _id; }
void Nhdc12832::setpixel(unsigned int x, unsigned int y){ if( (x <= xmax()) && (y <= ymax()) ){ nhd_mem[x][y/8] |= mask[7-(y&0x07)]; } }