void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem) { QPainterPath path; #ifndef Q_WS_MAC path.setFillRule(Qt::WindingFill); #endif if (staticTextItem->numGlyphs == 0) return; QFontEngine *fontEngine = staticTextItem->fontEngine(); fontEngine->addGlyphsToPath(staticTextItem->glyphs, staticTextItem->glyphPositions, staticTextItem->numGlyphs, &path, 0); if (!path.isEmpty()) { QPainterState *s = state(); QPainter::RenderHints oldHints = s->renderHints; bool changedHints = false; if (bool(oldHints & QPainter::TextAntialiasing) && !bool(fontEngine->fontDef.styleStrategy & QFont::NoAntialias) && !bool(oldHints & QPainter::Antialiasing)) { s->renderHints |= QPainter::Antialiasing; renderHintsChanged(); changedHints = true; } fill(qtVectorPathForPath(path), s->pen.color()); if (changedHints) { s->renderHints = oldHints; renderHintsChanged(); } } }
// the stroke/fill triangulation functions may be invoked either on the gui // thread or some worker thread and must thus be self-contained. void QQuickShapeGenericRenderer::triangulateFill(const QPainterPath &path, const Color4ub &fillColor, VertexContainerType *fillVertices, IndexContainerType *fillIndices, QSGGeometry::Type *indexType, bool supportsElementIndexUint) { const QVectorPath &vp = qtVectorPathForPath(path); QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(TRI_SCALE, TRI_SCALE), 1, supportsElementIndexUint); const int vertexCount = ts.vertices.count() / 2; // just a qreal vector with x,y hence the / 2 fillVertices->resize(vertexCount); ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data()); const qreal *vsrc = ts.vertices.constData(); for (int i = 0; i < vertexCount; ++i) vdst[i].set(vsrc[i * 2] / TRI_SCALE, vsrc[i * 2 + 1] / TRI_SCALE, fillColor); size_t indexByteSize; if (ts.indices.type() == QVertexIndexVector::UnsignedShort) { *indexType = QSGGeometry::UnsignedShortType; // fillIndices is still QVector<quint32>. Just resize to N/2 and pack // the N quint16s into it. fillIndices->resize(ts.indices.size() / 2); indexByteSize = ts.indices.size() * sizeof(quint16); } else { *indexType = QSGGeometry::UnsignedIntType; fillIndices->resize(ts.indices.size()); indexByteSize = ts.indices.size() * sizeof(quint32); } memcpy(fillIndices->data(), ts.indices.data(), indexByteSize); }
void QPaintEngineEx::clip(const QPainterPath &path, Qt::ClipOperation op) { if (path.isEmpty()) { QVectorPath vp(0, 0); clip(vp, op); } else { clip(qtVectorPathForPath(path), op); } }
void QQuickShapeGenericRenderer::triangulateStroke(const QPainterPath &path, const QPen &pen, const Color4ub &strokeColor, VertexContainerType *strokeVertices, const QSize &clipSize) { const QVectorPath &vp = qtVectorPathForPath(path); const QRectF clip(QPointF(0, 0), clipSize); const qreal inverseScale = 1.0 / TRI_SCALE; QTriangulatingStroker stroker; stroker.setInvScale(inverseScale); if (pen.style() == Qt::SolidLine) { stroker.process(vp, pen, clip, 0); } else { QDashedStrokeProcessor dashStroker; dashStroker.setInvScale(inverseScale); dashStroker.process(vp, pen, clip, 0); QVectorPath dashStroke(dashStroker.points(), dashStroker.elementCount(), dashStroker.elementTypes(), 0); stroker.process(dashStroke, pen, clip, 0); } if (!stroker.vertexCount()) { strokeVertices->clear(); return; } const int vertexCount = stroker.vertexCount() / 2; // just a float vector with x,y hence the / 2 strokeVertices->resize(vertexCount); ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(strokeVertices->data()); const float *vsrc = stroker.vertices(); for (int i = 0; i < vertexCount; ++i) vdst[i].set(vsrc[i * 2], vsrc[i * 2 + 1], strokeColor); }
void QPaintEngineEx::drawPath(const QPainterPath &path) { if (!path.isEmpty()) draw(qtVectorPathForPath(path)); }