diff -wbBur orig/qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper.cpp qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper.cpp --- orig/qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper.cpp 2009-06-20 07:01:58.000000000 +0200 +++ qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper.cpp 2009-09-12 11:19:10.156250000 +0200 @@ -74,6 +74,39 @@ return QRectF(QPointF(minx, miny), QPointF(maxx, maxy)); } +static QPainterPath vp_convertToPainterPath(const QVectorPath &vp) +{ + QPainterPath path; + + if (vp.elementCount() == 0) + return path; + + const QPointF *points = (const QPointF *) vp.points(); + + if (vp.elements()) { + for (int i=0; i QT_RASTER_COORD_LIMIT - || controlPointRect.top() < -QT_RASTER_COORD_LIMIT - || controlPointRect.bottom() > QT_RASTER_COORD_LIMIT); + const bool do_clip = (controlPointRect.left() < -(QT_RASTER_COORD_LIMIT + 1) + || controlPointRect.right() > (QT_RASTER_COORD_LIMIT + 1) + || controlPointRect.top() < - (QT_RASTER_COORD_LIMIT + 1) + || controlPointRect.bottom() > (QT_RASTER_COORD_LIMIT + 1) ); - if (do_clip) { + if (do_clip) + { + //if the path consists only of straight lines, we can use a faster clipping algorithm + if(element_count > 10000 && !isCurved()) + { + QDataBuffer* trimBuffer; + if (m_txop == QTransform::TxNone) + { + trimBuffer = &m_elements; + } + else + { + trimBuffer = &m_elements_dev; + } + trimFeature(trimBuffer, trimBuffer->at(0) != trimBuffer->at(trimBuffer->size() - 1)); + } + else + { clipElements(elements, elementTypes(), element_count); - } else { + } + } + else + { convertElements(elements, elementTypes(), element_count); } } @@ -409,4 +440,18 @@ m_txop = old_txop; } +bool QOutlineMapper::isCurved() const +{ + bool isCurved = false; + for(int i = 0; i < m_element_types.size(); ++i) + { + if(m_element_types.at(i) == QPainterPath::CurveToElement || m_element_types.at(i) == QPainterPath::CurveToDataElement) + { + isCurved = true; + break; + } + } + return isCurved; +} + QT_END_NAMESPACE diff -wbBur orig/qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper_p.h qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper_p.h --- orig/qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper_p.h 2009-06-20 07:01:58.000000000 +0200 +++ qt-win-opensource-src-4.5.2/src/gui/painting/qoutlinemapper_p.h 2009-09-12 11:17:14.281250000 +0200 @@ -65,11 +65,15 @@ #include #include "qpaintengineex_p.h" +#include + QT_BEGIN_NAMESPACE // This limitations comes from qgrayraster.c. Any higher and // rasterization of shapes will produce incorrect results. const int QT_RASTER_COORD_LIMIT = 32767; +const int QT_NEGATIVE_RASTER_COORD_LIMIT = -32767; +static const double SMALL_NUM = 1e-12; //#define QT_DEBUG_CONVERT @@ -231,8 +235,191 @@ private: bool m_round_coords; + + // A handy way to refer to the four boundaries + enum Boundary {XMax, XMin, YMax, YMin}; + + /**Trims the feature to the bounding box defined by +-QT_RASTER_COORD_LIMIT. +// Uses Sutherland and Hodgman's polygon-clipping algorithm. See J. D. Foley, A. van Dam, +// S. K. Feiner, and J. F. Hughes, Computer Graphics, Principles and +// Practice. Addison-Wesley Systems Programming Series, +// Addison-Wesley, 2nd ed., 1991.*/ + void trimFeature(QDataBuffer* elements, bool shapeOpen); + + // Trims the given feature to the given boundary. Returns the + // trimmed feature in the outX and outY vectors. + void trimFeatureToBoundary( const QDataBuffer* in, + QDataBuffer* out, + Boundary b, + bool shapeOpen ); + + /**True if the path contains CurveToElement or CurveToDataElement, false if if only consists straight lines*/ + bool isCurved() const; + + // Determines if a point is inside or outside the given boundary + static bool inside( const double x, const double y, Boundary b ); + + // Calculates the intersection point between a line defined by a + // (x1, y1), and (x2, y2) and the given boundary + static QPointF intersect( const double x1, const double y1, + const double x2, const double y2, + Boundary b ); }; + +//inline functions +// An auxilary function to trimPolygonToBoundarY() that returns +// whether a point is inside or outside the given boundary. + +inline void QOutlineMapper::trimFeature(QDataBuffer* elements, bool shapeOpen) +{ + QDataBuffer tmpElements; + trimFeatureToBoundary( elements, &tmpElements, XMax, shapeOpen); + elements->reset(); + trimFeatureToBoundary( &tmpElements, elements, YMax, shapeOpen ); + tmpElements.reset(); + trimFeatureToBoundary( elements, &tmpElements, XMin, shapeOpen ); + elements->reset(); + trimFeatureToBoundary( &tmpElements, elements, YMin, shapeOpen ); + tmpElements.reset(); + + QPainterPath path; + if(elements->size() > 0) + { + path.moveTo(elements->at(0)); + } + for(int i = 1; i < elements->size(); ++i) + { + path.lineTo(elements->at(i)); + } + uint old_txop = m_txop; + m_txop = QTransform::TxNone; + convertPath(path); + m_txop = old_txop; +} + +inline void QOutlineMapper::trimFeatureToBoundary( const QDataBuffer* in, QDataBuffer* out, Boundary b, bool shapeOpen ) +{ + + // The shapeOpen parameter selects whether this function treats the + // shape as open or closed. False is appropriate for polygons and + // true for polylines. + unsigned int i1 = in->size() - 1; + + // and compare to the first point initially. + for ( int i2 = 0; i2 < in->size() ; ++i2 ) + { // look at each edge of the polygon in turn + if ( inside( in->at(i2).x(), in->at(i2).y(), b ) ) // end point of edge is inside boundary + { + if ( inside( in->at(i1).x(), in->at(i1).y(), b ) ) + { + out->add(in->at(i2)); + } + else + { + // edge crosses into the boundary, so trim back to the boundary, and + // store both ends of the new edge + if ( !( i2 == 0 && shapeOpen ) ) + { + QPointF p = intersect( in->at(i1).x(), in->at(i1).y(), in->at(i2).x(), in->at(i2).y(), b); + out->add(p); + } + out->add(in->at(i2)); + } + } + else // end point of edge is outside boundary + { + // start point is in boundary, so need to trim back + if ( inside( in->at(i1).x(), in->at(i1).y(), b ) ) + { + if ( !( i2 == 0 && shapeOpen ) ) + { + QPointF p = intersect( in->at(i1).x(), in->at(i1).y(), in->at(i2).x(), in->at(i2).y(), b ); + out->add(p); + } + } + } + i1 = i2; + } +} + + +inline bool QOutlineMapper::inside( const double x, const double y, Boundary b ) +{ + switch ( b ) + { + case XMax: // x < QT_RASTER_COORD_LIMIT is inside + if ( x < QT_RASTER_COORD_LIMIT ) + return true; + break; + case XMin: // x > -QT_RASTER_COORD_LIMIT is inside + if ( x > QT_NEGATIVE_RASTER_COORD_LIMIT ) + return true; + break; + case YMax: // y < QT_RASTER_COORD_LIMIT is inside + if ( y < QT_RASTER_COORD_LIMIT) + return true; + break; + case YMin: // y > -QT_RASTER_COORD_LIMIT is inside + if ( y > QT_NEGATIVE_RASTER_COORD_LIMIT ) + return true; + break; + } + return false; +} + +// An auxilary function to trimPolygonToBoundarY() that calculates and +// returns the intersection of the line defined by the given points +// and the given boundary. + +inline QPointF QOutlineMapper::intersect( const double x1, const double y1, + const double x2, const double y2, + Boundary b ) +{ + // This function assumes that the two given points (x1, y1), and + // (x2, y2) cross the given boundary. Making this assumption allows + // some optimisations. + + double r_n = SMALL_NUM, r_d = SMALL_NUM; + + switch ( b ) + { + case XMax: // x = MAX_X boundary + r_n = -( x1 - QT_RASTER_COORD_LIMIT ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + r_d = ( x2 - x1 ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + break; + case XMin: // x = MIN_X boundary + r_n = -( x1 - QT_NEGATIVE_RASTER_COORD_LIMIT ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + r_d = ( x2 - x1 ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + break; + case YMax: // y = MAX_Y boundary + r_n = ( y1 - QT_RASTER_COORD_LIMIT ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + r_d = -( y2 - y1 ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + break; + case YMin: // y = MIN_Y boundary + r_n = ( y1 - QT_NEGATIVE_RASTER_COORD_LIMIT ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + r_d = -( y2 - y1 ) * ( QT_RASTER_COORD_LIMIT - QT_NEGATIVE_RASTER_COORD_LIMIT ); + break; + } + + QPointF p; + + if ( std::abs( r_d ) > SMALL_NUM && std::abs( r_n ) > SMALL_NUM ) + { // they cross + double r = r_n / r_d; + p.setX( x1 + r*( x2 - x1 ) ); + p.setY( y1 + r*( y2 - y1 ) ); + } + else + { + // Should never get here, but if we do for some reason, cause a + // clunk because something else is wrong if we do. + Q_ASSERT( std::abs( r_d ) > SMALL_NUM && std::abs( r_n ) > SMALL_NUM ); + } + + return p; +} + QT_END_NAMESPACE #endif // QOUTLINEMAPPER_P_H diff -wbBur orig/qt-win-opensource-src-4.5.2/src/gui/painting/qprintengine_pdf.cpp qt-win-opensource-src-4.5.2/src/gui/painting/qprintengine_pdf.cpp --- orig/qt-win-opensource-src-4.5.2/src/gui/painting/qprintengine_pdf.cpp 2009-06-20 07:01:59.000000000 +0200 +++ qt-win-opensource-src-4.5.2/src/gui/painting/qprintengine_pdf.cpp 2010-04-01 11:18:56.390625000 +0200 @@ -99,7 +99,7 @@ inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features() { QPaintEngine::PaintEngineFeatures f = QPaintEngine::AllFeatures; - f &= ~(QPaintEngine::PorterDuff | QPaintEngine::PerspectiveTransform + f &= (QPaintEngine::PorterDuff | QPaintEngine::PerspectiveTransform | QPaintEngine::ObjectBoundingModeGradients #ifndef USE_NATIVE_GRADIENTS | QPaintEngine::LinearGradientFill diff -wbBur orig/qt-win-opensource-src-4.5.2/src/plugins/sqldrivers/sqlite/sqlite.pro qt-win-opensource-src-4.5.2/src/plugins/sqldrivers/sqlite/sqlite.pro --- orig/qt-win-opensource-src-4.5.2/src/plugins/sqldrivers/sqlite/sqlite.pro 2009-06-20 07:01:59.000000000 +0200 +++ qt-win-opensource-src-4.5.2/src/plugins/sqldrivers/sqlite/sqlite.pro 2010-04-26 17:21:49.125000000 +0200 @@ -6,7 +6,7 @@ !system-sqlite:!contains( LIBS, .*sqlite.* ) { CONFIG(release, debug|release):DEFINES *= NDEBUG - DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE + DEFINES += SQLITE_OMIT_COMPLETE INCLUDEPATH += ../../../3rdparty/sqlite SOURCES += ../../../3rdparty/sqlite/sqlite3.c } else { diff -wbBur orig/qt-win-opensource-src-4.5.2/src/sql/models/qsqltablemodel.cpp qt-win-opensource-src-4.5.2/src/sql/models/qsqltablemodel.cpp --- orig/qt-win-opensource-src-4.5.2/src/sql/models/qsqltablemodel.cpp 2009-06-20 07:01:59.000000000 +0200 +++ qt-win-opensource-src-4.5.2/src/sql/models/qsqltablemodel.cpp 2010-04-01 12:20:26.484375000 +0200 @@ -202,7 +202,7 @@ editQuery.addBindValue(rec.value(i)); } for (i = 0; i < whereValues.count(); ++i) { - if (whereValues.isGenerated(i)) + if (whereValues.isGenerated(i) && !whereValues.isNull(i)) editQuery.addBindValue(whereValues.value(i)); }