📄 qpaintengine_raster.cpp
字号:
const QPointF &e = m_elements.at(i); m_elements_dev << QPointF(e.x() + m_dx, e.y() + m_dy); } } else if (m_txop == QTransform::TxScale) { for (int i=0; i<m_elements.size(); ++i) { const QPointF &e = m_elements.at(i); m_elements_dev << QPointF(m_m11 * e.x() + m_dx, m_m22 * e.y() + m_dy); } } else if (m_txop < QTransform::TxProject) { for (int i=0; i<m_elements.size(); ++i) { const QPointF &e = m_elements.at(i); m_elements_dev << QPointF(m_m11 * e.x() + m_m21 * e.y() + m_dx, m_m22 * e.y() + m_m12 * e.x() + m_dy); } } else { for (int i=0; i<m_elements.size(); ++i) { const QPointF &e = m_elements.at(i); qreal x = m_m11 * e.x() + m_m21 * e.y() + m_dx; qreal y = m_m22 * e.y() + m_m12 * e.x() + m_dy; qreal w = m_m13*e.x() + m_m23*e.y() + 1.; w = 1/w; x *= w; y *= w; m_elements_dev << QPointF(x, y); } } elements = m_elements_dev.data(); } controlPointRect = boundingRect(elements, element_count); // Check for out of dev bounds... const bool do_clip = (controlPointRect.left() < -QT_RASTER_COORD_LIMIT || controlPointRect.right() > QT_RASTER_COORD_LIMIT || controlPointRect.top() < -QT_RASTER_COORD_LIMIT || controlPointRect.bottom() > QT_RASTER_COORD_LIMIT); if (do_clip) { clipElements(elements, m_element_types.data(), element_count); } else { convertElements(elements, m_element_types.data(), element_count); }}void QFTOutlineMapper::convertElements(const QPointF *elements, const QPainterPath::ElementType *types, int element_count){ // Translate into FT coords const QPointF *e = elements; for (int i=0; i<element_count; ++i) { switch (*types) { case QPainterPath::MoveToElement: { QT_FT_Vector pt_fixed = { qreal_to_fixed_26_6(e->x()), qreal_to_fixed_26_6(e->y()) }; if (i != 0) m_contours << m_points.size() - 1; m_points << pt_fixed; m_tags << QT_FT_CURVE_TAG_ON; } break; case QPainterPath::LineToElement: { QT_FT_Vector pt_fixed = { qreal_to_fixed_26_6(e->x()), qreal_to_fixed_26_6(e->y()) }; m_points << pt_fixed; m_tags << QT_FT_CURVE_TAG_ON; } break; case QPainterPath::CurveToElement: { QT_FT_Vector cp1_fixed = { qreal_to_fixed_26_6(e->x()), qreal_to_fixed_26_6(e->y()) }; ++e; QT_FT_Vector cp2_fixed = { qreal_to_fixed_26_6((e)->x()), qreal_to_fixed_26_6((e)->y()) }; ++e; QT_FT_Vector ep_fixed = { qreal_to_fixed_26_6((e)->x()), qreal_to_fixed_26_6((e)->y()) }; m_points << cp1_fixed << cp2_fixed << ep_fixed; m_tags << QT_FT_CURVE_TAG_CUBIC << QT_FT_CURVE_TAG_CUBIC << QT_FT_CURVE_TAG_ON; types += 2; i += 2; } break; default: break; } ++types; ++e; } // close the very last subpath m_contours << m_points.size() - 1; m_outline.n_contours = m_contours.size(); m_outline.n_points = m_points.size(); m_outline.points = m_points.data(); m_outline.tags = m_tags.data(); m_outline.contours = m_contours.data();#ifdef QT_DEBUG_CONVERT printf("QFTOutlineMapper::endOutline\n"); printf(" - contours: %d\n", m_outline.n_contours); for (int i=0; i<m_outline.n_contours; ++i) { printf(" - %d\n", m_outline.contours[i]); } printf(" - points: %d\n", m_outline.n_points); for (int i=0; i<m_outline.n_points; ++i) { printf(" - %d -- %.2f, %.2f, (%d, %d)\n", i, m_outline.points[i].x / 64.0, m_outline.points[i].y / 64.0, m_outline.points[i], m_outline.points[i]); }#endif}void QFTOutlineMapper::clipElements(const QPointF *elements, const QPainterPath::ElementType *types, int element_count){ // We could save a bit of time by actually implementing them fully // instead of going through convenience functionallity, but since // this part of code hardly every used, it shouldn't matter. QPainterPath path; for (int i=0; i<element_count; ++i) { switch (types[i]) { case QPainterPath::MoveToElement: path.moveTo(elements[i]); break; case QPainterPath::LineToElement: path.lineTo(elements[i]); break; case QPainterPath::CurveToElement: path.cubicTo(elements[i], elements[i+1], elements[i+2]); i += 2; break; default: break; } } QPolygonF polygon = path.toFillPolygon(); QRasterFloatPoint *clipped_points; int clipped_count; m_clipper.clipPolygon((QRasterFloatPoint *) polygon.constData(), polygon.size(), &clipped_points, &clipped_count, true);#ifdef QT_DEBUG_CONVERT printf(" - shape was clipped\n"); for (int i=0; i<clipped_count; ++i) { printf(" - %.2f, -%.2f\n", clipped_points[i].x(), clipped_points[i].y()); }#endif if (!clipped_count) { m_valid = false; return; } QPainterPath::ElementType *point_types = new QPainterPath::ElementType[clipped_count]; point_types[0] = QPainterPath::MoveToElement; for (int i=0; i<clipped_count; ++i) point_types[i] = QPainterPath::LineToElement; convertElements((const QPointF *)clipped_points, point_types, clipped_count); delete[] point_types;}static void qt_ft_outline_move_to(qfixed x, qfixed y, void *data){ ((QFTOutlineMapper *) data)->moveTo(QPointF(qt_fixed_to_real(x), qt_fixed_to_real(y)));}static void qt_ft_outline_line_to(qfixed x, qfixed y, void *data){ ((QFTOutlineMapper *) data)->lineTo(QPointF(qt_fixed_to_real(x), qt_fixed_to_real(y)));}static void qt_ft_outline_cubic_to(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey, void *data){ ((QFTOutlineMapper *) data)->curveTo(QPointF(qt_fixed_to_real(c1x), qt_fixed_to_real(c1y)), QPointF(qt_fixed_to_real(c2x), qt_fixed_to_real(c2y)), QPointF(qt_fixed_to_real(ex), qt_fixed_to_real(ey)));}#if !defined(QT_NO_DEBUG) && 0static void qt_debug_path(const QPainterPath &path){ const char *names[] = { "MoveTo ", "LineTo ", "CurveTo ", "CurveToData" }; printf("\nQPainterPath: elementCount=%d\n", path.elementCount()); for (int i=0; i<path.elementCount(); ++i) { const QPainterPath::Element &e = path.elementAt(i); Q_ASSERT(e.type >= 0 && e.type <= QPainterPath::CurveToDataElement); printf(" - %3d:: %s, (%.2f, %.2f)\n", i, names[e.type], e.x, e.y); }}#endifstatic inline bool needsResolving(QSpanData *data){ return ((data->type == QSpanData::LinearGradient || data->type == QSpanData::RadialGradient || data->type == QSpanData::ConicalGradient) && data->gradient.needsResolving);}static inline void resolveGradientBounds(const QRectF &rect, QSpanData *data){ GradientData &gradient = data->gradient; switch(data->type) { case QSpanData::LinearGradient: { gradient.linear.origin.x = rect.x() + rect.width() * gradient.unresolvedLinear.origin.x; gradient.linear.origin.y = rect.y() + rect.height() * gradient.unresolvedLinear.origin.y; gradient.linear.end.x = rect.x() + rect.width() * gradient.unresolvedLinear.end.x; gradient.linear.end.y = rect.y() + rect.height() * gradient.unresolvedLinear.end.y; break; } case QSpanData::RadialGradient: { gradient.radial.center.x = rect.x() + rect.width() * gradient.unresolvedRadial.center.x; gradient.radial.center.y = rect.y() + rect.height() * gradient.unresolvedRadial.center.y; gradient.radial.focal.x = rect.x() + rect.width() * gradient.unresolvedRadial.focal.x; gradient.radial.focal.y = rect.y() + rect.height() * gradient.unresolvedRadial.focal.y; gradient.radial.radius = qMin(rect.x() + rect.width() * gradient.unresolvedRadial.radius, rect.y() + rect.height() * gradient.unresolvedRadial.radius); break; } case QSpanData::ConicalGradient: gradient.conical.center.x = rect.x() + rect.width() * gradient.unresolvedConical.center.x; gradient.conical.center.y = rect.y() + rect.height() * gradient.unresolvedConical.center.y; gradient.conical.angle = gradient.unresolvedConical.angle; break; default: break; }}// use this when there's no overhead in computing the rectanglestatic inline void resolveGradientBoundsConditional(const QRectF &rect, QSpanData *data){ if (data->blend && needsResolving(data)) resolveGradientBounds(rect, data);}/*! \class QRasterPaintEngine \preliminary \ingroup qws \since 4.2 \brief The QRasterPaintEngine class enables hardware acceleration of painting operations in Qtopia Core. Note that this functionality is only available in \l {Qtopia Core}. In \l {Qtopia Core}, painting is a pure software implementation. But starting with \l{Qtopia Core} 4.2, it is possible to add an accelerated graphics driver to take advantage of available hardware resources. Hardware acceleration is accomplished by creating a custom screen driver, accelerating the copying from memory to the screen, and implementing a custom paint engine accelerating the various painting operations. Then a custom paint device (derived from the QCustomRasterPaintDevice class) and a custom window surface (derived from QWSWindowSurface) must be implemented to make \l {Qtopia Core} aware of the accelerated driver. \note The QRasterPaintEngine class does not support 8-bit images. Instead, they need to be converted to a supported format, such as QImage::Format_ARGB32_Premultiplied. See the \l {Adding an Accelerated Graphics Driver in Qtopia Core} documentation for details. \sa QCustomRasterPaintDevice, QPaintEngine*//*! \fn Type QRasterPaintEngine::type() const \reimp*//*! \typedef QSpan \relates QRasterPaintEngine A struct equivalent to QT_FT_Span, containing a position (x, y), the span's length in pixels and its color/coverage (a value ranging from 0 to 255).*//*! Creates a raster based paint engine with the complete set of \l {QPaintEngine::PaintEngineFeature}{paint engine features and capabilities}.*/QRasterPaintEngine::QRasterPaintEngine() : QPaintEngine(*(new QRasterPaintEnginePrivate), QPaintEngine::PaintEngineFeatures(AllFeatures) ){ init();}/*! \internal*/QRasterPaintEngine::QRasterPaintEngine(QRasterPaintEnginePrivate &dd) : QPaintEngine(dd, QPaintEngine::PaintEngineFeatures(AllFeatures)){ init();}void QRasterPaintEngine::init(){ Q_D(QRasterPaintEngine); d->rasterPoolSize = 4096; d->rasterPoolBase =#if defined(Q_WS_WIN64) (unsigned char *) _aligned_malloc(d->rasterPoolSize, __alignof(void*));#else (unsigned char *) malloc(d->rasterPoolSize);#endif // The antialiasing raster. d->grayRaster = new QT_FT_Raster; qt_ft_grays_raster.raster_new(0, d->grayRaster); qt_ft_grays_raster.raster_reset(*d->grayRaster, d->rasterPoolBase, d->rasterPoolSize); // Initialize the standard raster. d->blackRaster = new QT_FT_Raster; qt_ft_standard_raster.raster_new(0, d->blackRaster); qt_ft_standard_raster.raster_reset(*d->blackRaster, d->rasterPoolBase, d->rasterPoolSize); d->rasterBuffer = new QRasterBuffer();#ifdef Q_WS_WIN d->fontRasterBuffer = new QRasterBuffer();#endif d->outlineMapper = new QFTOutlineMapper; d->dashStroker = 0; d->flushOnEnd = true; d->basicStroker.setMoveToHook(qt_ft_outline_move_to); d->basicStroker.setLineToHook(qt_ft_outline_line_to); d->basicStroker.setCubicToHook(qt_ft_outline_cubic_to); d->dashStroker = 0;}/*! Destroys this paint engine.*/QRasterPaintEngine::~QRasterPaintEngine(){ Q_D(QRasterPaintEngine);#if defined(Q_WS_WIN64) _aligned_free(d->rasterPoolBase);#else free(d->rasterPoolBase);#endif qt_ft_grays_raster.raster_done(*d->grayRaster); delete d->grayRaster; qt_ft_standard_raster.raster_done(*d->blackRaster); delete d->blackRaster;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -