Changeset 846 for trunk/src/gui/painting
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 4 deleted
- 163 edited
- 8 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/painting/painting.pri
r811 r846 92 92 HEADERS += \ 93 93 painting/qpaintengine_raster_p.h \ 94 painting/qdrawhelper_p.h \ 95 painting/qblendfunctions_p.h \ 94 96 painting/qrasterdefs_p.h \ 95 97 painting/qgrayraster_p.h … … 124 126 HEADERS += \ 125 127 painting/qgraphicssystem_raster_p.h \ 128 painting/qgraphicssystem_runtime_p.h \ 126 129 painting/qgraphicssystemfactory_p.h \ 127 130 painting/qgraphicssystemplugin_p.h \ … … 130 133 SOURCES += \ 131 134 painting/qgraphicssystem_raster.cpp \ 135 painting/qgraphicssystem_runtime.cpp \ 132 136 painting/qgraphicssystemfactory.cpp \ 133 137 painting/qgraphicssystemplugin.cpp \ … … 210 214 } 211 215 212 contains(QMAKE_MAC_XARCH, no) { 213 DEFINES += QT_NO_MAC_XARCH 214 } else:if(mmx|3dnow|sse|sse2|iwmmxt) { 216 if(mmx|3dnow|sse|sse2|iwmmxt) { 215 217 HEADERS += painting/qdrawhelper_x86_p.h \ 216 218 painting/qdrawhelper_mmx_p.h \ 217 painting/qdrawhelper_sse_p.h 218 mmx { 219 DEFINES += QT_HAVE_MMX 220 MMX_SOURCES += painting/qdrawhelper_mmx.cpp 221 } 222 3dnow { 223 DEFINES += QT_HAVE_3DNOW 224 MMX3DNOW_SOURCES += painting/qdrawhelper_mmx3dnow.cpp 225 sse { 226 SSE3DNOW_SOURCES += painting/qdrawhelper_sse3dnow.cpp 227 } 228 } 229 sse { 230 DEFINES += QT_HAVE_SSE 231 SSE_SOURCES += painting/qdrawhelper_sse.cpp 232 233 DEFINES += QT_HAVE_MMXEXT 234 } 235 sse2 { 236 DEFINES += QT_HAVE_SSE2 237 SSE2_SOURCES += painting/qdrawhelper_sse2.cpp 238 } 239 iwmmxt { 240 DEFINES += QT_HAVE_IWMMXT 241 IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp 242 } 243 244 win32-g++|!win32:!*-icc* { 245 mmx { 246 os2:mmx_compiler.commands = $$QMAKE_RUN_CXX -Winline 247 else:mmx_compiler.commands = $$QMAKE_CXX -c -Winline 248 249 mac { 250 mmx_compiler.commands += -Xarch_i386 -mmmx 251 mmx_compiler.commands += -Xarch_x86_64 -mmmx 252 } else { 253 mmx_compiler.commands += -mmmx 254 } 255 256 os2 { 257 mmx_compiler.commands = $$replace(mmx_compiler.commands, \\$src, ${QMAKE_FILE_IN}) 258 mmx_compiler.commands = $$replace(mmx_compiler.commands, \\$obj, ${QMAKE_FILE_OUT}) 259 } else { 260 mmx_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} 261 } 262 mmx_compiler.dependency_type = TYPE_C 263 mmx_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} 264 mmx_compiler.input = MMX_SOURCES 265 mmx_compiler.variable_out = OBJECTS 266 mmx_compiler.name = compiling[mmx] ${QMAKE_FILE_IN} 267 silent:mmx_compiler.commands = @echo compiling[mmx] ${QMAKE_FILE_IN} && $$mmx_compiler.commands 268 QMAKE_EXTRA_COMPILERS += mmx_compiler 269 } 270 3dnow { 271 os2:mmx3dnow_compiler.commands = $$QMAKE_RUN_CXX -Winline 272 else:mmx3dnow_compiler.commands = $$QMAKE_CXX -c -Winline 273 274 mac { 275 mmx3dnow_compiler.commands += -Xarch_i386 -m3dnow -Xarch_i386 -mmmx 276 mmx3dnow_compiler.commands += -Xarch_x86_64 -m3dnow -Xarch_x86_64 -mmmx 277 } else { 278 mmx3dnow_compiler.commands += -m3dnow -mmmx 279 } 280 281 os2 { 282 mmx3dnow_compiler.commands = $$replace(mmx3dnow_compiler.commands, \\$src, ${QMAKE_FILE_IN}) 283 mmx3dnow_compiler.commands = $$replace(mmx3dnow_compiler.commands, \\$obj, ${QMAKE_FILE_OUT}) 284 } else { 285 mmx3dnow_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} 286 } 287 mmx3dnow_compiler.dependency_type = TYPE_C 288 mmx3dnow_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} 289 mmx3dnow_compiler.input = MMX3DNOW_SOURCES 290 mmx3dnow_compiler.variable_out = OBJECTS 291 mmx3dnow_compiler.name = compiling[mmx3dnow] ${QMAKE_FILE_IN} 292 silent:mmx3dnow_compiler.commands = @echo compiling[mmx3dnow] ${QMAKE_FILE_IN} && $$mmx3dnow_compiler.commands 293 QMAKE_EXTRA_COMPILERS += mmx3dnow_compiler 294 sse { 295 os2:sse3dnow_compiler.commands = $$QMAKE_RUN_CXX -Winline 296 else:sse3dnow_compiler.commands = $$QMAKE_CXX -c -Winline 297 298 mac { 299 sse3dnow_compiler.commands += -Xarch_i386 -m3dnow -Xarch_i386 -msse 300 sse3dnow_compiler.commands += -Xarch_x86_64 -m3dnow -Xarch_x86_64 -msse 301 } else:os2 { 302 # SSE data types (__m128i etc.) don't get 16-byte alignment on stack with GCC 4.4.4 303 # (compiler bug?), force it with -mstackrealign to avoid spontaneous SIGSEGVs 304 sse3dnow_compiler.commands += -m3dnow -msse -mstackrealign 305 } else { 306 sse3dnow_compiler.commands += -m3dnow -msse 307 } 308 309 os2 { 310 sse3dnow_compiler.commands = $$replace(sse3dnow_compiler.commands, \\$src, ${QMAKE_FILE_IN}) 311 sse3dnow_compiler.commands = $$replace(sse3dnow_compiler.commands, \\$obj, ${QMAKE_FILE_OUT}) 312 } else { 313 sse3dnow_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} 314 } 315 sse3dnow_compiler.dependency_type = TYPE_C 316 sse3dnow_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} 317 sse3dnow_compiler.input = SSE3DNOW_SOURCES 318 sse3dnow_compiler.variable_out = OBJECTS 319 sse3dnow_compiler.name = compiling[sse3dnow] ${QMAKE_FILE_IN} 320 silent:sse3dnow_compiler.commands = @echo compiling[sse3dnow] ${QMAKE_FILE_IN} && $$sse3dnow_compiler.commands 321 QMAKE_EXTRA_COMPILERS += sse3dnow_compiler 322 } 323 } 324 sse { 325 os2:sse_compiler.commands = $$QMAKE_RUN_CXX -Winline 326 else:sse_compiler.commands = $$QMAKE_CXX -c -Winline 327 328 mac { 329 sse_compiler.commands += -Xarch_i386 -msse 330 sse_compiler.commands += -Xarch_x86_64 -msse 331 } else:os2 { 332 # SSE data types (__m128i etc.) don't get 16-byte alignment on stack with GCC 4.4.4 333 # (compiler bug?), force it with -mstackrealign to avoid spontaneous SIGSEGVs 334 sse_compiler.commands += -msse -mstackrealign 335 } else { 336 sse_compiler.commands += -msse 337 } 338 339 os2 { 340 sse_compiler.commands = $$replace(sse_compiler.commands, \\$src, ${QMAKE_FILE_IN}) 341 sse_compiler.commands = $$replace(sse_compiler.commands, \\$obj, ${QMAKE_FILE_OUT}) 342 } else { 343 sse_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} 344 } 345 sse_compiler.dependency_type = TYPE_C 346 sse_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} 347 sse_compiler.input = SSE_SOURCES 348 sse_compiler.variable_out = OBJECTS 349 sse_compiler.name = compiling[sse] ${QMAKE_FILE_IN} 350 silent:sse_compiler.commands = @echo compiling[sse] ${QMAKE_FILE_IN} && $$sse_compiler.commands 351 QMAKE_EXTRA_COMPILERS += sse_compiler 352 } 353 sse2 { 354 os2:sse2_compiler.commands = $$QMAKE_RUN_CXX -Winline 355 else:sse2_compiler.commands = $$QMAKE_CXX -c -Winline 356 357 mac { 358 sse2_compiler.commands += -Xarch_i386 -msse2 359 sse2_compiler.commands += -Xarch_x86_64 -msse2 360 } else:os2 { 361 # SSE data types (__m128i etc.) don't get 16-byte alignment on stack with GCC 4.4.4 362 # (compiler bug?), force it with -mstackrealign to avoid spontaneous SIGSEGVs 363 sse2_compiler.commands += -msse2 -mstackrealign 364 } else { 365 sse2_compiler.commands += -msse2 366 } 367 368 os2 { 369 sse2_compiler.commands = $$replace(sse2_compiler.commands, \\$src, ${QMAKE_FILE_IN}) 370 sse2_compiler.commands = $$replace(sse2_compiler.commands, \\$obj, ${QMAKE_FILE_OUT}) 371 } else { 372 sse2_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} 373 } 374 sse2_compiler.dependency_type = TYPE_C 375 sse2_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} 376 sse2_compiler.input = SSE2_SOURCES 377 sse2_compiler.variable_out = OBJECTS 378 sse2_compiler.name = compiling[sse2] ${QMAKE_FILE_IN} 379 silent:sse2_compiler.commands = @echo compiling[sse2] ${QMAKE_FILE_IN} && $$sse2_compiler.commands 380 QMAKE_EXTRA_COMPILERS += sse2_compiler 381 } 382 iwmmxt { 383 os2:iwmmxt_compiler.commands = $$QMAKE_RUN_CXX -Winline 384 else:iwmmxt_compiler.commands = $$QMAKE_CXX -c -Winline 385 iwmmxt_compiler.commands += -mcpu=iwmmxt 386 os2 { 387 iwmmxt_compiler.commands = $$replace(iwmmxt_compiler.commands, \\$src, ${QMAKE_FILE_IN}) 388 iwmmxt_compiler.commands = $$replace(iwmmxt_compiler.commands, \\$obj, ${QMAKE_FILE_OUT}) 389 } else { 390 iwmmxt_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} 391 } 392 iwmmxt_compiler.dependency_type = TYPE_C 393 iwmmxt_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} 394 iwmmxt_compiler.input = IWMMXT_SOURCES 395 iwmmxt_compiler.variable_out = OBJECTS 396 iwmmxt_compiler.name = compiling[iwmmxt] ${QMAKE_FILE_IN} 397 silent:iwmmxt_compiler.commands = @echo compiling[iwmmxt] ${QMAKE_FILE_IN} && $$iwmmxt_compiler.commands 398 QMAKE_EXTRA_COMPILERS += iwmmxt_compiler 399 } 400 } else { 401 mmx: SOURCES += $$MMX_SOURCES 402 3dnow: SOURCES += $$MMX3DNOW_SOURCES 403 3dnow:sse: SOURCES += $$SSE3DNOW_SOURCES 404 sse: SOURCES += $$SSE_SOURCES 405 sse2: SOURCES += $$SSE2_SOURCES 406 iwmmxt: SOURCES += $$IWMMXT_SOURCES 407 } 219 painting/qdrawhelper_sse_p.h \ 220 painting/qdrawingprimitive_sse2_p.h 221 MMX_SOURCES += painting/qdrawhelper_mmx.cpp 222 MMX3DNOW_SOURCES += painting/qdrawhelper_mmx3dnow.cpp 223 SSE3DNOW_SOURCES += painting/qdrawhelper_sse3dnow.cpp 224 SSE_SOURCES += painting/qdrawhelper_sse.cpp 225 SSE2_SOURCES += painting/qdrawhelper_sse2.cpp 226 SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp 227 IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp 408 228 } 409 229 … … 429 249 430 250 symbian { 431 HEADERS += painting/qwindowsurface_s60_p.h 251 HEADERS += painting/qwindowsurface_s60_p.h \ 252 painting/qdrawhelper_arm_simd_p.h 432 253 SOURCES += painting/qwindowsurface_s60.cpp 433 254 armccIfdefBlock = \ 434 255 "$${LITERAL_HASH}if defined(ARMV6)" \ 256 "MACRO QT_HAVE_ARM_SIMD" \ 435 257 "SOURCEPATH painting" \ 436 "SOURCE qblendfunctions_armv6_rvct.s" \ 437 "SOURCE qdrawhelper_armv6_rvct.s" \ 258 "SOURCE qdrawhelper_arm_simd.cpp" \ 438 259 "$${LITERAL_HASH}endif" 439 260 … … 442 263 } 443 264 444 neon { 445 DEFINES += QT_HAVE_NEON 446 HEADERS += painting/qdrawhelper_neon_p.h 447 SOURCES += painting/qdrawhelper_neon.cpp 448 QMAKE_CXXFLAGS *= -mfpu=neon 449 } 450 451 contains(QT_CONFIG, zlib) { 452 INCLUDEPATH += ../3rdparty/zlib 453 } else:!contains(QT_CONFIG, no-zlib) { 454 unix:LIBS_PRIVATE += -lz 455 # win32:LIBS += libz.lib 456 } 457 265 NEON_SOURCES += painting/qdrawhelper_neon.cpp 266 NEON_HEADERS += painting/qdrawhelper_neon_p.h 267 NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S 268 269 include($$PWD/../../3rdparty/zlib_dependency.pri) -
trunk/src/gui/painting/qbackingstore.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 264 264 const QPoint pos(tlwOffset + widget->mapTo(tlw, rect.topLeft())); 265 265 const QRect tlwRect(QRect(pos, rect.size())); 266 if ( dirty.intersects(tlwRect))266 if (fullUpdatePending || dirty.intersects(tlwRect)) 267 267 return false; // We don't want to scroll junk. 268 268 return windowSurface->scroll(tlwRect, dx, dy); … … 353 353 dirtyOnScreen += toClean; 354 354 355 #if def Q_WS_QWS355 #if defined(Q_WS_QWS) && !defined(Q_BACKINGSTORE_SUBSURFACES) 356 356 toClean.translate(tlwOffset); 357 357 #endif … … 403 403 const QRect tlwRect(topLevelRect()); 404 404 const QRect surfaceGeometry(windowSurface->geometry()); 405 if ( surfaceGeometry != tlwRect && surfaceGeometry.size() != tlwRect.size()) {405 if (fullUpdatePending || (surfaceGeometry != tlwRect && surfaceGeometry.size() != tlwRect.size())) { 406 406 if (widgetDirty) { 407 407 const QRect dirtyTlwRect = QRect(QPoint(), tlwRect.size()); … … 447 447 /*! 448 448 Returns the static content inside the \a parent if non-zero; otherwise the static content 449 for the entire backing store is returned. The content will be clipped to \a within gClipRect449 for the entire backing store is returned. The content will be clipped to \a withinClipRect 450 450 if non-empty. 451 451 */ … … 553 553 if (!eventAlreadyPosted || updateImmediately) 554 554 sendUpdateRequest(widget, updateImmediately); 555 return; 556 } 557 558 if (fullUpdatePending) { 559 if (updateImmediately) 560 sendUpdateRequest(tlw, updateImmediately); 561 return; 562 } 563 564 if (!windowSurface->hasPartialUpdateSupport()) { 565 fullUpdatePending = true; 566 sendUpdateRequest(tlw, updateImmediately); 555 567 return; 556 568 } … … 639 651 } 640 652 653 if (fullUpdatePending) { 654 if (updateImmediately) 655 sendUpdateRequest(tlw, updateImmediately); 656 return; 657 } 658 659 if (!windowSurface->hasPartialUpdateSupport()) { 660 fullUpdatePending = true; 661 sendUpdateRequest(tlw, updateImmediately); 662 return; 663 } 664 641 665 const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); 642 666 const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint()))); … … 834 858 QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel) 835 859 : tlw(topLevel), dirtyOnScreenWidgets(0), hasDirtyFromPreviousSync(false) 860 , fullUpdatePending(0) 836 861 { 837 862 windowSurface = tlw->windowSurface(); … … 885 910 QRect clipR(pd->clipRect()); 886 911 #ifdef Q_WS_QWS 887 QWidgetBackingStore *wbs = x->backingStore ;912 QWidgetBackingStore *wbs = x->backingStore.data(); 888 913 QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface); 889 914 clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect()); … … 915 940 } else { 916 941 917 QWidgetBackingStore *wbs = x->backingStore ;942 QWidgetBackingStore *wbs = x->backingStore.data(); 918 943 QRegion childExpose(newRect & clipR); 919 944 … … 958 983 return; 959 984 960 QWidgetBackingStore *wbs = x->backingStore ;985 QWidgetBackingStore *wbs = x->backingStore.data(); 961 986 if (!wbs) 962 987 return; … … 1123 1148 resetWidget(dirtyWidgets.at(i)); 1124 1149 dirtyWidgets.clear(); 1150 fullUpdatePending = false; 1125 1151 } 1126 1152 return; … … 1133 1159 bool repaintAllWidgets = false; 1134 1160 1135 if (inTopLevelResize || surfaceGeometry != tlwRect) { 1136 if ((inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) { 1137 if (hasStaticContents()) { 1138 // Repaint existing dirty area and newly visible area. 1139 const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height()); 1140 const QRegion staticRegion(staticContents(0, clipRect)); 1141 QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height()); 1142 newVisible -= staticRegion; 1143 dirty += newVisible; 1144 windowSurface->setStaticContents(staticRegion); 1145 } else { 1146 // Repaint everything. 1147 dirty = QRegion(0, 0, tlwRect.width(), tlwRect.height()); 1148 for (int i = 0; i < dirtyWidgets.size(); ++i) 1149 resetWidget(dirtyWidgets.at(i)); 1150 dirtyWidgets.clear(); 1151 repaintAllWidgets = true; 1152 } 1153 } 1161 if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) { 1162 if (hasStaticContents()) { 1163 // Repaint existing dirty area and newly visible area. 1164 const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height()); 1165 const QRegion staticRegion(staticContents(0, clipRect)); 1166 QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height()); 1167 newVisible -= staticRegion; 1168 dirty += newVisible; 1169 windowSurface->setStaticContents(staticRegion); 1170 } else { 1171 // Repaint everything. 1172 dirty = QRegion(0, 0, tlwRect.width(), tlwRect.height()); 1173 for (int i = 0; i < dirtyWidgets.size(); ++i) 1174 resetWidget(dirtyWidgets.at(i)); 1175 dirtyWidgets.clear(); 1176 repaintAllWidgets = true; 1177 } 1178 } 1179 1180 if (inTopLevelResize || surfaceGeometry != tlwRect) 1154 1181 windowSurface->setGeometry(tlwRect); 1155 }1156 1182 1157 1183 if (updatesDisabled) … … 1213 1239 dirtyWidgets.clear(); 1214 1240 1241 fullUpdatePending = false; 1242 1215 1243 if (toClean.isEmpty()) { 1216 1244 // Nothing to repaint. However, we might have newly exposed areas on the … … 1267 1295 QWindowSurface *subSurface = w->windowSurface(); 1268 1296 BeginPaintInfo beginPaintInfo; 1269 beginPaint(toBePainted, w, subSurface, &beginPaintInfo, false); 1297 1298 QPoint off = w->mapTo(tlw, QPoint()); 1299 toBePainted.translate(off); 1300 beginPaint(toBePainted, w, subSurface, &beginPaintInfo, true); 1301 toBePainted.translate(-off); 1302 1270 1303 if (beginPaintInfo.nothingToPaint) 1271 1304 continue; -
trunk/src/gui/painting/qbackingstore_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 92 92 { 93 93 return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !hasDirtyFromPreviousSync 94 && !fullUpdatePending 94 95 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) 95 96 && !hasDirtyWindowDecoration() … … 116 117 QList<QWindowSurface*> subSurfaces; 117 118 #endif 118 bool hasDirtyFromPreviousSync; 119 uint hasDirtyFromPreviousSync : 1; 120 uint fullUpdatePending : 1; 119 121 120 122 QPoint tlwOffset; -
trunk/src/gui/painting/qbezier.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 94 94 \internal 95 95 */ 96 QPolygonF QBezier::toPolygon( ) const96 QPolygonF QBezier::toPolygon(qreal bezier_flattening_threshold) const 97 97 { 98 98 // flattening is done by splitting the bezier until we can replace the segment by a straight … … 109 109 QPolygonF polygon; 110 110 polygon.append(QPointF(x1, y1)); 111 addToPolygon(&polygon );111 addToPolygon(&polygon, bezier_flattening_threshold); 112 112 return polygon; 113 113 } 114 114 115 //0.5 is really low 116 static const qreal flatness = 0.5; 117 118 //based on "Fast, precise flattening of cubic Bezier path and offset curves" 119 // by T. F. Hain, A. L. Ahmad, S. V. R. Racherla and D. D. Langan 120 static inline void flattenBezierWithoutInflections(QBezier &bez, 121 QPolygonF *&p) 122 { 123 QBezier left; 124 125 while (1) { 126 qreal dx = bez.x2 - bez.x1; 127 qreal dy = bez.y2 - bez.y1; 128 129 qreal normalized = qSqrt(dx * dx + dy * dy); 130 if (qFuzzyIsNull(normalized)) 131 break; 132 133 qreal d = qAbs(dx * (bez.y3 - bez.y2) - dy * (bez.x3 - bez.x2)); 134 135 qreal t = qSqrt(4. / 3. * normalized * flatness / d); 136 if (t > 1 || qFuzzyIsNull(t - (qreal)1.)) 137 break; 138 bez.parameterSplitLeft(t, &left); 139 p->append(bez.pt1()); 140 } 141 } 142 115 QBezier QBezier::mapBy(const QTransform &transform) const 116 { 117 return QBezier::fromPoints(transform.map(pt1()), transform.map(pt2()), transform.map(pt3()), transform.map(pt4())); 118 } 119 120 QBezier QBezier::getSubRange(qreal t0, qreal t1) const 121 { 122 QBezier result; 123 QBezier temp; 124 125 // cut at t1 126 if (qFuzzyIsNull(t1 - qreal(1.))) { 127 result = *this; 128 } else { 129 temp = *this; 130 temp.parameterSplitLeft(t1, &result); 131 } 132 133 // cut at t0 134 if (!qFuzzyIsNull(t0)) 135 result.parameterSplitLeft(t0 / t1, &temp); 136 137 return result; 138 } 143 139 144 140 static inline int quadraticRoots(qreal a, qreal b, qreal c, … … 200 196 201 197 202 void QBezier::addToPolygon(QPolygonF *polygon ) const198 void QBezier::addToPolygon(QPolygonF *polygon, qreal bezier_flattening_threshold) const 203 199 { 204 200 QBezier beziers[32]; … … 220 216 l = 1.; 221 217 } 222 if (d < flatness*l || b == beziers + 31) {218 if (d < bezier_flattening_threshold*l || b == beziers + 31) { 223 219 // good enough, we pop it off and add the endpoint 224 220 polygon->append(QPointF(b->x4, b->y4)); … … 228 224 b->split(b+1, b); 229 225 ++b; 230 }231 }232 }233 234 void QBezier::addToPolygonMixed(QPolygonF *polygon) const235 {236 qreal ax = -x1 + 3*x2 - 3*x3 + x4;237 qreal ay = -y1 + 3*y2 - 3*y3 + y4;238 qreal bx = 3*x1 - 6*x2 + 3*x3;239 qreal by = 3*y1 - 6*y2 + 3*y3;240 qreal cx = -3*x1 + 3*x2;241 qreal cy = -3*y1 + 2*y2;242 qreal a = 6 * (ay * bx - ax * by);243 qreal b = 6 * (ay * cx - ax * cy);244 qreal c = 2 * (by * cx - bx * cy);245 246 if ((qFuzzyIsNull(a) && qFuzzyIsNull(b)) ||247 (b * b - 4 * a *c) < 0) {248 QBezier bez(*this);249 flattenBezierWithoutInflections(bez, polygon);250 polygon->append(QPointF(x4, y4));251 } else {252 QBezier beziers[32];253 beziers[0] = *this;254 QBezier *b = beziers;255 256 while (b >= beziers) {257 // check if we can pop the top bezier curve from the stack258 qreal y4y1 = b->y4 - b->y1;259 qreal x4x1 = b->x4 - b->x1;260 qreal l = qAbs(x4x1) + qAbs(y4y1);261 qreal d;262 if (l > 1.) {263 d = qAbs( (x4x1)*(b->y1 - b->y2) - (y4y1)*(b->x1 - b->x2) )264 + qAbs( (x4x1)*(b->y1 - b->y3) - (y4y1)*(b->x1 - b->x3) );265 } else {266 d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +267 qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);268 l = 1.;269 }270 if (d < .5*l || b == beziers + 31) {271 // good enough, we pop it off and add the endpoint272 polygon->append(QPointF(b->x4, b->y4));273 --b;274 } else {275 // split, second half of the polygon goes lower into the stack276 b->split(b+1, b);277 ++b;278 }279 226 } 280 227 } … … 347 294 } 348 295 349 static inline QLineF qline_shifted(const QPointF &p1, const QPointF &p2, qreal offset)350 {351 QLineF l(p1, p2);352 QLineF ln = l.normalVector().unitVector();353 l.translate(ln.dx() * offset, ln.dy() * offset);354 return l;355 }356 357 static bool qbezier_is_line(QPointF *points, int pointCount)358 {359 Q_ASSERT(pointCount > 2);360 361 qreal dx13 = points[2].x() - points[0].x();362 qreal dy13 = points[2].y() - points[0].y();363 364 qreal dx12 = points[1].x() - points[0].x();365 qreal dy12 = points[1].y() - points[0].y();366 367 if (pointCount == 3) {368 return qFuzzyCompare(dx12 * dy13, dx13 * dy12);369 } else if (pointCount == 4) {370 qreal dx14 = points[3].x() - points[0].x();371 qreal dy14 = points[3].y() - points[0].y();372 373 return (qFuzzyCompare(dx12 * dy13, dx13 * dy12) && qFuzzyCompare(dx12 * dy14, dx14 * dy12));374 }375 376 return false;377 }378 379 296 static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold) 380 297 { … … 406 323 if (np == 1) 407 324 return Discard; 408 409 // We need to specialcase lines of 3 or 4 points due to numerical410 // instability in intersections below411 if (np > 2 && qbezier_is_line(points, np)) {412 if (points[0] == points[np-1])413 return Discard;414 415 QLineF l = qline_shifted(points[0], points[np-1], offset);416 *shifted = QBezier::fromPoints(l.p1(), l.pointAt(qreal(0.33)), l.pointAt(qreal(0.66)), l.p2());417 return Ok;418 }419 325 420 326 QRectF b = orig->bounds(); … … 589 495 } 590 496 591 #if 0592 static inline bool IntersectBB(const QBezier &a, const QBezier &b)593 {594 return a.bounds().intersects(b.bounds());595 }596 #else597 static int IntersectBB(const QBezier &a, const QBezier &b)598 {599 // Compute bounding box for a600 qreal minax, maxax, minay, maxay;601 if (a.x1 > a.x4) // These are the most likely to be extremal602 minax = a.x4, maxax = a.x1;603 else604 minax = a.x1, maxax = a.x4;605 606 if (a.x3 < minax)607 minax = a.x3;608 else if (a.x3 > maxax)609 maxax = a.x3;610 611 if (a.x2 < minax)612 minax = a.x2;613 else if (a.x2 > maxax)614 maxax = a.x2;615 616 if (a.y1 > a.y4)617 minay = a.y4, maxay = a.y1;618 else619 minay = a.y1, maxay = a.y4;620 621 if (a.y3 < minay)622 minay = a.y3;623 else if (a.y3 > maxay)624 maxay = a.y3;625 626 if (a.y2 < minay)627 minay = a.y2;628 else if (a.y2 > maxay)629 maxay = a.y2;630 631 // Compute bounding box for b632 qreal minbx, maxbx, minby, maxby;633 if (b.x1 > b.x4)634 minbx = b.x4, maxbx = b.x1;635 else636 minbx = b.x1, maxbx = b.x4;637 638 if (b.x3 < minbx)639 minbx = b.x3;640 else if (b.x3 > maxbx)641 maxbx = b.x3;642 643 if (b.x2 < minbx)644 minbx = b.x2;645 else if (b.x2 > maxbx)646 maxbx = b.x2;647 648 if (b.y1 > b.y4)649 minby = b.y4, maxby = b.y1;650 else651 minby = b.y1, maxby = b.y4;652 653 if (b.y3 < minby)654 minby = b.y3;655 else if (b.y3 > maxby)656 maxby = b.y3;657 658 if (b.y2 < minby)659 minby = b.y2;660 else if (b.y2 > maxby)661 maxby = b.y2;662 663 // Test bounding box of b against bounding box of a664 if ((minax > maxbx) || (minay > maxby) // Not >= : need boundary case665 || (minbx > maxax) || (minby > maxay))666 return 0; // they don't intersect667 else668 return 1; // they intersect669 }670 #endif671 672 673 497 #ifdef QDEBUG_BEZIER 674 498 static QDebug operator<<(QDebug dbg, const QBezier &bz) … … 682 506 #endif 683 507 684 static bool RecursivelyIntersect(const QBezier &a, qreal t0, qreal t1, int deptha,685 const QBezier &b, qreal u0, qreal u1, int depthb,686 QVector<QPair<qreal, qreal> > *t)687 {688 #ifdef QDEBUG_BEZIER689 static int I = 0;690 int currentD = I;691 fprintf(stderr, "%d) t0 = %lf, t1 = %lf, deptha = %d\n"692 "u0 = %lf, u1 = %lf, depthb = %d\n", I++, t0, t1, deptha,693 u0, u1, depthb);694 #endif695 if (deptha > 0) {696 QBezier A[2];697 a.split(&A[0], &A[1]);698 qreal tmid = (t0+t1)*0.5;699 //qDebug()<<"\t1)"<<A[0];700 //qDebug()<<"\t2)"<<A[1];701 deptha--;702 if (depthb > 0) {703 QBezier B[2];704 b.split(&B[0], &B[1]);705 //qDebug()<<"\t3)"<<B[0];706 //qDebug()<<"\t4)"<<B[1];707 qreal umid = (u0+u1)*0.5;708 depthb--;709 if (IntersectBB(A[0], B[0])) {710 //fprintf(stderr, "\t 1 from %d\n", currentD);711 if (RecursivelyIntersect(A[0], t0, tmid, deptha,712 B[0], u0, umid, depthb,713 t) && !t)714 return true;715 }716 if (IntersectBB(A[1], B[0])) {717 //fprintf(stderr, "\t 2 from %d\n", currentD);718 if (RecursivelyIntersect(A[1], tmid, t1, deptha,719 B[0], u0, umid, depthb,720 t) && !t)721 return true;722 }723 if (IntersectBB(A[0], B[1])) {724 //fprintf(stderr, "\t 3 from %d\n", currentD);725 if (RecursivelyIntersect(A[0], t0, tmid, deptha,726 B[1], umid, u1, depthb,727 t) && !t)728 return true;729 }730 if (IntersectBB(A[1], B[1])) {731 //fprintf(stderr, "\t 4 from %d\n", currentD);732 if (RecursivelyIntersect(A[1], tmid, t1, deptha,733 B[1], umid, u1, depthb,734 t) && !t)735 return true;736 }737 return t ? !t->isEmpty() : false;738 } else {739 if (IntersectBB(A[0], b)) {740 //fprintf(stderr, "\t 5 from %d\n", currentD);741 if (RecursivelyIntersect(A[0], t0, tmid, deptha,742 b, u0, u1, depthb,743 t) && !t)744 return true;745 }746 if (IntersectBB(A[1], b)) {747 //fprintf(stderr, "\t 6 from %d\n", currentD);748 if (RecursivelyIntersect(A[1], tmid, t1, deptha,749 b, u0, u1, depthb,750 t) && !t)751 return true;752 }753 return t ? !t->isEmpty() : false;754 }755 } else {756 if (depthb > 0) {757 QBezier B[2];758 b.split(&B[0], &B[1]);759 qreal umid = (u0 + u1)*0.5;760 depthb--;761 if (IntersectBB(a, B[0])) {762 //fprintf(stderr, "\t 7 from %d\n", currentD);763 if (RecursivelyIntersect(a, t0, t1, deptha,764 B[0], u0, umid, depthb,765 t) && !t)766 return true;767 }768 if (IntersectBB(a, B[1])) {769 //fprintf(stderr, "\t 8 from %d\n", currentD);770 if (RecursivelyIntersect(a, t0, t1, deptha,771 B[1], umid, u1, depthb,772 t) && !t)773 return true;774 }775 return t ? !t->isEmpty() : false;776 }777 else {778 // Both segments are fully subdivided; now do line segments779 qreal xlk = a.x4 - a.x1;780 qreal ylk = a.y4 - a.y1;781 qreal xnm = b.x4 - b.x1;782 qreal ynm = b.y4 - b.y1;783 qreal xmk = b.x1 - a.x1;784 qreal ymk = b.y1 - a.y1;785 qreal det = xnm * ylk - ynm * xlk;786 if (1.0 + det == 1.0) {787 return false;788 } else {789 qreal detinv = 1.0 / det;790 qreal rs = (xnm * ymk - ynm *xmk) * detinv;791 qreal rt = (xlk * ymk - ylk * xmk) * detinv;792 if ((rs < 0.0) || (rs > 1.0) || (rt < 0.0) || (rt > 1.0))793 return false;794 795 if (t) {796 const qreal alpha_a = t0 + rs * (t1 - t0);797 const qreal alpha_b = u0 + rt * (u1 - u0);798 799 *t << qMakePair(alpha_a, alpha_b);800 }801 802 return true;803 }804 }805 }806 }807 808 QVector< QPair<qreal, qreal> > QBezier::findIntersections(const QBezier &a, const QBezier &b)809 {810 QVector< QPair<qreal, qreal> > v(2);811 findIntersections(a, b, &v);812 return v;813 }814 815 bool QBezier::findIntersections(const QBezier &a, const QBezier &b,816 QVector<QPair<qreal, qreal> > *t)817 {818 if (IntersectBB(a, b)) {819 QPointF la1(qFabs((a.x3 - a.x2) - (a.x2 - a.x1)),820 qFabs((a.y3 - a.y2) - (a.y2 - a.y1)));821 QPointF la2(qFabs((a.x4 - a.x3) - (a.x3 - a.x2)),822 qFabs((a.y4 - a.y3) - (a.y3 - a.y2)));823 QPointF la;824 if (la1.x() > la2.x()) la.setX(la1.x()); else la.setX(la2.x());825 if (la1.y() > la2.y()) la.setY(la1.y()); else la.setY(la2.y());826 QPointF lb1(qFabs((b.x3 - b.x2) - (b.x2 - b.x1)),827 qFabs((b.y3 - b.y2) - (b.y2 - b.y1)));828 QPointF lb2(qFabs((b.x4 - b.x3) - (b.x3 - b.x2)),829 qFabs((b.y4 - b.y3) - (b.y3 - b.y2)));830 QPointF lb;831 if (lb1.x() > lb2.x()) lb.setX(lb1.x()); else lb.setX(lb2.x());832 if (lb1.y() > lb2.y()) lb.setY(lb1.y()); else lb.setY(lb2.y());833 qreal l0;834 if (la.x() > la.y())835 l0 = la.x();836 else837 l0 = la.y();838 int ra;839 if (l0 * 0.75 * M_SQRT2 + 1.0 == 1.0)840 ra = 0;841 else842 ra = qCeil(log4(M_SQRT2 * 6.0 / 8.0 * INV_EPS * l0));843 if (lb.x() > lb.y())844 l0 = lb.x();845 else846 l0 = lb.y();847 int rb;848 if (l0 * 0.75 * M_SQRT2 + 1.0 == 1.0)849 rb = 0;850 else851 rb = qCeil(log4(M_SQRT2 * 6.0 / 8.0 * INV_EPS * l0));852 853 // if qreal is float then halve the number of subdivisions854 if (sizeof(qreal) == 4) {855 ra /= 2;856 rb /= 2;857 }858 859 return RecursivelyIntersect(a, 0., 1., ra, b, 0., 1., rb, t);860 }861 862 //Don't sort here because it breaks the orders of corresponding863 // intersections points. this way t's at the same locations correspond864 // to the same intersection point.865 //qSort(parameters[0].begin(), parameters[0].end(), qLess<qreal>());866 //qSort(parameters[1].begin(), parameters[1].end(), qLess<qreal>());867 868 return false;869 }870 871 508 static inline void splitBezierAt(const QBezier &bez, qreal t, 872 509 QBezier *left, QBezier *right) … … 895 532 right->x4 = bez.x4; 896 533 right->y4 = bez.y4; 897 }898 899 QVector< QList<QBezier> > QBezier::splitAtIntersections(QBezier &b)900 {901 QVector< QList<QBezier> > curves(2);902 903 QVector< QPair<qreal, qreal> > allInters = findIntersections(*this, b);904 905 QList<qreal> inters1;906 QList<qreal> inters2;907 908 for (int i = 0; i < allInters.size(); ++i) {909 inters1 << allInters[i].first;910 inters2 << allInters[i].second;911 }912 913 qSort(inters1.begin(), inters1.end(), qLess<qreal>());914 qSort(inters2.begin(), inters2.end(), qLess<qreal>());915 916 Q_ASSERT(inters1.count() == inters2.count());917 918 int i;919 for (i = 0; i < inters1.count(); ++i) {920 qreal t1 = inters1.at(i);921 qreal t2 = inters2.at(i);922 923 QBezier curve1, curve2;924 parameterSplitLeft(t1, &curve1);925 b.parameterSplitLeft(t2, &curve2);926 curves[0].append(curve1);927 curves[0].append(curve2);928 }929 curves[0].append(*this);930 curves[1].append(b);931 932 return curves;933 534 } 934 535 … … 1019 620 const qreal c = -y1 + y2; 1020 621 622 if (qFuzzyIsNull(a)) { 623 if (qFuzzyIsNull(b)) 624 return 0; 625 626 t0 = -c / b; 627 return t0 > 0 && t0 < 1; 628 } 629 1021 630 qreal reciprocal = b * b - 4 * a * c; 1022 1023 QList<qreal> result;1024 631 1025 632 if (qFuzzyIsNull(reciprocal)) { 1026 633 t0 = -b / (2 * a); 1027 return 1;634 return t0 > 0 && t0 < 1; 1028 635 } else if (reciprocal > 0) { 1029 636 qreal temp = qSqrt(reciprocal); … … 1100 707 } 1101 708 1102 1103 static inline void bindInflectionPoint(const QBezier &bez, const qreal t,1104 qreal *tMinus , qreal *tPlus)1105 {1106 if (t <= 0) {1107 *tMinus = *tPlus = -1;1108 return;1109 } else if (t >= 1) {1110 *tMinus = *tPlus = 2;1111 return;1112 }1113 1114 QBezier left, right;1115 splitBezierAt(bez, t, &left, &right);1116 1117 qreal ax = -right.x1 + 3*right.x2 - 3*right.x3 + right.x4;1118 qreal ay = -right.y1 + 3*right.y2 - 3*right.y3 + right.y4;1119 qreal ex = 3 * (right.x2 - right.x3);1120 qreal ey = 3 * (right.y2 - right.y3);1121 1122 qreal s4 = qAbs(6 * (ey * ax - ex * ay) / qSqrt(ex * ex + ey * ey)) + 0.00001f;1123 qreal tf = qPow(qreal(9 * flatness / s4), qreal(1./3.));1124 *tMinus = t - (1 - t) * tf;1125 *tPlus = t + (1 - t) * tf;1126 }1127 1128 void QBezier::addToPolygonIterative(QPolygonF *p) const1129 {1130 qreal t1, t2, tcusp;1131 qreal t1min, t1plus, t2min, t2plus;1132 1133 qreal ax = -x1 + 3*x2 - 3*x3 + x4;1134 qreal ay = -y1 + 3*y2 - 3*y3 + y4;1135 qreal bx = 3*x1 - 6*x2 + 3*x3;1136 qreal by = 3*y1 - 6*y2 + 3*y3;1137 qreal cx = -3*x1 + 3*x2;1138 qreal cy = -3*y1 + 2*y2;1139 1140 if (findInflections(6 * (ay * bx - ax * by),1141 6 * (ay * cx - ax * cy),1142 2 * (by * cx - bx * cy),1143 &t1, &t2, &tcusp)) {1144 bindInflectionPoint(*this, t1, &t1min, &t1plus);1145 bindInflectionPoint(*this, t2, &t2min, &t2plus);1146 1147 QBezier tmpBez = *this;1148 QBezier left, right, bez1, bez2, bez3;1149 if (t1min > 0) {1150 if (t1min >= 1) {1151 flattenBezierWithoutInflections(tmpBez, p);1152 } else {1153 splitBezierAt(tmpBez, t1min, &left, &right);1154 flattenBezierWithoutInflections(left, p);1155 p->append(tmpBez.pointAt(t1min));1156 1157 if (t2min < t1plus) {1158 if (tcusp < 1) {1159 p->append(tmpBez.pointAt(tcusp));1160 }1161 if (t2plus < 1) {1162 splitBezierAt(tmpBez, t2plus, &left, &right);1163 flattenBezierWithoutInflections(right, p);1164 }1165 } else if (t1plus < 1) {1166 if (t2min < 1) {1167 splitBezierAt(tmpBez, t2min, &bez3, &right);1168 splitBezierAt(bez3, t1plus, &left, &bez2);1169 1170 flattenBezierWithoutInflections(bez2, p);1171 p->append(tmpBez.pointAt(t2min));1172 1173 if (t2plus < 1) {1174 splitBezierAt(tmpBez, t2plus, &left, &bez2);1175 flattenBezierWithoutInflections(bez2, p);1176 }1177 } else {1178 splitBezierAt(tmpBez, t1plus, &left, &bez2);1179 flattenBezierWithoutInflections(bez2, p);1180 }1181 }1182 }1183 } else if (t1plus > 0) {1184 p->append(QPointF(x1, y1));1185 if (t2min < t1plus) {1186 if (tcusp < 1) {1187 p->append(tmpBez.pointAt(tcusp));1188 }1189 if (t2plus < 1) {1190 splitBezierAt(tmpBez, t2plus, &left, &bez2);1191 flattenBezierWithoutInflections(bez2, p);1192 }1193 } else if (t1plus < 1) {1194 if (t2min < 1) {1195 splitBezierAt(tmpBez, t2min, &bez3, &right);1196 splitBezierAt(bez3, t1plus, &left, &bez2);1197 1198 flattenBezierWithoutInflections(bez2, p);1199 1200 p->append(tmpBez.pointAt(t2min));1201 if (t2plus < 1) {1202 splitBezierAt(tmpBez, t2plus, &left, &bez2);1203 flattenBezierWithoutInflections(bez2, p);1204 }1205 } else {1206 splitBezierAt(tmpBez, t1plus, &left, &bez2);1207 flattenBezierWithoutInflections(bez2, p);1208 }1209 }1210 } else if (t2min > 0) {1211 if (t2min < 1) {1212 splitBezierAt(tmpBez, t2min, &bez1, &right);1213 flattenBezierWithoutInflections(bez1, p);1214 p->append(tmpBez.pointAt(t2min));1215 1216 if (t2plus < 1) {1217 splitBezierAt(tmpBez, t2plus, &left, &bez2);1218 flattenBezierWithoutInflections(bez2, p);1219 }1220 } else {1221 //### in here we should check whether the area of the1222 // triangle formed between pt1/pt2/pt3 is smaller1223 // or equal to 0 and then do iterative flattening1224 // if not we should fallback and do the recursive1225 // flattening.1226 flattenBezierWithoutInflections(tmpBez, p);1227 }1228 } else if (t2plus > 0) {1229 p->append(QPointF(x1, y1));1230 if (t2plus < 1) {1231 splitBezierAt(tmpBez, t2plus, &left, &bez2);1232 flattenBezierWithoutInflections(bez2, p);1233 }1234 } else {1235 flattenBezierWithoutInflections(tmpBez, p);1236 }1237 } else {1238 QBezier bez = *this;1239 flattenBezierWithoutInflections(bez, p);1240 }1241 1242 p->append(QPointF(x4, y4));1243 }1244 1245 709 QT_END_NAMESPACE -
trunk/src/gui/painting/qbezier_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 60 60 #include "QtCore/qlist.h" 61 61 #include "QtCore/qpair.h" 62 #include "QtGui/qtransform.h" 62 63 63 64 QT_BEGIN_NAMESPACE … … 79 80 inline QPointF secondDerivedAt(qreal t) const; 80 81 81 QPolygonF toPolygon() const; 82 void addToPolygon(QPolygonF *p) const; 83 void addToPolygonIterative(QPolygonF *p) const; 84 void addToPolygonMixed(QPolygonF *p) const; 82 QPolygonF toPolygon(qreal bezier_flattening_threshold = 0.5) const; 83 void addToPolygon(QPolygonF *p, qreal bezier_flattening_threshold = 0.5) const; 84 85 85 QRectF bounds() const; 86 86 qreal length(qreal error = 0.01) const; … … 97 97 QPointF pt4() const { return QPointF(x4, y4); } 98 98 99 QBezier mapBy(const QTransform &transform) const; 100 99 101 inline QPointF midPoint() const; 100 102 inline QLineF midTangent() const; … … 105 107 inline void parameterSplitLeft(qreal t, QBezier *left); 106 108 inline void split(QBezier *firstHalf, QBezier *secondHalf) const; 109 107 110 int shifted(QBezier *curveSegments, int maxSegmets, 108 111 qreal offset, float threshold) const; 109 112 110 QVector< QList<QBezier> > splitAtIntersections(QBezier &a);111 112 113 QBezier bezierOnInterval(qreal t0, qreal t1) const; 113 114 static QVector< QPair<qreal, qreal> > findIntersections(const QBezier &a, 115 const QBezier &b); 116 117 static bool findIntersections(const QBezier &a, const QBezier &b, 118 QVector<QPair<qreal, qreal> > *t); 114 QBezier getSubRange(qreal t0, qreal t1) const; 119 115 120 116 qreal x1, y1, x2, y2, x3, y3, x4, y4; -
trunk/src/gui/painting/qblendfunctions.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 41 41 42 42 #include <qmath.h> 43 #include "q drawhelper_p.h"43 #include "qblendfunctions_p.h" 44 44 45 45 QT_BEGIN_NAMESPACE … … 89 89 struct Blend_RGB16_on_RGB16_NoAlpha { 90 90 inline void write(quint16 *dst, quint16 src) { *dst = src; } 91 92 inline void flush(void *) {} 91 93 }; 92 94 … … 100 102 *dst = BYTE_MUL_RGB16(src, m_alpha) + BYTE_MUL_RGB16(*dst, m_ialpha); 101 103 } 104 105 inline void flush(void *) {} 102 106 103 107 quint32 m_alpha; … … 115 119 } 116 120 } 121 122 inline void flush(void *) {} 117 123 }; 118 124 … … 133 139 } 134 140 141 inline void flush(void *) {} 142 135 143 quint32 m_alpha; 136 144 }; … … 146 154 } 147 155 } 156 157 inline void flush(void *) {} 148 158 }; 149 159 … … 164 174 } 165 175 176 inline void flush(void *) {} 177 166 178 quint32 m_alpha; 167 179 }; 168 169 template <typename SRC, typename T>170 void qt_scale_image_16bit(uchar *destPixels, int dbpl,171 const uchar *srcPixels, int sbpl,172 const QRectF &targetRect,173 const QRectF &srcRect,174 const QRect &clip,175 T blender)176 {177 qreal sx = targetRect.width() / (qreal) srcRect.width();178 qreal sy = targetRect.height() / (qreal) srcRect.height();179 180 int ix = 0x00010000 / sx;181 int iy = 0x00010000 / sy;182 183 // qDebug() << "scale:" << endl184 // << " - target" << targetRect << endl185 // << " - source" << srcRect << endl186 // << " - clip" << clip << endl187 // << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy;188 189 int cx1 = clip.x();190 int cx2 = clip.x() + clip.width();191 int cy1 = clip.top();192 int cy2 = clip.y() + clip.height();193 194 int tx1 = qRound(targetRect.left());195 int tx2 = qRound(targetRect.right());196 int ty1 = qRound(targetRect.top());197 int ty2 = qRound(targetRect.bottom());198 199 if (tx2 < tx1)200 qSwap(tx2, tx1);201 202 if (ty2 < ty1)203 qSwap(ty2, ty1);204 205 if (tx1 < cx1)206 tx1 = cx1;207 208 if (tx2 >= cx2)209 tx2 = cx2;210 211 if (tx1 >= tx2)212 return;213 214 if (ty1 < cy1)215 ty1 = cy1;216 217 if (ty2 >= cy2)218 ty2 = cy2;219 220 if (ty1 >= ty2)221 return;222 223 int h = ty2 - ty1;224 int w = tx2 - tx1;225 226 227 quint32 basex;228 quint32 srcy;229 230 if (sx < 0) {231 int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;232 basex = quint32(srcRect.right() * 65536) + dstx;233 } else {234 int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;235 basex = quint32(srcRect.left() * 65536) + dstx;236 }237 if (sy < 0) {238 int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;239 srcy = quint32(srcRect.bottom() * 65536) + dsty;240 } else {241 int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;242 srcy = quint32(srcRect.top() * 65536) + dsty;243 }244 245 quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;246 247 while (h--) {248 const SRC *src = (const SRC *) (srcPixels + (srcy >> 16) * sbpl);249 int srcx = basex;250 for (int x=0; x<w; ++x) {251 blender.write(&dst[x], src[srcx >> 16]);252 srcx += ix;253 }254 dst = (quint16 *)(((uchar *) dst) + dbpl);255 srcy += iy;256 }257 }258 180 259 181 void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, … … 333 255 } 334 256 335 staticvoid qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,336 337 338 257 void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl, 258 const uchar *src, int sbpl, 259 int w, int h, 260 int const_alpha) 339 261 { 340 262 #ifdef QT_DEBUG_DRAW … … 448 370 449 371 450 staticvoid qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl,451 452 453 372 void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, 373 const uchar *srcPixels, int sbpl, 374 int w, int h, 375 int const_alpha) 454 376 { 455 377 quint16 *dst = (quint16 *) destPixels; … … 644 566 struct Blend_RGB32_on_RGB32_NoAlpha { 645 567 inline void write(quint32 *dst, quint32 src) { *dst = src; } 568 569 inline void flush(void *) {} 646 570 }; 647 571 … … 656 580 } 657 581 582 inline void flush(void *) {} 583 658 584 quint32 m_alpha; 659 585 quint32 m_ialpha; … … 664 590 *dst = src + BYTE_MUL(*dst, qAlpha(~src)); 665 591 } 592 593 inline void flush(void *) {} 666 594 }; 667 595 … … 677 605 } 678 606 607 inline void flush(void *) {} 608 679 609 quint32 m_alpha; 680 610 quint32 m_ialpha; 681 611 }; 682 683 template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,684 const uchar *srcPixels, int sbpl,685 const QRectF &targetRect,686 const QRectF &srcRect,687 const QRect &clip,688 T blender)689 {690 qreal sx = targetRect.width() / (qreal) srcRect.width();691 qreal sy = targetRect.height() / (qreal) srcRect.height();692 693 int ix = 0x00010000 / sx;694 int iy = 0x00010000 / sy;695 696 // qDebug() << "scale:" << endl697 // << " - target" << targetRect << endl698 // << " - source" << srcRect << endl699 // << " - clip" << clip << endl700 // << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy;701 702 int cx1 = clip.x();703 int cx2 = clip.x() + clip.width();704 int cy1 = clip.top();705 int cy2 = clip.y() + clip.height();706 707 int tx1 = qRound(targetRect.left());708 int tx2 = qRound(targetRect.right());709 int ty1 = qRound(targetRect.top());710 int ty2 = qRound(targetRect.bottom());711 712 if (tx2 < tx1)713 qSwap(tx2, tx1);714 715 if (ty2 < ty1)716 qSwap(ty2, ty1);717 718 if (tx1 < cx1)719 tx1 = cx1;720 721 if (tx2 >= cx2)722 tx2 = cx2;723 724 if (tx1 >= tx2)725 return;726 727 if (ty1 < cy1)728 ty1 = cy1;729 730 if (ty2 >= cy2)731 ty2 = cy2;732 733 if (ty1 >= ty2)734 return;735 736 int h = ty2 - ty1;737 int w = tx2 - tx1;738 739 quint32 basex;740 quint32 srcy;741 742 if (sx < 0) {743 int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;744 basex = quint32(srcRect.right() * 65536) + dstx;745 } else {746 int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;747 basex = quint32(srcRect.left() * 65536) + dstx;748 }749 if (sy < 0) {750 int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;751 srcy = quint32(srcRect.bottom() * 65536) + dsty;752 } else {753 int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;754 srcy = quint32(srcRect.top() * 65536) + dsty;755 }756 757 quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;758 759 while (h--) {760 const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl);761 int srcx = basex;762 for (int x=0; x<w; ++x) {763 blender.write(&dst[x], src[srcx >> 16]);764 srcx += ix;765 }766 dst = (quint32 *)(((uchar *) dst) + dbpl);767 srcy += iy;768 }769 }770 612 771 613 void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl, … … 819 661 } 820 662 821 struct QTransformImageVertex822 {823 qreal x, y, u, v; // destination coordinates (x, y) and source coordinates (u, v)824 };825 826 template <class SrcT, class DestT, class Blender>827 void qt_transform_image_rasterize(DestT *destPixels, int dbpl,828 const SrcT *srcPixels, int sbpl,829 const QTransformImageVertex &topLeft, const QTransformImageVertex &bottomLeft,830 const QTransformImageVertex &topRight, const QTransformImageVertex &bottomRight,831 const QRect &sourceRect,832 const QRect &clip,833 qreal topY, qreal bottomY,834 int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,835 Blender blender)836 {837 int fromY = qMax(qRound(topY), clip.top());838 int toY = qMin(qRound(bottomY), clip.top() + clip.height());839 if (fromY >= toY)840 return;841 842 qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);843 qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);844 int dx_l = int(leftSlope * 0x10000);845 int dx_r = int(rightSlope * 0x10000);846 int x_l = int((topLeft.x + (0.5 + fromY - topLeft.y) * leftSlope + 0.5) * 0x10000);847 int x_r = int((topRight.x + (0.5 + fromY - topRight.y) * rightSlope + 0.5) * 0x10000);848 849 int fromX, toX, x1, x2, u, v, i, ii;850 DestT *line;851 for (int y = fromY; y < toY; ++y) {852 line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);853 854 fromX = qMax(x_l >> 16, clip.left());855 toX = qMin(x_r >> 16, clip.left() + clip.width());856 if (fromX < toX) {857 // Because of rounding, we can get source coordinates outside the source image.858 // Clamp these coordinates to the source rect to avoid segmentation fault and859 // garbage on the screen.860 861 // Find the first pixel on the current scan line where the source coordinates are within the source rect.862 x1 = fromX;863 u = x1 * dudx + y * dudy + u0;864 v = x1 * dvdx + y * dvdy + v0;865 for (; x1 < toX; ++x1) {866 int uu = u >> 16;867 int vv = v >> 16;868 if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()869 && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {870 break;871 }872 u += dudx;873 v += dvdx;874 }875 876 // Find the last pixel on the current scan line where the source coordinates are within the source rect.877 x2 = toX;878 u = (x2 - 1) * dudx + y * dudy + u0;879 v = (x2 - 1) * dvdx + y * dvdy + v0;880 for (; x2 > x1; --x2) {881 int uu = u >> 16;882 int vv = v >> 16;883 if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()884 && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {885 break;886 }887 u -= dudx;888 v -= dvdx;889 }890 891 // Set up values at the beginning of the scan line.892 u = fromX * dudx + y * dudy + u0;893 v = fromX * dvdx + y * dvdy + v0;894 line += fromX;895 896 // Beginning of the scan line, with per-pixel checks.897 i = x1 - fromX;898 while (i) {899 int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);900 int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);901 blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);902 u += dudx;903 v += dvdx;904 ++line;905 --i;906 }907 908 // Middle of the scan line, without checks.909 // Manual loop unrolling.910 i = x2 - x1;911 ii = i >> 3;912 while (ii) {913 blender.write(&line[0], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;914 blender.write(&line[1], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;915 blender.write(&line[2], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;916 blender.write(&line[3], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;917 blender.write(&line[4], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;918 blender.write(&line[5], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;919 blender.write(&line[6], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;920 blender.write(&line[7], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;921 line += 8;922 --ii;923 }924 switch (i & 7) {925 case 7: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;926 case 6: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;927 case 5: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;928 case 4: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;929 case 3: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;930 case 2: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;931 case 1: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;932 }933 934 // End of the scan line, with per-pixel checks.935 i = toX - x2;936 while (i) {937 int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);938 int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);939 blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);940 u += dudx;941 v += dvdx;942 ++line;943 --i;944 }945 }946 x_l += dx_l;947 x_r += dx_r;948 }949 }950 951 template <class SrcT, class DestT, class Blender>952 void qt_transform_image(DestT *destPixels, int dbpl,953 const SrcT *srcPixels, int sbpl,954 const QRectF &targetRect,955 const QRectF &sourceRect,956 const QRect &clip,957 const QTransform &targetRectTransform,958 Blender blender)959 {960 enum Corner961 {962 TopLeft,963 TopRight,964 BottomRight,965 BottomLeft966 };967 968 // map source rectangle to destination.969 QTransformImageVertex v[4];970 v[TopLeft].u = v[BottomLeft].u = sourceRect.left();971 v[TopLeft].v = v[TopRight].v = sourceRect.top();972 v[TopRight].u = v[BottomRight].u = sourceRect.right();973 v[BottomLeft].v = v[BottomRight].v = sourceRect.bottom();974 targetRectTransform.map(targetRect.left(), targetRect.top(), &v[TopLeft].x, &v[TopLeft].y);975 targetRectTransform.map(targetRect.right(), targetRect.top(), &v[TopRight].x, &v[TopRight].y);976 targetRectTransform.map(targetRect.left(), targetRect.bottom(), &v[BottomLeft].x, &v[BottomLeft].y);977 targetRectTransform.map(targetRect.right(), targetRect.bottom(), &v[BottomRight].x, &v[BottomRight].y);978 979 // find topmost vertex.980 int topmost = 0;981 for (int i = 1; i < 4; ++i) {982 if (v[i].y < v[topmost].y)983 topmost = i;984 }985 // rearrange array such that topmost vertex is at index 0.986 switch (topmost) {987 case 1:988 {989 QTransformImageVertex t = v[0];990 for (int i = 0; i < 3; ++i)991 v[i] = v[i+1];992 v[3] = t;993 }994 break;995 case 2:996 qSwap(v[0], v[2]);997 qSwap(v[1], v[3]);998 break;999 case 3:1000 {1001 QTransformImageVertex t = v[3];1002 for (int i = 3; i > 0; --i)1003 v[i] = v[i-1];1004 v[0] = t;1005 }1006 break;1007 }1008 1009 // if necessary, swap vertex 1 and 3 such that 1 is to the left of 3.1010 qreal dx1 = v[1].x - v[0].x;1011 qreal dy1 = v[1].y - v[0].y;1012 qreal dx2 = v[3].x - v[0].x;1013 qreal dy2 = v[3].y - v[0].y;1014 if (dx1 * dy2 - dx2 * dy1 > 0)1015 qSwap(v[1], v[3]);1016 1017 QTransformImageVertex u = {v[1].x - v[0].x, v[1].y - v[0].y, v[1].u - v[0].u, v[1].v - v[0].v};1018 QTransformImageVertex w = {v[2].x - v[0].x, v[2].y - v[0].y, v[2].u - v[0].u, v[2].v - v[0].v};1019 1020 qreal det = u.x * w.y - u.y * w.x;1021 if (det == 0)1022 return;1023 1024 qreal invDet = 1.0 / det;1025 qreal m11, m12, m21, m22, mdx, mdy;1026 1027 m11 = (u.u * w.y - u.y * w.u) * invDet;1028 m12 = (u.x * w.u - u.u * w.x) * invDet;1029 m21 = (u.v * w.y - u.y * w.v) * invDet;1030 m22 = (u.x * w.v - u.v * w.x) * invDet;1031 mdx = v[0].u - m11 * v[0].x - m12 * v[0].y;1032 mdy = v[0].v - m21 * v[0].x - m22 * v[0].y;1033 1034 int dudx = int(m11 * 0x10000);1035 int dvdx = int(m21 * 0x10000);1036 int dudy = int(m12 * 0x10000);1037 int dvdy = int(m22 * 0x10000);1038 int u0 = qCeil((0.5 * m11 + 0.5 * m12 + mdx) * 0x10000) - 1;1039 int v0 = qCeil((0.5 * m21 + 0.5 * m22 + mdy) * 0x10000) - 1;1040 1041 int x1 = qFloor(sourceRect.left());1042 int y1 = qFloor(sourceRect.top());1043 int x2 = qCeil(sourceRect.right());1044 int y2 = qCeil(sourceRect.bottom());1045 QRect sourceRectI(x1, y1, x2 - x1, y2 - y1);1046 1047 // rasterize trapezoids.1048 if (v[1].y < v[3].y) {1049 qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);1050 qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[0], v[3], sourceRectI, clip, v[1].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);1051 qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[3].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);1052 } else {1053 qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);1054 qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[3], v[2], sourceRectI, clip, v[3].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);1055 qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[1].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);1056 }1057 }1058 1059 663 void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, 1060 664 const uchar *srcPixels, int sbpl, -
trunk/src/gui/painting/qbrush.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 49 49 #include "qdebug.h" 50 50 #include <QtCore/qcoreapplication.h> 51 #include "private/qstylehelper_p.h" 51 52 52 53 QT_BEGIN_NAMESPACE … … 97 98 QPixmap qt_pixmapForBrush(int brushStyle, bool invert) 98 99 { 100 99 101 QPixmap pm; 100 QString key = QLatin1String("$qt-brush$") + QString::number(brushStyle) 101 + QString::number((int)invert); 102 QString key = QLatin1Literal("$qt-brush$") 103 % HexString<uint>(brushStyle) 104 % QLatin1Char(invert ? '1' : '0'); 102 105 if (!QPixmapCache::find(key, pm)) { 103 106 pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert), … … 330 333 \endtable 331 334 332 For more information about painting in general, see \l{ThePaint333 System} documentation.335 For more information about painting in general, see the \l{Paint 336 System}. 334 337 335 338 \sa Qt::BrushStyle, QPainter, QColor … … 912 915 913 916 Two brushes are different if they have different styles, colors or 914 pixmaps.917 transforms or different pixmaps or gradients depending on the style. 915 918 916 919 \sa operator==() … … 924 927 925 928 Two brushes are equal if they have equal styles, colors and 926 pixmaps.929 transforms and equal pixmaps or gradients depending on the style. 927 930 928 931 \sa operator!=() … … 933 936 if (b.d == d) 934 937 return true; 935 if (b.d->style == d->style && b.d->color == d->color) { 936 switch (d->style) { 937 case Qt::TexturePattern: { 938 QPixmap &us = (static_cast<QTexturedBrushData *>(d.data()))->pixmap(); 939 QPixmap &them = (static_cast<QTexturedBrushData *>(b.d.data()))->pixmap(); 938 if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform) 939 return false; 940 switch (d->style) { 941 case Qt::TexturePattern: 942 { 943 const QPixmap &us = (static_cast<QTexturedBrushData *>(d.data()))->pixmap(); 944 const QPixmap &them = (static_cast<QTexturedBrushData *>(b.d.data()))->pixmap(); 940 945 return ((us.isNull() && them.isNull()) || us.cacheKey() == them.cacheKey()); 941 946 } 942 case Qt::LinearGradientPattern: 943 case Qt::RadialGradientPattern: 944 case Qt::ConicalGradientPattern: 945 { 946 QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.data()); 947 QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.data()); 948 return d1->gradient == d2->gradient; 949 } 950 default: 951 return true; 947 case Qt::LinearGradientPattern: 948 case Qt::RadialGradientPattern: 949 case Qt::ConicalGradientPattern: 950 { 951 const QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.data()); 952 const QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.data()); 953 return d1->gradient == d2->gradient; 952 954 } 953 } 954 return false; 955 default: 956 return true; 957 } 955 958 } 956 959 … … 1014 1017 reference to the \a stream. 1015 1018 1016 \sa { Format of the QDataStream Operators}1019 \sa {Serializing Qt Data Types} 1017 1020 */ 1018 1021 … … 1082 1085 reference to the \a stream. 1083 1086 1084 \sa { Format of the QDataStream Operators}1087 \sa {Serializing Qt Data Types} 1085 1088 */ 1086 1089 … … 1216 1219 \endtable 1217 1220 1218 The colors in a gradient is defined using stop points of the 1219 QGradientStop type, i.e. a position and a color. Use the 1220 setColorAt() function to define a single stop 1221 point. Alternatively, use the setStops() function to define 1222 several stop points in one go. Note that the latter function \e 1223 replaces the current set of stop points. 1221 The colors in a gradient are defined using stop points of the 1222 QGradientStop type; i.e., a position and a color. Use the setColorAt() 1223 function to define a single stop point. Alternatively, use the 1224 setStops() function to define several stop points in one go. Note that 1225 the latter function \e replaces the current set of stop points. 1224 1226 1225 1227 It is the gradient's complete set of stop points (accessible 1226 1228 through the stops() function) that describes how the gradient area 1227 should be filled. If no stop points have been specified, a 1228 gradientof black at 0 to white at 1 is used.1229 should be filled. If no stop points have been specified, a gradient 1230 of black at 0 to white at 1 is used. 1229 1231 1230 1232 A diagonal linear gradient from black at (100, 100) to white at -
trunk/src/gui/painting/qbrush.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolor.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 134 134 maps the color to the hardware. 135 135 136 For more information about painting in general, see \l{ThePaint136 For more information about painting in general, see the \l{Paint 137 137 System} documentation. 138 138 … … 533 533 void QColor::setNamedColor(const QString &name) 534 534 { 535 if (!setColorFromString(name)) 536 qWarning("QColor::setNamedColor: Unknown color name '%s'", name.toLatin1().constData()); 537 } 538 539 /*! 540 \since 4.7 541 542 Returns true if the \a name is a valid color name and can 543 be used to construct a valid QColor object, otherwise returns 544 false. 545 546 It uses the same algorithm used in setNamedColor(). 547 548 \sa setNamedColor() 549 */ 550 bool QColor::isValidColor(const QString &name) 551 { 552 return !name.isEmpty() && QColor().setColorFromString(name); 553 } 554 555 bool QColor::setColorFromString(const QString &name) 556 { 535 557 if (name.isEmpty()) { 536 558 invalidate(); 537 return ;559 return true; 538 560 } 539 561 … … 542 564 if (qt_get_hex_rgb(name.constData(), name.length(), &rgb)) { 543 565 setRgb(rgb); 566 return true; 544 567 } else { 545 568 invalidate(); 569 return false; 546 570 } 547 return;548 571 } 549 572 … … 552 575 if (qt_get_named_rgb(name.constData(), name.length(), &rgb)) { 553 576 setRgba(rgb); 577 return true; 554 578 } else 555 579 #endif … … 562 586 && XParseColor(QX11Info::display(), QX11Info::appColormap(), name.toLatin1().constData(), &result)) { 563 587 setRgb(result.red >> 8, result.green >> 8, result.blue >> 8); 588 return true; 564 589 } else 565 590 #endif 566 591 { 567 qWarning("QColor::setNamedColor: Unknown color name '%s'", name.toLatin1().constData());568 592 invalidate(); 593 return false; 569 594 } 570 595 } … … 2499 2524 Writes the \a color to the \a stream. 2500 2525 2501 \sa { Format of the QDataStream Operators}2526 \sa {Serializing Qt Data Types} 2502 2527 */ 2503 2528 QDataStream &operator<<(QDataStream &stream, const QColor &color) … … 2535 2560 Reads the \a color from the \a stream. 2536 2561 2537 \sa { Format of the QDataStream Operators}2562 \sa {Serializing Qt Data Types} 2538 2563 */ 2539 2564 QDataStream &operator>>(QDataStream &stream, QColor &color) … … 2693 2718 */ 2694 2719 2695 /*! \fn void QColormap::initialize()2696 \internal2697 */2698 2699 /*! \fn void QColormap::cleanup()2700 \internal2701 */2702 2703 2720 QT_END_NAMESPACE -
trunk/src/gui/painting/qcolor.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 226 226 #endif 227 227 228 static bool isValidColor(const QString &name); 229 228 230 private: 229 231 #ifndef QT3_SUPPORT … … 233 235 234 236 void invalidate(); 237 bool setColorFromString(const QString &name); 235 238 236 239 Spec cspec; -
trunk/src/gui/painting/qcolor_p.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolor_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolormap.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolormap.qdoc
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 7 7 ** This file is part of the documentation of the Qt Toolkit. 8 8 ** 9 ** $QT_BEGIN_LICENSE: LGPL$9 ** $QT_BEGIN_LICENSE:FDL$ 10 10 ** Commercial Usage 11 11 ** Licensees holding valid Qt Commercial licenses may use this file in 12 12 ** accordance with the Qt Commercial License Agreement provided with the 13 ** Software or, alternatively, in accordance with the terms contained in 14 ** awritten agreement between you and Nokia.13 ** Software or, alternatively, in accordance with the terms contained in a 14 ** written agreement between you and Nokia. 15 15 ** 16 ** GNU Lesser General Public License Usage 17 ** Alternatively, this file may be used under the terms of the GNU Lesser 18 ** General Public License version 2.1 as published by the Free Software 19 ** Foundation and appearing in the file LICENSE.LGPL included in the 20 ** packaging of this file. Please review the following information to 21 ** ensure the GNU Lesser General Public License version 2.1 requirements 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 23 ** 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 ** 28 ** GNU General Public License Usage 29 ** Alternatively, this file may be used under the terms of the GNU 30 ** General Public License version 3.0 as published by the Free Software 31 ** Foundation and appearing in the file LICENSE.GPL included in the 32 ** packaging of this file. Please review the following information to 33 ** ensure the GNU General Public License version 3.0 requirements will be 34 ** met: http://www.gnu.org/copyleft/gpl.html. 16 ** GNU Free Documentation License 17 ** Alternatively, this file may be used under the terms of the GNU Free 18 ** Documentation License version 1.3 as published by the Free Software 19 ** Foundation and appearing in the file included in the packaging of this 20 ** file. 35 21 ** 36 22 ** If you have questions regarding the use of this file, please contact … … 151 137 a reference to \e this color map. 152 138 */ 139 140 /*! 141 \fn void QColormap::initialize() 142 \internal 143 */ 144 145 /*! 146 \fn void QColormap::cleanup() 147 \internal 148 */ -
trunk/src/gui/painting/qcolormap_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolormap_qws.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolormap_s60.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolormap_win.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcolormap_x11.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcssutil.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcssutil_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qcups.cpp
r778 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 378 378 return false; 379 379 const char *ppdFile = _cupsGetPPD(printerName); 380 if (ppdFile != 0)380 if (ppdFile) 381 381 unlink(ppdFile); 382 382 return (ppdFile != 0); -
trunk/src/gui/painting/qcups_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 64 64 #endif 65 65 #include <cups/cups.h> 66 #include <cups/ppd.h> 66 67 67 68 QT_BEGIN_NAMESPACE -
trunk/src/gui/painting/qdatabuffer_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 61 61 { 62 62 public: 63 QDataBuffer(int res = 64)63 QDataBuffer(int res) 64 64 { 65 65 capacity = res; 66 buffer = (Type*) qMalloc(capacity * sizeof(Type)); 66 if (res) 67 buffer = (Type*) qMalloc(capacity * sizeof(Type)); 68 else 69 buffer = 0; 67 70 siz = 0; 68 71 } … … 70 73 ~QDataBuffer() 71 74 { 72 qFree(buffer); 75 if (buffer) 76 qFree(buffer); 73 77 } 74 78 … … 82 86 inline Type &at(int i) { Q_ASSERT(i >= 0 && i < siz); return buffer[i]; } 83 87 inline const Type &at(int i) const { Q_ASSERT(i >= 0 && i < siz); return buffer[i]; } 88 inline Type &last() { Q_ASSERT(!isEmpty()); return buffer[siz-1]; } 84 89 inline const Type &last() const { Q_ASSERT(!isEmpty()); return buffer[siz-1]; } 90 inline Type &first() { Q_ASSERT(!isEmpty()); return buffer[0]; } 85 91 inline const Type &first() const { Q_ASSERT(!isEmpty()); return buffer[0]; } 86 92 … … 89 95 buffer[siz] = t; 90 96 ++siz; 97 } 98 99 inline void pop_back() { 100 Q_ASSERT(siz > 0); 101 --siz; 91 102 } 92 103 … … 98 109 inline void reserve(int size) { 99 110 if (size > capacity) { 111 if (capacity == 0) 112 capacity = 1; 100 113 while (capacity < size) 101 114 capacity *= 2; … … 106 119 inline void shrink(int size) { 107 120 capacity = size; 108 buffer = (Type*) qRealloc(buffer, capacity * sizeof(Type)); 121 if (size) 122 buffer = (Type*) qRealloc(buffer, capacity * sizeof(Type)); 123 else { 124 qFree(buffer); 125 buffer = 0; 126 } 109 127 } 110 128 -
trunk/src/gui/painting/qdrawhelper.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include <private/qpainter_p.h> 45 45 #include <private/qdrawhelper_x86_p.h> 46 #include <private/qdrawhelper_arm v6_p.h>46 #include <private/qdrawhelper_arm_simd_p.h> 47 47 #include <private/qdrawhelper_neon_p.h> 48 48 #include <private/qmath_p.h> … … 70 70 */ 71 71 72 static const int fixed_scale = 1 << 16; 73 static const int half_point = 1 << 15; 72 enum { 73 fixed_scale = 1 << 16, 74 half_point = 1 << 15 75 }; 74 76 static const int buffer_size = 2048; 75 77 … … 175 177 # define SPANFUNC_POINTER_DESTFETCH(Arg) destFetch<Arg> 176 178 177 static constDestFetchProc destFetchProc[QImage::NImageFormats] =179 static DestFetchProc destFetchProc[QImage::NImageFormats] = 178 180 { 179 181 0, // Format_Invalid … … 323 325 # define SPANFUNC_POINTER_DESTSTORE(DEST) destStore<DEST> 324 326 325 static constDestStoreProc destStoreProc[QImage::NImageFormats] =327 static DestStoreProc destStoreProc[QImage::NImageFormats] = 326 328 { 327 329 0, // Format_Invalid … … 654 656 } 655 657 658 /** \internal 659 interpolate 4 argb pixels with the distx and disty factor. 660 distx and disty bust be between 0 and 16 661 */ 662 static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, int distx, int disty) 663 { 664 uint distxy = distx * disty; 665 //idistx * disty = (16-distx) * disty = 16*disty - distxy 666 //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*dity + distxy 667 uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy); 668 uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy); 669 uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy)); 670 uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy)); 671 uint blrb = ((bl & 0x00ff00ff) * (disty*16 - distxy)); 672 uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy)); 673 uint brrb = ((br & 0x00ff00ff) * (distxy)); 674 uint brag = (((br & 0xff00ff00) >> 8) * (distxy)); 675 return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00); 676 } 677 678 #if defined(QT_ALWAYS_HAVE_SSE2) 679 #define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b) \ 680 { \ 681 const __m128i dxdy = _mm_mullo_epi16 (distx, disty); \ 682 const __m128i distx_ = _mm_slli_epi16(distx, 4); \ 683 const __m128i disty_ = _mm_slli_epi16(disty, 4); \ 684 const __m128i idxidy = _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_))); \ 685 const __m128i dxidy = _mm_sub_epi16(distx_, dxdy); \ 686 const __m128i idxdy = _mm_sub_epi16(disty_, dxdy); \ 687 \ 688 __m128i tlAG = _mm_srli_epi16(tl, 8); \ 689 __m128i tlRB = _mm_and_si128(tl, colorMask); \ 690 __m128i trAG = _mm_srli_epi16(tr, 8); \ 691 __m128i trRB = _mm_and_si128(tr, colorMask); \ 692 __m128i blAG = _mm_srli_epi16(bl, 8); \ 693 __m128i blRB = _mm_and_si128(bl, colorMask); \ 694 __m128i brAG = _mm_srli_epi16(br, 8); \ 695 __m128i brRB = _mm_and_si128(br, colorMask); \ 696 \ 697 tlAG = _mm_mullo_epi16(tlAG, idxidy); \ 698 tlRB = _mm_mullo_epi16(tlRB, idxidy); \ 699 trAG = _mm_mullo_epi16(trAG, dxidy); \ 700 trRB = _mm_mullo_epi16(trRB, dxidy); \ 701 blAG = _mm_mullo_epi16(blAG, idxdy); \ 702 blRB = _mm_mullo_epi16(blRB, idxdy); \ 703 brAG = _mm_mullo_epi16(brAG, dxdy); \ 704 brRB = _mm_mullo_epi16(brRB, dxdy); \ 705 \ 706 /* Add the values, and shift to only keep 8 significant bits per colors */ \ 707 __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG)); \ 708 __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB)); \ 709 rAG = _mm_andnot_si128(colorMask, rAG); \ 710 rRB = _mm_srli_epi16(rRB, 8); \ 711 _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \ 712 } 713 #endif 714 715 #if defined(QT_ALWAYS_HAVE_NEON) 716 #define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \ 717 { \ 718 const int16x8_t dxdy = vmulq_s16(distx, disty); \ 719 const int16x8_t distx_ = vshlq_n_s16(distx, 4); \ 720 const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_))); \ 721 const int16x8_t dxidy = vsubq_s16(distx_, dxdy); \ 722 const int16x8_t idxdy = vsubq_s16(disty_, dxdy); \ 723 \ 724 int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8)); \ 725 int16x8_t tlRB = vandq_s16(tl, colorMask); \ 726 int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8)); \ 727 int16x8_t trRB = vandq_s16(tr, colorMask); \ 728 int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8)); \ 729 int16x8_t blRB = vandq_s16(bl, colorMask); \ 730 int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8)); \ 731 int16x8_t brRB = vandq_s16(br, colorMask); \ 732 \ 733 int16x8_t rAG = vmulq_s16(tlAG, idxidy); \ 734 int16x8_t rRB = vmulq_s16(tlRB, idxidy); \ 735 rAG = vmlaq_s16(rAG, trAG, dxidy); \ 736 rRB = vmlaq_s16(rRB, trRB, dxidy); \ 737 rAG = vmlaq_s16(rAG, blAG, idxdy); \ 738 rRB = vmlaq_s16(rRB, blRB, idxdy); \ 739 rAG = vmlaq_s16(rAG, brAG, dxdy); \ 740 rRB = vmlaq_s16(rRB, brRB, dxdy); \ 741 \ 742 rAG = vandq_s16(invColorMask, rAG); \ 743 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); \ 744 vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \ 745 } 746 #endif 747 748 template<TextureBlendType blendType> 749 Q_STATIC_TEMPLATE_FUNCTION inline void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2) 750 { 751 if (blendType == BlendTransformedBilinearTiled) { 752 v1 %= max; 753 if (v1 < 0) v1 += max; 754 v2 = v1 + 1; 755 v2 %= max; 756 } else { 757 if (v1 < l1) { 758 v2 = v1 = l1; 759 } else if (v1 >= l2) { 760 v2 = v1 = l2; 761 } else { 762 v2 = v1 + 1; 763 } 764 } 765 766 Q_ASSERT(v1 >= 0 && v1 < max); 767 Q_ASSERT(v2 >= 0 && v2 < max); 768 } 769 656 770 template<TextureBlendType blendType, QImage::Format format> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */ 657 771 Q_STATIC_TEMPLATE_FUNCTION … … 672 786 int image_height = data->texture.height; 673 787 788 int image_x1 = data->texture.x1; 789 int image_y1 = data->texture.y1; 790 int image_x2 = data->texture.x2 - 1; 791 int image_y2 = data->texture.y2 - 1; 792 674 793 const qreal cx = x + 0.5; 675 794 const qreal cy = y + 0.5; 676 795 677 constuint *end = buffer + length;796 uint *end = buffer + length; 678 797 uint *b = buffer; 679 798 if (data->fast_matrix) { … … 689 808 fx -= half_point; 690 809 fy -= half_point; 691 while (b < end) { 692 int x1 = (fx >> 16); 693 int x2 = x1 + 1; 810 811 if (fdy == 0) { //simple scale, no rotation 694 812 int y1 = (fy >> 16); 695 int y2 = y1 + 1; 696 697 int distx = ((fx - (x1 << 16)) >> 8); 698 int disty = ((fy - (y1 << 16)) >> 8); 699 int idistx = 256 - distx; 700 int idisty = 256 - disty; 701 702 if (blendType == BlendTransformedBilinearTiled) { 703 x1 %= image_width; 704 x2 %= image_width; 705 y1 %= image_height; 706 y2 %= image_height; 707 708 if (x1 < 0) x1 += image_width; 709 if (x2 < 0) x2 += image_width; 710 if (y1 < 0) y1 += image_height; 711 if (y2 < 0) y2 += image_height; 712 713 Q_ASSERT(x1 >= 0 && x1 < image_width); 714 Q_ASSERT(x2 >= 0 && x2 < image_width); 715 Q_ASSERT(y1 >= 0 && y1 < image_height); 716 Q_ASSERT(y2 >= 0 && y2 < image_height); 717 } else { 718 x1 = qBound(0, x1, image_width - 1); 719 x2 = qBound(0, x2, image_width - 1); 720 y1 = qBound(0, y1, image_height - 1); 721 y2 = qBound(0, y2, image_height - 1); 722 } 723 813 int y2; 814 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 724 815 const uchar *s1 = data->texture.scanLine(y1); 725 816 const uchar *s2 = data->texture.scanLine(y2); 726 817 727 uint tl = fetch(s1, x1, data->texture.colorTable); 728 uint tr = fetch(s1, x2, data->texture.colorTable); 729 uint bl = fetch(s2, x1, data->texture.colorTable); 730 uint br = fetch(s2, x2, data->texture.colorTable); 731 732 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); 733 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); 734 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); 735 736 fx += fdx; 737 fy += fdy; 738 ++b; 818 if (fdx <= fixed_scale && fdx > 0) { // scale up on X 819 int disty = (fy & 0x0000ffff) >> 8; 820 int idisty = 256 - disty; 821 int x = fx >> 16; 822 823 // The idea is first to do the interpolation between the row s1 and the row s2 824 // into an intermediate buffer, then we interpolate between two pixel of this buffer. 825 826 // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB 827 // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG 828 quint32 intermediate_buffer[2][buffer_size + 2]; 829 // count is the size used in the intermediate_buffer. 830 int count = qCeil(length * data->m11) + 2; //+1 for the last pixel to interpolate with, and +1 for rounding errors. 831 Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case 832 int f = 0; 833 int lim = count; 834 if (blendType == BlendTransformedBilinearTiled) { 835 x %= image_width; 836 if (x < 0) x += image_width; 837 } else { 838 lim = qMin(count, image_x2-x+1); 839 if (x < image_x1) { 840 Q_ASSERT(x <= image_x2); 841 uint t = fetch(s1, image_x1, data->texture.colorTable); 842 uint b = fetch(s2, image_x1, data->texture.colorTable); 843 quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; 844 quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff; 845 do { 846 intermediate_buffer[0][f] = rb; 847 intermediate_buffer[1][f] = ag; 848 f++; 849 x++; 850 } while (x < image_x1 && f < lim); 851 } 852 } 853 854 if (blendType != BlendTransformedBilinearTiled && 855 (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { 856 #if defined(QT_ALWAYS_HAVE_SSE2) 857 const __m128i disty_ = _mm_set1_epi16(disty); 858 const __m128i idisty_ = _mm_set1_epi16(idisty); 859 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 860 861 lim -= 3; 862 for (; f < lim; x += 4, f += 4) { 863 // Load 4 pixels from s1, and split the alpha-green and red-blue component 864 __m128i top = _mm_loadu_si128((__m128i*)((const uint *)(s1)+x)); 865 __m128i topAG = _mm_srli_epi16(top, 8); 866 __m128i topRB = _mm_and_si128(top, colorMask); 867 // Multiplies each colour component by idisty 868 topAG = _mm_mullo_epi16 (topAG, idisty_); 869 topRB = _mm_mullo_epi16 (topRB, idisty_); 870 871 // Same for the s2 vector 872 __m128i bottom = _mm_loadu_si128((__m128i*)((const uint *)(s2)+x)); 873 __m128i bottomAG = _mm_srli_epi16(bottom, 8); 874 __m128i bottomRB = _mm_and_si128(bottom, colorMask); 875 bottomAG = _mm_mullo_epi16 (bottomAG, disty_); 876 bottomRB = _mm_mullo_epi16 (bottomRB, disty_); 877 878 // Add the values, and shift to only keep 8 significant bits per colors 879 __m128i rAG =_mm_add_epi16(topAG, bottomAG); 880 rAG = _mm_srli_epi16(rAG, 8); 881 _mm_storeu_si128((__m128i*)(&intermediate_buffer[1][f]), rAG); 882 __m128i rRB =_mm_add_epi16(topRB, bottomRB); 883 rRB = _mm_srli_epi16(rRB, 8); 884 _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB); 885 } 886 #elif defined(QT_ALWAYS_HAVE_NEON) 887 const int16x8_t disty_ = vdupq_n_s16(disty); 888 const int16x8_t idisty_ = vdupq_n_s16(idisty); 889 const int16x8_t colorMask = vdupq_n_s16(0x00ff); 890 891 lim -= 3; 892 for (; f < lim; x += 4, f += 4) { 893 // Load 4 pixels from s1, and split the alpha-green and red-blue component 894 int16x8_t top = vld1q_s16((int16_t*)((const uint *)(s1)+x)); 895 int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8)); 896 int16x8_t topRB = vandq_s16(top, colorMask); 897 // Multiplies each colour component by idisty 898 topAG = vmulq_s16(topAG, idisty_); 899 topRB = vmulq_s16(topRB, idisty_); 900 901 // Same for the s2 vector 902 int16x8_t bottom = vld1q_s16((int16_t*)((const uint *)(s2)+x)); 903 int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8)); 904 int16x8_t bottomRB = vandq_s16(bottom, colorMask); 905 bottomAG = vmulq_s16(bottomAG, disty_); 906 bottomRB = vmulq_s16(bottomRB, disty_); 907 908 // Add the values, and shift to only keep 8 significant bits per colors 909 int16x8_t rAG = vaddq_s16(topAG, bottomAG); 910 rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8)); 911 vst1q_s16((int16_t*)(&intermediate_buffer[1][f]), rAG); 912 int16x8_t rRB = vaddq_s16(topRB, bottomRB); 913 rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); 914 vst1q_s16((int16_t*)(&intermediate_buffer[0][f]), rRB); 915 } 916 #endif 917 } 918 for (; f < count; f++) { // Same as above but without sse2 919 if (blendType == BlendTransformedBilinearTiled) { 920 if (x >= image_width) x -= image_width; 921 } else { 922 x = qMin(x, image_x2); 923 } 924 925 uint t = fetch(s1, x, data->texture.colorTable); 926 uint b = fetch(s2, x, data->texture.colorTable); 927 928 intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; 929 intermediate_buffer[1][f] = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff; 930 x++; 931 } 932 // Now interpolate the values from the intermediate_buffer to get the final result. 933 fx &= fixed_scale - 1; 934 Q_ASSERT((fx >> 16) == 0); 935 while (b < end) { 936 register int x1 = (fx >> 16); 937 register int x2 = x1 + 1; 938 Q_ASSERT(x1 >= 0); 939 Q_ASSERT(x2 < count); 940 941 register int distx = (fx & 0x0000ffff) >> 8; 942 register int idistx = 256 - distx; 943 int rb = ((intermediate_buffer[0][x1] * idistx + intermediate_buffer[0][x2] * distx) >> 8) & 0xff00ff; 944 int ag = (intermediate_buffer[1][x1] * idistx + intermediate_buffer[1][x2] * distx) & 0xff00ff00; 945 *b = rb | ag; 946 b++; 947 fx += fdx; 948 } 949 } else if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x 950 int y1 = (fy >> 16); 951 int y2; 952 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 953 const uchar *s1 = data->texture.scanLine(y1); 954 const uchar *s2 = data->texture.scanLine(y2); 955 int disty = (fy & 0x0000ffff) >> 8; 956 int idisty = 256 - disty; 957 while (b < end) { 958 int x1 = (fx >> 16); 959 int x2; 960 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 961 uint tl = fetch(s1, x1, data->texture.colorTable); 962 uint tr = fetch(s1, x2, data->texture.colorTable); 963 uint bl = fetch(s2, x1, data->texture.colorTable); 964 uint br = fetch(s2, x2, data->texture.colorTable); 965 966 int distx = (fx & 0x0000ffff) >> 8; 967 int idistx = 256 - distx; 968 969 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); 970 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); 971 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); 972 973 fx += fdx; 974 ++b; 975 } 976 } else { //scale down 977 int y1 = (fy >> 16); 978 int y2; 979 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 980 const uchar *s1 = data->texture.scanLine(y1); 981 const uchar *s2 = data->texture.scanLine(y2); 982 int disty = (fy & 0x0000ffff) >> 12; 983 984 if (blendType != BlendTransformedBilinearTiled && 985 (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32)) { 986 987 #define BILINEAR_DOWNSCALE_BOUNDS_PROLOG \ 988 while (b < end) { \ 989 int x1 = (fx >> 16); \ 990 int x2; \ 991 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); \ 992 if (x1 != x2) \ 993 break; \ 994 uint tl = fetch(s1, x1, data->texture.colorTable); \ 995 uint tr = fetch(s1, x2, data->texture.colorTable); \ 996 uint bl = fetch(s2, x1, data->texture.colorTable); \ 997 uint br = fetch(s2, x2, data->texture.colorTable); \ 998 int distx = (fx & 0x0000ffff) >> 12; \ 999 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \ 1000 fx += fdx; \ 1001 ++b; \ 1002 } \ 1003 uint *boundedEnd; \ 1004 if (fdx > 0) \ 1005 boundedEnd = qMin(end, buffer + uint((image_x2 - (fx >> 16)) / data->m11)); \ 1006 else \ 1007 boundedEnd = qMin(end, buffer + uint((image_x1 - (fx >> 16)) / data->m11)); \ 1008 boundedEnd -= 3; 1009 1010 #if defined(QT_ALWAYS_HAVE_SSE2) 1011 BILINEAR_DOWNSCALE_BOUNDS_PROLOG 1012 1013 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 1014 const __m128i v_256 = _mm_set1_epi16(256); 1015 const __m128i v_disty = _mm_set1_epi16(disty); 1016 __m128i v_fdx = _mm_set1_epi32(fdx*4); 1017 1018 ptrdiff_t secondLine = reinterpret_cast<const uint *>(s2) - reinterpret_cast<const uint *>(s1); 1019 1020 union Vect_buffer { __m128i vect; quint32 i[4]; }; 1021 Vect_buffer v_fx; 1022 1023 for (int i = 0; i < 4; i++) { 1024 v_fx.i[i] = fx; 1025 fx += fdx; 1026 } 1027 1028 while (b < boundedEnd) { 1029 1030 Vect_buffer tl, tr, bl, br; 1031 1032 for (int i = 0; i < 4; i++) { 1033 int x1 = v_fx.i[i] >> 16; 1034 const uint *addr_tl = reinterpret_cast<const uint *>(s1) + x1; 1035 const uint *addr_tr = addr_tl + 1; 1036 tl.i[i] = *addr_tl; 1037 tr.i[i] = *addr_tr; 1038 bl.i[i] = *(addr_tl+secondLine); 1039 br.i[i] = *(addr_tr+secondLine); 1040 } 1041 __m128i v_distx = _mm_srli_epi16(v_fx.vect, 12); 1042 v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0)); 1043 v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0)); 1044 1045 interpolate_4_pixels_16_sse2(tl.vect, tr.vect, bl.vect, br.vect, v_distx, v_disty, colorMask, v_256, b); 1046 b+=4; 1047 v_fx.vect = _mm_add_epi32(v_fx.vect, v_fdx); 1048 } 1049 fx = v_fx.i[0]; 1050 #elif defined(QT_ALWAYS_HAVE_NEON) 1051 BILINEAR_DOWNSCALE_BOUNDS_PROLOG 1052 1053 const int16x8_t colorMask = vdupq_n_s16(0x00ff); 1054 const int16x8_t invColorMask = vmvnq_s16(colorMask); 1055 const int16x8_t v_256 = vdupq_n_s16(256); 1056 const int16x8_t v_disty = vdupq_n_s16(disty); 1057 const int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4); 1058 int32x4_t v_fdx = vdupq_n_s32(fdx*4); 1059 1060 ptrdiff_t secondLine = reinterpret_cast<const uint *>(s2) - reinterpret_cast<const uint *>(s1); 1061 1062 union Vect_buffer { int32x4_t vect; quint32 i[4]; }; 1063 Vect_buffer v_fx; 1064 1065 for (int i = 0; i < 4; i++) { 1066 v_fx.i[i] = fx; 1067 fx += fdx; 1068 } 1069 1070 const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff); 1071 1072 while (b < boundedEnd) { 1073 1074 Vect_buffer tl, tr, bl, br; 1075 1076 Vect_buffer v_fx_shifted; 1077 v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16); 1078 1079 int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12); 1080 1081 for (int i = 0; i < 4; i++) { 1082 int x1 = v_fx_shifted.i[i]; 1083 const uint *addr_tl = reinterpret_cast<const uint *>(s1) + x1; 1084 const uint *addr_tr = addr_tl + 1; 1085 tl.i[i] = *addr_tl; 1086 tr.i[i] = *addr_tr; 1087 bl.i[i] = *(addr_tl+secondLine); 1088 br.i[i] = *(addr_tr+secondLine); 1089 } 1090 1091 v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16)); 1092 1093 interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b); 1094 b+=4; 1095 v_fx.vect = vaddq_s32(v_fx.vect, v_fdx); 1096 } 1097 fx = v_fx.i[0]; 1098 #endif 1099 } 1100 1101 while (b < end) { 1102 int x1 = (fx >> 16); 1103 int x2; 1104 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1105 uint tl = fetch(s1, x1, data->texture.colorTable); 1106 uint tr = fetch(s1, x2, data->texture.colorTable); 1107 uint bl = fetch(s2, x1, data->texture.colorTable); 1108 uint br = fetch(s2, x2, data->texture.colorTable); 1109 int distx = (fx & 0x0000ffff) >> 12; 1110 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); 1111 fx += fdx; 1112 ++b; 1113 } 1114 } 1115 } else { //rotation 1116 if (fabs(data->m11) > 8 || fabs(data->m22) > 8) { 1117 //if we are zooming more than 8 times, we use 8bit precision for the position. 1118 while (b < end) { 1119 int x1 = (fx >> 16); 1120 int x2; 1121 int y1 = (fy >> 16); 1122 int y2; 1123 1124 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1125 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 1126 1127 const uchar *s1 = data->texture.scanLine(y1); 1128 const uchar *s2 = data->texture.scanLine(y2); 1129 1130 uint tl = fetch(s1, x1, data->texture.colorTable); 1131 uint tr = fetch(s1, x2, data->texture.colorTable); 1132 uint bl = fetch(s2, x1, data->texture.colorTable); 1133 uint br = fetch(s2, x2, data->texture.colorTable); 1134 1135 int distx = (fx & 0x0000ffff) >> 8; 1136 int disty = (fy & 0x0000ffff) >> 8; 1137 int idistx = 256 - distx; 1138 int idisty = 256 - disty; 1139 1140 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); 1141 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); 1142 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); 1143 1144 fx += fdx; 1145 fy += fdy; 1146 ++b; 1147 } 1148 } else { 1149 //we are zooming less than 8x, use 4bit precision 1150 while (b < end) { 1151 int x1 = (fx >> 16); 1152 int x2; 1153 int y1 = (fy >> 16); 1154 int y2; 1155 1156 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1157 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 1158 1159 const uchar *s1 = data->texture.scanLine(y1); 1160 const uchar *s2 = data->texture.scanLine(y2); 1161 1162 uint tl = fetch(s1, x1, data->texture.colorTable); 1163 uint tr = fetch(s1, x2, data->texture.colorTable); 1164 uint bl = fetch(s2, x1, data->texture.colorTable); 1165 uint br = fetch(s2, x2, data->texture.colorTable); 1166 1167 int distx = (fx & 0x0000ffff) >> 12; 1168 int disty = (fy & 0x0000ffff) >> 12; 1169 1170 *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); 1171 1172 fx += fdx; 1173 fy += fdy; 1174 ++b; 1175 } 1176 } 739 1177 } 740 1178 } else { … … 753 1191 754 1192 int x1 = int(px) - (px < 0); 755 int x2 = x1 + 1;1193 int x2; 756 1194 int y1 = int(py) - (py < 0); 757 int y2 = y1 + 1;1195 int y2; 758 1196 759 1197 int distx = int((px - x1) * 256); … … 762 1200 int idisty = 256 - disty; 763 1201 764 if (blendType == BlendTransformedBilinearTiled) { 765 x1 %= image_width; 766 x2 %= image_width; 767 y1 %= image_height; 768 y2 %= image_height; 769 770 if (x1 < 0) x1 += image_width; 771 if (x2 < 0) x2 += image_width; 772 if (y1 < 0) y1 += image_height; 773 if (y2 < 0) y2 += image_height; 774 775 Q_ASSERT(x1 >= 0 && x1 < image_width); 776 Q_ASSERT(x2 >= 0 && x2 < image_width); 777 Q_ASSERT(y1 >= 0 && y1 < image_height); 778 Q_ASSERT(y2 >= 0 && y2 < image_height); 779 } else { 780 x1 = qBound(0, x1, image_width - 1); 781 x2 = qBound(0, x2, image_width - 1); 782 y1 = qBound(0, y1, image_height - 1); 783 y2 = qBound(0, y2, image_height - 1); 784 } 1202 fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); 1203 fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); 785 1204 786 1205 const uchar *s1 = data->texture.scanLine(y1); … … 1282 1701 } 1283 1702 1284 staticvoid QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)1703 void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) 1285 1704 { 1286 1705 comp_func_Clear_impl(dest, length, const_alpha); 1287 1706 } 1288 1707 1289 staticvoid QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)1708 void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) 1290 1709 { 1291 1710 comp_func_Clear_impl(dest, length, const_alpha); … … 1296 1715 dest = s * ca + d * cia 1297 1716 */ 1298 staticvoid QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)1717 void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha) 1299 1718 { 1300 1719 if (const_alpha == 255) { … … 1311 1730 } 1312 1731 1313 staticvoid QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha)1732 void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha) 1314 1733 { 1315 1734 if (const_alpha == 255) { … … 1325 1744 } 1326 1745 1327 staticvoid QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)1328 { 1329 } 1330 1331 staticvoid QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)1746 void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint) 1747 { 1748 } 1749 1750 void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint) 1332 1751 { 1333 1752 } … … 1339 1758 = s * ca + d * (1 - sa*ca) 1340 1759 */ 1341 staticvoid QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)1760 void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha) 1342 1761 { 1343 1762 if ((const_alpha & qAlpha(color)) == 255) { … … 1354 1773 } 1355 1774 1356 staticvoid QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha)1775 void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha) 1357 1776 { 1358 1777 PRELOAD_INIT2(dest, src) … … 1380 1799 = d + s * dia * ca 1381 1800 */ 1382 staticvoid QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)1801 void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha) 1383 1802 { 1384 1803 if (const_alpha != 255) … … 1392 1811 } 1393 1812 1394 staticvoid QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha)1813 void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha) 1395 1814 { 1396 1815 PRELOAD_INIT2(dest, src) … … 1415 1834 dest = s * da * ca + d * cia 1416 1835 */ 1417 staticvoid QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)1836 void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha) 1418 1837 { 1419 1838 PRELOAD_INIT(dest) … … 1434 1853 } 1435 1854 1436 staticvoid QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha)1855 void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha) 1437 1856 { 1438 1857 PRELOAD_INIT2(dest, src) … … 1458 1877 = d * (sa * ca + cia) 1459 1878 */ 1460 staticvoid QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)1879 void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha) 1461 1880 { 1462 1881 uint a = qAlpha(color); … … 1471 1890 } 1472 1891 1473 staticvoid QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha)1892 void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha) 1474 1893 { 1475 1894 PRELOAD_INIT2(dest, src) … … 1494 1913 */ 1495 1914 1496 staticvoid QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)1915 void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha) 1497 1916 { 1498 1917 PRELOAD_INIT(dest) … … 1513 1932 } 1514 1933 1515 staticvoid QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha)1934 void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha) 1516 1935 { 1517 1936 PRELOAD_INIT2(dest, src) … … 1537 1956 = d * (sia * ca + cia) 1538 1957 */ 1539 staticvoid QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)1958 void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha) 1540 1959 { 1541 1960 uint a = qAlpha(~color); … … 1549 1968 } 1550 1969 1551 staticvoid QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha)1970 void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha) 1552 1971 { 1553 1972 PRELOAD_INIT2(dest, src) … … 1573 1992 = s*ca * da + d * (1 - sa*ca) 1574 1993 */ 1575 staticvoid QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)1994 void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha) 1576 1995 { 1577 1996 if (const_alpha != 255) { … … 1586 2005 } 1587 2006 1588 staticvoid QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha)2007 void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha) 1589 2008 { 1590 2009 PRELOAD_INIT2(dest, src) … … 1611 2030 = s*ca * dia + d * (sa*ca + cia) 1612 2031 */ 1613 staticvoid QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)2032 void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha) 1614 2033 { 1615 2034 uint a = qAlpha(color); … … 1626 2045 } 1627 2046 1628 staticvoid QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha)2047 void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha) 1629 2048 { 1630 2049 PRELOAD_INIT2(dest, src) … … 1654 2073 = s*ca * dia + d * (1 - sa*ca) 1655 2074 */ 1656 staticvoid QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)2075 void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha) 1657 2076 { 1658 2077 if (const_alpha != 255) … … 1668 2087 } 1669 2088 1670 staticvoid QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha)2089 void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha) 1671 2090 { 1672 2091 PRELOAD_INIT2(dest, src) … … 1688 2107 } 1689 2108 1690 static const uint AMASK = 0xff000000;1691 static const uint RMASK = 0x00ff0000;1692 static const uint GMASK = 0x0000ff00;1693 static const uint BMASK = 0x000000ff;1694 1695 2109 struct QFullCoverage { 1696 2110 inline void store(uint *dest, const uint src) const … … 1735 2149 PRELOAD_COND(dest) 1736 2150 uint d = dest[i]; 1737 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) 1738 d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); 1739 #undef MIX 2151 d = comp_func_Plus_one_pixel(d, s); 1740 2152 coverage.store(&dest[i], d); 1741 2153 } 1742 2154 } 1743 2155 1744 staticvoid QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)2156 void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha) 1745 2157 { 1746 2158 if (const_alpha == 255) … … 1759 2171 uint s = src[i]; 1760 2172 1761 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) 1762 d = (MIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); 1763 #undef MIX 2173 d = comp_func_Plus_one_pixel(d, s); 1764 2174 1765 2175 coverage.store(&dest[i], d); … … 1767 2177 } 1768 2178 1769 staticvoid QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha)2179 void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha) 1770 2180 { 1771 2181 if (const_alpha == 255) … … 1808 2218 } 1809 2219 1810 staticvoid QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)2220 void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha) 1811 2221 { 1812 2222 if (const_alpha == 255) … … 1839 2249 } 1840 2250 1841 staticvoid QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha)2251 void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha) 1842 2252 { 1843 2253 if (const_alpha == 255) … … 1876 2286 } 1877 2287 1878 staticvoid QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)2288 void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha) 1879 2289 { 1880 2290 if (const_alpha == 255) … … 1907 2317 } 1908 2318 1909 staticvoid QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)2319 void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha) 1910 2320 { 1911 2321 if (const_alpha == 255) … … 1955 2365 } 1956 2366 1957 staticvoid QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)2367 void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha) 1958 2368 { 1959 2369 if (const_alpha == 255) … … 1986 2396 } 1987 2397 1988 staticvoid QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha)2398 void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha) 1989 2399 { 1990 2400 if (const_alpha == 255) … … 2028 2438 } 2029 2439 2030 staticvoid QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)2440 void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha) 2031 2441 { 2032 2442 if (const_alpha == 255) … … 2059 2469 } 2060 2470 2061 staticvoid QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha)2471 void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha) 2062 2472 { 2063 2473 if (const_alpha == 255) … … 2101 2511 } 2102 2512 2103 staticvoid QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)2513 void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha) 2104 2514 { 2105 2515 if (const_alpha == 255) … … 2132 2542 } 2133 2543 2134 staticvoid QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha)2544 void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha) 2135 2545 { 2136 2546 if (const_alpha == 255) … … 2184 2594 } 2185 2595 2186 staticvoid QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)2596 void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha) 2187 2597 { 2188 2598 if (const_alpha == 255) … … 2215 2625 } 2216 2626 2217 staticvoid QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha)2627 void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha) 2218 2628 { 2219 2629 if (const_alpha == 255) … … 2267 2677 } 2268 2678 2269 staticvoid QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)2679 void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha) 2270 2680 { 2271 2681 if (const_alpha == 255) … … 2298 2708 } 2299 2709 2300 staticvoid QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha)2710 void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha) 2301 2711 { 2302 2712 if (const_alpha == 255) … … 2347 2757 } 2348 2758 2349 staticvoid QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)2759 void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha) 2350 2760 { 2351 2761 if (const_alpha == 255) … … 2378 2788 } 2379 2789 2380 staticvoid QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha)2790 void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha) 2381 2791 { 2382 2792 if (const_alpha == 255) … … 2438 2848 } 2439 2849 2440 staticvoid QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)2850 void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha) 2441 2851 { 2442 2852 if (const_alpha == 255) … … 2469 2879 } 2470 2880 2471 staticvoid QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha)2881 void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha) 2472 2882 { 2473 2883 if (const_alpha == 255) … … 2511 2921 } 2512 2922 2513 staticvoid QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)2923 void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha) 2514 2924 { 2515 2925 if (const_alpha == 255) … … 2542 2952 } 2543 2953 2544 staticvoid QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha)2954 void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha) 2545 2955 { 2546 2956 if (const_alpha == 255) … … 2578 2988 } 2579 2989 2580 staticvoid QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)2990 void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha) 2581 2991 { 2582 2992 if (const_alpha == 255) … … 2609 3019 } 2610 3020 2611 staticvoid QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha)3021 void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha) 2612 3022 { 2613 3023 if (const_alpha == 255) … … 2622 3032 #endif 2623 3033 2624 staticvoid QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,2625 2626 2627 3034 void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, 3035 int length, 3036 uint color, 3037 uint const_alpha) 2628 3038 { 2629 3039 Q_UNUSED(const_alpha); … … 2632 3042 } 2633 3043 2634 staticvoid QT_FASTCALL rasterop_SourceOrDestination(uint *dest,2635 2636 2637 3044 void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, 3045 const uint *src, 3046 int length, 3047 uint const_alpha) 2638 3048 { 2639 3049 Q_UNUSED(const_alpha); … … 2642 3052 } 2643 3053 2644 staticvoid QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,2645 2646 2647 3054 void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest, 3055 int length, 3056 uint color, 3057 uint const_alpha) 2648 3058 { 2649 3059 Q_UNUSED(const_alpha); … … 2653 3063 } 2654 3064 2655 staticvoid QT_FASTCALL rasterop_SourceAndDestination(uint *dest,2656 2657 2658 3065 void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, 3066 const uint *src, 3067 int length, 3068 uint const_alpha) 2659 3069 { 2660 3070 Q_UNUSED(const_alpha); … … 2665 3075 } 2666 3076 2667 staticvoid QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,2668 2669 2670 3077 void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest, 3078 int length, 3079 uint color, 3080 uint const_alpha) 2671 3081 { 2672 3082 Q_UNUSED(const_alpha); … … 2676 3086 } 2677 3087 2678 staticvoid QT_FASTCALL rasterop_SourceXorDestination(uint *dest,2679 2680 2681 3088 void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, 3089 const uint *src, 3090 int length, 3091 uint const_alpha) 2682 3092 { 2683 3093 Q_UNUSED(const_alpha); … … 2688 3098 } 2689 3099 2690 staticvoid QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,2691 2692 2693 3100 void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest, 3101 int length, 3102 uint color, 3103 uint const_alpha) 2694 3104 { 2695 3105 Q_UNUSED(const_alpha); … … 2701 3111 } 2702 3112 2703 staticvoid QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest,2704 2705 2706 3113 void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, 3114 const uint *src, 3115 int length, 3116 uint const_alpha) 2707 3117 { 2708 3118 Q_UNUSED(const_alpha); … … 2713 3123 } 2714 3124 2715 staticvoid QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,2716 2717 2718 3125 void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest, 3126 int length, 3127 uint color, 3128 uint const_alpha) 2719 3129 { 2720 3130 Q_UNUSED(const_alpha); … … 2726 3136 } 2727 3137 2728 staticvoid QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest,2729 2730 2731 3138 void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, 3139 const uint *src, 3140 int length, 3141 uint const_alpha) 2732 3142 { 2733 3143 Q_UNUSED(const_alpha); … … 2738 3148 } 2739 3149 2740 staticvoid QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,2741 2742 2743 3150 void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest, 3151 int length, 3152 uint color, 3153 uint const_alpha) 2744 3154 { 2745 3155 Q_UNUSED(const_alpha); … … 2751 3161 } 2752 3162 2753 staticvoid QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest,2754 2755 2756 3163 void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, 3164 const uint *src, 3165 int length, 3166 uint const_alpha) 2757 3167 { 2758 3168 Q_UNUSED(const_alpha); … … 2763 3173 } 2764 3174 2765 staticvoid QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,2766 3175 void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, 3176 uint color, uint const_alpha) 2767 3177 { 2768 3178 Q_UNUSED(const_alpha); … … 2770 3180 } 2771 3181 2772 staticvoid QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src,2773 3182 void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, 3183 int length, uint const_alpha) 2774 3184 { 2775 3185 Q_UNUSED(const_alpha); … … 2778 3188 } 2779 3189 2780 staticvoid QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,2781 2782 2783 3190 void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, 3191 int length, 3192 uint color, 3193 uint const_alpha) 2784 3194 { 2785 3195 Q_UNUSED(const_alpha); … … 2791 3201 } 2792 3202 2793 staticvoid QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest,2794 2795 2796 3203 void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, 3204 const uint *src, 3205 int length, 3206 uint const_alpha) 2797 3207 { 2798 3208 Q_UNUSED(const_alpha); … … 2803 3213 } 2804 3214 2805 staticvoid QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,2806 2807 2808 3215 void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, 3216 int length, 3217 uint color, 3218 uint const_alpha) 2809 3219 { 2810 3220 Q_UNUSED(const_alpha); … … 2815 3225 } 2816 3226 2817 staticvoid QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest,2818 2819 2820 3227 void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, 3228 const uint *src, 3229 int length, 3230 uint const_alpha) 2821 3231 { 2822 3232 Q_UNUSED(const_alpha); … … 2827 3237 } 2828 3238 2829 static constCompositionFunctionSolid functionForModeSolid_C[] = {3239 static CompositionFunctionSolid functionForModeSolid_C[] = { 2830 3240 comp_func_solid_SourceOver, 2831 3241 comp_func_solid_DestinationOver, … … 2865 3275 static const CompositionFunctionSolid *functionForModeSolid = functionForModeSolid_C; 2866 3276 2867 static constCompositionFunction functionForMode_C[] = {3277 static CompositionFunction functionForMode_C[] = { 2868 3278 comp_func_SourceOver, 2869 3279 comp_func_DestinationOver, … … 3701 4111 inline quint32 alpha_4(const qargb8555 *src) 3702 4112 { 3703 Q_ASSERT(( long(src) & 0x3) == 0);4113 Q_ASSERT((quintptr(src) & 0x3) == 0); 3704 4114 const quint8 *src8 = reinterpret_cast<const quint8*>(src); 3705 4115 return src8[0] << 24 | src8[3] << 16 | src8[6] << 8 | src8[9]; … … 3884 4294 inline void interpolate_pixel_2(DST *dest, const SRC *src, quint16 alpha) 3885 4295 { 3886 Q_ASSERT(( long(dest) & 0x3) == 0);3887 Q_ASSERT(( long(src) & 0x3) == 0);4296 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4297 Q_ASSERT((quintptr(src) & 0x3) == 0); 3888 4298 3889 4299 const quint16 a = eff_alpha_2(alpha, dest); … … 3958 4368 const SRC *src, quint8 b) 3959 4369 { 3960 Q_ASSERT(( long(dest) & 0x3) == 0);3961 Q_ASSERT(( long(src) & 0x3) == 0);4370 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4371 Q_ASSERT((quintptr(src) & 0x3) == 0); 3962 4372 3963 4373 Q_ASSERT(!SRC::hasAlpha()); … … 4007 4417 inline void interpolate_pixel_4(DST *dest, const SRC *src, quint32 alpha) 4008 4418 { 4009 Q_ASSERT(( long(dest) & 0x3) == 0);4010 Q_ASSERT(( long(src) & 0x3) == 0);4419 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4420 Q_ASSERT((quintptr(src) & 0x3) == 0); 4011 4421 4012 4422 const quint32 a = eff_alpha_4(alpha, dest); … … 4027 4437 quint32 alpha) 4028 4438 { 4029 Q_ASSERT(( long(dest) & 0x3) == 0);4030 Q_ASSERT(( long(src) & 0x3) == 0);4439 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4440 Q_ASSERT((quintptr(src) & 0x3) == 0); 4031 4441 4032 4442 const quint32 a = eff_alpha_4(alpha, dest); … … 4123 4533 quint32 alpha) 4124 4534 { 4125 Q_ASSERT(( long(dest) & 0x3) == 0);4126 Q_ASSERT(( long(src) & 0x3) == 0);4535 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4536 Q_ASSERT((quintptr(src) & 0x3) == 0); 4127 4537 4128 4538 … … 4219 4629 quint32 alpha) 4220 4630 { 4221 Q_ASSERT(( long(dest) & 0x3) == 0);4222 Q_ASSERT(( long(src) & 0x3) == 0);4631 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4632 Q_ASSERT((quintptr(src) & 0x3) == 0); 4223 4633 4224 4634 const quint32 a = eff_alpha_4(alpha, dest); … … 4292 4702 const SRC *src, quint8 b) 4293 4703 { 4294 Q_ASSERT(( long(dest) & 0x3) == 0);4295 Q_ASSERT(( long(src) & 0x3) == 0);4704 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4705 Q_ASSERT((quintptr(src) & 0x3) == 0); 4296 4706 4297 4707 dest[0] = dest[0].byte_mul(a) + DST(src[0]).byte_mul(b); … … 4304 4714 inline void blend_sourceOver_4(DST *dest, const SRC *src) 4305 4715 { 4306 Q_ASSERT(( long(dest) & 0x3) == 0);4307 Q_ASSERT(( long(src) & 0x3) == 0);4716 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4717 Q_ASSERT((quintptr(src) & 0x3) == 0); 4308 4718 4309 4719 const quint32 a = alpha_4(src); … … 4320 4730 inline void blend_sourceOver_4(qargb8565 *dest, const qargb8565 *src) 4321 4731 { 4322 Q_ASSERT(( long(dest) & 0x3) == 0);4323 Q_ASSERT(( long(src) & 0x3) == 0);4732 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4733 Q_ASSERT((quintptr(src) & 0x3) == 0); 4324 4734 4325 4735 const quint32 a = alpha_4(src); … … 4334 4744 inline void blend_sourceOver_4(qargb8555 *dest, const qargb8555 *src) 4335 4745 { 4336 Q_ASSERT(( long(dest) & 0x3) == 0);4337 Q_ASSERT(( long(src) & 0x3) == 0);4746 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4747 Q_ASSERT((quintptr(src) & 0x3) == 0); 4338 4748 4339 4749 const quint32 a = alpha_4(src); … … 4348 4758 inline void blend_sourceOver_4(qargb6666 *dest, const qargb6666 *src) 4349 4759 { 4350 Q_ASSERT(( long(dest) & 0x3) == 0);4351 Q_ASSERT(( long(src) & 0x3) == 0);4760 Q_ASSERT((quintptr(dest) & 0x3) == 0); 4761 Q_ASSERT((quintptr(src) & 0x3) == 0); 4352 4762 4353 4763 const quint32 a = alpha_4(src); … … 4411 4821 Q_ASSERT(sizeof(DST) == 2); 4412 4822 Q_ASSERT(sizeof(SRC) == 2); 4413 Q_ASSERT(( long(dest) & 0x3) == (long(src) & 0x3));4823 Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); 4414 4824 Q_ASSERT(coverage > 0); 4415 4825 … … 4479 4889 4480 4890 while (length >= 2) { 4481 Q_ASSERT(( long(dest) & 3) == 0);4482 Q_ASSERT(( long(src) & 3) == 0);4891 Q_ASSERT((quintptr(dest) & 3) == 0); 4892 Q_ASSERT((quintptr(src) & 3) == 0); 4483 4893 4484 4894 const quint16 a = alpha_2(src); … … 4511 4921 quint8 coverage, int length) 4512 4922 { 4513 Q_ASSERT(( long(dest) & 0x3) == (long(src) & 0x3));4923 Q_ASSERT((quintptr(dest) & 0x3) == (quintptr(src) & 0x3)); 4514 4924 Q_ASSERT(sizeof(DST) == 3); 4515 4925 Q_ASSERT(coverage > 0); … … 4536 4946 if (SRC::hasAlpha()) { 4537 4947 while (length >= 4) { 4538 const quint32 alpha = BYTE_MUL(uint(alpha_4(src)), uint(coverage));4948 const quint32 alpha = QT_PREPEND_NAMESPACE(BYTE_MUL)(uint(alpha_4(src)), uint(coverage)); 4539 4949 if (alpha) 4540 4950 interpolate_pixel_4(dest, src, alpha); … … 4734 5144 void *userData) 4735 5145 { 4736 #if defined(QT_QWS_DEPTH_16)5146 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 4737 5147 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 4738 5148 … … 4987 5397 copy_image_width *= 2; 4988 5398 } 4989 qt_memconvert(dest, src, length); 5399 if (length > 0) 5400 qt_memconvert(dest, src, length); 4990 5401 } else { 4991 5402 while (length) { … … 5072 5483 static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) 5073 5484 { 5074 #if defined(QT_QWS_DEPTH_16)5485 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 5075 5486 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 5076 5487 … … 5138 5549 #endif 5139 5550 blend_tiled_generic<RegularSpans>(count, spans, userData); 5140 }5141 5142 5143 template <SpanMethod spanMethod>5144 Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData)5145 {5146 QSpanData *data = reinterpret_cast<QSpanData *>(userData);5147 if (data->texture.format != QImage::Format_ARGB32_Premultiplied5148 && data->texture.format != QImage::Format_RGB32) {5149 blend_src_generic<spanMethod>(count, spans, userData);5150 return;5151 }5152 5153 CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];5154 uint buffer[buffer_size];5155 5156 int image_x1 = data->texture.x1;5157 int image_y1 = data->texture.y1;5158 int image_x2 = data->texture.x2;5159 int image_y2 = data->texture.y2;5160 const int scanline_offset = data->texture.bytesPerLine / 4;5161 5162 if (data->fast_matrix) {5163 // The increment pr x in the scanline5164 int fdx = (int)(data->m11 * fixed_scale);5165 int fdy = (int)(data->m12 * fixed_scale);5166 5167 while (count--) {5168 void *t = data->rasterBuffer->scanLine(spans->y);5169 5170 uint *target = ((uint *)t) + spans->x;5171 uint *image_bits = (uint *)data->texture.imageData;5172 5173 const qreal cx = spans->x + 0.5;5174 const qreal cy = spans->y + 0.5;5175 5176 int x = int((data->m21 * cy5177 + data->m11 * cx + data->dx) * fixed_scale) - half_point;5178 int y = int((data->m22 * cy5179 + data->m12 * cx + data->dy) * fixed_scale) - half_point;5180 5181 int length = spans->len;5182 const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;5183 while (length) {5184 int l = qMin(length, buffer_size);5185 const uint *end = buffer + l;5186 uint *b = buffer;5187 while (b < end) {5188 int x1 = (x >> 16);5189 int x2 = x1 + 1;5190 int y1 = (y >> 16);5191 int y2 = y1 + 1;5192 5193 int distx = ((x - (x1 << 16)) >> 8);5194 int disty = ((y - (y1 << 16)) >> 8);5195 int idistx = 256 - distx;5196 int idisty = 256 - disty;5197 5198 x1 = qBound(image_x1, x1, image_x2 - 1);5199 x2 = qBound(image_x1, x2, image_x2 - 1);5200 y1 = qBound(image_y1, y1, image_y2 - 1);5201 y2 = qBound(image_y1, y2, image_y2 - 1);5202 5203 int y1_offset = y1 * scanline_offset;5204 int y2_offset = y2 * scanline_offset;5205 5206 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5207 uint tl = gccBug(image_bits[y1_offset + x1]);5208 uint tr = gccBug(image_bits[y1_offset + x2]);5209 uint bl = gccBug(image_bits[y2_offset + x1]);5210 uint br = gccBug(image_bits[y2_offset + x2]);5211 #else5212 uint tl = image_bits[y1_offset + x1];5213 uint tr = image_bits[y1_offset + x2];5214 uint bl = image_bits[y2_offset + x1];5215 uint br = image_bits[y2_offset + x2];5216 #endif5217 5218 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5219 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5220 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5221 ++b;5222 5223 x += fdx;5224 y += fdy;5225 }5226 if (spanMethod == RegularSpans)5227 func(target, buffer, l, coverage);5228 else5229 drawBufferSpan(data, buffer, buffer_size,5230 spans->x + spans->len - length,5231 spans->y, l, coverage);5232 target += l;5233 length -= l;5234 }5235 ++spans;5236 }5237 } else {5238 const qreal fdx = data->m11;5239 const qreal fdy = data->m12;5240 const qreal fdw = data->m13;5241 5242 while (count--) {5243 void *t = data->rasterBuffer->scanLine(spans->y);5244 5245 uint *target = ((uint *)t) + spans->x;5246 uint *image_bits = (uint *)data->texture.imageData;5247 5248 const qreal cx = spans->x + 0.5;5249 const qreal cy = spans->y + 0.5;5250 5251 qreal x = data->m21 * cy + data->m11 * cx + data->dx;5252 qreal y = data->m22 * cy + data->m12 * cx + data->dy;5253 qreal w = data->m23 * cy + data->m13 * cx + data->m33;5254 5255 int length = spans->len;5256 const int coverage = (data->texture.const_alpha * spans->coverage) >> 8;5257 while (length) {5258 int l = qMin(length, buffer_size);5259 const uint *end = buffer + l;5260 uint *b = buffer;5261 while (b < end) {5262 const qreal iw = w == 0 ? 1 : 1 / w;5263 const qreal px = x * iw - 0.5;5264 const qreal py = y * iw - 0.5;5265 5266 int x1 = int(px) - (px < 0);5267 int x2 = x1 + 1;5268 int y1 = int(py) - (py < 0);5269 int y2 = y1 + 1;5270 5271 int distx = int((px - x1) * 256);5272 int disty = int((py - y1) * 256);5273 int idistx = 256 - distx;5274 int idisty = 256 - disty;5275 5276 x1 = qBound(image_x1, x1, image_x2 - 1);5277 x2 = qBound(image_x1, x2, image_x2 - 1);5278 y1 = qBound(image_y1, y1, image_y2 - 1);5279 y2 = qBound(image_y1, y2, image_y2 - 1);5280 5281 int y1_offset = y1 * scanline_offset;5282 int y2_offset = y2 * scanline_offset;5283 5284 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5285 uint tl = gccBug(image_bits[y1_offset + x1]);5286 uint tr = gccBug(image_bits[y1_offset + x2]);5287 uint bl = gccBug(image_bits[y2_offset + x1]);5288 uint br = gccBug(image_bits[y2_offset + x2]);5289 #else5290 uint tl = image_bits[y1_offset + x1];5291 uint tr = image_bits[y1_offset + x2];5292 uint bl = image_bits[y2_offset + x1];5293 uint br = image_bits[y2_offset + x2];5294 #endif5295 5296 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5297 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5298 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5299 ++b;5300 5301 x += fdx;5302 y += fdy;5303 w += fdw;5304 }5305 if (spanMethod == RegularSpans)5306 func(target, buffer, l, coverage);5307 else5308 drawBufferSpan(data, buffer, buffer_size,5309 spans->x + spans->len - length,5310 spans->y, l, coverage);5311 target += l;5312 length -= l;5313 }5314 ++spans;5315 }5316 }5317 5551 } 5318 5552 … … 5366 5600 while (b < end) { 5367 5601 int x1 = (x >> 16); 5368 int x2 = x1 + 1;5602 int x2; 5369 5603 int y1 = (y >> 16); 5370 int y2 = y1 + 1; 5371 5372 const int distx = ((x - (x1 << 16)) >> 8); 5373 const int disty = ((y - (y1 << 16)) >> 8); 5374 x1 = qBound(src_minx, x1, src_maxx); 5375 x2 = qBound(src_minx, x2, src_maxx); 5376 y1 = qBound(src_miny, y1, src_maxy); 5377 y2 = qBound(src_miny, y2, src_maxy); 5378 5604 int y2; 5605 5606 const int distx = (x & 0x0000ffff) >> 8; 5607 const int disty = (y & 0x0000ffff) >> 8; 5608 5609 if (x1 < src_minx) { 5610 x2 = x1 = src_minx; 5611 } else if (x1 >= src_maxx) { 5612 x2 = x1 = src_maxx; 5613 } else { 5614 x2 = x1 + 1; 5615 } 5616 if (y1 < src_miny) { 5617 y2 = y1 = src_miny; 5618 } else if (y1 >= src_maxy) { 5619 y2 = y1 = src_maxy; 5620 } else { 5621 y2 = y1 + 1; 5622 } 5379 5623 #if 0 5380 5624 if (x1 == x2) { … … 5467 5711 5468 5712 int x1 = int(px) - (px < 0); 5469 int x2 = x1 + 1;5713 int x2; 5470 5714 int y1 = int(py) - (py < 0); 5471 int y2 = y1 + 1;5715 int y2; 5472 5716 5473 5717 const int distx = int((px - x1) * 256); 5474 5718 const int disty = int((py - y1) * 256); 5475 5719 5476 x1 = qBound(src_minx, x1, src_maxx); 5477 x2 = qBound(src_minx, x2, src_maxx); 5478 y1 = qBound(src_miny, y1, src_maxy); 5479 y2 = qBound(src_miny, y2, src_maxy); 5720 if (x1 < src_minx) { 5721 x2 = x1 = src_minx; 5722 } else if (x1 >= src_maxx) { 5723 x2 = x1 = src_maxx; 5724 } else { 5725 x2 = x1 + 1; 5726 } 5727 if (y1 < src_miny) { 5728 y2 = y1 = src_miny; 5729 } else if (y1 >= src_maxy) { 5730 y2 = y1 = src_maxy; 5731 } else { 5732 y2 = y1 + 1; 5733 } 5480 5734 5481 5735 const SRC *src1 = (SRC*)data->texture.scanLine(y1); … … 5577 5831 void *userData) 5578 5832 { 5579 #if defined(QT_QWS_DEPTH_16)5833 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 5580 5834 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 5581 5835 … … 5643 5897 #endif 5644 5898 blend_src_generic<RegularSpans>(count, spans, userData); 5645 }5646 5647 template <SpanMethod spanMethod>5648 Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData)5649 {5650 QSpanData *data = reinterpret_cast<QSpanData *>(userData);5651 if (data->texture.format != QImage::Format_ARGB32_Premultiplied5652 && data->texture.format != QImage::Format_RGB32) {5653 blend_src_generic<spanMethod>(count, spans, userData);5654 return;5655 }5656 5657 CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode];5658 uint buffer[buffer_size];5659 5660 int image_width = data->texture.width;5661 int image_height = data->texture.height;5662 const int scanline_offset = data->texture.bytesPerLine / 4;5663 5664 if (data->fast_matrix) {5665 // The increment pr x in the scanline5666 int fdx = (int)(data->m11 * fixed_scale);5667 int fdy = (int)(data->m12 * fixed_scale);5668 5669 while (count--) {5670 void *t = data->rasterBuffer->scanLine(spans->y);5671 5672 uint *target = ((uint *)t) + spans->x;5673 uint *image_bits = (uint *)data->texture.imageData;5674 5675 const qreal cx = spans->x + 0.5;5676 const qreal cy = spans->y + 0.5;5677 5678 int x = int((data->m21 * cy5679 + data->m11 * cx + data->dx) * fixed_scale) - half_point;5680 int y = int((data->m22 * cy5681 + data->m12 * cx + data->dy) * fixed_scale) - half_point;5682 5683 int length = spans->len;5684 const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;5685 while (length) {5686 int l = qMin(length, buffer_size);5687 const uint *end = buffer + l;5688 uint *b = buffer;5689 while (b < end) {5690 int x1 = (x >> 16);5691 int x2 = (x1 + 1);5692 int y1 = (y >> 16);5693 int y2 = (y1 + 1);5694 5695 int distx = ((x - (x1 << 16)) >> 8);5696 int disty = ((y - (y1 << 16)) >> 8);5697 int idistx = 256 - distx;5698 int idisty = 256 - disty;5699 5700 x1 %= image_width;5701 x2 %= image_width;5702 y1 %= image_height;5703 y2 %= image_height;5704 5705 if (x1 < 0) x1 += image_width;5706 if (x2 < 0) x2 += image_width;5707 if (y1 < 0) y1 += image_height;5708 if (y2 < 0) y2 += image_height;5709 5710 Q_ASSERT(x1 >= 0 && x1 < image_width);5711 Q_ASSERT(x2 >= 0 && x2 < image_width);5712 Q_ASSERT(y1 >= 0 && y1 < image_height);5713 Q_ASSERT(y2 >= 0 && y2 < image_height);5714 5715 int y1_offset = y1 * scanline_offset;5716 int y2_offset = y2 * scanline_offset;5717 5718 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5719 uint tl = gccBug(image_bits[y1_offset + x1]);5720 uint tr = gccBug(image_bits[y1_offset + x2]);5721 uint bl = gccBug(image_bits[y2_offset + x1]);5722 uint br = gccBug(image_bits[y2_offset + x2]);5723 #else5724 uint tl = image_bits[y1_offset + x1];5725 uint tr = image_bits[y1_offset + x2];5726 uint bl = image_bits[y2_offset + x1];5727 uint br = image_bits[y2_offset + x2];5728 #endif5729 5730 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5731 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5732 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5733 ++b;5734 x += fdx;5735 y += fdy;5736 }5737 if (spanMethod == RegularSpans)5738 func(target, buffer, l, coverage);5739 else5740 drawBufferSpan(data, buffer, buffer_size,5741 spans->x + spans->len - length,5742 spans->y, l, coverage);5743 target += l;5744 length -= l;5745 }5746 ++spans;5747 }5748 } else {5749 const qreal fdx = data->m11;5750 const qreal fdy = data->m12;5751 const qreal fdw = data->m13;5752 while (count--) {5753 void *t = data->rasterBuffer->scanLine(spans->y);5754 5755 uint *target = ((uint *)t) + spans->x;5756 uint *image_bits = (uint *)data->texture.imageData;5757 5758 const qreal cx = spans->x + 0.5;5759 const qreal cy = spans->y + 0.5;5760 5761 qreal x = data->m21 * cy + data->m11 * cx + data->dx;5762 qreal y = data->m22 * cy + data->m12 * cx + data->dy;5763 qreal w = data->m23 * cy + data->m13 * cx + data->m33;5764 5765 int length = spans->len;5766 const int coverage = (spans->coverage * data->texture.const_alpha) >> 8;5767 while (length) {5768 int l = qMin(length, buffer_size);5769 const uint *end = buffer + l;5770 uint *b = buffer;5771 while (b < end) {5772 const qreal iw = w == 0 ? 1 : 1 / w;5773 const qreal px = x * iw - 0.5;5774 const qreal py = y * iw - 0.5;5775 5776 int x1 = int(px) - (px < 0);5777 int x2 = x1 + 1;5778 int y1 = int(py) - (py < 0);5779 int y2 = y1 + 1;5780 5781 int distx = int((px - x1) * 256);5782 int disty = int((py - y1) * 256);5783 int idistx = 256 - distx;5784 int idisty = 256 - disty;5785 5786 x1 %= image_width;5787 x2 %= image_width;5788 y1 %= image_height;5789 y2 %= image_height;5790 5791 if (x1 < 0) x1 += image_width;5792 if (x2 < 0) x2 += image_width;5793 if (y1 < 0) y1 += image_height;5794 if (y2 < 0) y2 += image_height;5795 5796 Q_ASSERT(x1 >= 0 && x1 < image_width);5797 Q_ASSERT(x2 >= 0 && x2 < image_width);5798 Q_ASSERT(y1 >= 0 && y1 < image_height);5799 Q_ASSERT(y2 >= 0 && y2 < image_height);5800 5801 int y1_offset = y1 * scanline_offset;5802 int y2_offset = y2 * scanline_offset;5803 5804 #if defined(Q_IRIX_GCC3_3_WORKAROUND)5805 uint tl = gccBug(image_bits[y1_offset + x1]);5806 uint tr = gccBug(image_bits[y1_offset + x2]);5807 uint bl = gccBug(image_bits[y2_offset + x1]);5808 uint br = gccBug(image_bits[y2_offset + x2]);5809 #else5810 uint tl = image_bits[y1_offset + x1];5811 uint tr = image_bits[y1_offset + x2];5812 uint bl = image_bits[y2_offset + x1];5813 uint br = image_bits[y2_offset + x2];5814 #endif5815 5816 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);5817 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);5818 *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);5819 ++b;5820 x += fdx;5821 y += fdy;5822 w += fdw;5823 }5824 if (spanMethod == RegularSpans)5825 func(target, buffer, l, coverage);5826 else5827 drawBufferSpan(data, buffer, buffer_size,5828 spans->x + spans->len - length,5829 spans->y, l, coverage);5830 target += l;5831 length -= l;5832 }5833 ++spans;5834 }5835 }5836 5899 } 5837 5900 … … 6164 6227 void *userData) 6165 6228 { 6166 #if defined(QT_QWS_DEPTH_16)6229 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 6167 6230 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 6168 6231 … … 6480 6543 int py = int(ty) - (ty < 0); 6481 6544 6545 px %= image_width; 6546 py %= image_height; 6482 6547 if (px < 0) 6483 6548 px += image_width; … … 6577 6642 void *userData) 6578 6643 { 6579 #if defined(QT_QWS_DEPTH_16)6644 #if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) 6580 6645 QSpanData *data = reinterpret_cast<QSpanData *>(userData); 6581 6646 … … 6738 6803 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 6739 6804 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 6740 SPANFUNC_POINTER(blend_ transformed_bilinear_argb, RegularSpans), // ARGB32_Premultiplied6805 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied 6741 6806 blend_transformed_bilinear_rgb565, 6742 6807 blend_transformed_bilinear_argb8565, … … 6757 6822 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 6758 6823 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 6759 SPANFUNC_POINTER(blend_ transformed_bilinear_tiled_argb, RegularSpans), // ARGB32_Premultiplied6824 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32_Premultiplied 6760 6825 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16 6761 6826 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied … … 6856 6921 blend_src_generic<CallbackSpans>, // RGB32 6857 6922 blend_src_generic<CallbackSpans>, // ARGB32 6858 blend_ transformed_bilinear_argb<CallbackSpans>, // ARGB32_Premultiplied6923 blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied 6859 6924 blend_src_generic<CallbackSpans>, // RGB16 6860 6925 blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied … … 6875 6940 blend_src_generic<CallbackSpans>, // RGB32 6876 6941 blend_src_generic<CallbackSpans>, // ARGB32 6877 blend_ transformed_bilinear_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied6942 blend_src_generic<CallbackSpans>, // ARGB32_Premultiplied 6878 6943 blend_src_generic<CallbackSpans>, // RGB16 6879 6944 blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied … … 7135 7200 if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) 7136 7201 smoothing = winSmooth / 1000.0; 7202 7203 // Safeguard ourselves against corrupt registry values... 7204 if (smoothing > 5 || smoothing < 1) 7205 smoothing = 1.4; 7206 7137 7207 #endif 7138 7208 … … 7721 7791 qt_memfill16_func qt_memfill16 = qt_memfill16_setup; 7722 7792 7723 enum CPUFeatures {7724 None = 0,7725 MMX = 0x1,7726 MMXEXT = 0x2,7727 MMX3DNOW = 0x4,7728 MMX3DNOWEXT = 0x8,7729 SSE = 0x10,7730 SSE2 = 0x20,7731 CMOV = 0x40,7732 IWMMXT = 0x80,7733 NEON = 0x1007734 };7735 7736 static uint detectCPUFeatures()7737 {7738 #if defined (Q_OS_WINCE)7739 #if defined (ARM)7740 if (IsProcessorFeaturePresent(PF_ARM_INTEL_WMMX))7741 return IWMMXT;7742 #elif defined(_X86_)7743 uint features = 0;7744 #if defined QT_HAVE_MMX7745 if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE))7746 features |= MMX;7747 #endif7748 #if defined QT_HAVE_3DNOW7749 if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE))7750 features |= MMX3DNOW;7751 #endif7752 return features;7753 #endif7754 return 0;7755 #elif defined(QT_HAVE_IWMMXT)7756 // runtime detection only available when running as a previlegied process7757 static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();7758 return doIWMMXT ? IWMMXT : 0;7759 #elif defined(QT_HAVE_NEON)7760 static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();7761 return doNEON ? NEON : 0;7762 #else7763 uint features = 0;7764 #if defined(__x86_64__) || defined(Q_OS_WIN64)7765 features = MMX|SSE|SSE2|CMOV;7766 #elif defined(__ia64__)7767 features = MMX|SSE|SSE2;7768 #elif defined(__i386__) || defined(_M_IX86)7769 unsigned int extended_result = 0;7770 uint result = 0;7771 /* see p. 118 of amd64 instruction set manual Vol3 */7772 #if defined(Q_CC_GNU)7773 asm ("push %%ebx\n"7774 "pushf\n"7775 "pop %%eax\n"7776 "mov %%eax, %%ebx\n"7777 "xor $0x00200000, %%eax\n"7778 "push %%eax\n"7779 "popf\n"7780 "pushf\n"7781 "pop %%eax\n"7782 "xor %%edx, %%edx\n"7783 "xor %%ebx, %%eax\n"7784 "jz 1f\n"7785 7786 "mov $0x00000001, %%eax\n"7787 "cpuid\n"7788 "1:\n"7789 "pop %%ebx\n"7790 "mov %%edx, %0\n"7791 : "=r" (result)7792 :7793 : "%eax", "%ecx", "%edx"7794 );7795 7796 asm ("push %%ebx\n"7797 "pushf\n"7798 "pop %%eax\n"7799 "mov %%eax, %%ebx\n"7800 "xor $0x00200000, %%eax\n"7801 "push %%eax\n"7802 "popf\n"7803 "pushf\n"7804 "pop %%eax\n"7805 "xor %%edx, %%edx\n"7806 "xor %%ebx, %%eax\n"7807 "jz 2f\n"7808 7809 "mov $0x80000000, %%eax\n"7810 "cpuid\n"7811 "cmp $0x80000000, %%eax\n"7812 "jbe 2f\n"7813 "mov $0x80000001, %%eax\n"7814 "cpuid\n"7815 "2:\n"7816 "pop %%ebx\n"7817 "mov %%edx, %0\n"7818 : "=r" (extended_result)7819 :7820 : "%eax", "%ecx", "%edx"7821 );7822 #elif defined (Q_OS_WIN)7823 _asm {7824 push eax7825 push ebx7826 push ecx7827 push edx7828 pushfd7829 pop eax7830 mov ebx, eax7831 xor eax, 00200000h7832 push eax7833 popfd7834 pushfd7835 pop eax7836 mov edx, 07837 xor eax, ebx7838 jz skip7839 7840 mov eax, 17841 cpuid7842 mov result, edx7843 skip:7844 pop edx7845 pop ecx7846 pop ebx7847 pop eax7848 }7849 7850 _asm {7851 push eax7852 push ebx7853 push ecx7854 push edx7855 pushfd7856 pop eax7857 mov ebx, eax7858 xor eax, 00200000h7859 push eax7860 popfd7861 pushfd7862 pop eax7863 mov edx, 07864 xor eax, ebx7865 jz skip27866 7867 mov eax, 80000000h7868 cpuid7869 cmp eax, 80000000h7870 jbe skip27871 mov eax, 80000001h7872 cpuid7873 mov extended_result, edx7874 skip2:7875 pop edx7876 pop ecx7877 pop ebx7878 pop eax7879 }7880 #endif7881 7882 // result now contains the standard feature bits7883 if (result & (1u << 15))7884 features |= CMOV;7885 if (result & (1u << 23))7886 features |= MMX;7887 if (extended_result & (1u << 22))7888 features |= MMXEXT;7889 if (extended_result & (1u << 31))7890 features |= MMX3DNOW;7891 if (extended_result & (1u << 30))7892 features |= MMX3DNOWEXT;7893 if (result & (1u << 25))7894 features |= SSE;7895 if (result & (1u << 26))7896 features |= SSE2;7897 #endif // i3867898 7899 if (qgetenv("QT_NO_MMX").toInt())7900 features ^= MMX;7901 if (qgetenv("QT_NO_MMXEXT").toInt())7902 features ^= MMXEXT;7903 if (qgetenv("QT_NO_3DNOW").toInt())7904 features ^= MMX3DNOW;7905 if (qgetenv("QT_NO_3DNOWEXT").toInt())7906 features ^= MMX3DNOWEXT;7907 if (qgetenv("QT_NO_SSE").toInt())7908 features ^= SSE;7909 if (qgetenv("QT_NO_SSE2").toInt())7910 features ^= SSE2;7911 7912 return features;7913 #endif7914 }7915 7916 #if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6)7917 // Move these to qdrawhelper_arm.c when all7918 // functions are implemented using arm assembly.7919 static CompositionFunctionSolid qt_functionForModeSolid_ARMv6[numCompositionFunctions] = {7920 comp_func_solid_SourceOver,7921 comp_func_solid_DestinationOver,7922 comp_func_solid_Clear,7923 comp_func_solid_Source,7924 comp_func_solid_Destination,7925 comp_func_solid_SourceIn,7926 comp_func_solid_DestinationIn,7927 comp_func_solid_SourceOut,7928 comp_func_solid_DestinationOut,7929 comp_func_solid_SourceAtop,7930 comp_func_solid_DestinationAtop,7931 comp_func_solid_XOR,7932 comp_func_solid_Plus,7933 comp_func_solid_Multiply,7934 comp_func_solid_Screen,7935 comp_func_solid_Overlay,7936 comp_func_solid_Darken,7937 comp_func_solid_Lighten,7938 comp_func_solid_ColorDodge,7939 comp_func_solid_ColorBurn,7940 comp_func_solid_HardLight,7941 comp_func_solid_SoftLight,7942 comp_func_solid_Difference,7943 comp_func_solid_Exclusion,7944 rasterop_solid_SourceOrDestination,7945 rasterop_solid_SourceAndDestination,7946 rasterop_solid_SourceXorDestination,7947 rasterop_solid_NotSourceAndNotDestination,7948 rasterop_solid_NotSourceOrNotDestination,7949 rasterop_solid_NotSourceXorDestination,7950 rasterop_solid_NotSource,7951 rasterop_solid_NotSourceAndDestination,7952 rasterop_solid_SourceAndNotDestination7953 };7954 7955 static CompositionFunction qt_functionForMode_ARMv6[numCompositionFunctions] = {7956 comp_func_SourceOver_armv6,7957 comp_func_DestinationOver,7958 comp_func_Clear,7959 comp_func_Source_armv6,7960 comp_func_Destination,7961 comp_func_SourceIn,7962 comp_func_DestinationIn,7963 comp_func_SourceOut,7964 comp_func_DestinationOut,7965 comp_func_SourceAtop,7966 comp_func_DestinationAtop,7967 comp_func_XOR,7968 comp_func_Plus,7969 comp_func_Multiply,7970 comp_func_Screen,7971 comp_func_Overlay,7972 comp_func_Darken,7973 comp_func_Lighten,7974 comp_func_ColorDodge,7975 comp_func_ColorBurn,7976 comp_func_HardLight,7977 comp_func_SoftLight,7978 comp_func_Difference,7979 comp_func_Exclusion,7980 rasterop_SourceOrDestination,7981 rasterop_SourceAndDestination,7982 rasterop_SourceXorDestination,7983 rasterop_NotSourceAndNotDestination,7984 rasterop_NotSourceOrNotDestination,7985 rasterop_NotSourceXorDestination,7986 rasterop_NotSource,7987 rasterop_NotSourceAndDestination,7988 rasterop_SourceAndNotDestination7989 };7990 7991 static void qt_blend_color_argb_armv6(int count, const QSpan *spans, void *userData)7992 {7993 QSpanData *data = reinterpret_cast<QSpanData *>(userData);7994 7995 CompositionFunctionSolid func = qt_functionForModeSolid_ARMv6[data->rasterBuffer->compositionMode];7996 while (count--) {7997 uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x;7998 func(target, spans->len, data->solid.color, spans->coverage);7999 ++spans;8000 }8001 }8002 8003 #endif // Q_CC_RVCT && QT_HAVE_ARMV68004 8005 8006 7793 void qInitDrawhelperAsm() 8007 7794 { 8008 static uint features = 0xffffffff;8009 if (features != 0xffffffff)8010 return;8011 features = detectCPUFeatures();8012 7795 8013 7796 qt_memfill32 = qt_memfill_template<quint32, quint32>; … … 8017 7800 CompositionFunctionSolid *functionForModeSolidAsm = 0; 8018 7801 8019 #ifdef QT_NO_DEBUG 7802 const uint features = qDetectCPUFeatures(); 8020 7803 if (false) { 8021 7804 #ifdef QT_HAVE_SSE2 … … 8039 7822 #endif 8040 7823 #endif // SSE 8041 #if defined(QT_HAVE_MMXEXT) && defined(QT_HAVE_SSE)8042 } else if (features & MMXEXT) {8043 qt_memfill32 = qt_memfill32_sse;8044 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse;8045 # ifdef QT_HAVE_3DNOW8046 if (features & MMX3DNOW) {8047 qt_memfill32 = qt_memfill32_sse3dnow;8048 qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse3dnow;8049 }8050 # endif // 3DNOW8051 #endif // MMXEXT8052 7824 } 8053 7825 #ifdef QT_HAVE_MMX 8054 7826 if (features & MMX) { 8055 7827 functionForModeAsm = qt_functionForMode_MMX; 7828 8056 7829 functionForModeSolidAsm = qt_functionForModeSolid_MMX; 8057 7830 qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_mmx; … … 8080 7853 } 8081 7854 #endif // MMX 7855 7856 #ifdef QT_HAVE_SSE 7857 if (features & SSE) { 7858 extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl, 7859 const uchar *srcPixels, int sbpl, 7860 int w, int h, 7861 int const_alpha); 7862 extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl, 7863 const uchar *srcPixels, int sbpl, 7864 int w, int h, 7865 int const_alpha); 7866 7867 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 7868 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 7869 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 7870 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 7871 } 7872 #endif // SSE 7873 7874 #ifdef QT_HAVE_SSE2 7875 if (features & SSE2) { 7876 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, 7877 const uchar *srcPixels, int sbpl, 7878 int w, int h, 7879 int const_alpha); 7880 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, 7881 const uchar *srcPixels, int sbpl, 7882 int w, int h, 7883 int const_alpha); 7884 7885 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 7886 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 7887 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 7888 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 7889 } 7890 7891 #ifdef QT_HAVE_SSSE3 7892 if (features & SSSE3) { 7893 extern void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, 7894 const uchar *srcPixels, int sbpl, 7895 int w, int h, 7896 int const_alpha); 7897 7898 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; 7899 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3; 7900 } 7901 #endif // SSSE3 7902 7903 #endif // SSE2 8082 7904 8083 7905 #ifdef QT_HAVE_SSE … … 8097 7919 #ifdef QT_HAVE_SSE2 8098 7920 if (features & SSE2) { 8099 extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, 8100 const uchar *srcPixels, int sbpl, 8101 int w, int h, 8102 int const_alpha); 8103 extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, 8104 const uchar *srcPixels, int sbpl, 8105 int w, int h, 8106 int const_alpha); 8107 8108 8109 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 8110 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; 8111 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 8112 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; 8113 } else 7921 extern void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, 7922 const uint *srcPixels, 7923 int length, 7924 uint const_alpha); 7925 extern void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha); 7926 extern void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha); 7927 extern void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha); 7928 7929 functionForModeAsm[0] = comp_func_SourceOver_sse2; 7930 functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_sse2; 7931 functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_sse2; 7932 functionForModeSolidAsm[0] = comp_func_solid_SourceOver_sse2; 7933 } 8114 7934 #endif 8115 { 8116 extern void qt_blend_rgb32_on_rgb32_sse(uchar *destPixels, int dbpl, 8117 const uchar *srcPixels, int sbpl, 8118 int w, int h, 8119 int const_alpha); 8120 extern void qt_blend_argb32_on_argb32_sse(uchar *destPixels, int dbpl, 8121 const uchar *srcPixels, int sbpl, 8122 int w, int h, 8123 int const_alpha); 8124 8125 8126 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 8127 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse; 8128 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 8129 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse; 8130 } 8131 } 8132 #endif // SSE 7935 } 7936 #elif defined(QT_HAVE_SSE2) 7937 // this is the special case when SSE2 is usable but MMX/SSE is not usable (e.g.: Windows x64 + visual studio) 7938 if (features & SSE2) { 7939 functionForModeAsm = qt_functionForMode_onlySSE2; 7940 functionForModeSolidAsm = qt_functionForModeSolid_onlySSE2; 7941 } 7942 #endif 8133 7943 8134 7944 #ifdef QT_HAVE_IWMMXT … … 8140 7950 #endif // IWMMXT 8141 7951 8142 #endif // QT_NO_DEBUG 8143 8144 #if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6) 8145 functionForModeAsm = qt_functionForMode_ARMv6; 8146 functionForModeSolidAsm = qt_functionForModeSolid_ARMv6; 8147 8148 qt_memfill32 = qt_memfill32_armv6; 8149 8150 qDrawHelper[QImage::Format_ARGB32_Premultiplied].blendColor = qt_blend_color_argb_armv6; 8151 8152 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; 8153 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6; 8154 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; 8155 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6; 7952 #if defined(QT_HAVE_ARM_SIMD) 7953 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; 7954 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_arm_simd; 7955 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; 7956 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_arm_simd; 8156 7957 #elif defined(QT_HAVE_NEON) 8157 if (features & NEON) { 8158 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 8159 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 8160 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 8161 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 8162 } 7958 if (features & NEON) { 7959 qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 7960 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon; 7961 qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 7962 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon; 7963 qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon; 7964 qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon; 7965 qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon; 7966 7967 qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon; 7968 qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon; 7969 7970 qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon; 7971 qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon; 7972 7973 qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon; 7974 7975 functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon; 7976 functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon; 7977 functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon; 7978 destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; 7979 destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; 7980 7981 qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; 7982 qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; 7983 qt_memfill32 = qt_memfill32_neon; 7984 } 8163 7985 #endif 8164 7986 … … 8174 7996 functionForModeSolid = functionForModeSolidAsm; 8175 7997 } 8176 if (functionForModeAsm) { 8177 const int destinationMode = QPainter::CompositionMode_Destination; 8178 functionForModeAsm[destinationMode] = functionForMode_C[destinationMode]; 8179 8180 // use the default qdrawhelper implementation for the 8181 // extended composition modes 8182 for (int mode = 12; mode < numCompositionFunctions; ++mode) 8183 functionForModeAsm[mode] = functionForMode_C[mode]; 8184 7998 if (functionForModeAsm) 8185 7999 functionForMode = functionForModeAsm; 8186 }8187 8000 8188 8001 qt_build_pow_tables(); -
trunk/src/gui/painting/qdrawhelper_iwmmxt.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 107 107 comp_func_Clear<QIWMMXTIntrinsics>, 108 108 comp_func_Source<QIWMMXTIntrinsics>, 109 0,109 comp_func_Destination, 110 110 comp_func_SourceIn<QIWMMXTIntrinsics>, 111 111 comp_func_DestinationIn<QIWMMXTIntrinsics>, … … 114 114 comp_func_SourceAtop<QIWMMXTIntrinsics>, 115 115 comp_func_DestinationAtop<QIWMMXTIntrinsics>, 116 comp_func_XOR<QIWMMXTIntrinsics> 116 comp_func_XOR<QIWMMXTIntrinsics>, 117 comp_func_Plus, 118 comp_func_Multiply, 119 comp_func_Screen, 120 comp_func_Overlay, 121 comp_func_Darken, 122 comp_func_Lighten, 123 comp_func_ColorDodge, 124 comp_func_ColorBurn, 125 comp_func_HardLight, 126 comp_func_SoftLight, 127 comp_func_Difference, 128 comp_func_Exclusion, 129 rasterop_SourceOrDestination, 130 rasterop_SourceAndDestination, 131 rasterop_SourceXorDestination, 132 rasterop_NotSourceAndNotDestination, 133 rasterop_NotSourceOrNotDestination, 134 rasterop_NotSourceXorDestination, 135 rasterop_NotSource, 136 rasterop_NotSourceAndDestination, 137 rasterop_SourceAndNotDestination 117 138 }; 118 139 -
trunk/src/gui/painting/qdrawhelper_mmx.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 78 78 comp_func_Clear<QMMXIntrinsics>, 79 79 comp_func_Source<QMMXIntrinsics>, 80 0,80 comp_func_Destination, 81 81 comp_func_SourceIn<QMMXIntrinsics>, 82 82 comp_func_DestinationIn<QMMXIntrinsics>, … … 86 86 comp_func_DestinationAtop<QMMXIntrinsics>, 87 87 comp_func_XOR<QMMXIntrinsics>, 88 comp_func_Plus, 89 comp_func_Multiply, 90 comp_func_Screen, 91 comp_func_Overlay, 92 comp_func_Darken, 93 comp_func_Lighten, 94 comp_func_ColorDodge, 95 comp_func_ColorBurn, 96 comp_func_HardLight, 97 comp_func_SoftLight, 98 comp_func_Difference, 99 comp_func_Exclusion, 100 rasterop_SourceOrDestination, 101 rasterop_SourceAndDestination, 102 rasterop_SourceXorDestination, 103 rasterop_NotSourceAndNotDestination, 104 rasterop_NotSourceOrNotDestination, 105 rasterop_NotSourceXorDestination, 106 rasterop_NotSource, 107 rasterop_NotSourceAndDestination, 108 rasterop_SourceAndNotDestination 88 109 }; 89 110 -
trunk/src/gui/painting/qdrawhelper_mmx3dnow.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 86 86 comp_func_Clear<QMMX3DNOWIntrinsics>, 87 87 comp_func_Source<QMMX3DNOWIntrinsics>, 88 0,88 comp_func_Destination, 89 89 comp_func_SourceIn<QMMX3DNOWIntrinsics>, 90 90 comp_func_DestinationIn<QMMX3DNOWIntrinsics>, … … 93 93 comp_func_SourceAtop<QMMX3DNOWIntrinsics>, 94 94 comp_func_DestinationAtop<QMMX3DNOWIntrinsics>, 95 comp_func_XOR<QMMX3DNOWIntrinsics> 95 comp_func_XOR<QMMX3DNOWIntrinsics>, 96 comp_func_Plus, 97 comp_func_Multiply, 98 comp_func_Screen, 99 comp_func_Overlay, 100 comp_func_Darken, 101 comp_func_Lighten, 102 comp_func_ColorDodge, 103 comp_func_ColorBurn, 104 comp_func_HardLight, 105 comp_func_SoftLight, 106 comp_func_Difference, 107 comp_func_Exclusion, 108 rasterop_SourceOrDestination, 109 rasterop_SourceAndDestination, 110 rasterop_SourceXorDestination, 111 rasterop_NotSourceAndNotDestination, 112 rasterop_NotSourceOrNotDestination, 113 rasterop_NotSourceXorDestination, 114 rasterop_NotSource, 115 rasterop_NotSourceAndDestination, 116 rasterop_SourceAndNotDestination 96 117 }; 97 118 -
trunk/src/gui/painting/qdrawhelper_mmx_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qdrawhelper_neon.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 41 41 42 42 #include <private/qdrawhelper_p.h> 43 #include <private/qblendfunctions_p.h> 44 #include <private/qmath_p.h> 43 45 44 46 #ifdef QT_HAVE_NEON 45 47 46 48 #include <private/qdrawhelper_neon_p.h> 49 #include <private/qpaintengine_raster_p.h> 47 50 #include <arm_neon.h> 48 51 49 52 QT_BEGIN_NAMESPACE 53 54 void qt_memfill32_neon(quint32 *dest, quint32 value, int count) 55 { 56 const int epilogueSize = count % 16; 57 if (count >= 16) { 58 quint32 *const neonEnd = dest + count - epilogueSize; 59 register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value); 60 register uint32x4_t valueVector2 asm ("q1") = valueVector1; 61 while (dest != neonEnd) { 62 asm volatile ( 63 "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t" 64 "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t" 65 : [DST]"+r" (dest) 66 : [VALUE1]"w"(valueVector1), [VALUE2]"w"(valueVector2) 67 : "memory" 68 ); 69 } 70 } 71 72 switch (epilogueSize) 73 { 74 case 15: *dest++ = value; 75 case 14: *dest++ = value; 76 case 13: *dest++ = value; 77 case 12: *dest++ = value; 78 case 11: *dest++ = value; 79 case 10: *dest++ = value; 80 case 9: *dest++ = value; 81 case 8: *dest++ = value; 82 case 7: *dest++ = value; 83 case 6: *dest++ = value; 84 case 5: *dest++ = value; 85 case 4: *dest++ = value; 86 case 3: *dest++ = value; 87 case 2: *dest++ = value; 88 case 1: *dest++ = value; 89 } 90 } 50 91 51 92 static inline uint16x8_t qvdiv_255_u16(uint16x8_t x, uint16x8_t half) … … 86 127 87 128 return vaddq_u16(src16, qvbyte_mul_u16(dst16, alpha16, half)); 129 } 130 131 extern "C" void 132 pixman_composite_over_8888_0565_asm_neon (int32_t w, 133 int32_t h, 134 uint16_t *dst, 135 int32_t dst_stride, 136 uint32_t *src, 137 int32_t src_stride); 138 139 extern "C" void 140 pixman_composite_over_8888_8888_asm_neon (int32_t w, 141 int32_t h, 142 uint32_t *dst, 143 int32_t dst_stride, 144 uint32_t *src, 145 int32_t src_stride); 146 147 extern "C" void 148 pixman_composite_src_0565_8888_asm_neon (int32_t w, 149 int32_t h, 150 uint32_t *dst, 151 int32_t dst_stride, 152 uint16_t *src, 153 int32_t src_stride); 154 155 extern "C" void 156 pixman_composite_over_n_8_0565_asm_neon (int32_t w, 157 int32_t h, 158 uint16_t *dst, 159 int32_t dst_stride, 160 uint32_t src, 161 int32_t unused, 162 uint8_t *mask, 163 int32_t mask_stride); 164 165 extern "C" void 166 pixman_composite_scanline_over_asm_neon (int32_t w, 167 const uint32_t *dst, 168 const uint32_t *src); 169 170 extern "C" void 171 pixman_composite_src_0565_0565_asm_neon (int32_t w, 172 int32_t h, 173 uint16_t *dst, 174 int32_t dst_stride, 175 uint16_t *src, 176 int32_t src_stride); 177 178 // qblendfunctions.cpp 179 void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl, 180 const uchar *srcPixels, int sbpl, 181 int w, int h, 182 int const_alpha); 183 184 void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, 185 const uchar *srcPixels, int sbpl, 186 int w, int h, 187 int const_alpha) 188 { 189 dbpl /= 4; 190 sbpl /= 2; 191 192 quint32 *dst = (quint32 *) destPixels; 193 quint16 *src = (quint16 *) srcPixels; 194 195 if (const_alpha != 256) { 196 quint8 a = (255 * const_alpha) >> 8; 197 quint8 ia = 255 - a; 198 199 while (h--) { 200 for (int x=0; x<w; ++x) 201 dst[x] = INTERPOLATE_PIXEL_255(qt_colorConvert(src[x], dst[x]), a, dst[x], ia); 202 dst += dbpl; 203 src += sbpl; 204 } 205 return; 206 } 207 208 pixman_composite_src_0565_8888_asm_neon(w, h, dst, dbpl, src, sbpl); 209 } 210 211 // qblendfunctions.cpp 212 void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl, 213 const uchar *src, int sbpl, 214 int w, int h, 215 int const_alpha); 216 217 template <int N> 218 static inline void scanLineBlit16(quint16 *dst, quint16 *src, int dstride) 219 { 220 if (N >= 2) { 221 ((quint32 *)dst)[0] = ((quint32 *)src)[0]; 222 __builtin_prefetch(dst + dstride, 1, 0); 223 } 224 for (int i = 1; i < N/2; ++i) 225 ((quint32 *)dst)[i] = ((quint32 *)src)[i]; 226 if (N & 1) 227 dst[N-1] = src[N-1]; 228 } 229 230 template <int Width> 231 static inline void blockBlit16(quint16 *dst, quint16 *src, int dstride, int sstride, int h) 232 { 233 union { 234 quintptr address; 235 quint16 *pointer; 236 } u; 237 238 u.pointer = dst; 239 240 if (u.address & 2) { 241 while (h--) { 242 // align dst 243 dst[0] = src[0]; 244 if (Width > 1) 245 scanLineBlit16<Width-1>(dst + 1, src + 1, dstride); 246 dst += dstride; 247 src += sstride; 248 } 249 } else { 250 while (h--) { 251 scanLineBlit16<Width>(dst, src, dstride); 252 253 dst += dstride; 254 src += sstride; 255 } 256 } 257 } 258 259 void qt_blend_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, 260 const uchar *srcPixels, int sbpl, 261 int w, int h, 262 int const_alpha) 263 { 264 // testing show that the default memcpy is faster for widths 150 and up 265 if (const_alpha != 256 || w >= 150) { 266 qt_blend_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha); 267 return; 268 } 269 270 int dstride = dbpl / 2; 271 int sstride = sbpl / 2; 272 273 quint16 *dst = (quint16 *) destPixels; 274 quint16 *src = (quint16 *) srcPixels; 275 276 switch (w) { 277 #define BLOCKBLIT(n) case n: blockBlit16<n>(dst, src, dstride, sstride, h); return; 278 BLOCKBLIT(1); 279 BLOCKBLIT(2); 280 BLOCKBLIT(3); 281 BLOCKBLIT(4); 282 BLOCKBLIT(5); 283 BLOCKBLIT(6); 284 BLOCKBLIT(7); 285 BLOCKBLIT(8); 286 BLOCKBLIT(9); 287 BLOCKBLIT(10); 288 BLOCKBLIT(11); 289 BLOCKBLIT(12); 290 BLOCKBLIT(13); 291 BLOCKBLIT(14); 292 BLOCKBLIT(15); 293 #undef BLOCKBLIT 294 default: 295 break; 296 } 297 298 pixman_composite_src_0565_0565_asm_neon (w, h, dst, dstride, src, sstride); 299 } 300 301 extern "C" void blend_8_pixels_argb32_on_rgb16_neon(quint16 *dst, const quint32 *src, int const_alpha); 302 303 void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, 304 const uchar *srcPixels, int sbpl, 305 int w, int h, 306 int const_alpha) 307 { 308 quint16 *dst = (quint16 *) destPixels; 309 quint32 *src = (quint32 *) srcPixels; 310 311 if (const_alpha != 256) { 312 for (int y=0; y<h; ++y) { 313 int i = 0; 314 for (; i < w-7; i += 8) 315 blend_8_pixels_argb32_on_rgb16_neon(&dst[i], &src[i], const_alpha); 316 317 if (i < w) { 318 int tail = w - i; 319 320 quint16 dstBuffer[8]; 321 quint32 srcBuffer[8]; 322 323 for (int j = 0; j < tail; ++j) { 324 dstBuffer[j] = dst[i + j]; 325 srcBuffer[j] = src[i + j]; 326 } 327 328 blend_8_pixels_argb32_on_rgb16_neon(dstBuffer, srcBuffer, const_alpha); 329 330 for (int j = 0; j < tail; ++j) { 331 dst[i + j] = dstBuffer[j]; 332 src[i + j] = srcBuffer[j]; 333 } 334 } 335 336 dst = (quint16 *)(((uchar *) dst) + dbpl); 337 src = (quint32 *)(((uchar *) src) + sbpl); 338 } 339 return; 340 } 341 342 pixman_composite_over_8888_0565_asm_neon(w, h, dst, dbpl / 2, src, sbpl / 4); 343 } 344 345 void qt_blend_argb32_on_argb32_scanline_neon(uint *dest, const uint *src, int length, uint const_alpha) 346 { 347 if (const_alpha == 255) { 348 pixman_composite_scanline_over_asm_neon(length, dest, src); 349 } else { 350 qt_blend_argb32_on_argb32_neon((uchar *)dest, 4 * length, (uchar *)src, 4 * length, length, 1, (const_alpha * 256) / 255); 351 } 88 352 } 89 353 … … 98 362 uint16x8_t full = vdupq_n_u16(0xff); 99 363 if (const_alpha == 256) { 100 for (int y = 0; y < h; ++y) { 101 int x = 0; 102 for (; x < w-3; x += 4) { 103 uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); 104 if ((src[x] & src[x+1] & src[x+2] & src[x+3]) >= 0xff000000) { 105 // all opaque 106 vst1q_u32((uint32_t *)&dst[x], src32); 107 } else if (src[x] | src[x+1] | src[x+2] | src[x+3]) { 108 uint32x4_t dst32 = vld1q_u32((uint32_t *)&dst[x]); 109 110 const uint8x16_t src8 = vreinterpretq_u8_u32(src32); 111 const uint8x16_t dst8 = vreinterpretq_u8_u32(dst32); 112 113 const uint8x8_t src8_low = vget_low_u8(src8); 114 const uint8x8_t dst8_low = vget_low_u8(dst8); 115 116 const uint8x8_t src8_high = vget_high_u8(src8); 117 const uint8x8_t dst8_high = vget_high_u8(dst8); 118 119 const uint16x8_t src16_low = vmovl_u8(src8_low); 120 const uint16x8_t dst16_low = vmovl_u8(dst8_low); 121 122 const uint16x8_t src16_high = vmovl_u8(src8_high); 123 const uint16x8_t dst16_high = vmovl_u8(dst8_high); 124 125 const uint16x8_t result16_low = qvsource_over_u16(src16_low, dst16_low, half, full); 126 const uint16x8_t result16_high = qvsource_over_u16(src16_high, dst16_high, half, full); 127 128 const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); 129 const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); 130 131 vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); 132 } 133 } 134 for (; x<w; ++x) { 135 uint s = src[x]; 136 if (s >= 0xff000000) 137 dst[x] = s; 138 else if (s != 0) 139 dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); 140 } 141 dst = (quint32 *)(((uchar *) dst) + dbpl); 142 src = (const quint32 *)(((const uchar *) src) + sbpl); 143 } 364 pixman_composite_over_8888_8888_asm_neon(w, h, (uint32_t *)destPixels, dbpl / 4, (uint32_t *)srcPixels, sbpl / 4); 144 365 } else if (const_alpha != 0) { 145 366 const_alpha = (const_alpha * 255) >> 8; … … 255 476 } 256 477 478 void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, 479 int x, int y, quint32 color, 480 const uchar *bitmap, 481 int mapWidth, int mapHeight, int mapStride, 482 const QClipData *) 483 { 484 quint16 *dest = reinterpret_cast<quint16*>(rasterBuffer->scanLine(y)) + x; 485 const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint16); 486 487 uchar *mask = const_cast<uchar *>(bitmap); 488 489 pixman_composite_over_n_8_0565_asm_neon(mapWidth, mapHeight, dest, destStride, color, 0, mask, mapStride); 490 } 491 492 extern "C" void blend_8_pixels_rgb16_on_rgb16_neon(quint16 *dst, const quint16 *src, int const_alpha); 493 494 template <typename SRC, typename BlendFunc> 495 struct Blend_on_RGB16_SourceAndConstAlpha_Neon { 496 Blend_on_RGB16_SourceAndConstAlpha_Neon(BlendFunc blender, int const_alpha) 497 : m_index(0) 498 , m_blender(blender) 499 , m_const_alpha(const_alpha) 500 { 501 } 502 503 inline void write(quint16 *dst, quint32 src) 504 { 505 srcBuffer[m_index++] = src; 506 507 if (m_index == 8) { 508 m_blender(dst - 7, srcBuffer, m_const_alpha); 509 m_index = 0; 510 } 511 } 512 513 inline void flush(quint16 *dst) 514 { 515 if (m_index > 0) { 516 quint16 dstBuffer[8]; 517 for (int i = 0; i < m_index; ++i) 518 dstBuffer[i] = dst[i - m_index]; 519 520 m_blender(dstBuffer, srcBuffer, m_const_alpha); 521 522 for (int i = 0; i < m_index; ++i) 523 dst[i - m_index] = dstBuffer[i]; 524 525 m_index = 0; 526 } 527 } 528 529 SRC srcBuffer[8]; 530 531 int m_index; 532 BlendFunc m_blender; 533 int m_const_alpha; 534 }; 535 536 template <typename SRC, typename BlendFunc> 537 Blend_on_RGB16_SourceAndConstAlpha_Neon<SRC, BlendFunc> 538 Blend_on_RGB16_SourceAndConstAlpha_Neon_create(BlendFunc blender, int const_alpha) 539 { 540 return Blend_on_RGB16_SourceAndConstAlpha_Neon<SRC, BlendFunc>(blender, const_alpha); 541 } 542 543 void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, 544 const uchar *srcPixels, int sbpl, 545 const QRectF &targetRect, 546 const QRectF &sourceRect, 547 const QRect &clip, 548 int const_alpha) 549 { 550 if (const_alpha == 0) 551 return; 552 553 qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, 554 Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint32>(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); 555 } 556 557 void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, 558 const uchar *srcPixels, int sbpl, 559 const QRectF &targetRect, 560 const QRectF &sourceRect, 561 const QRect &clip, 562 int const_alpha); 563 564 void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, 565 const uchar *srcPixels, int sbpl, 566 const QRectF &targetRect, 567 const QRectF &sourceRect, 568 const QRect &clip, 569 int const_alpha) 570 { 571 if (const_alpha == 0) 572 return; 573 574 if (const_alpha == 256) { 575 qt_scale_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, const_alpha); 576 return; 577 } 578 579 qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, 580 Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint16>(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha)); 581 } 582 583 extern void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, 584 const uchar *srcPixels, int sbpl, 585 const QRectF &targetRect, 586 const QRectF &sourceRect, 587 const QRect &clip, 588 const QTransform &targetRectTransform, 589 int const_alpha); 590 591 void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, 592 const uchar *srcPixels, int sbpl, 593 const QRectF &targetRect, 594 const QRectF &sourceRect, 595 const QRect &clip, 596 const QTransform &targetRectTransform, 597 int const_alpha) 598 { 599 if (const_alpha == 0) 600 return; 601 602 if (const_alpha == 256) { 603 qt_transform_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, targetRectTransform, const_alpha); 604 return; 605 } 606 607 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 608 reinterpret_cast<const quint16 *>(srcPixels), sbpl, targetRect, sourceRect, clip, targetRectTransform, 609 Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint16>(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha)); 610 } 611 612 void qt_transform_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, 613 const uchar *srcPixels, int sbpl, 614 const QRectF &targetRect, 615 const QRectF &sourceRect, 616 const QRect &clip, 617 const QTransform &targetRectTransform, 618 int const_alpha) 619 { 620 if (const_alpha == 0) 621 return; 622 623 qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl, 624 reinterpret_cast<const quint32 *>(srcPixels), sbpl, targetRect, sourceRect, clip, targetRectTransform, 625 Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint32>(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); 626 } 627 628 static inline void convert_8_pixels_rgb16_to_argb32(quint32 *dst, const quint16 *src) 629 { 630 asm volatile ( 631 "vld1.16 { d0, d1 }, [%[SRC]]\n\t" 632 633 /* convert 8 r5g6b5 pixel data from {d0, d1} to planar 8-bit format 634 and put data into d4 - red, d3 - green, d2 - blue */ 635 "vshrn.u16 d4, q0, #8\n\t" 636 "vshrn.u16 d3, q0, #3\n\t" 637 "vsli.u16 q0, q0, #5\n\t" 638 "vsri.u8 d4, d4, #5\n\t" 639 "vsri.u8 d3, d3, #6\n\t" 640 "vshrn.u16 d2, q0, #2\n\t" 641 642 /* fill d5 - alpha with 0xff */ 643 "mov r2, #255\n\t" 644 "vdup.8 d5, r2\n\t" 645 646 "vst4.8 { d2, d3, d4, d5 }, [%[DST]]" 647 : : [DST]"r" (dst), [SRC]"r" (src) 648 : "memory", "r2", "d0", "d1", "d2", "d3", "d4", "d5" 649 ); 650 } 651 652 uint * QT_FASTCALL qt_destFetchRGB16_neon(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) 653 { 654 const ushort *data = (const ushort *)rasterBuffer->scanLine(y) + x; 655 656 int i = 0; 657 for (; i < length - 7; i += 8) 658 convert_8_pixels_rgb16_to_argb32(&buffer[i], &data[i]); 659 660 if (i < length) { 661 quint16 srcBuffer[8]; 662 quint32 dstBuffer[8]; 663 664 int tail = length - i; 665 for (int j = 0; j < tail; ++j) 666 srcBuffer[j] = data[i + j]; 667 668 convert_8_pixels_rgb16_to_argb32(dstBuffer, srcBuffer); 669 670 for (int j = 0; j < tail; ++j) 671 buffer[i + j] = dstBuffer[j]; 672 } 673 674 return buffer; 675 } 676 677 static inline void convert_8_pixels_argb32_to_rgb16(quint16 *dst, const quint32 *src) 678 { 679 asm volatile ( 680 "vld4.8 { d0, d1, d2, d3 }, [%[SRC]]\n\t" 681 682 /* convert to r5g6b5 and store it into {d28, d29} */ 683 "vshll.u8 q14, d2, #8\n\t" 684 "vshll.u8 q8, d1, #8\n\t" 685 "vshll.u8 q9, d0, #8\n\t" 686 "vsri.u16 q14, q8, #5\n\t" 687 "vsri.u16 q14, q9, #11\n\t" 688 689 "vst1.16 { d28, d29 }, [%[DST]]" 690 : : [DST]"r" (dst), [SRC]"r" (src) 691 : "memory", "d0", "d1", "d2", "d3", "d16", "d17", "d18", "d19", "d28", "d29" 692 ); 693 } 694 695 void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) 696 { 697 quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x; 698 699 int i = 0; 700 for (; i < length - 7; i += 8) 701 convert_8_pixels_argb32_to_rgb16(&data[i], &buffer[i]); 702 703 if (i < length) { 704 quint32 srcBuffer[8]; 705 quint16 dstBuffer[8]; 706 707 int tail = length - i; 708 for (int j = 0; j < tail; ++j) 709 srcBuffer[j] = buffer[i + j]; 710 711 convert_8_pixels_argb32_to_rgb16(dstBuffer, srcBuffer); 712 713 for (int j = 0; j < tail; ++j) 714 data[i + j] = dstBuffer[j]; 715 } 716 } 717 718 void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha) 719 { 720 if ((const_alpha & qAlpha(color)) == 255) { 721 QT_MEMFILL_UINT(destPixels, length, color); 722 } else { 723 if (const_alpha != 255) 724 color = BYTE_MUL(color, const_alpha); 725 726 const quint32 minusAlphaOfColor = qAlpha(~color); 727 int x = 0; 728 729 uint32_t *dst = (uint32_t *) destPixels; 730 const uint32x4_t colorVector = vdupq_n_u32(color); 731 uint16x8_t half = vdupq_n_u16(0x80); 732 const uint16x8_t minusAlphaOfColorVector = vdupq_n_u16(minusAlphaOfColor); 733 734 for (; x < length-3; x += 4) { 735 uint32x4_t dstVector = vld1q_u32(&dst[x]); 736 737 const uint8x16_t dst8 = vreinterpretq_u8_u32(dstVector); 738 739 const uint8x8_t dst8_low = vget_low_u8(dst8); 740 const uint8x8_t dst8_high = vget_high_u8(dst8); 741 742 const uint16x8_t dst16_low = vmovl_u8(dst8_low); 743 const uint16x8_t dst16_high = vmovl_u8(dst8_high); 744 745 const uint16x8_t result16_low = qvbyte_mul_u16(dst16_low, minusAlphaOfColorVector, half); 746 const uint16x8_t result16_high = qvbyte_mul_u16(dst16_high, minusAlphaOfColorVector, half); 747 748 const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result16_low)); 749 const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result16_high)); 750 751 uint32x4_t blendedPixels = vcombine_u32(result32_low, result32_high); 752 uint32x4_t colorPlusBlendedPixels = vaddq_u32(colorVector, blendedPixels); 753 vst1q_u32(&dst[x], colorPlusBlendedPixels); 754 } 755 756 for (;x < length; ++x) 757 destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); 758 } 759 } 760 761 void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha) 762 { 763 if (const_alpha == 255) { 764 uint *const end = dst + length; 765 uint *const neonEnd = end - 3; 766 767 while (dst < neonEnd) { 768 asm volatile ( 769 "vld2.8 { d0, d1 }, [%[SRC]] !\n\t" 770 "vld2.8 { d2, d3 }, [%[DST]]\n\t" 771 "vqadd.u8 q0, q0, q1\n\t" 772 "vst2.8 { d0, d1 }, [%[DST]] !\n\t" 773 : [DST]"+r" (dst), [SRC]"+r" (src) 774 : 775 : "memory", "d0", "d1", "d2", "d3", "q0", "q1" 776 ); 777 } 778 779 while (dst != end) { 780 *dst = comp_func_Plus_one_pixel(*dst, *src); 781 ++dst; 782 ++src; 783 } 784 } else { 785 int x = 0; 786 const int one_minus_const_alpha = 255 - const_alpha; 787 const uint16x8_t constAlphaVector = vdupq_n_u16(const_alpha); 788 const uint16x8_t oneMinusconstAlphaVector = vdupq_n_u16(one_minus_const_alpha); 789 790 const uint16x8_t half = vdupq_n_u16(0x80); 791 for (; x < length - 3; x += 4) { 792 const uint32x4_t src32 = vld1q_u32((uint32_t *)&src[x]); 793 const uint8x16_t src8 = vreinterpretq_u8_u32(src32); 794 uint8x16_t dst8 = vld1q_u8((uint8_t *)&dst[x]); 795 uint8x16_t result = vqaddq_u8(dst8, src8); 796 797 uint16x8_t result_low = vmovl_u8(vget_low_u8(result)); 798 uint16x8_t result_high = vmovl_u8(vget_high_u8(result)); 799 800 uint16x8_t dst_low = vmovl_u8(vget_low_u8(dst8)); 801 uint16x8_t dst_high = vmovl_u8(vget_high_u8(dst8)); 802 803 result_low = qvinterpolate_pixel_255(result_low, constAlphaVector, dst_low, oneMinusconstAlphaVector, half); 804 result_high = qvinterpolate_pixel_255(result_high, constAlphaVector, dst_high, oneMinusconstAlphaVector, half); 805 806 const uint32x2_t result32_low = vreinterpret_u32_u8(vmovn_u16(result_low)); 807 const uint32x2_t result32_high = vreinterpret_u32_u8(vmovn_u16(result_high)); 808 vst1q_u32((uint32_t *)&dst[x], vcombine_u32(result32_low, result32_high)); 809 } 810 811 for (; x < length; ++x) 812 dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha); 813 } 814 } 815 816 static const int tileSize = 32; 817 818 extern "C" void qt_rotate90_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count); 819 820 void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sstride, uchar *destPixels, int dstride) 821 { 822 const ushort *src = (const ushort *)srcPixels; 823 ushort *dest = (ushort *)destPixels; 824 825 sstride /= sizeof(ushort); 826 dstride /= sizeof(ushort); 827 828 const int pack = sizeof(quint32) / sizeof(ushort); 829 const int unaligned = 830 qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(ushort)), uint(h)); 831 const int restX = w % tileSize; 832 const int restY = (h - unaligned) % tileSize; 833 const int unoptimizedY = restY % pack; 834 const int numTilesX = w / tileSize + (restX > 0); 835 const int numTilesY = (h - unaligned) / tileSize + (restY >= pack); 836 837 for (int tx = 0; tx < numTilesX; ++tx) { 838 const int startx = w - tx * tileSize - 1; 839 const int stopx = qMax(startx - tileSize, 0); 840 841 if (unaligned) { 842 for (int x = startx; x >= stopx; --x) { 843 ushort *d = dest + (w - x - 1) * dstride; 844 for (int y = 0; y < unaligned; ++y) { 845 *d++ = src[y * sstride + x]; 846 } 847 } 848 } 849 850 for (int ty = 0; ty < numTilesY; ++ty) { 851 const int starty = ty * tileSize + unaligned; 852 const int stopy = qMin(starty + tileSize, h - unoptimizedY); 853 854 int x = startx; 855 // qt_rotate90_16_neon writes to eight rows, four pixels at a time 856 for (; x >= stopx + 7; x -= 8) { 857 ushort *d = dest + (w - x - 1) * dstride + starty; 858 const ushort *s = &src[starty * sstride + x - 7]; 859 qt_rotate90_16_neon(d, s, sstride * 2, dstride * 2, stopy - starty); 860 } 861 862 for (; x >= stopx; --x) { 863 quint32 *d = reinterpret_cast<quint32*>(dest + (w - x - 1) * dstride + starty); 864 for (int y = starty; y < stopy; y += pack) { 865 quint32 c = src[y * sstride + x]; 866 for (int i = 1; i < pack; ++i) { 867 const int shift = (sizeof(int) * 8 / pack * i); 868 const ushort color = src[(y + i) * sstride + x]; 869 c |= color << shift; 870 } 871 *d++ = c; 872 } 873 } 874 } 875 876 if (unoptimizedY) { 877 const int starty = h - unoptimizedY; 878 for (int x = startx; x >= stopx; --x) { 879 ushort *d = dest + (w - x - 1) * dstride + starty; 880 for (int y = starty; y < h; ++y) { 881 *d++ = src[y * sstride + x]; 882 } 883 } 884 } 885 } 886 } 887 888 extern "C" void qt_rotate270_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count); 889 890 void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, 891 int sstride, 892 uchar *destPixels, int dstride) 893 { 894 const ushort *src = (const ushort *)srcPixels; 895 ushort *dest = (ushort *)destPixels; 896 897 sstride /= sizeof(ushort); 898 dstride /= sizeof(ushort); 899 900 const int pack = sizeof(quint32) / sizeof(ushort); 901 const int unaligned = 902 qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(ushort)), uint(h)); 903 const int restX = w % tileSize; 904 const int restY = (h - unaligned) % tileSize; 905 const int unoptimizedY = restY % pack; 906 const int numTilesX = w / tileSize + (restX > 0); 907 const int numTilesY = (h - unaligned) / tileSize + (restY >= pack); 908 909 for (int tx = 0; tx < numTilesX; ++tx) { 910 const int startx = tx * tileSize; 911 const int stopx = qMin(startx + tileSize, w); 912 913 if (unaligned) { 914 for (int x = startx; x < stopx; ++x) { 915 ushort *d = dest + x * dstride; 916 for (int y = h - 1; y >= h - unaligned; --y) { 917 *d++ = src[y * sstride + x]; 918 } 919 } 920 } 921 922 for (int ty = 0; ty < numTilesY; ++ty) { 923 const int starty = h - 1 - unaligned - ty * tileSize; 924 const int stopy = qMax(starty - tileSize, unoptimizedY); 925 926 int x = startx; 927 // qt_rotate90_16_neon writes to eight rows, four pixels at a time 928 for (; x < stopx - 7; x += 8) { 929 ushort *d = dest + x * dstride + h - 1 - starty; 930 const ushort *s = &src[starty * sstride + x]; 931 qt_rotate90_16_neon(d + 7 * dstride, s, -sstride * 2, -dstride * 2, starty - stopy); 932 } 933 934 for (; x < stopx; ++x) { 935 quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride 936 + h - 1 - starty); 937 for (int y = starty; y > stopy; y -= pack) { 938 quint32 c = src[y * sstride + x]; 939 for (int i = 1; i < pack; ++i) { 940 const int shift = (sizeof(int) * 8 / pack * i); 941 const ushort color = src[(y - i) * sstride + x]; 942 c |= color << shift; 943 } 944 *d++ = c; 945 } 946 } 947 } 948 if (unoptimizedY) { 949 const int starty = unoptimizedY - 1; 950 for (int x = startx; x < stopx; ++x) { 951 ushort *d = dest + x * dstride + h - 1 - starty; 952 for (int y = starty; y >= 0; --y) { 953 *d++ = src[y * sstride + x]; 954 } 955 } 956 } 957 } 958 } 959 257 960 QT_END_NAMESPACE 258 961 -
trunk/src/gui/painting/qdrawhelper_neon_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 70 70 int const_alpha); 71 71 72 void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, 73 const uchar *srcPixels, int sbpl, 74 int w, int h, 75 int const_alpha); 76 77 void qt_blend_argb32_on_argb32_scanline_neon(uint *dest, 78 const uint *src, 79 int length, 80 uint const_alpha); 81 82 void qt_blend_rgb16_on_argb32_neon(uchar *destPixels, int dbpl, 83 const uchar *srcPixels, int sbpl, 84 int w, int h, 85 int const_alpha); 86 87 void qt_blend_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, 88 const uchar *srcPixels, int sbpl, 89 int w, int h, 90 int const_alpha); 91 92 void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer, 93 int x, int y, quint32 color, 94 const uchar *bitmap, 95 int mapWidth, int mapHeight, int mapStride, 96 const QClipData *clip); 97 98 void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, 99 const uchar *srcPixels, int sbpl, 100 const QRectF &targetRect, 101 const QRectF &sourceRect, 102 const QRect &clip, 103 int const_alpha); 104 105 void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, 106 const uchar *srcPixels, int sbpl, 107 const QRectF &targetRect, 108 const QRectF &sourceRect, 109 const QRect &clip, 110 int const_alpha); 111 112 void qt_transform_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, 113 const uchar *srcPixels, int sbpl, 114 const QRectF &targetRect, 115 const QRectF &sourceRect, 116 const QRect &clip, 117 const QTransform &targetRectTransform, 118 int const_alpha); 119 120 void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, 121 const uchar *srcPixels, int sbpl, 122 const QRectF &targetRect, 123 const QRectF &sourceRect, 124 const QRect &clip, 125 const QTransform &targetRectTransform, 126 int const_alpha); 127 128 void qt_memfill32_neon(quint32 *dest, quint32 value, int count); 129 void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); 130 void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); 131 132 uint * QT_FASTCALL qt_destFetchRGB16_neon(uint *buffer, 133 QRasterBuffer *rasterBuffer, 134 int x, int y, int length); 135 136 void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, 137 int x, int y, const uint *buffer, int length); 138 139 void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha); 140 void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha); 141 72 142 #endif // QT_HAVE_NEON 73 143 -
trunk/src/gui/painting/qdrawhelper_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 63 63 #endif 64 64 #include "private/qrasterdefs_p.h" 65 #include <private/qsimd_p.h> 65 66 66 67 #ifdef Q_WS_QWS 67 68 #include "QtGui/qscreen_qws.h" 68 #endif69 70 // Disable MMX and SSE on Mac/PPC builds, or if the compiler71 // does not support -Xarch argument passing72 #if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__)))73 #undef QT_HAVE_SSE274 #undef QT_HAVE_SSE75 #undef QT_HAVE_3DNOW76 #undef QT_HAVE_MMX77 69 #endif 78 70 … … 93 85 # define Q_STATIC_INLINE_FUNCTION static inline 94 86 #endif 87 88 static const uint AMASK = 0xff000000; 89 static const uint RMASK = 0x00ff0000; 90 static const uint GMASK = 0x0000ff00; 91 static const uint BMASK = 0x000000ff; 95 92 96 93 /******************************************************************************* … … 155 152 int const_alpha); 156 153 154 typedef void (*MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); 157 155 158 156 struct DrawHelper { … … 168 166 extern SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats]; 169 167 extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats]; 168 extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3]; 170 169 171 170 extern DrawHelper qDrawHelper[QImage::NImageFormats]; … … 310 309 }; 311 310 312 313 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) { 314 a += 1; 315 uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0; 316 t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f; 317 return t; 318 } 319 320 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) { 321 uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0; 322 t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f; 323 return t; 311 #if defined(Q_CC_RVCT) 312 # pragma push 313 # pragma arm 314 #endif 315 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) { 316 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; 317 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; 318 t &= 0xff00ff; 319 320 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; 321 x = (x + ((x >> 8) & 0xff00ff) + 0x800080); 322 x &= 0xff00ff00; 323 x |= t; 324 return x; 325 } 326 #if defined(Q_CC_RVCT) 327 # pragma pop 328 #endif 329 330 #if QT_POINTER_SIZE == 8 // 64-bit versions 331 332 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { 333 quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; 334 t += (((quint64(y)) | ((quint64(y)) << 24)) & 0x00ff00ff00ff00ff) * b; 335 t >>= 8; 336 t &= 0x00ff00ff00ff00ff; 337 return (uint(t)) | (uint(t >> 24)); 338 } 339 340 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) { 341 quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; 342 t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8; 343 t &= 0x00ff00ff00ff00ff; 344 return (uint(t)) | (uint(t >> 24)); 345 } 346 347 Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) { 348 uint a = x >> 24; 349 quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; 350 t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8; 351 t &= 0x000000ff00ff00ff; 352 return (uint(t)) | (uint(t >> 24)) | (a << 24); 353 } 354 355 #else // 32-bit versions 356 357 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { 358 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; 359 t >>= 8; 360 t &= 0xff00ff; 361 362 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; 363 x &= 0xff00ff00; 364 x |= t; 365 return x; 324 366 } 325 367 … … 354 396 x |= t | (a << 24); 355 397 return x; 398 } 399 #endif 400 401 402 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) { 403 a += 1; 404 uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0; 405 t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f; 406 return t; 407 } 408 409 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) { 410 uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0; 411 t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f; 412 return t; 356 413 } 357 414 … … 1628 1685 QT_TRIVIAL_MEMCONVERT_IMPL(qrgb666) 1629 1686 QT_TRIVIAL_MEMCONVERT_IMPL(quint16) 1630 #ifdef Q_WS_QWS1631 1687 QT_TRIVIAL_MEMCONVERT_IMPL(qrgb565) 1632 #endif1633 1688 QT_TRIVIAL_MEMCONVERT_IMPL(qargb8565) 1634 1689 QT_TRIVIAL_MEMCONVERT_IMPL(qargb8555) … … 1650 1705 } 1651 1706 1652 const int align = ( long(dest) & 3);1707 const int align = (quintptr(dest) & 3); 1653 1708 switch (align) { 1654 1709 case 1: *dest++ = qrgb666(*src++); --count; … … 1727 1782 QT_RECTCONVERT_TRIVIAL_IMPL(qargb6666) 1728 1783 QT_RECTCONVERT_TRIVIAL_IMPL(qrgb666) 1729 #ifdef Q_WS_QWS1730 1784 QT_RECTCONVERT_TRIVIAL_IMPL(qrgb565) 1731 #endif1732 1785 QT_RECTCONVERT_TRIVIAL_IMPL(qargb8565) 1733 1786 QT_RECTCONVERT_TRIVIAL_IMPL(quint16) … … 1842 1895 return (b << 3) | (b >> 2); 1843 1896 } 1844 1845 #if 11846 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {1847 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;1848 t >>= 8;1849 t &= 0xff00ff;1850 1851 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;1852 x &= 0xff00ff00;1853 x |= t;1854 return x;1855 }1856 1857 #if defined(Q_CC_RVCT)1858 # pragma push1859 # pragma arm1860 #endif1861 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) {1862 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;1863 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;1864 t &= 0xff00ff;1865 1866 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;1867 x = (x + ((x >> 8) & 0xff00ff) + 0x800080);1868 x &= 0xff00ff00;1869 x |= t;1870 return x;1871 }1872 #if defined(Q_CC_RVCT)1873 # pragma pop1874 #endif1875 #else1876 // possible implementation for 64 bit1877 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {1878 ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;1879 t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b;1880 t >>= 8;1881 t &= 0x00ff00ff00ff00ff;1882 return (uint(t)) | (uint(t >> 24));1883 }1884 1885 Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) {1886 ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;1887 t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b;1888 t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);1889 t &= 0x00ff00ff00ff00ff;1890 return (uint(t)) | (uint(t >> 24));1891 }1892 1893 Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) {1894 ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;1895 t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);1896 t &= 0x00ff00ff00ff00ff;1897 return (uint(t)) | (uint(t >> 24));1898 }1899 1900 Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) {1901 uint a = x >> 24;1902 ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a;1903 t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080);1904 t &= 0x00ff00ff00ff00ff;1905 return (uint(t)) | (uint(t >> 24)) | 0xff000000;1906 }1907 #endif1908 1897 1909 1898 const uint qt_bayer_matrix[16][16] = { … … 1946 1935 1947 1936 1937 #if QT_POINTER_SIZE == 8 // 64-bit versions 1938 #define AMIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) 1939 #define MIX(mask) (qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) 1940 #else // 32 bits 1941 // The mask for alpha can overflow over 32 bits 1942 #define AMIX(mask) quint32(qMin(((qint64(s)&mask) + (qint64(d)&mask)), qint64(mask))) 1943 #define MIX(mask) (qMin(((quint32(s)&mask) + (quint32(d)&mask)), quint32(mask))) 1944 #endif 1945 1946 inline int comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha) 1947 { 1948 const int result = (AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); 1949 return INTERPOLATE_PIXEL_255(result, const_alpha, d, one_minus_const_alpha); 1950 } 1951 1952 inline int comp_func_Plus_one_pixel(uint d, const uint s) 1953 { 1954 const int result = (AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK)); 1955 return result; 1956 } 1957 1958 #undef MIX 1959 #undef AMIX 1960 1961 // prototypes of all the composition functions 1962 void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int length, uint const_alpha); 1963 void QT_FASTCALL comp_func_DestinationOver(uint *dest, const uint *src, int length, uint const_alpha); 1964 void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha); 1965 void QT_FASTCALL comp_func_Source(uint *dest, const uint *src, int length, uint const_alpha); 1966 void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint); 1967 void QT_FASTCALL comp_func_SourceIn(uint *dest, const uint *src, int length, uint const_alpha); 1968 void QT_FASTCALL comp_func_DestinationIn(uint *dest, const uint *src, int length, uint const_alpha); 1969 void QT_FASTCALL comp_func_SourceOut(uint *dest, const uint *src, int length, uint const_alpha); 1970 void QT_FASTCALL comp_func_DestinationOut(uint *dest, const uint *src, int length, uint const_alpha); 1971 void QT_FASTCALL comp_func_SourceAtop(uint *dest, const uint *src, int length, uint const_alpha); 1972 void QT_FASTCALL comp_func_DestinationAtop(uint *dest, const uint *src, int length, uint const_alpha); 1973 void QT_FASTCALL comp_func_XOR(uint *dest, const uint *src, int length, uint const_alpha); 1974 void QT_FASTCALL comp_func_Plus(uint *dest, const uint *src, int length, uint const_alpha); 1975 void QT_FASTCALL comp_func_Multiply(uint *dest, const uint *src, int length, uint const_alpha); 1976 void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha); 1977 void QT_FASTCALL comp_func_Overlay(uint *dest, const uint *src, int length, uint const_alpha); 1978 void QT_FASTCALL comp_func_Darken(uint *dest, const uint *src, int length, uint const_alpha); 1979 void QT_FASTCALL comp_func_Lighten(uint *dest, const uint *src, int length, uint const_alpha); 1980 void QT_FASTCALL comp_func_ColorDodge(uint *dest, const uint *src, int length, uint const_alpha); 1981 void QT_FASTCALL comp_func_ColorBurn(uint *dest, const uint *src, int length, uint const_alpha); 1982 void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int length, uint const_alpha); 1983 void QT_FASTCALL comp_func_SoftLight(uint *dest, const uint *src, int length, uint const_alpha); 1984 void QT_FASTCALL comp_func_Difference(uint *dest, const uint *src, int length, uint const_alpha); 1985 void QT_FASTCALL comp_func_Exclusion(uint *dest, const uint *src, int length, uint const_alpha); 1986 void QT_FASTCALL rasterop_SourceOrDestination(uint *dest, const uint *src, int length, uint const_alpha); 1987 void QT_FASTCALL rasterop_SourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha); 1988 void QT_FASTCALL rasterop_SourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha); 1989 void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha); 1990 void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *dest, const uint *src, int length, uint const_alpha); 1991 void QT_FASTCALL rasterop_NotSourceXorDestination(uint *dest, const uint *src, int length, uint const_alpha); 1992 void QT_FASTCALL rasterop_NotSource(uint *dest, const uint *src, int length, uint const_alpha); 1993 void QT_FASTCALL rasterop_NotSourceAndDestination(uint *dest, const uint *src, int length, uint const_alpha); 1994 void QT_FASTCALL rasterop_SourceAndNotDestination(uint *dest, const uint *src, int length, uint const_alpha); 1995 1996 // prototypes of all the solid composition functions 1997 void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha); 1998 void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha); 1999 void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint color, uint const_alpha); 2000 void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha); 2001 void QT_FASTCALL comp_func_solid_Destination(uint *dest, int length, uint color, uint const_alpha); 2002 void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha); 2003 void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha); 2004 void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha); 2005 void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha); 2006 void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha); 2007 void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha); 2008 void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha); 2009 void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha); 2010 void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha); 2011 void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha); 2012 void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha); 2013 void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha); 2014 void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha); 2015 void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha); 2016 void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha); 2017 void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha); 2018 void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha); 2019 void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha); 2020 void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha); 2021 void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest, int length, uint color, uint const_alpha); 2022 void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest, int length, uint color, uint const_alpha); 2023 void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest, int length, uint color, uint const_alpha); 2024 void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest, int length, uint color, uint const_alpha); 2025 void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest, int length, uint color, uint const_alpha); 2026 void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest, int length, uint color, uint const_alpha); 2027 void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length, uint color, uint const_alpha); 2028 void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest, int length, uint color, uint const_alpha); 2029 void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest, int length, uint color, uint const_alpha); 2030 1948 2031 QT_END_NAMESPACE 1949 2032 -
trunk/src/gui/painting/qdrawhelper_sse.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 78 78 comp_func_Clear<QSSEIntrinsics>, 79 79 comp_func_Source<QSSEIntrinsics>, 80 0,80 comp_func_Destination, 81 81 comp_func_SourceIn<QSSEIntrinsics>, 82 82 comp_func_DestinationIn<QSSEIntrinsics>, … … 85 85 comp_func_SourceAtop<QSSEIntrinsics>, 86 86 comp_func_DestinationAtop<QSSEIntrinsics>, 87 comp_func_XOR<QSSEIntrinsics> 87 comp_func_XOR<QSSEIntrinsics>, 88 comp_func_Plus, 89 comp_func_Multiply, 90 comp_func_Screen, 91 comp_func_Overlay, 92 comp_func_Darken, 93 comp_func_Lighten, 94 comp_func_ColorDodge, 95 comp_func_ColorBurn, 96 comp_func_HardLight, 97 comp_func_SoftLight, 98 comp_func_Difference, 99 comp_func_Exclusion, 100 rasterop_SourceOrDestination, 101 rasterop_SourceAndDestination, 102 rasterop_SourceXorDestination, 103 rasterop_NotSourceAndNotDestination, 104 rasterop_NotSourceOrNotDestination, 105 rasterop_NotSourceXorDestination, 106 rasterop_NotSource, 107 rasterop_NotSourceAndDestination, 108 rasterop_SourceAndNotDestination 88 109 }; 89 110 -
trunk/src/gui/painting/qdrawhelper_sse2.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #ifdef QT_HAVE_SSE2 45 45 46 #include <private/qdrawingprimitive_sse2_p.h> 46 47 #include <private/qpaintengine_raster_p.h> 47 48 48 #ifdef QT_LINUXBASE49 // this is an evil hack - the posix_memalign declaration in LSB50 // is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=243151 # define posix_memalign _lsb_hack_posix_memalign52 # include <emmintrin.h>53 # undef posix_memalign54 #else55 # include <emmintrin.h>56 #endif57 58 49 QT_BEGIN_NAMESPACE 59 60 /*61 * Multiply the components of pixelVector by alphaChannel62 * Each 32bits components of alphaChannel must be in the form 0x00AA00AA63 * colorMask must have 0x00ff00ff on each 32 bits component64 * half must have the value 128 (0x80) for each 32 bits compnent65 */66 #define BYTE_MUL_SSE2(result, pixelVector, alphaChannel, colorMask, half) \67 { \68 /* 1. separate the colors in 2 vectors so each color is on 16 bits \69 (in order to be multiplied by the alpha \70 each 32 bit of dstVectorAG are in the form 0x00AA00GG \71 each 32 bit of dstVectorRB are in the form 0x00RR00BB */\72 __m128i pixelVectorAG = _mm_srli_epi16(pixelVector, 8); \73 __m128i pixelVectorRB = _mm_and_si128(pixelVector, colorMask); \74 \75 /* 2. multiply the vectors by the alpha channel */\76 pixelVectorAG = _mm_mullo_epi16(pixelVectorAG, alphaChannel); \77 pixelVectorRB = _mm_mullo_epi16(pixelVectorRB, alphaChannel); \78 \79 /* 3. devide by 255, that's the tricky part. \80 we do it like for BYTE_MUL(), with bit shift: X/255 ~= (X + X/256 + rounding)/256 */ \81 /** so first (X + X/256 + rounding) */\82 pixelVectorRB = _mm_add_epi16(pixelVectorRB, _mm_srli_epi16(pixelVectorRB, 8)); \83 pixelVectorRB = _mm_add_epi16(pixelVectorRB, half); \84 pixelVectorAG = _mm_add_epi16(pixelVectorAG, _mm_srli_epi16(pixelVectorAG, 8)); \85 pixelVectorAG = _mm_add_epi16(pixelVectorAG, half); \86 \87 /** second devide by 256 */\88 pixelVectorRB = _mm_srli_epi16(pixelVectorRB, 8); \89 /** for AG, we could >> 8 to divide followed by << 8 to put the \90 bytes in the correct position. By masking instead, we execute \91 only one instruction */\92 pixelVectorAG = _mm_andnot_si128(colorMask, pixelVectorAG); \93 \94 /* 4. combine the 2 pairs of colors */ \95 result = _mm_or_si128(pixelVectorAG, pixelVectorRB); \96 }97 98 /*99 * Each 32bits components of alphaChannel must be in the form 0x00AA00AA100 * oneMinusAlphaChannel must be 255 - alpha for each 32 bits component101 * colorMask must have 0x00ff00ff on each 32 bits component102 * half must have the value 128 (0x80) for each 32 bits compnent103 */104 #define INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, alphaChannel, oneMinusAlphaChannel, colorMask, half) { \105 /* interpolate AG */\106 __m128i srcVectorAG = _mm_srli_epi16(srcVector, 8); \107 __m128i dstVectorAG = _mm_srli_epi16(dstVector, 8); \108 __m128i srcVectorAGalpha = _mm_mullo_epi16(srcVectorAG, alphaChannel); \109 __m128i dstVectorAGoneMinusAlphalpha = _mm_mullo_epi16(dstVectorAG, oneMinusAlphaChannel); \110 __m128i finalAG = _mm_add_epi16(srcVectorAGalpha, dstVectorAGoneMinusAlphalpha); \111 finalAG = _mm_add_epi16(finalAG, _mm_srli_epi16(finalAG, 8)); \112 finalAG = _mm_add_epi16(finalAG, half); \113 finalAG = _mm_andnot_si128(colorMask, finalAG); \114 \115 /* interpolate RB */\116 __m128i srcVectorRB = _mm_and_si128(srcVector, colorMask); \117 __m128i dstVectorRB = _mm_and_si128(dstVector, colorMask); \118 __m128i srcVectorRBalpha = _mm_mullo_epi16(srcVectorRB, alphaChannel); \119 __m128i dstVectorRBoneMinusAlphalpha = _mm_mullo_epi16(dstVectorRB, oneMinusAlphaChannel); \120 __m128i finalRB = _mm_add_epi16(srcVectorRBalpha, dstVectorRBoneMinusAlphalpha); \121 finalRB = _mm_add_epi16(finalRB, _mm_srli_epi16(finalRB, 8)); \122 finalRB = _mm_add_epi16(finalRB, half); \123 finalRB = _mm_srli_epi16(finalRB, 8); \124 \125 /* combine */\126 result = _mm_or_si128(finalAG, finalRB); \127 }128 50 129 51 void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, … … 133 55 { 134 56 const quint32 *src = (const quint32 *) srcPixels; 135 quint32 *dst = ( uint*) destPixels;57 quint32 *dst = (quint32 *) destPixels; 136 58 if (const_alpha == 256) { 137 59 const __m128i alphaMask = _mm_set1_epi32(0xff000000); … … 141 63 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 142 64 for (int y = 0; y < h; ++y) { 143 int x = 0; 144 for (; x < w-3; x += 4) { 145 const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); 146 const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); 147 if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { 148 // all opaque 149 _mm_storeu_si128((__m128i *)&dst[x], srcVector); 150 } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { 151 // not fully transparent 152 // result = s + d * (1-alpha) 153 154 // extract the alpha channel on 2 x 16 bits 155 // so we have room for the multiplication 156 // each 32 bits will be in the form 0x00AA00AA 157 // with A being the 1 - alpha 158 __m128i alphaChannel = _mm_srli_epi32(srcVector, 24); 159 alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); 160 alphaChannel = _mm_sub_epi16(one, alphaChannel); 161 162 const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]); 163 __m128i destMultipliedByOneMinusAlpha; 164 BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); 165 166 // result = s + d * (1-alpha) 167 const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); 168 _mm_storeu_si128((__m128i *)&dst[x], result); 169 } 170 } 171 for (; x<w; ++x) { 172 uint s = src[x]; 173 if (s >= 0xff000000) 174 dst[x] = s; 175 else if (s != 0) 176 dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); 177 } 65 BLEND_SOURCE_OVER_ARGB32_SSE2(dst, src, w, nullVector, half, one, colorMask, alphaMask); 178 66 dst = (quint32 *)(((uchar *) dst) + dbpl); 179 67 src = (const quint32 *)(((const uchar *) src) + sbpl); … … 190 78 const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); 191 79 for (int y = 0; y < h; ++y) { 192 int x = 0; 193 for (; x < w-3; x += 4) { 194 __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); 195 if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { 196 BYTE_MUL_SSE2(srcVector, srcVector, constAlphaVector, colorMask, half); 197 198 __m128i alphaChannel = _mm_srli_epi32(srcVector, 24); 199 alphaChannel = _mm_or_si128(alphaChannel, _mm_slli_epi32(alphaChannel, 16)); 200 alphaChannel = _mm_sub_epi16(one, alphaChannel); 201 202 const __m128i dstVector = _mm_loadu_si128((__m128i *)&dst[x]); 203 __m128i destMultipliedByOneMinusAlpha; 204 BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); 205 206 const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); 207 _mm_storeu_si128((__m128i *)&dst[x], result); 208 } 209 } 210 for (; x<w; ++x) { 211 quint32 s = src[x]; 212 if (s != 0) { 213 s = BYTE_MUL(s, const_alpha); 214 dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s)); 215 } 216 } 80 BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2(dst, src, w, nullVector, half, one, colorMask, constAlphaVector) 217 81 dst = (quint32 *)(((uchar *) dst) + dbpl); 218 82 src = (const quint32 *)(((const uchar *) src) + sbpl); … … 233 97 { 234 98 const quint32 *src = (const quint32 *) srcPixels; 235 quint32 *dst = ( uint*) destPixels;99 quint32 *dst = (quint32 *) destPixels; 236 100 if (const_alpha != 256) { 237 101 if (const_alpha != 0) { … … 246 110 for (int y = 0; y < h; ++y) { 247 111 int x = 0; 112 113 // First, align dest to 16 bytes: 114 ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) { 115 quint32 s = src[x]; 116 s = BYTE_MUL(s, const_alpha); 117 dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); 118 } 119 248 120 for (; x < w-3; x += 4) { 249 121 __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); 250 122 if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVector, nullVector)) != 0xffff) { 251 const __m128i dstVector = _mm_load u_si128((__m128i *)&dst[x]);123 const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); 252 124 __m128i result; 253 125 INTERPOLATE_PIXEL_255_SSE2(result, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half); 254 _mm_store u_si128((__m128i *)&dst[x], result);126 _mm_store_si128((__m128i *)&dst[x], result); 255 127 } 256 128 } … … 269 141 } 270 142 143 void QT_FASTCALL comp_func_SourceOver_sse2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha) 144 { 145 Q_ASSERT(const_alpha < 256); 146 147 const quint32 *src = (const quint32 *) srcPixels; 148 quint32 *dst = (quint32 *) destPixels; 149 150 const __m128i nullVector = _mm_set1_epi32(0); 151 const __m128i half = _mm_set1_epi16(0x80); 152 const __m128i one = _mm_set1_epi16(0xff); 153 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 154 if (const_alpha == 255) { 155 const __m128i alphaMask = _mm_set1_epi32(0xff000000); 156 BLEND_SOURCE_OVER_ARGB32_SSE2(dst, src, length, nullVector, half, one, colorMask, alphaMask); 157 } else { 158 const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); 159 BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2(dst, src, length, nullVector, half, one, colorMask, constAlphaVector); 160 } 161 } 162 163 void QT_FASTCALL comp_func_Plus_sse2(uint *dst, const uint *src, int length, uint const_alpha) 164 { 165 int x = 0; 166 167 if (const_alpha == 255) { 168 // 1) Prologue: align destination on 16 bytes 169 ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) 170 dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]); 171 172 // 2) composition with SSE2 173 for (; x < length - 3; x += 4) { 174 const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); 175 const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); 176 177 const __m128i result = _mm_adds_epu8(srcVector, dstVector); 178 _mm_store_si128((__m128i *)&dst[x], result); 179 } 180 181 // 3) Epilogue: 182 for (; x < length; ++x) 183 dst[x] = comp_func_Plus_one_pixel(dst[x], src[x]); 184 } else { 185 const int one_minus_const_alpha = 255 - const_alpha; 186 const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); 187 const __m128i oneMinusConstAlpha = _mm_set1_epi16(one_minus_const_alpha); 188 189 // 1) Prologue: align destination on 16 bytes 190 ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) 191 dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha); 192 193 const __m128i half = _mm_set1_epi16(0x80); 194 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 195 // 2) composition with SSE2 196 for (; x < length - 3; x += 4) { 197 const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); 198 const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); 199 200 __m128i result = _mm_adds_epu8(srcVector, dstVector); 201 INTERPOLATE_PIXEL_255_SSE2(result, result, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half) 202 _mm_store_si128((__m128i *)&dst[x], result); 203 } 204 205 // 3) Epilogue: 206 for (; x < length; ++x) 207 dst[x] = comp_func_Plus_one_pixel_const_alpha(dst[x], src[x], const_alpha, one_minus_const_alpha); 208 } 209 } 210 211 void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, uint const_alpha) 212 { 213 if (const_alpha == 255) { 214 ::memcpy(dst, src, length * sizeof(uint)); 215 } else { 216 const int ialpha = 255 - const_alpha; 217 218 int x = 0; 219 220 // 1) prologue, align on 16 bytes 221 ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) 222 dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); 223 224 // 2) interpolate pixels with SSE2 225 const __m128i half = _mm_set1_epi16(0x80); 226 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 227 const __m128i constAlphaVector = _mm_set1_epi16(const_alpha); 228 const __m128i oneMinusConstAlpha = _mm_set1_epi16(ialpha); 229 for (; x < length - 3; x += 4) { 230 const __m128i srcVector = _mm_loadu_si128((__m128i *)&src[x]); 231 __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); 232 INTERPOLATE_PIXEL_255_SSE2(dstVector, srcVector, dstVector, constAlphaVector, oneMinusConstAlpha, colorMask, half) 233 _mm_store_si128((__m128i *)&dst[x], dstVector); 234 } 235 236 // 3) Epilogue 237 for (; x < length; ++x) 238 dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], ialpha); 239 } 240 } 241 271 242 void qt_memfill32_sse2(quint32 *dest, quint32 value, int count) 272 243 { … … 296 267 int n = (count128 + 3) / 4; 297 268 switch (count128 & 0x3) { 298 case 0: do { _mm_st ore_si128(dst128++, value128);299 case 3: _mm_st ore_si128(dst128++, value128);300 case 2: _mm_st ore_si128(dst128++, value128);301 case 1: _mm_st ore_si128(dst128++, value128);269 case 0: do { _mm_stream_si128(dst128++, value128); 270 case 3: _mm_stream_si128(dst128++, value128); 271 case 2: _mm_stream_si128(dst128++, value128); 272 case 1: _mm_stream_si128(dst128++, value128); 302 273 } while (--n > 0); 303 274 } … … 312 283 } 313 284 } 285 286 void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha) 287 { 288 if ((const_alpha & qAlpha(color)) == 255) { 289 qt_memfill32_sse2(destPixels, color, length); 290 } else { 291 if (const_alpha != 255) 292 color = BYTE_MUL(color, const_alpha); 293 294 const quint32 minusAlphaOfColor = qAlpha(~color); 295 int x = 0; 296 297 quint32 *dst = (quint32 *) destPixels; 298 const __m128i colorVector = _mm_set1_epi32(color); 299 const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); 300 const __m128i half = _mm_set1_epi16(0x80); 301 const __m128i minusAlphaOfColorVector = _mm_set1_epi16(minusAlphaOfColor); 302 303 ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) 304 destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); 305 306 for (; x < length-3; x += 4) { 307 __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); 308 BYTE_MUL_SSE2(dstVector, dstVector, minusAlphaOfColorVector, colorMask, half); 309 dstVector = _mm_add_epi8(colorVector, dstVector); 310 _mm_store_si128((__m128i *)&dst[x], dstVector); 311 } 312 for (;x < length; ++x) 313 destPixels[x] = color + BYTE_MUL(destPixels[x], minusAlphaOfColor); 314 } 315 } 316 317 CompositionFunctionSolid qt_functionForModeSolid_onlySSE2[numCompositionFunctions] = { 318 comp_func_solid_SourceOver_sse2, 319 comp_func_solid_DestinationOver, 320 comp_func_solid_Clear, 321 comp_func_solid_Source, 322 comp_func_solid_Destination, 323 comp_func_solid_SourceIn, 324 comp_func_solid_DestinationIn, 325 comp_func_solid_SourceOut, 326 comp_func_solid_DestinationOut, 327 comp_func_solid_SourceAtop, 328 comp_func_solid_DestinationAtop, 329 comp_func_solid_XOR, 330 comp_func_solid_Plus, 331 comp_func_solid_Multiply, 332 comp_func_solid_Screen, 333 comp_func_solid_Overlay, 334 comp_func_solid_Darken, 335 comp_func_solid_Lighten, 336 comp_func_solid_ColorDodge, 337 comp_func_solid_ColorBurn, 338 comp_func_solid_HardLight, 339 comp_func_solid_SoftLight, 340 comp_func_solid_Difference, 341 comp_func_solid_Exclusion, 342 rasterop_solid_SourceOrDestination, 343 rasterop_solid_SourceAndDestination, 344 rasterop_solid_SourceXorDestination, 345 rasterop_solid_NotSourceAndNotDestination, 346 rasterop_solid_NotSourceOrNotDestination, 347 rasterop_solid_NotSourceXorDestination, 348 rasterop_solid_NotSource, 349 rasterop_solid_NotSourceAndDestination, 350 rasterop_solid_SourceAndNotDestination 351 }; 352 353 CompositionFunction qt_functionForMode_onlySSE2[numCompositionFunctions] = { 354 comp_func_SourceOver_sse2, 355 comp_func_DestinationOver, 356 comp_func_Clear, 357 comp_func_Source_sse2, 358 comp_func_Destination, 359 comp_func_SourceIn, 360 comp_func_DestinationIn, 361 comp_func_SourceOut, 362 comp_func_DestinationOut, 363 comp_func_SourceAtop, 364 comp_func_DestinationAtop, 365 comp_func_XOR, 366 comp_func_Plus_sse2, 367 comp_func_Multiply, 368 comp_func_Screen, 369 comp_func_Overlay, 370 comp_func_Darken, 371 comp_func_Lighten, 372 comp_func_ColorDodge, 373 comp_func_ColorBurn, 374 comp_func_HardLight, 375 comp_func_SoftLight, 376 comp_func_Difference, 377 comp_func_Exclusion, 378 rasterop_SourceOrDestination, 379 rasterop_SourceAndDestination, 380 rasterop_SourceXorDestination, 381 rasterop_NotSourceAndNotDestination, 382 rasterop_NotSourceOrNotDestination, 383 rasterop_NotSourceXorDestination, 384 rasterop_NotSource, 385 rasterop_NotSourceAndDestination, 386 rasterop_SourceAndNotDestination 387 }; 314 388 315 389 void qt_memfill16_sse2(quint16 *dest, quint16 value, int count) -
trunk/src/gui/painting/qdrawhelper_sse3dnow.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 86 86 comp_func_Clear<QSSE3DNOWIntrinsics>, 87 87 comp_func_Source<QSSE3DNOWIntrinsics>, 88 0,88 comp_func_Destination, 89 89 comp_func_SourceIn<QSSE3DNOWIntrinsics>, 90 90 comp_func_DestinationIn<QSSE3DNOWIntrinsics>, … … 93 93 comp_func_SourceAtop<QSSE3DNOWIntrinsics>, 94 94 comp_func_DestinationAtop<QSSE3DNOWIntrinsics>, 95 comp_func_XOR<QSSE3DNOWIntrinsics> 95 comp_func_XOR<QSSE3DNOWIntrinsics>, 96 comp_func_Plus, 97 comp_func_Multiply, 98 comp_func_Screen, 99 comp_func_Overlay, 100 comp_func_Darken, 101 comp_func_Lighten, 102 comp_func_ColorDodge, 103 comp_func_ColorBurn, 104 comp_func_HardLight, 105 comp_func_SoftLight, 106 comp_func_Difference, 107 comp_func_Exclusion, 108 rasterop_SourceOrDestination, 109 rasterop_SourceAndDestination, 110 rasterop_SourceXorDestination, 111 rasterop_NotSourceAndNotDestination, 112 rasterop_NotSourceOrNotDestination, 113 rasterop_NotSourceXorDestination, 114 rasterop_NotSource, 115 rasterop_NotSourceAndDestination, 116 rasterop_SourceAndNotDestination 96 117 }; 97 118 -
trunk/src/gui/painting/qdrawhelper_sse_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qdrawhelper_x86_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 123 123 int w, int h, 124 124 int const_alpha); 125 126 extern CompositionFunction qt_functionForMode_onlySSE2[]; 127 extern CompositionFunctionSolid qt_functionForModeSolid_onlySSE2[]; 125 128 #endif // QT_HAVE_SSE2 126 129 -
trunk/src/gui/painting/qdrawutil.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 49 49 #include <qvarlengtharray.h> 50 50 #include <qmath.h> 51 #include <private/qstylehelper_p.h> 51 52 52 53 QT_BEGIN_NAMESPACE … … 1019 1020 #ifndef QT_NO_IMAGE_HEURISTIC_MASK 1020 1021 } else { // color pixmap, no mask 1021 QString k = QString::fromLatin1("$qt-drawitem-%1").arg(pm.cacheKey()); 1022 QString k = QLatin1Literal("$qt-drawitem") 1023 % HexString<qint64>(pm.cacheKey()); 1024 1022 1025 if (!QPixmapCache::find(k, pm)) { 1023 1026 pm = pm.createHeuristicMask(); … … 1082 1085 */ 1083 1086 1084 typedef QVarLengthArray<Q DrawPixmaps::Data, 16> QDrawPixmapsDataArray;1087 typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray; 1085 1088 1086 1089 /*! … … 1103 1106 const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) 1104 1107 { 1105 Q DrawPixmaps::Datad;1108 QPainter::PixmapFragment d; 1106 1109 d.opacity = 1.0; 1107 1110 d.rotation = 0.0; 1108 1111 1109 Q DrawPixmapsDataArray opaqueData;1110 Q DrawPixmapsDataArray translucentData;1112 QPixmapFragmentsArray opaqueData; 1113 QPixmapFragmentsArray translucentData; 1111 1114 1112 1115 // source center … … 1138 1141 yTarget.resize(rows + 1); 1139 1142 1143 bool oldAA = painter->testRenderHint(QPainter::Antialiasing); 1144 if (painter->paintEngine()->type() != QPaintEngine::OpenGL 1145 && painter->paintEngine()->type() != QPaintEngine::OpenGL2 1146 && oldAA && painter->combinedTransform().type() != QTransform::TxNone) { 1147 painter->setRenderHint(QPainter::Antialiasing, false); 1148 } 1149 1140 1150 xTarget[0] = targetRect.left(); 1141 1151 xTarget[1] = targetCenterLeft; … … 1183 1193 // corners 1184 1194 if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left 1185 d.point.setX(0.5 * (xTarget[1] + xTarget[0])); 1186 d.point.setY(0.5 * (yTarget[1] + yTarget[0])); 1187 d.source = QRectF(sourceRect.left(), sourceRect.top(), sourceMargins.left(), sourceMargins.top()); 1188 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); 1189 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); 1195 d.x = (0.5 * (xTarget[1] + xTarget[0])); 1196 d.y = (0.5 * (yTarget[1] + yTarget[0])); 1197 d.sourceLeft = sourceRect.left(); 1198 d.sourceTop = sourceRect.top(); 1199 d.width = sourceMargins.left(); 1200 d.height = sourceMargins.top(); 1201 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; 1202 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; 1190 1203 if (hints & QDrawBorderPixmap::OpaqueTopLeft) 1191 1204 opaqueData.append(d); … … 1194 1207 } 1195 1208 if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right 1196 d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); 1197 d.point.setY(0.5 * (yTarget[1] + yTarget[0])); 1198 d.source = QRectF(sourceCenterRight, sourceRect.top(), sourceMargins.right(), sourceMargins.top()); 1199 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); 1200 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); 1209 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); 1210 d.y = (0.5 * (yTarget[1] + yTarget[0])); 1211 d.sourceLeft = sourceCenterRight; 1212 d.sourceTop = sourceRect.top(); 1213 d.width = sourceMargins.right(); 1214 d.height = sourceMargins.top(); 1215 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; 1216 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; 1201 1217 if (hints & QDrawBorderPixmap::OpaqueTopRight) 1202 1218 opaqueData.append(d); … … 1205 1221 } 1206 1222 if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left 1207 d.point.setX(0.5 * (xTarget[1] + xTarget[0])); 1208 d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); 1209 d.source = QRectF(sourceRect.left(), sourceCenterBottom, sourceMargins.left(), sourceMargins.bottom()); 1210 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); 1211 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); 1223 d.x = (0.5 * (xTarget[1] + xTarget[0])); 1224 d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1])); 1225 d.sourceLeft = sourceRect.left(); 1226 d.sourceTop = sourceCenterBottom; 1227 d.width = sourceMargins.left(); 1228 d.height = sourceMargins.bottom(); 1229 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; 1230 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; 1212 1231 if (hints & QDrawBorderPixmap::OpaqueBottomLeft) 1213 1232 opaqueData.append(d); … … 1216 1235 } 1217 1236 if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right 1218 d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); 1219 d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); 1220 d.source = QRectF(sourceCenterRight, sourceCenterBottom, sourceMargins.right(), sourceMargins.bottom()); 1221 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); 1222 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); 1237 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); 1238 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); 1239 d.sourceLeft = sourceCenterRight; 1240 d.sourceTop = sourceCenterBottom; 1241 d.width = sourceMargins.right(); 1242 d.height = sourceMargins.bottom(); 1243 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; 1244 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; 1223 1245 if (hints & QDrawBorderPixmap::OpaqueBottomRight) 1224 1246 opaqueData.append(d); … … 1230 1252 if (targetCenterWidth > 0 && sourceCenterWidth > 0) { 1231 1253 if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top 1232 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; 1233 d.source = QRectF(sourceCenterLeft, sourceRect.top(), sourceCenterWidth, sourceMargins.top()); 1234 d.point.setY(0.5 * (yTarget[1] + yTarget[0])); 1235 d.scaleX = dx / d.source.width(); 1236 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height(); 1254 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; 1255 d.sourceLeft = sourceCenterLeft; 1256 d.sourceTop = sourceRect.top(); 1257 d.width = sourceCenterWidth; 1258 d.height = sourceMargins.top(); 1259 d.y = (0.5 * (yTarget[1] + yTarget[0])); 1260 d.scaleX = dx / d.width; 1261 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; 1237 1262 for (int i = 1; i < columns - 1; ++i) { 1238 d. point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));1263 d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); 1239 1264 data.append(d); 1240 1265 } 1241 1266 if (rules.horizontal == Qt::RepeatTile) 1242 data[data.size() - 1]. source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);1267 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); 1243 1268 } 1244 1269 if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom 1245 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; 1246 d.source = QRectF(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());; 1247 d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1])); 1248 d.scaleX = dx / d.source.width(); 1249 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height(); 1270 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; 1271 d.sourceLeft = sourceCenterLeft; 1272 d.sourceTop = sourceCenterBottom; 1273 d.width = sourceCenterWidth; 1274 d.height = sourceMargins.bottom(); 1275 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); 1276 d.scaleX = dx / d.width; 1277 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; 1250 1278 for (int i = 1; i < columns - 1; ++i) { 1251 d. point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));1279 d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); 1252 1280 data.append(d); 1253 1281 } 1254 1282 if (rules.horizontal == Qt::RepeatTile) 1255 data[data.size() - 1]. source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);1283 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); 1256 1284 } 1257 1285 } … … 1260 1288 if (targetCenterHeight > 0 && sourceCenterHeight > 0) { 1261 1289 if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left 1262 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; 1263 d.source = QRectF(sourceRect.left(), sourceCenterTop, sourceMargins.left(), sourceCenterHeight); 1264 d.point.setX(0.5 * (xTarget[1] + xTarget[0])); 1265 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width(); 1266 d.scaleY = dy / d.source.height(); 1290 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; 1291 d.sourceLeft = sourceRect.left(); 1292 d.sourceTop = sourceCenterTop; 1293 d.width = sourceMargins.left(); 1294 d.height = sourceCenterHeight; 1295 d.x = (0.5 * (xTarget[1] + xTarget[0])); 1296 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; 1297 d.scaleY = dy / d.height; 1267 1298 for (int i = 1; i < rows - 1; ++i) { 1268 d. point.setY(0.5 * (yTarget[i + 1] + yTarget[i]));1299 d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); 1269 1300 data.append(d); 1270 1301 } 1271 1302 if (rules.vertical == Qt::RepeatTile) 1272 data[data.size() - 1]. source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);1303 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); 1273 1304 } 1274 1305 if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right 1275 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; 1276 d.source = QRectF(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight); 1277 d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1])); 1278 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width(); 1279 d.scaleY = dy / d.source.height(); 1306 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; 1307 d.sourceLeft = sourceCenterRight; 1308 d.sourceTop = sourceCenterTop; 1309 d.width = sourceMargins.right(); 1310 d.height = sourceCenterHeight; 1311 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); 1312 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; 1313 d.scaleY = dy / d.height; 1280 1314 for (int i = 1; i < rows - 1; ++i) { 1281 d. point.setY(0.5 * (yTarget[i + 1] + yTarget[i]));1315 d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); 1282 1316 data.append(d); 1283 1317 } 1284 1318 if (rules.vertical == Qt::RepeatTile) 1285 data[data.size() - 1]. source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);1319 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); 1286 1320 } 1287 1321 } … … 1289 1323 // center 1290 1324 if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) { 1291 QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; 1292 d.source = QRectF(sourceCenterLeft, sourceCenterTop, sourceCenterWidth, sourceCenterHeight); 1293 d.scaleX = dx / d.source.width(); 1294 d.scaleY = dy / d.source.height(); 1325 QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; 1326 d.sourceLeft = sourceCenterLeft; 1327 d.sourceTop = sourceCenterTop; 1328 d.width = sourceCenterWidth; 1329 d.height = sourceCenterHeight; 1330 d.scaleX = dx / d.width; 1331 d.scaleY = dy / d.height; 1295 1332 1296 1333 qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX; … … 1298 1335 1299 1336 for (int j = 1; j < rows - 1; ++j) { 1300 d. point.setY(0.5 * (yTarget[j + 1] + yTarget[j]));1337 d.y = (0.5 * (yTarget[j + 1] + yTarget[j])); 1301 1338 for (int i = 1; i < columns - 1; ++i) { 1302 d. point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));1339 d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); 1303 1340 data.append(d); 1304 1341 } 1305 1342 if (rules.horizontal == Qt::RepeatTile) 1306 data[data.size() - 1]. source.setWidth(repeatWidth);1343 data[data.size() - 1].width = repeatWidth; 1307 1344 } 1308 1345 if (rules.vertical == Qt::RepeatTile) { 1309 1346 for (int i = 1; i < columns - 1; ++i) 1310 data[data.size() - i]. source.setHeight(repeatHeight);1347 data[data.size() - i].height = repeatHeight; 1311 1348 } 1312 1349 } 1313 1350 1314 1351 if (opaqueData.size()) 1315 qDrawPixmaps(painter, opaqueData.data(), opaqueData.size(), pixmap, QDrawPixmaps::OpaqueHint);1352 painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint); 1316 1353 if (translucentData.size()) 1317 qDrawPixmaps(painter, translucentData.data(), translucentData.size(), pixmap); 1318 } 1319 1320 /*! 1321 \class QDrawPixmaps::Data 1322 \since 4.6 1323 \internal 1324 1325 This structure is used with the qDrawPixmaps() function. 1326 1327 QPointF point: Specifies the center of the target rectangle. 1328 QRectF source: Specifies the source rectangle in the pixmap passed into the qDrawPixmaps() call. 1329 qreal scaleX: Specifies the horizontal scale of the target rectangle. 1330 qreal scaleY: Specifies the vertical scale of the target rectangle. 1331 qreal rotation: Specifies the rotation of the target rectangle in degrees. 1332 The target rectangle is rotated after scaling. 1333 qreal opacity: Specifies the opacity of the rectangle. 1334 */ 1335 1336 /*! 1337 \enum QDrawPixmaps::DrawingHint 1338 \internal 1339 */ 1340 1341 /*! 1342 \internal 1343 \since 4.6 1344 1345 This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, at multiple positions 1346 with different scale, rotation and opacity on \a painter. \a drawingData is an array of \a 1347 dataCount elements specifying the parameters used to draw each pixmap instance. 1348 This can be used for example to implement a particle system. 1349 */ 1350 void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints) 1351 { 1352 QPaintEngine *engine = painter->paintEngine(); 1353 if (!engine) 1354 return; 1355 1356 if (engine->isExtended()) { 1357 static_cast<QPaintEngineEx *>(engine)->drawPixmaps(drawingData, dataCount, pixmap, hints); 1358 } else { 1359 qreal oldOpacity = painter->opacity(); 1360 QTransform oldTransform = painter->transform(); 1361 1362 for (int i = 0; i < dataCount; ++i) { 1363 QTransform transform = oldTransform; 1364 qreal xOffset = 0; 1365 qreal yOffset = 0; 1366 if (drawingData[i].rotation == 0) { 1367 xOffset = drawingData[i].point.x(); 1368 yOffset = drawingData[i].point.y(); 1369 } else { 1370 transform.translate(drawingData[i].point.x(), drawingData[i].point.y()); 1371 transform.rotate(drawingData[i].rotation); 1372 } 1373 painter->setTransform(transform); 1374 painter->setOpacity(oldOpacity * drawingData[i].opacity); 1375 1376 qreal w = drawingData[i].scaleX * drawingData[i].source.width(); 1377 qreal h = drawingData[i].scaleY * drawingData[i].source.height(); 1378 painter->drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, drawingData[i].source); 1379 } 1380 1381 painter->setOpacity(oldOpacity); 1382 painter->setTransform(oldTransform); 1383 } 1354 painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap); 1355 1356 if (oldAA) 1357 painter->setRenderHint(QPainter::Antialiasing, true); 1384 1358 } 1385 1359 -
trunk/src/gui/painting/qdrawutil.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 189 189 } 190 190 191 // For internal use only.192 namespace QDrawPixmaps193 {194 struct Data195 {196 QPointF point;197 QRectF source;198 qreal scaleX;199 qreal scaleY;200 qreal rotation;201 qreal opacity;202 };203 204 enum DrawingHint205 {206 OpaqueHint = 0x01207 };208 209 Q_DECLARE_FLAGS(DrawingHints, DrawingHint)210 }211 212 // This function is private and may change without notice. Do not use outside Qt!!!213 Q_GUI_EXPORT void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData,214 int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints = 0);215 216 191 QT_END_NAMESPACE 217 192 -
trunk/src/gui/painting/qemulationpaintengine.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 173 173 fillBGRect(rect); 174 174 } 175 176 QPainterState *s = state(); 177 Qt::BrushStyle style = qbrush_style(s->pen.brush()); 178 if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) 179 { 180 QPen savedPen = s->pen; 181 QGradient g = *s->pen.brush().gradient(); 182 183 if (g.coordinateMode() > QGradient::LogicalMode) { 184 QTransform mat = s->pen.brush().transform(); 185 if (g.coordinateMode() == QGradient::StretchToDeviceMode) { 186 mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height()); 187 } else if (g.coordinateMode() == QGradient::ObjectBoundingMode) { 188 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); 189 QRectF r(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal()); 190 mat.translate(r.x(), r.y()); 191 mat.scale(r.width(), r.height()); 192 } 193 g.setCoordinateMode(QGradient::LogicalMode); 194 QBrush brush(g); 195 brush.setTransform(mat); 196 s->pen.setBrush(brush); 197 penChanged(); 198 real_engine->drawTextItem(p, textItem); 199 s->pen = savedPen; 200 penChanged(); 201 return; 202 } 203 } 204 175 205 real_engine->drawTextItem(p, textItem); 206 } 207 208 void QEmulationPaintEngine::drawStaticTextItem(QStaticTextItem *item) 209 { 210 real_engine->drawStaticTextItem(item); 176 211 } 177 212 … … 234 269 } 235 270 271 void QEmulationPaintEngine::beginNativePainting() 272 { 273 real_engine->beginNativePainting(); 274 } 275 276 void QEmulationPaintEngine::endNativePainting() 277 { 278 real_engine->endNativePainting(); 279 } 236 280 237 281 void QEmulationPaintEngine::fillBGRect(const QRectF &r) -
trunk/src/gui/painting/qemulationpaintengine_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 79 79 virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); 80 80 virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); 81 virtual void drawStaticTextItem(QStaticTextItem *item); 81 82 virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); 82 83 virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags); … … 92 93 93 94 virtual void setState(QPainterState *s); 95 96 virtual void beginNativePainting(); 97 virtual void endNativePainting(); 94 98 95 99 virtual uint flags() const {return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate;} -
trunk/src/gui/painting/qfixed_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystem.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 54 54 # include <private/qpixmap_mac_p.h> 55 55 #endif 56 #ifdef Q_ WS_S6056 #ifdef Q_OS_SYMBIAN 57 57 # include <private/qpixmap_s60_p.h> 58 58 #endif … … 77 77 #elif defined(Q_WS_MAC) 78 78 return new QMacPixmapData(type); 79 #elif defined(Q_ WS_S60)79 #elif defined(Q_OS_SYMBIAN) 80 80 return new QS60PixmapData(type); 81 81 #elif !defined(Q_WS_QWS) … … 85 85 } 86 86 87 QPixmapData *QGraphicsSystem::createPixmapData(QPixmapData *origin) 88 { 89 return createPixmapData(origin->pixelType()); 90 } 87 91 88 92 QT_END_NAMESPACE -
trunk/src/gui/painting/qgraphicssystem_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystem_mac_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystem_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 65 65 public: 66 66 virtual QPixmapData *createPixmapData(QPixmapData::PixelType type) const = 0; 67 virtual QPixmapData *createPixmapData(QPixmapData *origin); 67 68 virtual QWindowSurface *createWindowSurface(QWidget *widget) const = 0; 68 69 -
trunk/src/gui/painting/qgraphicssystem_qws.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 50 50 { 51 51 if (screen->pixmapDataFactory()) 52 return screen->pixmapDataFactory()->create(type); //### For 4.4 compat ability52 return screen->pixmapDataFactory()->create(type); //### For 4.4 compatibility 53 53 else 54 54 return new QRasterPixmapData(type); -
trunk/src/gui/painting/qgraphicssystem_qws_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystem_raster.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystem_raster_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystemfactory.cpp
r706 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 47 47 #include "qapplication.h" 48 48 #include "qgraphicssystem_raster_p.h" 49 #include "qgraphicssystem_runtime_p.h" 49 50 #include "qdebug.h" 50 51 51 52 QT_BEGIN_NAMESPACE 52 53 53 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)54 #ifndef QT_NO_LIBRARY 54 55 Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, 55 56 (QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive)) … … 69 70 system = QLatin1String("openvg"); 70 71 } 71 #elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_WS_PM) && !defined(Q_OS_SYMBIAN) 72 #elif defined (QT_GRAPHICSSYSTEM_RUNTIME) 73 if (system.isEmpty()) { 74 system = QLatin1String("runtime"); 75 } 76 #elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) && !defined(Q_WS_PM) 72 77 if (system.isEmpty()) { 73 78 system = QLatin1String("raster"); … … 77 82 if (system == QLatin1String("raster")) 78 83 return new QRasterGraphicsSystem; 84 else if (system == QLatin1String("runtime")) 85 return new QRuntimeGraphicsSystem; 79 86 else if (system.isEmpty() || system == QLatin1String("native")) 80 87 return 0; 81 88 82 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)89 #ifndef QT_NO_LIBRARY 83 90 if (!ret) { 84 91 if (QGraphicsSystemFactoryInterface *factory = qobject_cast<QGraphicsSystemFactoryInterface*>(loader()->instance(system))) … … 101 108 QStringList QGraphicsSystemFactory::keys() 102 109 { 103 #if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)110 #ifndef QT_NO_LIBRARY 104 111 QStringList list = loader()->keys(); 105 112 #else -
trunk/src/gui/painting/qgraphicssystemfactory_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystemplugin.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgraphicssystemplugin_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qgrayraster.c
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 157 157 #define ErrRaster_Invalid_Argument -3 158 158 #define ErrRaster_Memory_Overflow -4 159 #define ErrRaster_OutOfMemory -6 159 160 160 161 #define QT_FT_BEGIN_HEADER … … 223 224 #endif 224 225 225 226 226 /*************************************************************************/ 227 227 /* */ … … 234 234 235 235 typedef int TCoord; /* integer scanline/pixel coordinate */ 236 typedef longTPos; /* sub-pixel coordinate */236 typedef int TPos; /* sub-pixel coordinate */ 237 237 238 238 /* determine the type used to store cell areas. This normally takes at */ … … 318 318 int ycount; 319 319 320 int skip_spans; 320 321 } TWorker, *PWorker; 321 322 … … 325 326 void* buffer; 326 327 long buffer_size; 328 long buffer_allocated_size; 327 329 int band_size; 328 330 void* memory; … … 331 333 } TRaster, *PRaster; 332 334 333 335 int q_gray_rendered_spans(TRaster *raster) 336 { 337 if ( raster && raster->worker ) 338 return raster->worker->skip_spans > 0 ? 0 : -raster->worker->skip_spans; 339 return 0; 340 } 334 341 335 342 /*************************************************************************/ … … 539 546 { 540 547 TCoord ex1, ex2, fx1, fx2, delta; 541 longp, first, dx;548 int p, first, dx; 542 549 int incr, lift, mod, rem; 543 550 … … 644 651 TCoord ey1, ey2, fy1, fy2; 645 652 TPos dx, dy, x, x2; 646 longp, first;653 int p, first; 647 654 int delta, rem, mod, lift, incr; 648 655 … … 976 983 if ( dx < 0 ) 977 984 dx = -dx; 978 dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1-> x+ control2->y );985 dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->y + control2->y ); 979 986 if ( dy < 0 ) 980 987 dy = -dy; … … 1183 1190 QT_FT_Span* span; 1184 1191 int coverage; 1192 int skip; 1185 1193 1186 1194 … … 1233 1241 if ( ras.num_gray_spans >= QT_FT_MAX_GRAY_SPANS ) 1234 1242 { 1235 if ( ras.render_span ) 1236 ras.render_span( ras.num_gray_spans, ras.gray_spans, 1243 if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) 1244 { 1245 skip = ras.skip_spans > 0 ? ras.skip_spans : 0; 1246 ras.render_span( ras.num_gray_spans - skip, 1247 ras.gray_spans + skip, 1237 1248 ras.render_span_data ); 1249 } 1250 1251 ras.skip_spans -= ras.num_gray_spans; 1252 1238 1253 /* ras.render_span( span->y, ras.gray_spans, count ); */ 1239 1254 … … 1360 1375 /* outline :: A pointer to the source target. */ 1361 1376 /* */ 1362 /* func_interface :: A table of `emitters', i.e,. function pointers */1363 /* called during decomposition to indicate path */1364 /* operations. */1365 /* */1366 1377 /* user :: A typeless pointer which is passed to each */ 1367 1378 /* emitter during the decomposition. It can be */ … … 1374 1385 static 1375 1386 int QT_FT_Outline_Decompose( const QT_FT_Outline* outline, 1376 const QT_FT_Outline_Funcs* func_interface,1377 1387 void* user ) 1378 1388 { 1379 1389 #undef SCALED 1380 #if 01381 #define SCALED( x ) ( ( (x) << shift ) - delta )1382 #else1383 1390 #define SCALED( x ) (x) 1384 #endif1385 1391 1386 1392 QT_FT_Vector v_last; … … 1396 1402 int error; 1397 1403 char tag; /* current point's state */ 1398 1399 #if 01400 int shift = func_interface->shift;1401 TPos delta = func_interface->delta;1402 #endif1403 1404 1404 1405 1405 first = 0; … … 1456 1456 } 1457 1457 1458 error = func_interface->move_to( &v_start, user );1458 error = gray_move_to( &v_start, user ); 1459 1459 if ( error ) 1460 1460 goto Exit; … … 1476 1476 vec.y = SCALED( point->y ); 1477 1477 1478 error = func_interface->line_to( &vec, user );1478 error = gray_line_to( &vec, user ); 1479 1479 if ( error ) 1480 1480 goto Exit; … … 1503 1503 if ( tag == QT_FT_CURVE_TAG_ON ) 1504 1504 { 1505 error = func_interface->conic_to( &v_control, &vec,1505 error = gray_conic_to( &v_control, &vec, 1506 1506 user ); 1507 1507 if ( error ) … … 1516 1516 v_middle.y = ( v_control.y + vec.y ) / 2; 1517 1517 1518 error = func_interface->conic_to( &v_control, &v_middle,1518 error = gray_conic_to( &v_control, &v_middle, 1519 1519 user ); 1520 1520 if ( error ) … … 1525 1525 } 1526 1526 1527 error = func_interface->conic_to( &v_control, &v_start,1527 error = gray_conic_to( &v_control, &v_start, 1528 1528 user ); 1529 1529 goto Close; … … 1556 1556 vec.y = SCALED( point->y ); 1557 1557 1558 error = func_interface->cubic_to( &vec1, &vec2, &vec, user );1558 error = gray_cubic_to( &vec1, &vec2, &vec, user ); 1559 1559 if ( error ) 1560 1560 goto Exit; … … 1562 1562 } 1563 1563 1564 error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );1564 error = gray_cubic_to( &vec1, &vec2, &v_start, user ); 1565 1565 goto Close; 1566 1566 } … … 1569 1569 1570 1570 /* close the contour with a line segment */ 1571 error = func_interface->line_to( &v_start, user );1571 error = gray_line_to( &v_start, user ); 1572 1572 1573 1573 Close: … … 1597 1597 gray_convert_glyph_inner( RAS_ARG ) 1598 1598 { 1599 static1600 const QT_FT_Outline_Funcs func_interface =1601 {1602 (QT_FT_Outline_MoveTo_Func) gray_move_to,1603 (QT_FT_Outline_LineTo_Func) gray_line_to,1604 (QT_FT_Outline_ConicTo_Func)gray_conic_to,1605 (QT_FT_Outline_CubicTo_Func)gray_cubic_to,1606 0,1607 01608 };1609 1610 1599 volatile int error = 0; 1611 1600 1612 1601 if ( qt_ft_setjmp( ras.jump_buffer ) == 0 ) 1613 1602 { 1614 error = QT_FT_Outline_Decompose( &ras.outline, & func_interface, &ras );1603 error = QT_FT_Outline_Decompose( &ras.outline, &ras ); 1615 1604 gray_record_cell( RAS_VAR ); 1616 1605 } … … 1631 1620 int volatile n, num_bands; 1632 1621 TPos volatile min, max, max_y; 1633 QT_FT_BBox* clip; 1622 QT_FT_BBox* clip; 1623 int skip; 1634 1624 1635 1625 ras.num_gray_spans = 0; … … 1701 1691 PCell cells_max; 1702 1692 int yindex; 1703 longcell_start, cell_end, cell_mod;1693 int cell_start, cell_end, cell_mod; 1704 1694 1705 1695 … … 1758 1748 fprintf( stderr, "Rotten glyph!\n" ); 1759 1749 #endif 1760 /* == Raster_Err_OutOfMemory in qblackraster.c */ 1761 return -6; 1750 return ErrRaster_OutOfMemory; 1762 1751 } 1763 1752 … … 1773 1762 } 1774 1763 1775 if ( ras.render_span && ras.num_gray_spans > 0 ) 1776 ras.render_span( ras.num_gray_spans, 1777 ras.gray_spans, ras.render_span_data ); 1764 if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) 1765 { 1766 skip = ras.skip_spans > 0 ? ras.skip_spans : 0; 1767 ras.render_span( ras.num_gray_spans - skip, 1768 ras.gray_spans + skip, 1769 ras.render_span_data ); 1770 } 1771 1772 ras.skip_spans -= ras.num_gray_spans; 1778 1773 1779 1774 if ( ras.band_shoot > 8 && ras.band_size > 16 ) … … 1785 1780 1786 1781 static int 1787 gray_raster_render( PRaster raster,1782 gray_raster_render( QT_FT_Raster raster, 1788 1783 const QT_FT_Raster_Params* params ) 1789 1784 { … … 1795 1790 if ( !raster || !raster->buffer || !raster->buffer_size ) 1796 1791 return ErrRaster_Invalid_Argument; 1792 1793 if ( raster->worker ) 1794 raster->worker->skip_spans = params->skip_spans; 1795 1796 // If raster object and raster buffer are allocated, but 1797 // raster size isn't of the minimum size, indicate out of 1798 // memory. 1799 if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE ) 1800 return ErrRaster_OutOfMemory; 1797 1801 1798 1802 /* return immediately if the outline is empty */ … … 1875 1879 1876 1880 static int 1877 gray_raster_new( void * memory, 1878 QT_FT_Raster* araster ) 1879 { 1880 if (memory) 1881 fprintf(stderr, "gray_raster_new(), memory ignored"); 1882 memory = malloc(sizeof(TRaster)); 1883 if (!memory) { 1881 gray_raster_new( QT_FT_Raster* araster ) 1882 { 1883 *araster = malloc(sizeof(TRaster)); 1884 if (!*araster) { 1884 1885 *araster = 0; 1885 1886 return ErrRaster_Memory_Overflow; 1886 1887 } 1887 QT_FT_MEM_ZERO(memory, sizeof(TRaster)); 1888 1889 *araster = (QT_FT_Raster) memory; 1888 QT_FT_MEM_ZERO(*araster, sizeof(TRaster)); 1889 1890 1890 return 0; 1891 1891 } … … 1906 1906 PRaster rast = (PRaster)raster; 1907 1907 1908 1909 1908 if ( raster ) 1910 1909 { 1911 if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048)1910 if ( pool_base && ( pool_size >= MINIMUM_POOL_SIZE ) ) 1912 1911 { 1913 1912 PWorker worker = (PWorker)pool_base; … … 1924 1923 ( sizeof ( TCell ) * 8 ) ); 1925 1924 } 1925 else if ( pool_base) 1926 { // Case when there is a raster pool allocated, but it 1927 // doesn't have the minimum size (and so memory will be reallocated) 1928 rast->buffer = pool_base; 1929 rast->worker = NULL; 1930 rast->buffer_size = pool_size; 1931 } 1926 1932 else 1927 1933 { … … 1930 1936 rast->worker = NULL; 1931 1937 } 1938 rast->buffer_allocated_size = pool_size; 1932 1939 } 1933 1940 } -
trunk/src/gui/painting/qgrayraster_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 90 90 #endif 91 91 92 /* Minimum buffer size for raster object, that accounts 93 for TWorker and TCell sizes.*/ 94 #define MINIMUM_POOL_SIZE 4096 95 92 96 QT_FT_EXPORT_VAR( const QT_FT_Raster_Funcs ) qt_ft_grays_raster; 93 97 -
trunk/src/gui/painting/qimagescale.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 305 305 } 306 306 307 /* FIXME: NEED to optimi se ScaleAARGBA - currently its "ok" but needs work*/307 /* FIXME: NEED to optimize ScaleAARGBA - currently its "ok" but needs work*/ 308 308 309 309 /* scale by area sampling */ -
trunk/src/gui/painting/qimagescale_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qmath_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qmatrix.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 104 104 QPaintDevice has its origin located at the top-left position. The 105 105 \e x values increase to the right; \e y values increase 106 downward. For a complete description, see the \l { TheCoordinate106 downward. For a complete description, see the \l {Coordinate 107 107 System}{coordinate system} documentation. 108 108 … … 177 177 \endtable 178 178 179 \sa QPainter, QTransform, { TheCoordinate System},179 \sa QPainter, QTransform, {Coordinate System}, 180 180 {demos/affine}{Affine Transformations Demo}, {Transformations Example} 181 181 */ … … 1136 1136 reference to the stream. 1137 1137 1138 \sa { Format of the QDataStream Operators}1138 \sa {Serializing Qt Data Types} 1139 1139 */ 1140 1140 … … 1162 1162 reference to the stream. 1163 1163 1164 \sa { Format of the QDataStream Operators}1164 \sa {Serializing Qt Data Types} 1165 1165 */ 1166 1166 -
trunk/src/gui/painting/qmatrix.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qmemrotate.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 595 595 } 596 596 597 void qt_memrotate90_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl) 598 { 599 qt_memrotate90((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl); 600 } 601 602 void qt_memrotate180_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl) 603 { 604 qt_memrotate180((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl); 605 } 606 607 void qt_memrotate270_16(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl) 608 { 609 qt_memrotate270((const ushort *)srcPixels, w, h, sbpl, (ushort *)destPixels, dbpl); 610 } 611 612 void qt_memrotate90_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl) 613 { 614 qt_memrotate90((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl); 615 } 616 617 void qt_memrotate180_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl) 618 { 619 qt_memrotate180((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl); 620 } 621 622 void qt_memrotate270_32(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl) 623 { 624 qt_memrotate270((const uint *)srcPixels, w, h, sbpl, (uint *)destPixels, dbpl); 625 } 626 627 MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3] = 628 // 90, 180, 270 629 { 630 { 0, 0, 0 }, // Format_Invalid, 631 { 0, 0, 0 }, // Format_Mono, 632 { 0, 0, 0 }, // Format_MonoLSB, 633 { 0, 0, 0 }, // Format_Indexed8, 634 { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_RGB32, 635 { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_ARGB32, 636 { qt_memrotate90_32, qt_memrotate180_32, qt_memrotate270_32 }, // Format_ARGB32_Premultiplied, 637 { qt_memrotate90_16, qt_memrotate180_16, qt_memrotate270_16 }, // Format_RGB16, 638 { 0, 0, 0 }, // Format_ARGB8565_Premultiplied, 639 { 0, 0, 0 }, // Format_RGB666, 640 { 0, 0, 0 }, // Format_ARGB6666_Premultiplied, 641 { 0, 0, 0 }, // Format_RGB555, 642 { 0, 0, 0 }, // Format_ARGB8555_Premultiplied, 643 { 0, 0, 0 }, // Format_RGB888, 644 { 0, 0, 0 }, // Format_RGB444, 645 { 0, 0, 0 } // Format_ARGB4444_Premultiplied, 646 }; 647 597 648 QT_END_NAMESPACE -
trunk/src/gui/painting/qmemrotate_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 83 83 84 84 void Q_GUI_EXPORT qt_memrotate90(const quint32*, int, int, int, quint32*, int); 85 void Q_GUI_QWS_EXPORT qt_memrotate180(const quint32*, int, int, int, quint32*, int); 86 void Q_GUI_QWS_EXPORT qt_memrotate270(const quint32*, int, int, int, quint32*, int); 85 87 86 QT_DECL_MEMROTATE(quint32, quint32);87 88 QT_DECL_MEMROTATE(quint32, quint16); 88 89 QT_DECL_MEMROTATE(quint16, quint32); -
trunk/src/gui/painting/qoutlinemapper.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 155 155 156 156 m_elements.resize(count); 157 memcpy(m_elements.data(), path.points(), count* sizeof(QPointF)); 157 if (count) 158 memcpy(m_elements.data(), path.points(), count* sizeof(QPointF)); 158 159 159 160 m_element_types.resize(0); … … 234 235 235 236 // Check for out of dev bounds... 236 const bool do_clip = (controlPointRect.left() < -QT_RASTER_COORD_LIMIT237 const bool do_clip = !m_in_clip_elements && ((controlPointRect.left() < -QT_RASTER_COORD_LIMIT 237 238 || controlPointRect.right() > QT_RASTER_COORD_LIMIT 238 239 || controlPointRect.top() < -QT_RASTER_COORD_LIMIT 239 240 || controlPointRect.bottom() > QT_RASTER_COORD_LIMIT 240 241 || controlPointRect.width() > QT_RASTER_COORD_LIMIT 241 || controlPointRect.height() > QT_RASTER_COORD_LIMIT) ;242 || controlPointRect.height() > QT_RASTER_COORD_LIMIT)); 242 243 243 244 if (do_clip) { … … 353 354 // this part of code hardly every used, it shouldn't matter. 354 355 356 m_in_clip_elements = true; 357 355 358 QPainterPath path; 359 360 if (!(m_outline.flags & QT_FT_OUTLINE_EVEN_ODD_FILL)) 361 path.setFillRule(Qt::WindingFill); 362 356 363 if (types) { 357 364 for (int i=0; i<element_count; ++i) { … … 389 396 convertPath(clippedPath); 390 397 m_txop = old_txop; 398 399 m_in_clip_elements = false; 391 400 } 392 401 -
trunk/src/gui/painting/qoutlinemapper_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 88 88 { 89 89 public: 90 QOutlineMapper() 91 : m_round_coords(false) 90 QOutlineMapper() : 91 m_element_types(0), 92 m_elements(0), 93 m_elements_dev(0), 94 m_points(0), 95 m_tags(0), 96 m_contours(0), 97 m_polygon_dev(0), 98 m_in_clip_elements(false), 99 m_round_coords(false) 92 100 { 93 101 } … … 229 237 230 238 bool m_valid; 239 bool m_in_clip_elements; 231 240 232 241 private: -
trunk/src/gui/painting/qpaintbuffer.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 46 46 #include <private/qemulationpaintengine_p.h> 47 47 #include <private/qimage_p.h> 48 #include <qstatictext.h> 49 #include <private/qstatictext_p.h> 48 50 49 51 #include <QDebug> … … 268 270 #endif 269 271 270 if (painter && !painter->isActive()) 271 return; 272 processCommands(painter, frameStartIndex(frame), frameEndIndex(frame)); 273 274 #ifdef QPAINTBUFFER_DEBUG_DRAW 275 qDebug() << "QPaintBuffer::draw() -------------------------------- DONE!"; 276 #endif 277 } 278 279 int QPaintBuffer::frameStartIndex(int frame) const 280 { 281 return (frame == 0) ? 0 : d_ptr->frames.at(frame - 1); 282 } 283 284 int QPaintBuffer::frameEndIndex(int frame) const 285 { 286 return (frame == d_ptr->frames.size()) ? d_ptr->commands.size() : d_ptr->frames.at(frame); 287 } 288 289 int QPaintBuffer::processCommands(QPainter *painter, int begin, int end) const 290 { 291 if (!painter || !painter->isActive()) 292 return 0; 272 293 273 294 QPaintEngineEx *xengine = painter->paintEngine()->isExtended() … … 275 296 if (xengine) { 276 297 QPaintEngineExReplayer player; 277 player. draw(*this, painter, frame);298 player.processCommands(*this, painter, begin, end); 278 299 } else { 279 300 QPainterReplayer player; 280 player.draw(*this, painter, frame); 281 } 282 283 #ifdef QPAINTBUFFER_DEBUG_DRAW 284 qDebug() << "QPaintBuffer::draw() -------------------------------- DONE!"; 285 #endif 286 } 287 301 player.processCommands(*this, painter, begin, end); 302 } 303 304 int depth = 0; 305 for (int i = begin; i < end; ++i) { 306 const QPaintBufferCommand &cmd = d_ptr->commands.at(i); 307 if (cmd.id == QPaintBufferPrivate::Cmd_Save) 308 ++depth; 309 else if (cmd.id == QPaintBufferPrivate::Cmd_Restore) 310 --depth; 311 } 312 return depth; 313 } 314 315 #ifndef QT_NO_DEBUG_STREAM 316 QString QPaintBuffer::commandDescription(int command) const 317 { 318 QString desc; 319 QDebug debug(&desc); 320 321 const QPaintBufferCommand &cmd = d_ptr->commands.at(command); 322 323 switch (cmd.id) { 324 case QPaintBufferPrivate::Cmd_Save: { 325 debug << "Cmd_Save"; 326 break; } 327 328 case QPaintBufferPrivate::Cmd_Restore: { 329 debug << "Cmd_Restore"; 330 break; } 331 332 case QPaintBufferPrivate::Cmd_SetBrush: { 333 QBrush brush = qVariantValue<QBrush>(d_ptr->variants.at(cmd.offset)); 334 debug << "Cmd_SetBrush: " << brush; 335 break; } 336 337 case QPaintBufferPrivate::Cmd_SetBrushOrigin: { 338 debug << "Cmd_SetBrushOrigin: " << d_ptr->variants.at(cmd.offset).toPointF(); 339 break; } 340 341 case QPaintBufferPrivate::Cmd_SetCompositionMode: { 342 QPainter::CompositionMode mode = (QPainter::CompositionMode) cmd.extra; 343 debug << "ExCmd_SetCompositionMode, mode: " << mode; 344 break; } 345 346 case QPaintBufferPrivate::Cmd_SetOpacity: { 347 debug << "ExCmd_SetOpacity: " << d_ptr->variants.at(cmd.offset).toDouble(); 348 break; } 349 350 case QPaintBufferPrivate::Cmd_DrawVectorPath: { 351 debug << "ExCmd_DrawVectorPath: size: " << cmd.size 352 // << ", hints:" << d->ints[cmd.offset2+cmd.size] 353 << "pts/elms:" << cmd.offset << cmd.offset2; 354 break; } 355 356 case QPaintBufferPrivate::Cmd_StrokeVectorPath: { 357 QPen pen = qVariantValue<QPen>(d_ptr->variants.at(cmd.extra)); 358 debug << "ExCmd_StrokeVectorPath: size: " << cmd.size 359 // << ", hints:" << d->ints[cmd.offset2+cmd.size] 360 << "pts/elms:" << cmd.offset << cmd.offset2 << pen; 361 break; } 362 363 case QPaintBufferPrivate::Cmd_FillVectorPath: { 364 QBrush brush = qVariantValue<QBrush>(d_ptr->variants.at(cmd.extra)); 365 debug << "ExCmd_FillVectorPath: size: " << cmd.size 366 // << ", hints:" << d->ints[cmd.offset2+cmd.size] 367 << "pts/elms:" << cmd.offset << cmd.offset2 << brush; 368 break; } 369 370 case QPaintBufferPrivate::Cmd_FillRectBrush: { 371 QBrush brush = qVariantValue<QBrush>(d_ptr->variants.at(cmd.extra)); 372 QRectF *rect = (QRectF *)(d_ptr->floats.constData() + cmd.offset); 373 debug << "ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " brush: " << brush; 374 break; } 375 376 case QPaintBufferPrivate::Cmd_FillRectColor: { 377 QColor color = qVariantValue<QColor>(d_ptr->variants.at(cmd.extra)); 378 QRectF *rect = (QRectF *)(d_ptr->floats.constData() + cmd.offset); 379 debug << "ExCmd_FillRectBrush, offset: " << cmd.offset << " rect: " << *rect << " color: " << color; 380 break; } 381 382 case QPaintBufferPrivate::Cmd_DrawPolygonF: { 383 debug << "ExCmd_DrawPolygonF, offset: " << cmd.offset << " size: " << cmd.size 384 << " mode: " << cmd.extra 385 << d_ptr->floats.at(cmd.offset) 386 << d_ptr->floats.at(cmd.offset+1); 387 break; } 388 389 case QPaintBufferPrivate::Cmd_DrawPolygonI: { 390 debug << "ExCmd_DrawPolygonI, offset: " << cmd.offset << " size: " << cmd.size 391 << " mode: " << cmd.extra 392 << d_ptr->ints.at(cmd.offset) 393 << d_ptr->ints.at(cmd.offset+1); 394 break; } 395 396 case QPaintBufferPrivate::Cmd_DrawEllipseF: { 397 debug << "ExCmd_DrawEllipseF, offset: " << cmd.offset; 398 break; } 399 400 case QPaintBufferPrivate::Cmd_DrawLineF: { 401 debug << "ExCmd_DrawLineF, offset: " << cmd.offset << " size: " << cmd.size; 402 break; } 403 404 case QPaintBufferPrivate::Cmd_DrawLineI: { 405 debug << "ExCmd_DrawLineI, offset: " << cmd.offset << " size: " << cmd.size; 406 break; } 407 408 case QPaintBufferPrivate::Cmd_DrawPointsF: { 409 debug << "ExCmd_DrawPointsF, offset: " << cmd.offset << " size: " << cmd.size; 410 break; } 411 412 case QPaintBufferPrivate::Cmd_DrawPointsI: { 413 debug << "ExCmd_DrawPointsI, offset: " << cmd.offset << " size: " << cmd.size; 414 break; } 415 416 case QPaintBufferPrivate::Cmd_DrawPolylineF: { 417 debug << "ExCmd_DrawPolylineF, offset: " << cmd.offset << " size: " << cmd.size; 418 break; } 419 420 case QPaintBufferPrivate::Cmd_DrawPolylineI: { 421 debug << "ExCmd_DrawPolylineI, offset: " << cmd.offset << " size: " << cmd.size; 422 break; } 423 424 case QPaintBufferPrivate::Cmd_DrawRectF: { 425 debug << "ExCmd_DrawRectF, offset: " << cmd.offset << " size: " << cmd.size; 426 break; } 427 428 case QPaintBufferPrivate::Cmd_DrawRectI: { 429 debug << "ExCmd_DrawRectI, offset: " << cmd.offset << " size: " << cmd.size; 430 break; } 431 432 case QPaintBufferPrivate::Cmd_SetClipEnabled: { 433 bool clipEnabled = d_ptr->variants.at(cmd.offset).toBool(); 434 debug << "ExCmd_SetClipEnabled:" << clipEnabled; 435 break; } 436 437 case QPaintBufferPrivate::Cmd_ClipVectorPath: { 438 QVectorPathCmd path(d_ptr, cmd); 439 debug << "ExCmd_ClipVectorPath:" << path().elementCount(); 440 break; } 441 442 case QPaintBufferPrivate::Cmd_ClipRect: { 443 QRect rect(QPoint(d_ptr->ints.at(cmd.offset), d_ptr->ints.at(cmd.offset + 1)), 444 QPoint(d_ptr->ints.at(cmd.offset + 2), d_ptr->ints.at(cmd.offset + 3))); 445 debug << "ExCmd_ClipRect:" << rect << cmd.extra; 446 break; } 447 448 case QPaintBufferPrivate::Cmd_ClipRegion: { 449 QRegion region(d_ptr->variants.at(cmd.offset).value<QRegion>()); 450 debug << "ExCmd_ClipRegion:" << region.boundingRect() << cmd.extra; 451 break; } 452 453 case QPaintBufferPrivate::Cmd_SetPen: { 454 QPen pen = qVariantValue<QPen>(d_ptr->variants.at(cmd.offset)); 455 debug << "Cmd_SetPen: " << pen; 456 break; } 457 458 case QPaintBufferPrivate::Cmd_SetTransform: { 459 QTransform xform = qVariantValue<QTransform>(d_ptr->variants.at(cmd.offset)); 460 debug << "Cmd_SetTransform, offset: " << cmd.offset << xform; 461 break; } 462 463 case QPaintBufferPrivate::Cmd_SetRenderHints: { 464 debug << "Cmd_SetRenderHints, hints: " << cmd.extra; 465 break; } 466 467 case QPaintBufferPrivate::Cmd_SetBackgroundMode: { 468 debug << "Cmd_SetBackgroundMode: " << cmd.extra; 469 break; } 470 471 case QPaintBufferPrivate::Cmd_DrawConvexPolygonF: { 472 debug << "Cmd_DrawConvexPolygonF, offset: " << cmd.offset << " size: " << cmd.size; 473 break; } 474 475 case QPaintBufferPrivate::Cmd_DrawConvexPolygonI: { 476 debug << "Cmd_DrawConvexPolygonI, offset: " << cmd.offset << " size: " << cmd.size; 477 break; } 478 479 case QPaintBufferPrivate::Cmd_DrawEllipseI: { 480 debug << "Cmd_DrawEllipseI, offset: " << cmd.offset; 481 break; } 482 483 case QPaintBufferPrivate::Cmd_DrawPixmapRect: { 484 QPixmap pm(d_ptr->variants.at(cmd.offset).value<QPixmap>()); 485 QRectF r(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1), 486 d_ptr->floats.at(cmd.extra+2), d_ptr->floats.at(cmd.extra+3)); 487 488 QRectF sr(d_ptr->floats.at(cmd.extra+4), d_ptr->floats.at(cmd.extra+5), 489 d_ptr->floats.at(cmd.extra+6), d_ptr->floats.at(cmd.extra+7)); 490 debug << "Cmd_DrawPixmapRect:" << r << sr << pm.size(); 491 break; } 492 493 case QPaintBufferPrivate::Cmd_DrawPixmapPos: { 494 QPixmap pm(d_ptr->variants.at(cmd.offset).value<QPixmap>()); 495 QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); 496 debug << "Cmd_DrawPixmapPos:" << pos << pm.size(); 497 break; } 498 499 case QPaintBufferPrivate::Cmd_DrawTiledPixmap: { 500 QPixmap pm(d_ptr->variants.at(cmd.offset).value<QPixmap>()); 501 QRectF r(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1), 502 d_ptr->floats.at(cmd.extra+2), d_ptr->floats.at(cmd.extra+3)); 503 504 QPointF offset(d_ptr->floats.at(cmd.extra+4), d_ptr->floats.at(cmd.extra+5)); 505 debug << "Cmd_DrawTiledPixmap:" << r << offset << pm.size(); 506 break; } 507 508 case QPaintBufferPrivate::Cmd_DrawImageRect: { 509 QImage image(d_ptr->variants.at(cmd.offset).value<QImage>()); 510 QRectF r(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1), 511 d_ptr->floats.at(cmd.extra+2), d_ptr->floats.at(cmd.extra+3)); 512 QRectF sr(d_ptr->floats.at(cmd.extra+4), d_ptr->floats.at(cmd.extra+5), 513 d_ptr->floats.at(cmd.extra+6), d_ptr->floats.at(cmd.extra+7)); 514 debug << "Cmd_DrawImageRect:" << r << sr << image.size(); 515 break; } 516 517 case QPaintBufferPrivate::Cmd_DrawImagePos: { 518 QImage image(d_ptr->variants.at(cmd.offset).value<QImage>()); 519 QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); 520 debug << "Cmd_DrawImagePos:" << pos << image.size(); 521 break; } 522 523 case QPaintBufferPrivate::Cmd_DrawText: { 524 QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); 525 QList<QVariant> variants(d_ptr->variants.at(cmd.offset).value<QList<QVariant> >()); 526 527 QFont font(variants.at(0).value<QFont>()); 528 QString text(variants.at(1).value<QString>()); 529 530 debug << "Cmd_DrawText:" << pos << text << font.family(); 531 break; } 532 533 case QPaintBufferPrivate::Cmd_DrawTextItem: { 534 QPointF pos(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); 535 QTextItemIntCopy *tiCopy = reinterpret_cast<QTextItemIntCopy *>(qVariantValue<void *>(d_ptr->variants.at(cmd.offset))); 536 QTextItemInt &ti = (*tiCopy)(); 537 QString text(ti.text()); 538 539 QFont font(ti.font()); 540 font.setUnderline(false); 541 font.setStrikeOut(false); 542 font.setOverline(false); 543 544 const QTextItemInt &si = static_cast<const QTextItemInt &>(ti); 545 qreal justificationWidth = 0; 546 if (si.justified) 547 justificationWidth = si.width.toReal(); 548 549 debug << "Cmd_DrawTextItem:" << pos << " " << text; 550 break; } 551 case QPaintBufferPrivate::Cmd_SystemStateChanged: { 552 QRegion systemClip(d_ptr->variants.at(cmd.offset).value<QRegion>()); 553 554 debug << "Cmd_SystemStateChanged:" << systemClip; 555 break; } 556 case QPaintBufferPrivate::Cmd_Translate: { 557 QPointF delta(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1)); 558 debug << "Cmd_Translate:" << delta; 559 break; } 560 case QPaintBufferPrivate::Cmd_DrawStaticText: { 561 debug << "Cmd_DrawStaticText"; 562 break; } 563 } 564 565 return desc; 566 } 567 #endif 288 568 289 569 QRectF QPaintBuffer::boundingRect() const … … 307 587 q->buffer->addCommand(QPaintBufferPrivate::Cmd_SystemStateChanged, QVariant(systemClip)); 308 588 } 589 590 QTransform last; 309 591 }; 310 592 … … 493 775 void QPaintBufferEngine::transformChanged() 494 776 { 777 Q_D(QPaintBufferEngine); 778 const QTransform &transform = state()->matrix; 779 780 QTransform delta; 781 782 bool invertible = false; 783 if (transform.type() <= QTransform::TxScale && transform.type() == d->last.type()) 784 delta = transform * d->last.inverted(&invertible); 785 786 d->last = transform; 787 788 if (invertible && delta.type() == QTransform::TxNone) 789 return; 790 791 if (invertible && delta.type() == QTransform::TxTranslate) { 792 #ifdef QPAINTBUFFER_DEBUG_DRAW 793 qDebug() << "QPaintBufferEngine: transformChanged (translate only) " << state()->matrix; 794 #endif 795 QPaintBufferCommand *cmd = 796 buffer->addCommand(QPaintBufferPrivate::Cmd_Translate); 797 798 qreal data[] = { delta.dx(), delta.dy() }; 799 cmd->extra = buffer->addData((qreal *) data, 2); 800 return; 801 } 802 495 803 // ### accumulate, like in QBrush case... 496 804 if (!buffer->commands.isEmpty() … … 961 1269 } 962 1270 1271 void QPaintBufferEngine::drawStaticTextItem(QStaticTextItem *staticTextItem) 1272 { 1273 QVariantList variants; 1274 1275 variants << QVariant(staticTextItem->font); 1276 for (int i=0; i<staticTextItem->numGlyphs; ++i) { 1277 variants.append(staticTextItem->glyphs[i]); 1278 variants.append(staticTextItem->glyphPositions[i].toPointF()); 1279 } 1280 1281 buffer->addCommand(QPaintBufferPrivate::Cmd_DrawStaticText, QVariant(variants)); 1282 } 1283 963 1284 void QPaintBufferEngine::drawTextItem(const QPointF &pos, const QTextItem &ti) 964 1285 { … … 1000 1321 void QPaintBufferEngine::setState(QPainterState *s) 1001 1322 { 1323 Q_D(QPaintBufferEngine); 1002 1324 if (m_begin_detected) { 1003 1325 #ifdef QPAINTBUFFER_DEBUG_DRAW … … 1017 1339 buffer->addCommand(QPaintBufferPrivate::Cmd_Restore); 1018 1340 } 1341 1342 d->last = s->matrix; 1019 1343 1020 1344 QPaintEngineEx::setState(s); … … 1066 1390 } 1067 1391 1068 void QPainterReplayer:: draw(const QPaintBuffer &buffer, QPainter *_painter, int frame)1392 void QPainterReplayer::processCommands(const QPaintBuffer &buffer, QPainter *p, int begin, int end) 1069 1393 { 1070 1394 d = buffer.d_ptr; 1071 setupTransform(_painter); 1072 1073 int frameStart = (frame == 0) ? 0 : d->frames.at(frame-1); 1074 int frameEnd = (frame == d->frames.size()) ? d->commands.size() : d->frames.at(frame); 1075 1076 for (int cmdIndex=frameStart; cmdIndex<frameEnd; ++cmdIndex) { 1395 painter = p; 1396 1397 for (int cmdIndex = begin; cmdIndex < end; ++cmdIndex) { 1077 1398 const QPaintBufferCommand &cmd = d->commands.at(cmdIndex); 1078 1399 process(cmd); … … 1138 1459 painter->setTransform(xform * m_world_matrix); 1139 1460 break; } 1461 1462 case QPaintBufferPrivate::Cmd_Translate: { 1463 QPointF delta(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1)); 1464 #ifdef QPAINTBUFFER_DEBUG_DRAW 1465 qDebug() << " -> Cmd_Translate, offset: " << cmd.offset << delta; 1466 #endif 1467 painter->translate(delta.x(), delta.y()); 1468 return; 1469 } 1140 1470 1141 1471 case QPaintBufferPrivate::Cmd_SetCompositionMode: { … … 1426 1756 painter->setClipRegion(region, Qt::ClipOperation(cmd.extra)); 1427 1757 break; } 1758 1759 case QPaintBufferPrivate::Cmd_DrawStaticText: { 1760 1761 QVariantList variants(d->variants.at(cmd.offset).value<QVariantList>()); 1762 1763 QFont font = variants.at(0).value<QFont>(); 1764 1765 QVector<quint32> glyphs; 1766 QVector<QPointF> positions; 1767 1768 for (int i=0; i<(variants.size() - 1) / 2; ++i) { 1769 glyphs.append(variants.at(i*2 + 1).toUInt()); 1770 positions.append(variants.at(i*2 + 2).toPointF()); 1771 } 1772 1773 painter->setFont(font); 1774 1775 qt_draw_glyphs(painter, glyphs.constData(), positions.constData(), glyphs.size()); 1776 1777 break; 1778 } 1428 1779 1429 1780 case QPaintBufferPrivate::Cmd_DrawText: { … … 1771 2122 quint64 cacheKey; 1772 2123 }; 2124 2125 struct QPaintBufferCacheEntryV2 2126 { 2127 enum Type { 2128 ImageKey, 2129 PixmapKey 2130 }; 2131 2132 struct Flags { 2133 uint type : 8; 2134 uint key : 24; 2135 }; 2136 2137 union { 2138 Flags flags; 2139 uint bits; 2140 }; 2141 }; 2142 1773 2143 QT_END_NAMESPACE 1774 2144 Q_DECLARE_METATYPE(QPaintBufferCacheEntry) 2145 Q_DECLARE_METATYPE(QPaintBufferCacheEntryV2) 1775 2146 QT_BEGIN_NAMESPACE 1776 2147 … … 1783 2154 { 1784 2155 return stream >> entry.type >> entry.cacheKey; 2156 } 2157 2158 QDataStream &operator<<(QDataStream &stream, const QPaintBufferCacheEntryV2 &entry) 2159 { 2160 return stream << entry.bits; 2161 } 2162 2163 QDataStream &operator>>(QDataStream &stream, QPaintBufferCacheEntryV2 &entry) 2164 { 2165 return stream >> entry.bits; 1785 2166 } 1786 2167 … … 1789 2170 qRegisterMetaType<QPaintBufferCacheEntry>(); 1790 2171 qRegisterMetaTypeStreamOperators<QPaintBufferCacheEntry>("QPaintBufferCacheEntry"); 2172 qRegisterMetaType<QPaintBufferCacheEntryV2>(); 2173 qRegisterMetaTypeStreamOperators<QPaintBufferCacheEntryV2>("QPaintBufferCacheEntryV2"); 1791 2174 1792 2175 return 0; // something … … 1797 2180 QDataStream &operator<<(QDataStream &stream, const QPaintBuffer &buffer) 1798 2181 { 2182 QHash<qint64, uint> pixmapKeys; 2183 QHash<qint64, uint> imageKeys; 2184 1799 2185 QHash<qint64, QPixmap> pixmaps; 1800 2186 QHash<qint64, QImage> images; … … 1805 2191 if (v.type() == QVariant::Image) { 1806 2192 const QImage image(v.value<QImage>()); 1807 images[image.cacheKey()] = image; 1808 1809 QPaintBufferCacheEntry entry; 1810 entry.type = QVariant::Image; 1811 entry.cacheKey = image.cacheKey(); 2193 2194 QPaintBufferCacheEntryV2 entry; 2195 entry.flags.type = QPaintBufferCacheEntryV2::ImageKey; 2196 2197 QHash<qint64, uint>::iterator it = imageKeys.find(image.cacheKey()); 2198 if (it != imageKeys.end()) { 2199 entry.flags.key = *it; 2200 } else { 2201 imageKeys[image.cacheKey()] = entry.flags.key = images.size(); 2202 images[images.size()] = image; 2203 } 2204 1812 2205 variants[i] = QVariant::fromValue(entry); 1813 2206 } else if (v.type() == QVariant::Pixmap) { 1814 2207 const QPixmap pixmap(v.value<QPixmap>()); 1815 pixmaps[pixmap.cacheKey()] = pixmap; 1816 1817 QPaintBufferCacheEntry entry; 1818 entry.type = QVariant::Pixmap; 1819 entry.cacheKey = pixmap.cacheKey(); 2208 2209 QPaintBufferCacheEntryV2 entry; 2210 entry.flags.type = QPaintBufferCacheEntryV2::PixmapKey; 2211 2212 QHash<qint64, uint>::iterator it = pixmapKeys.find(pixmap.cacheKey()); 2213 if (it != pixmapKeys.end()) { 2214 entry.flags.key = *it; 2215 } else { 2216 pixmapKeys[pixmap.cacheKey()] = entry.flags.key = pixmaps.size(); 2217 pixmaps[pixmaps.size()] = pixmap; 2218 } 2219 1820 2220 variants[i] = QVariant::fromValue(entry); 1821 2221 } … … 1859 2259 else 1860 2260 variants[i] = QVariant(pixmaps.value(entry.cacheKey)); 2261 } else if (v.canConvert<QPaintBufferCacheEntryV2>()) { 2262 QPaintBufferCacheEntryV2 entry = v.value<QPaintBufferCacheEntryV2>(); 2263 2264 if (entry.flags.type == QPaintBufferCacheEntryV2::ImageKey) 2265 variants[i] = QVariant(images.value(entry.flags.key)); 2266 else if (entry.flags.type == QPaintBufferCacheEntryV2::PixmapKey) 2267 variants[i] = QVariant(pixmaps.value(entry.flags.key)); 2268 else 2269 qWarning() << "operator<<(QDataStream &stream, QPaintBuffer &buffer): unrecognized cache entry type:" << entry.flags.type; 1861 2270 } 1862 2271 } -
trunk/src/gui/painting/qpaintbuffer_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 79 79 80 80 void draw(QPainter *painter, int frame = 0) const; 81 82 int frameStartIndex(int frame) const; 83 int frameEndIndex(int frame) const; 84 int processCommands(QPainter *painter, int begin, int end) const; 85 #ifndef QT_NO_DEBUG_STREAM 86 QString commandDescription(int command) const; 87 #endif 88 81 89 void setBoundingRect(const QRectF &rect); 82 90 QRectF boundingRect() const; … … 184 192 185 193 Cmd_SystemStateChanged, 194 Cmd_Translate, 195 Cmd_DrawStaticText, 196 197 // new commands must be added above this line 186 198 187 199 Cmd_LastCommand … … 314 326 void setupTransform(QPainter *painter); 315 327 virtual void process(const QPaintBufferCommand &cmd); 316 void draw(const QPaintBuffer &buffer, QPainter *painter, int frame);328 void processCommands(const QPaintBuffer &buffer, QPainter *painter, int begin, int end); 317 329 318 330 protected: … … 395 407 396 408 virtual void drawTextItem(const QPointF &pos, const QTextItem &ti); 409 virtual void drawStaticTextItem(QStaticTextItem *staticTextItem); 397 410 398 411 virtual void setState(QPainterState *s); -
trunk/src/gui/painting/qpaintdevice.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintdevice.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintdevice.qdoc
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 7 7 ** This file is part of the documentation of the Qt Toolkit. 8 8 ** 9 ** $QT_BEGIN_LICENSE: LGPL$9 ** $QT_BEGIN_LICENSE:FDL$ 10 10 ** Commercial Usage 11 11 ** Licensees holding valid Qt Commercial licenses may use this file in 12 12 ** accordance with the Qt Commercial License Agreement provided with the 13 ** Software or, alternatively, in accordance with the terms contained in 14 ** a written agreement between you and Nokia. 15 ** 16 ** GNU Lesser General Public License Usage 17 ** Alternatively, this file may be used under the terms of the GNU Lesser 18 ** General Public License version 2.1 as published by the Free Software 19 ** Foundation and appearing in the file LICENSE.LGPL included in the 20 ** packaging of this file. Please review the following information to 21 ** ensure the GNU Lesser General Public License version 2.1 requirements 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 23 ** 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 ** 28 ** GNU General Public License Usage 29 ** Alternatively, this file may be used under the terms of the GNU 30 ** General Public License version 3.0 as published by the Free Software 31 ** Foundation and appearing in the file LICENSE.GPL included in the 32 ** packaging of this file. Please review the following information to 33 ** ensure the GNU General Public License version 3.0 requirements will be 34 ** met: http://www.gnu.org/copyleft/gpl.html. 13 ** Software or, alternatively, in accordance with the terms contained in a 14 ** written agreement between you and Nokia. 15 ** 16 ** GNU Free Documentation License 17 ** Alternatively, this file may be used under the terms of the GNU Free 18 ** Documentation License version 1.3 as published by the Free Software 19 ** Foundation and appearing in the file included in the packaging of this 20 ** file. 35 21 ** 36 22 ** If you have questions regarding the use of this file, please contact … … 88 74 paint device. 89 75 90 \sa QPaintEngine, QPainter, {The Coordinate System}, {The Paint 91 System} 76 \sa QPaintEngine, QPainter, {Coordinate System}, {Paint System} 92 77 */ 93 78 -
trunk/src/gui/painting/qpaintdevice_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintdevice_qws.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintdevice_win.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintdevice_x11.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 173 173 advantage of each to the fullest. 174 174 175 \sa QPainter, QPaintDevice::paintEngine(), { ThePaint System}175 \sa QPainter, QPaintDevice::paintEngine(), {Paint System} 176 176 */ 177 177 … … 993 993 \internal 994 994 995 Retr eives the rect for drawing within the backing store. This995 Retrieves the rect for drawing within the backing store. This 996 996 function should ONLY be used by the backing store. 997 997 */ -
trunk/src/gui/painting/qpaintengine.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine_alpha.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine_alpha_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 119 119 QTransform native = p->deviceTransform(); 120 120 QTransform logical = p->combinedTransform(); 121 121 122 if (p->hasClipping()) { 122 123 QRegion r = p->clipRegion(); 123 r.translate(native.dx() - logical.dx(), native.dy() - logical.dy());124 r.translate(native.dx(), native.dy()); 124 125 if (clip.isEmpty()) 125 126 clip = r; … … 129 130 qt_mac_clip_cg(context, clip, 0); 130 131 131 QPainterState *state = static_cast<QPainterState *>(pe->state); 132 Q_ASSERT(state); 133 if (!state->redirectionMatrix.isIdentity()) 134 CGContextTranslateCTM(context, state->redirectionMatrix.dx(), state->redirectionMatrix.dy()); 132 CGContextTranslateCTM(context, native.dx(), native.dy()); 135 133 } 136 134 } … … 1393 1391 kCGInterpolationHigh : kCGInterpolationNone); 1394 1392 } 1395 CGContextSetShouldSmoothFonts(d->hd, hints & QPainter::TextAntialiasing); 1393 bool textAntialiasing = (hints & QPainter::TextAntialiasing) == QPainter::TextAntialiasing; 1394 if (!textAntialiasing || d->disabledSmoothFonts) { 1395 d->disabledSmoothFonts = !textAntialiasing; 1396 CGContextSetShouldSmoothFonts(d->hd, textAntialiasing); 1397 } 1396 1398 } 1397 1399 -
trunk/src/gui/painting/qpaintengine_mac_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 149 149 public: 150 150 QCoreGraphicsPaintEnginePrivate() 151 : hd(0), shading(0), stackCount(0), complexXForm(false) 151 : hd(0), shading(0), stackCount(0), complexXForm(false), disabledSmoothFonts(false) 152 152 { 153 153 } … … 169 169 int stackCount; 170 170 bool complexXForm; 171 bool disabledSmoothFonts; 171 172 enum { CosmeticNone, CosmeticTransformPath, CosmeticSetPenWidth } cosmeticPen; 172 173 -
trunk/src/gui/painting/qpaintengine_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine_preview.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine_preview_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine_raster.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 41 41 42 42 #include <QtCore/qglobal.h> 43 #include <QtCore/qmutex.h> 43 44 44 45 #define QT_FT_BEGIN_HEADER … … 68 69 // #include <private/qrasterizer_p.h> 69 70 #include <private/qimage_p.h> 71 #include <private/qstatictext_p.h> 72 #include "qmemrotate_p.h" 70 73 71 74 #include "qpaintengine_raster_p.h" … … 251 254 #endif 252 255 256 QRasterPaintEnginePrivate::QRasterPaintEnginePrivate() : 257 QPaintEngineExPrivate(), 258 cachedLines(0) 259 { 260 } 253 261 254 262 … … 336 344 #endif 337 345 338 d->rasterPoolSize = 8192;339 d->rasterPoolBase =340 #if defined(Q_WS_WIN64)341 // We make use of setjmp and longjmp in qgrayraster.c which requires342 // 16-byte alignment, hence we hardcode this requirement here..343 (unsigned char *) _aligned_malloc(d->rasterPoolSize, sizeof(void*) * 2);344 #else345 (unsigned char *) malloc(d->rasterPoolSize);346 #endif347 Q_CHECK_PTR(d->rasterPoolBase);348 349 346 // The antialiasing raster. 350 347 d->grayRaster.reset(new QT_FT_Raster); 351 348 Q_CHECK_PTR(d->grayRaster.data()); 352 if (qt_ft_grays_raster.raster_new( 0,d->grayRaster.data()))349 if (qt_ft_grays_raster.raster_new(d->grayRaster.data())) 353 350 QT_THROW(std::bad_alloc()); // an error creating the raster is caused by a bad malloc 354 351 355 356 qt_ft_grays_raster.raster_reset(*d->grayRaster.data(), d->rasterPoolBase, d->rasterPoolSize);357 352 358 353 d->rasterizer.reset(new QRasterizer); … … 437 432 Q_D(QRasterPaintEngine); 438 433 439 #if defined(Q_WS_WIN64)440 _aligned_free(d->rasterPoolBase);441 #else442 free(d->rasterPoolBase);443 #endif444 445 434 qt_ft_grays_raster.raster_done(*d->grayRaster.data()); 446 435 } … … 455 444 if (device->devType() == QInternal::Pixmap) { 456 445 QPixmap *pixmap = static_cast<QPixmap *>(device); 457 if (pixmap->data->classId() == QPixmapData::RasterClass) 458 d->device = pixmap->data->buffer(); 446 QPixmapData *pd = pixmap->pixmapData(); 447 if (pd->classId() == QPixmapData::RasterClass) 448 d->device = pd->buffer(); 459 449 } else { 460 450 d->device = device; … … 471 461 QRasterPaintEngineState *s = state(); 472 462 ensureOutlineMapper(); 473 d->outlineMapper->m_clip_rect = d->deviceRect.adjusted(-10, -10, 10, 10); 474 475 // This is the upp 476 QRect bounds(-QT_RASTER_COORD_LIMIT, -QT_RASTER_COORD_LIMIT, 477 QT_RASTER_COORD_LIMIT*2 - 1, QT_RASTER_COORD_LIMIT * 2 - 1); 478 d->outlineMapper->m_clip_rect = bounds.intersected(d->outlineMapper->m_clip_rect); 479 463 d->outlineMapper->m_clip_rect = d->deviceRect; 464 465 if (d->outlineMapper->m_clip_rect.width() > QT_RASTER_COORD_LIMIT) 466 d->outlineMapper->m_clip_rect.setWidth(QT_RASTER_COORD_LIMIT); 467 if (d->outlineMapper->m_clip_rect.height() > QT_RASTER_COORD_LIMIT) 468 d->outlineMapper->m_clip_rect.setHeight(QT_RASTER_COORD_LIMIT); 480 469 481 470 d->rasterizer->setClipRect(d->deviceRect); … … 887 876 updateMatrix(s->matrix); 888 877 889 if (s->dirty & (DirtyPen|DirtyCompositionMode )) {878 if (s->dirty & (DirtyPen|DirtyCompositionMode|DirtyOpacity)) { 890 879 const QPainter::CompositionMode mode = s->composition_mode; 891 880 s->flags.fast_text = (s->penData.type == QSpanData::Solid) 881 && s->intOpacity == 256 892 882 && (mode == QPainter::CompositionMode_Source 893 883 || (mode == QPainter::CompositionMode_SourceOver … … 913 903 s->strokeFlags |= DirtyOpacity; 914 904 s->pixmapFlags |= DirtyOpacity; 905 s->dirty |= DirtyOpacity; 915 906 s->intOpacity = (int) (s->opacity * 256); 916 907 } … … 1115 1106 bool bilinear = q->state()->flags.bilinear; 1116 1107 1117 if (b.d->transform.type() > QTransform::TxNone) { // FALCON: optimi se1108 if (b.d->transform.type() > QTransform::TxNone) { // FALCON: optimize 1118 1109 spanData->setupMatrix(b.transform() * m, bilinear); 1119 1110 } else { … … 1222 1213 if (op != Qt::UniteClip && (op != Qt::IntersectClip || !s->clip 1223 1214 || s->clip->hasRectClip || s->clip->hasRegionClip)) { 1224 if (s->matrix.type() <= QTransform::Tx Translate1215 if (s->matrix.type() <= QTransform::TxScale 1225 1216 && ((path.shape() == QVectorPath::RectangleHint) 1226 1217 || (isRect(points, path.elementCount()) … … 1234 1225 1235 1226 QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]); 1236 clip(r.toRect(), op);1237 return;1227 if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op)) 1228 return; 1238 1229 } 1239 1230 } … … 1296 1287 #endif 1297 1288 1298 Q_D(QRasterPaintEngine);1299 1289 QRasterPaintEngineState *s = state(); 1300 1290 … … 1306 1296 return; 1307 1297 1308 } else if (op == Qt::ReplaceClip || s->clip == 0) { 1298 } else if (!setClipRectInDeviceCoords(s->matrix.mapRect(rect), op)) { 1299 QPaintEngineEx::clip(rect, op); 1300 return; 1301 } 1302 } 1303 1304 1305 bool QRasterPaintEngine::setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op) 1306 { 1307 Q_D(QRasterPaintEngine); 1308 QRect clipRect = r & d->deviceRect; 1309 QRasterPaintEngineState *s = state(); 1310 1311 if (op == Qt::ReplaceClip || s->clip == 0) { 1309 1312 1310 1313 // No current clip, hence we intersect with sysclip and be 1311 1314 // done with it... 1312 QRect clipRect = s->matrix.mapRect(rect) & d->deviceRect;1313 1315 QRegion clipRegion = systemClip(); 1314 1316 QClipData *clip = new QClipData(d->rasterBuffer->height()); … … 1326 1328 s->flags.has_clip_ownership = true; 1327 1329 1328 } else { // intersect clip with current clip1330 } else if (op == Qt::IntersectClip){ // intersect clip with current clip 1329 1331 QClipData *base = s->clip; 1330 1332 1331 1333 Q_ASSERT(base); 1332 1334 if (base->hasRectClip || base->hasRegionClip) { 1333 QRect clipRect = s->matrix.mapRect(rect) & d->deviceRect;1334 1335 if (!s->flags.has_clip_ownership) { 1335 1336 s->clip = new QClipData(d->rasterBuffer->height()); … … 1342 1343 s->clip->enabled = true; 1343 1344 } else { 1344 QPaintEngineEx::clip(rect, op); 1345 return; 1346 } 1347 } 1345 return false; 1346 } 1347 } else { 1348 return false; 1349 } 1350 1348 1351 qrasterpaintengine_dirty_clip(d, s); 1352 return true; 1349 1353 } 1350 1354 … … 1725 1729 int n = qFloor(dashOffset / patternLength); 1726 1730 dashOffset -= n * patternLength; 1727 while (dashOffset > pattern.at(dashIndex)) {1731 while (dashOffset >= pattern.at(dashIndex)) { 1728 1732 dashOffset -= pattern.at(dashIndex); 1729 dashIndex = (dashIndex + 1) % pattern.size(); 1733 if (++dashIndex >= pattern.size()) 1734 dashIndex = 0; 1730 1735 inDash = !inDash; 1731 1736 } … … 1738 1743 1739 1744 for (int i = 0; i < lineCount; ++i) { 1740 dashOffset = s->lastPen.dashOffset();1741 1745 if (lines[i].p1() == lines[i].p2()) { 1742 1746 if (s->lastPen.capStyle() != Qt::FlatCap) { … … 1812 1816 if (s->flags.tx_noshear) { 1813 1817 d->initializeRasterizer(&s->brushData); 1814 // ### Is normalizing really ne ssesary here?1818 // ### Is normalizing really necessary here? 1815 1819 const qreal *p = path.points(); 1816 1820 QRectF r = QRectF(p[0], p[1], p[2] - p[0], p[7] - p[1]).normalized(); … … 2372 2376 #endif 2373 2377 2374 if (pixmap.data->classId() == QPixmapData::RasterClass) { 2375 const QImage &image = static_cast<QRasterPixmapData *>(pixmap.data.data())->image; 2378 QPixmapData *pd = pixmap.pixmapData(); 2379 if (pd->classId() == QPixmapData::RasterClass) { 2380 const QImage &image = static_cast<QRasterPixmapData *>(pd)->image; 2376 2381 if (image.depth() == 1) { 2377 2382 Q_D(QRasterPaintEngine); … … 2412 2417 #endif 2413 2418 2414 if (pixmap.data->classId() == QPixmapData::RasterClass) { 2415 const QImage &image = static_cast<QRasterPixmapData *>(pixmap.data.data())->image; 2419 QPixmapData* pd = pixmap.pixmapData(); 2420 if (pd->classId() == QPixmapData::RasterClass) { 2421 const QImage &image = static_cast<QRasterPixmapData *>(pd)->image; 2416 2422 if (image.depth() == 1) { 2417 2423 Q_D(QRasterPaintEngine); … … 2430 2436 } 2431 2437 } else { 2432 const QImage image = pixmap.toImage(); 2438 QRect clippedSource = sr.toAlignedRect().intersected(pixmap.rect()); 2439 const QImage image = pd->toImage(clippedSource); 2440 QRectF translatedSource = sr.translated(-clippedSource.topLeft()); 2433 2441 if (image.depth() == 1) { 2434 2442 Q_D(QRasterPaintEngine); … … 2441 2449 return; 2442 2450 } else { 2443 drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);2451 drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), translatedSource); 2444 2452 } 2445 2453 } else { 2446 drawImage(r, image, sr);2454 drawImage(r, image, translatedSource); 2447 2455 } 2448 2456 } … … 2532 2540 } 2533 2541 2542 namespace { 2543 enum RotationType { 2544 Rotation90, 2545 Rotation180, 2546 Rotation270, 2547 NoRotation 2548 }; 2549 2550 inline RotationType qRotationType(const QTransform &transform) 2551 { 2552 QTransform::TransformationType type = transform.type(); 2553 2554 if (type > QTransform::TxRotate) 2555 return NoRotation; 2556 2557 if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(-1)) 2558 && qFuzzyCompare(transform.m21(), qreal(1)) && qFuzzyIsNull(transform.m22())) 2559 return Rotation90; 2560 2561 if (type == QTransform::TxScale && qFuzzyCompare(transform.m11(), qreal(-1)) && qFuzzyIsNull(transform.m12()) 2562 && qFuzzyIsNull(transform.m21()) && qFuzzyCompare(transform.m22(), qreal(-1))) 2563 return Rotation180; 2564 2565 if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(1)) 2566 && qFuzzyCompare(transform.m21(), qreal(-1)) && qFuzzyIsNull(transform.m22())) 2567 return Rotation270; 2568 2569 return NoRotation; 2570 } 2571 2572 inline bool isPixelAligned(const QRectF &rect) { 2573 return QRectF(rect.toRect()) == rect; 2574 } 2575 } 2576 2534 2577 /*! 2535 2578 \reimp … … 2552 2595 int sr_b = qCeil(sr.bottom()) - 1; 2553 2596 2554 if ( !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {2597 if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) { 2555 2598 // as fillRect will apply the aliased coordinate delta we need to 2556 2599 // subtract it here as we don't use it for image drawing … … 2593 2636 const QClipData *clip = d->clip(); 2594 2637 2638 if (s->matrix.type() > QTransform::TxTranslate 2639 && !stretch_sr 2640 && (!clip || clip->hasRectClip) 2641 && s->intOpacity == 256 2642 && (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver 2643 || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source) 2644 && d->rasterBuffer->format == img.format() 2645 && (d->rasterBuffer->format == QImage::Format_RGB16 2646 || d->rasterBuffer->format == QImage::Format_RGB32 2647 || (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied 2648 && d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source))) 2649 { 2650 RotationType rotationType = qRotationType(s->matrix); 2651 2652 if (rotationType != NoRotation && qMemRotateFunctions[d->rasterBuffer->format][rotationType] && img.rect().contains(sr.toAlignedRect())) { 2653 QRectF transformedTargetRect = s->matrix.mapRect(r); 2654 2655 if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing)) 2656 || (isPixelAligned(transformedTargetRect) && isPixelAligned(sr))) 2657 { 2658 QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect); 2659 if (clippedTransformedTargetRect.isNull()) 2660 return; 2661 2662 QRectF clippedTargetRect = s->matrix.inverted().mapRect(QRectF(clippedTransformedTargetRect)); 2663 2664 QRect clippedSourceRect 2665 = QRectF(sr.x() + clippedTargetRect.x() - r.x(), sr.y() + clippedTargetRect.y() - r.y(), 2666 clippedTargetRect.width(), clippedTargetRect.height()).toRect(); 2667 2668 uint dbpl = d->rasterBuffer->bytesPerLine(); 2669 uint sbpl = img.bytesPerLine(); 2670 2671 uchar *dst = d->rasterBuffer->buffer(); 2672 uint bpp = img.depth() >> 3; 2673 2674 const uchar *srcBase = img.bits() + clippedSourceRect.y() * sbpl + clippedSourceRect.x() * bpp; 2675 uchar *dstBase = dst + clippedTransformedTargetRect.y() * dbpl + clippedTransformedTargetRect.x() * bpp; 2676 2677 uint cw = clippedSourceRect.width(); 2678 uint ch = clippedSourceRect.height(); 2679 2680 qMemRotateFunctions[d->rasterBuffer->format][rotationType](srcBase, cw, ch, sbpl, dstBase, dbpl); 2681 2682 return; 2683 } 2684 } 2685 } 2686 2595 2687 if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) { 2596 2688 2597 if (s->flags.fast_images) { 2689 QRectF targetBounds = s->matrix.mapRect(r); 2690 bool exceedsPrecision = targetBounds.width() > 0xffff 2691 || targetBounds.height() > 0xffff; 2692 2693 if (s->flags.fast_images && !exceedsPrecision) { 2598 2694 if (s->matrix.type() > QTransform::TxScale) { 2599 2695 SrcOverTransformFunc func = qTransformFunctions[d->rasterBuffer->format][img.format()]; … … 2717 2813 QImage image; 2718 2814 2719 if (pixmap.data->classId() == QPixmapData::RasterClass) { 2720 image = static_cast<QRasterPixmapData *>(pixmap.data.data())->image; 2815 QPixmapData *pd = pixmap.pixmapData(); 2816 if (pd->classId() == QPixmapData::RasterClass) { 2817 image = static_cast<QRasterPixmapData *>(pd)->image; 2721 2818 } else { 2722 2819 image = pixmap.toImage(); … … 3003 3100 } 3004 3101 3005 void QRasterPaintEngine::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti) 3102 void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, 3103 const QFixedPoint *positions, QFontEngine *fontEngine) 3006 3104 { 3007 3105 Q_D(QRasterPaintEngine); 3008 3106 QRasterPaintEngineState *s = state(); 3009 3107 3010 QVarLengthArray<QFixedPoint> positions; 3011 QVarLengthArray<glyph_t> glyphs; 3012 QTransform matrix = s->matrix; 3013 matrix.translate(p.x(), p.y()); 3014 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); 3015 3016 QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : d->glyphCacheType; 3108 QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType; 3017 3109 3018 3110 QImageTextureGlyphCache *cache = 3019 (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(0, glyphType, s->matrix);3111 static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix)); 3020 3112 if (!cache) { 3021 3113 cache = new QImageTextureGlyphCache(glyphType, s->matrix); 3022 ti.fontEngine->setGlyphCache(0, cache);3023 } 3024 3025 cache->populate( ti, glyphs, positions);3114 fontEngine->setGlyphCache(0, cache); 3115 } 3116 3117 cache->populate(fontEngine, numGlyphs, glyphs, positions); 3026 3118 3027 3119 const QImage &image = cache->image(); … … 3041 3133 3042 3134 const uchar *bits = image.bits(); 3043 for (int i=0; i< glyphs.size(); ++i) {3135 for (int i=0; i<numGlyphs; ++i) { 3044 3136 const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]); 3045 3137 int x = qFloor(positions[i].x + offs) + c.baseLineX - margin; … … 3089 3181 TSize glyphBitmapSize; 3090 3182 fe->getCharacterData(glyphs[i], tmetrics, glyphBitmapBytes, glyphBitmapSize); 3091 const glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]); 3092 const int x = qFloor(positions[i].x + metrics.x + aliasDelta); 3093 const int y = qFloor(positions[i].y + metrics.y + aliasDelta); 3094 3183 const int x = qFloor(positions[i].x + tmetrics.HorizBearingX() + aliasDelta); 3184 const int y = qFloor(positions[i].y - tmetrics.HorizBearingY() + aliasDelta); 3095 3185 alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight); 3096 3186 } … … 3104 3194 3105 3195 /*! 3106 * Returns true if the rectangle is complet ly within the current clip3196 * Returns true if the rectangle is completely within the current clip 3107 3197 * state of the paint engine. 3108 3198 */ … … 3219 3309 3220 3310 /*! 3311 \reimp 3312 */ 3313 void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) 3314 { 3315 ensurePen(); 3316 ensureState(); 3317 3318 drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions, 3319 textItem->fontEngine()); 3320 } 3321 3322 /*! 3221 3323 \reimp 3222 3324 */ … … 3266 3368 #endif 3267 3369 if (drawCached) { 3268 drawCachedGlyphs(p, ti); 3370 QRasterPaintEngineState *s = state(); 3371 3372 QVarLengthArray<QFixedPoint> positions; 3373 QVarLengthArray<glyph_t> glyphs; 3374 3375 QTransform matrix = s->matrix; 3376 matrix.translate(p.x(), p.y()); 3377 3378 ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); 3379 3380 drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), ti.fontEngine); 3269 3381 return; 3270 3382 } … … 3373 3485 3374 3486 for(int i = 0; i < glyphs.size(); i++) { 3375 QFontEngineFT::Glyph *glyph = gset->g lyph_data.value(glyphs[i]);3487 QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i]); 3376 3488 3377 3489 if (!glyph || glyph->format != neededFormat) { … … 3609 3721 *dashOffset = 0; 3610 3722 *inDash = !(*inDash); 3611 *dashIndex = (*dashIndex + 1) % pattern.size(); 3723 if (++*dashIndex >= pattern.size()) 3724 *dashIndex = 0; 3612 3725 length -= dash; 3613 3726 l.setLength(dash); … … 3615 3728 } 3616 3729 3617 if (rasterize && dash !=0)3730 if (rasterize && dash > 0) 3618 3731 rasterizer->rasterizeLine(l.p1(), l.p2(), width / dash, squareCap); 3619 3732 } … … 3676 3789 || (qpen_style(s->lastPen) == Qt::NoPen && !s->flags.antialiased)) 3677 3790 && qMax(rect.width(), rect.height()) < QT_RASTER_COORD_LIMIT 3791 && !rect.isEmpty() 3678 3792 && s->matrix.type() <= QTransform::TxScale) // no shear 3679 3793 { … … 4049 4163 } 4050 4164 4165 extern "C" { 4166 int q_gray_rendered_spans(QT_FT_Raster raster); 4167 } 4168 4051 4169 void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, 4052 4170 ProcessSpans callback, … … 4071 4189 return; 4072 4190 } 4191 4192 // Initial size for raster pool is MINIMUM_POOL_SIZE so as to 4193 // minimize memory reallocations. However if initial size for 4194 // raster pool is changed for lower value, reallocations will 4195 // occur normally. 4196 const int rasterPoolInitialSize = MINIMUM_POOL_SIZE; 4197 int rasterPoolSize = rasterPoolInitialSize; 4198 unsigned char *rasterPoolBase; 4199 #if defined(Q_WS_WIN64) 4200 rasterPoolBase = 4201 // We make use of setjmp and longjmp in qgrayraster.c which requires 4202 // 16-byte alignment, hence we hardcode this requirement here.. 4203 (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2); 4204 #else 4205 unsigned char rasterPoolOnStack[rasterPoolInitialSize]; 4206 rasterPoolBase = rasterPoolOnStack; 4207 #endif 4208 Q_CHECK_PTR(rasterPoolBase); 4209 4210 qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); 4073 4211 4074 4212 void *data = userData; … … 4093 4231 int error; 4094 4232 4233 int rendered_spans = 0; 4234 4095 4235 while (!done) { 4096 4236 4097 4237 rasterParams.flags |= (QT_FT_RASTER_FLAG_AA | QT_FT_RASTER_FLAG_DIRECT); 4098 4238 rasterParams.gray_spans = callback; 4239 rasterParams.skip_spans = rendered_spans; 4099 4240 error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams); 4100 4241 4101 4242 // Out of memory, reallocate some more and try again... 4102 if (error == -6) { // -6 is Result_err_OutOfMemory4243 if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c 4103 4244 int new_size = rasterPoolSize * 2; 4104 4245 if (new_size > 1024 * 1024) { 4105 4246 qWarning("QPainter: Rasterization of primitive failed"); 4106 return;4247 break; 4107 4248 } 4249 4250 rendered_spans += q_gray_rendered_spans(*grayRaster.data()); 4108 4251 4109 4252 #if defined(Q_WS_WIN64) 4110 4253 _aligned_free(rasterPoolBase); 4111 4254 #else 4112 free(rasterPoolBase); 4255 if (rasterPoolBase != rasterPoolOnStack) // initially on the stack 4256 free(rasterPoolBase); 4113 4257 #endif 4114 4258 … … 4125 4269 4126 4270 qt_ft_grays_raster.raster_done(*grayRaster.data()); 4127 qt_ft_grays_raster.raster_new( 0,grayRaster.data());4271 qt_ft_grays_raster.raster_new(grayRaster.data()); 4128 4272 qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); 4129 4273 } else { … … 4131 4275 } 4132 4276 } 4277 4278 #if defined(Q_WS_WIN64) 4279 _aligned_free(rasterPoolBase); 4280 #else 4281 if (rasterPoolBase != rasterPoolOnStack) // initially on the stack 4282 free(rasterPoolBase); 4283 #endif 4133 4284 } 4134 4285 … … 4812 4963 hash_val += stops[i].second.rgba(); 4813 4964 4965 QMutexLocker lock(&mutex); 4814 4966 QGradientColorTableHash::const_iterator it = cache.constFind(hash_val); 4815 4967 … … 4845 4997 4846 4998 QGradientColorTableHash cache; 4999 QMutex mutex; 4847 5000 }; 4848 5001 -
trunk/src/gui/painting/qpaintengine_raster_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 204 204 void clip(const QRegion ®ion, Qt::ClipOperation op); 205 205 206 void drawStaticTextItem(QStaticTextItem *textItem); 207 206 208 enum ClipType { 207 209 RectClip, … … 258 260 void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill); 259 261 260 void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); 262 void drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, 263 QFontEngine *fontEngine); 261 264 262 265 #if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) 263 266 void drawGlyphsS60(const QPointF &p, const QTextItemInt &ti); 264 267 #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE 268 269 bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op); 265 270 266 271 inline void ensureBrush(const QBrush &brush) { … … 298 303 Q_DECLARE_PUBLIC(QRasterPaintEngine) 299 304 public: 305 QRasterPaintEnginePrivate(); 300 306 301 307 void rasterizeLine_dashed(QLineF line, qreal width, … … 352 358 353 359 QScopedPointer<QT_FT_Raster> grayRaster; 354 unsigned long rasterPoolSize;355 unsigned char *rasterPoolBase;356 360 357 361 QDataBuffer<QLineF> cachedLines; -
trunk/src/gui/painting/qpaintengine_s60.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 60 60 Q_D(QS60PaintEngine); 61 61 62 pixmapData->beginDataAccess(); 63 bool ret = QRasterPaintEngine::begin(device); 64 // Make sure QPaintEngine::paintDevice() returns the proper device. 65 // QRasterPaintEngine changes pdev to QImage in case of RasterClass QPixmapData 66 // which is incorrect in Symbian. 67 d->pdev = device; 68 return ret; 62 if (pixmapData->classId() == QPixmapData::RasterClass) { 63 pixmapData->beginDataAccess(); 64 bool ret = QRasterPaintEngine::begin(device); 65 // Make sure QPaintEngine::paintDevice() returns the proper device. 66 // QRasterPaintEngine changes pdev to QImage in case of RasterClass QPixmapData 67 // which is incorrect in Symbian. 68 d->pdev = device; 69 return ret; 70 } 71 72 return QRasterPaintEngine::begin(device); 69 73 } 70 74 71 75 bool QS60PaintEngine::end() 72 76 { 73 bool ret = QRasterPaintEngine::end(); 74 pixmapData->endDataAccess(); 75 return ret; 77 if (pixmapData->classId() == QPixmapData::RasterClass) { 78 bool ret = QRasterPaintEngine::end(); 79 pixmapData->endDataAccess(); 80 return ret; 81 } 82 return QRasterPaintEngine::end(); 76 83 } 77 84 78 85 void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm) 79 86 { 80 QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); 81 srcData->beginDataAccess(); 82 QRasterPaintEngine::drawPixmap(p, pm); 83 srcData->endDataAccess(); 87 if (pm.pixmapData()->classId() == QPixmapData::RasterClass) { 88 QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); 89 srcData->beginDataAccess(); 90 QRasterPaintEngine::drawPixmap(p, pm); 91 srcData->endDataAccess(); 92 } else { 93 QRasterPaintEngine::drawPixmap(p, pm); 94 } 84 95 } 85 96 86 97 void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) 87 98 { 88 QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); 89 srcData->beginDataAccess(); 90 QRasterPaintEngine::drawPixmap(r, pm, sr); 91 srcData->endDataAccess(); 99 if (pm.pixmapData()->classId() == QPixmapData::RasterClass) { 100 QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); 101 srcData->beginDataAccess(); 102 QRasterPaintEngine::drawPixmap(r, pm, sr); 103 srcData->endDataAccess(); 104 } else { 105 QRasterPaintEngine::drawPixmap(r, pm, sr); 106 } 92 107 } 93 108 94 109 void QS60PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) 95 110 { 96 QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); 97 srcData->beginDataAccess(); 98 QRasterPaintEngine::drawTiledPixmap(r, pm, sr); 99 srcData->endDataAccess(); 111 if (pm.pixmapData()->classId() == QPixmapData::RasterClass) { 112 QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); 113 srcData->beginDataAccess(); 114 QRasterPaintEngine::drawTiledPixmap(r, pm, sr); 115 srcData->endDataAccess(); 116 } else { 117 QRasterPaintEngine::drawTiledPixmap(r, pm, sr); 118 } 100 119 } 101 120 -
trunk/src/gui/painting/qpaintengine_s60_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengine_x11.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 80 80 #endif 81 81 82 #include <private/qstylehelper_p.h> 83 82 84 QT_BEGIN_NAMESPACE 83 85 … … 225 227 { 226 228 QPixmap pm; 227 QString key = QLatin1String("$qt-alpha-brush$") + QString::number(alpha) + QString::number(screen); 229 QString key = QLatin1Literal("$qt-alpha-brush$") 230 % HexString<uchar>(alpha) 231 % HexString<int>(screen); 232 228 233 if (!QPixmapCache::find(key, pm)) { 229 234 // #### why not use a mono image here???? … … 316 321 } 317 322 // none found, replace one 318 int i = rand() % 16;323 int i = qrand() % 16; 319 324 320 325 if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) { … … 1449 1454 void QX11PaintEngine::drawEllipse(const QRect &rect) 1450 1455 { 1456 if (rect.isEmpty()) { 1457 drawRects(&rect, 1); 1458 return; 1459 } 1460 1451 1461 Q_D(QX11PaintEngine); 1452 1462 QRect devclip(SHRT_MIN, SHRT_MIN, SHRT_MAX*2 - 1, SHRT_MAX*2 - 1); … … 1907 1917 1908 1918 QPixmap pixmap = qt_toX11Pixmap(px); 1919 if(pixmap.isNull()) 1920 return; 1909 1921 1910 1922 if ((d->xinfo && d->xinfo->screen() != pixmap.x11Info().screen()) -
trunk/src/gui/painting/qpaintengine_x11_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpaintengineex.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 150 150 151 151 struct StrokeHandler { 152 StrokeHandler(int reserve) : pts(reserve), types(reserve) {} 152 153 QDataBuffer<qreal> pts; 153 154 QDataBuffer<QPainterPath::ElementType> types; … … 395 396 396 397 if (!d->strokeHandler) { 397 d->strokeHandler = new StrokeHandler ;398 d->strokeHandler = new StrokeHandler(path.elementCount()+4); 398 399 d->stroker.setMoveToHook(qpaintengineex_moveTo); 399 400 d->stroker.setLineToHook(qpaintengineex_lineTo); … … 461 462 // non-cosmetic pens will be transformed as part of fill 462 463 // later, so they are also covered here.. 464 d->activeStroker->setCurveThresholdFromTransform(state()->matrix); 463 465 d->activeStroker->begin(d->strokeHandler); 464 466 if (types) { … … 493 495 d->activeStroker->moveTo(points[0], points[1]); 494 496 points += 2; 495 ++types;496 497 while (points < lastPoint) { 497 498 d->activeStroker->lineTo(points[0], points[1]); 498 499 points += 2; 499 ++types;500 500 } 501 501 if (path.hasImplicitClose()) … … 518 518 d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); 519 519 } else { 520 d->activeStroker->setCurveThresholdFromTransform(QTransform()); 520 521 d->activeStroker->begin(d->strokeHandler); 521 522 if (types) { … … 559 560 d->activeStroker->moveTo(p.x(), p.y()); 560 561 points += 2; 561 ++types;562 562 while (points < lastPoint) { 563 563 QPointF p = ((QPointF *)points)[0] * state()->matrix; 564 564 d->activeStroker->lineTo(p.x(), p.y()); 565 565 points += 2; 566 ++types;567 566 } 568 567 if (path.hasImplicitClose()) … … 608 607 qreal right = r.x() + r.width(); 609 608 qreal bottom = r.y() + r.height(); 610 qreal pts[] = { r.x(), r.y(),611 right, r.y(),609 qreal pts[] = { qreal(r.x()), qreal(r.y()), 610 right, qreal(r.y()), 612 611 right, bottom, 613 r.x(), bottom,614 r.x(), r.y() };612 qreal(r.x()), bottom, 613 qreal(r.x()), qreal(r.y()) }; 615 614 QVectorPath vp(pts, 5, 0, QVectorPath::RectangleHint); 616 615 clip(vp, op); … … 712 711 qreal right = r.x() + r.width(); 713 712 qreal bottom = r.y() + r.height(); 714 qreal pts[] = { r.x(), r.y(),715 right, r.y(),713 qreal pts[] = { qreal(r.x()), qreal(r.y()), 714 right, qreal(r.y()), 716 715 right, bottom, 717 r.x(), bottom,718 r.x(), r.y() };716 qreal(r.x()), bottom, 717 qreal(r.x()), qreal(r.y()) }; 719 718 QVectorPath vp(pts, 5, 0, QVectorPath::RectangleHint); 720 719 draw(vp); … … 770 769 x1, y2 - yRadius, 771 770 x1, y1 + yRadius, // LineTo 772 x1, y1 + KAPPA* yRadius, // CurveTo771 x1, y1 + (1 - KAPPA) * yRadius, // CurveTo 773 772 x1 + (1 - KAPPA) * xRadius, y1, 774 773 x1 + xRadius, y1 … … 833 832 int point_count = 0; 834 833 x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count); 835 QVectorPath vp((qreal *) pts, 13, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);834 QVectorPath vp((qreal *) pts, point_count, qpaintengineex_ellipse_types, QVectorPath::EllipseHint); 836 835 draw(vp); 837 836 } … … 894 893 pts[++oset] = points[i].x(); 895 894 pts[++oset] = points[i].y(); 896 pts[++oset] = points[i].x() + 1/63 ;895 pts[++oset] = points[i].x() + 1/63.; 897 896 pts[++oset] = points[i].y(); 898 897 } … … 904 903 } else { 905 904 for (int i=0; i<pointCount; ++i) { 906 qreal pts[] = { points[i].x(), points[i].y(), points[i].x() +1/63., points[i].y() }; 905 qreal pts[] = { qreal(points[i].x()), qreal(points[i].y()), 906 qreal(points[i].x() +1/63.), qreal(points[i].y()) }; 907 907 QVectorPath path(pts, 2, 0); 908 908 stroke(path, pen); … … 971 971 } 972 972 973 void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints /*hints*/) 974 { 973 void QPaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, 974 const QPixmap &pixmap, QPainter::PixmapFragmentHints /*hints*/) 975 { 976 if (pixmap.isNull()) 977 return; 978 975 979 qreal oldOpacity = state()->opacity; 976 980 QTransform oldTransform = state()->matrix; 977 981 978 for (int i = 0; i < dataCount; ++i) {982 for (int i = 0; i < fragmentCount; ++i) { 979 983 QTransform transform = oldTransform; 980 transform.translate( drawingData[i].point.x(), drawingData[i].point.y());981 transform.rotate( drawingData[i].rotation);982 state()->opacity = oldOpacity * drawingData[i].opacity;984 transform.translate(fragments[i].x, fragments[i].y); 985 transform.rotate(fragments[i].rotation); 986 state()->opacity = oldOpacity * fragments[i].opacity; 983 987 state()->matrix = transform; 984 988 opacityChanged(); 985 989 transformChanged(); 986 990 987 qreal w = drawingData[i].scaleX * drawingData[i].source.width(); 988 qreal h = drawingData[i].scaleY * drawingData[i].source.height(); 989 drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source); 991 qreal w = fragments[i].scaleX * fragments[i].width; 992 qreal h = fragments[i].scaleY * fragments[i].height; 993 QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop, 994 fragments[i].width, fragments[i].height); 995 drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect); 990 996 } 991 997 -
trunk/src/gui/painting/qpaintengineex_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 71 71 class QPainterState; 72 72 class QPaintEngineExPrivate; 73 class QStaticTextItem; 73 74 struct StrokeHandler; 74 75 … … 197 198 virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); 198 199 199 virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints); 200 virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, 201 QFlags<QPainter::PixmapFragmentHint> hints); 200 202 201 203 virtual void updateState(const QPaintEngineState &state); 204 205 virtual void drawStaticTextItem(QStaticTextItem *) = 0; 202 206 203 207 virtual void setState(QPainterState *s); -
trunk/src/gui/painting/qpainter.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 39 39 ** 40 40 ****************************************************************************/ 41 41 42 // QtCore 42 43 #include <qdebug.h> … … 70 71 #include <private/qpaintengine_raster_p.h> 71 72 #include <private/qmath_p.h> 73 #include <qstatictext.h> 74 #include <private/qstatictext_p.h> 75 #include <private/qstylehelper_p.h> 72 76 73 77 QT_BEGIN_NAMESPACE … … 87 91 int tabstops, int* tabarray, int tabarraylen, 88 92 QPainter *painter); 93 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, 94 QTextCharFormat::UnderlineStyle underlineStyle, 95 const QTextItem::RenderFlags flags, qreal width, 96 const QTextCharFormat &charFormat); 97 // Helper function to calculate left most position, width and flags for decoration drawing 98 static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, 99 const QFixedPoint *positions, int glyphCount, 100 QFontEngine *fontEngine, const QFont &font, 101 const QTextCharFormat &charFormat); 89 102 90 103 static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush) … … 684 697 skip = false; 685 698 686 QBrush penBrush = s->pen.brush();687 Qt::BrushStyle brushStyle = s->brush.style();688 Qt::BrushStyle penBrushStyle = penBrush.style();699 QBrush penBrush = (qpen_style(s->pen) == Qt::NoPen) ? QBrush(Qt::NoBrush) : qpen_brush(s->pen); 700 Qt::BrushStyle brushStyle = qbrush_style(s->brush); 701 Qt::BrushStyle penBrushStyle = qbrush_style(penBrush); 689 702 alpha = (penBrushStyle != Qt::NoBrush 690 703 && (penBrushStyle < Qt::LinearGradientPattern && penBrush.color().alpha() != 255) … … 968 981 device on which the painter paints, and paintEngine() returns the 969 982 paint engine that the painter is currently operating on. For more 970 information, see \l {The Paint System} documentation.983 information, see the \l {Paint System}. 971 984 972 985 Sometimes it is desirable to make someone else paint on an unusual … … 1013 1026 \o viewport(), window(), worldTransform() make up the painter's coordinate 1014 1027 transformation system. For more information, see the \l 1015 {Coordinate Transformations} section and the \l { TheCoordinate1028 {Coordinate Transformations} section and the \l {Coordinate 1016 1029 System} documentation. 1017 1030 … … 1220 1233 worldTransform(). A matrix transforms a point in the plane to another 1221 1234 point. For more information about the transformation matrix, see 1222 the \l { TheCoordinate System} and QTransform documentation.1235 the \l {Coordinate System} and QTransform documentation. 1223 1236 1224 1237 The setWorldTransform() function can replace or add to the currently … … 1242 1255 transformation matrix. 1243 1256 1244 See also \l { The Coordinate System} documentation.1257 See also \l {Coordinate System} 1245 1258 1246 1259 \section1 Clipping … … 1561 1574 d->engine->setDirty(QPaintEngine::DirtyFont); 1562 1575 } 1563 d->state->layoutDirection = widget->layoutDirection();1564 1576 } 1565 1577 … … 1871 1883 initFrom(widget); 1872 1884 } else { 1873 d->state->layoutDirection = Q Application::layoutDirection();1885 d->state->layoutDirection = Qt::LayoutDirectionAuto; 1874 1886 // make sure we have a font compatible with the paintdevice 1875 1887 d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device()); … … 2389 2401 return; 2390 2402 } 2403 if (d->state->composition_mode == mode) 2404 return; 2391 2405 if (d->extended) { 2392 2406 d->state->composition_mode = mode; … … 2704 2718 2705 2719 if (d->extended) { 2706 if ( !hasClipping() && (op == Qt::IntersectClip ||op == Qt::UniteClip))2720 if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) 2707 2721 op = Qt::ReplaceClip; 2708 2722 … … 2762 2776 } 2763 2777 2764 if ( !hasClipping() && (op == Qt::IntersectClip ||op == Qt::UniteClip))2778 if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) 2765 2779 op = Qt::ReplaceClip; 2766 2780 … … 2817 2831 } 2818 2832 2819 if ( !hasClipping() && (op == Qt::IntersectClip ||op == Qt::UniteClip))2833 if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) 2820 2834 op = Qt::ReplaceClip; 2821 2835 … … 2878 2892 2879 2893 For more information about the coordinate system, transformations 2880 and window-viewport conversion, see \l {The Coordinate System} 2881 documentation. 2894 and window-viewport conversion, see \l {Coordinate System}. 2882 2895 2883 2896 \sa setWorldTransform(), QTransform … … 2899 2912 2900 2913 \sa {QPainter#Coordinate Transformations}{Coordinate Transformations}, 2901 { TheCoordinate System}2914 {Coordinate System} 2902 2915 */ 2903 2916 … … 3042 3055 false. 3043 3056 3044 \sa setWorldMatrixEnabled(), worldTransform(), { TheCoordinate System}3057 \sa setWorldMatrixEnabled(), worldTransform(), {Coordinate System} 3045 3058 */ 3046 3059 … … 3223 3236 } 3224 3237 3225 if ( !hasClipping() && (op == Qt::IntersectClip ||op == Qt::UniteClip))3238 if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip)) 3226 3239 op = Qt::ReplaceClip; 3227 3240 … … 3384 3397 \endtable 3385 3398 3386 \sa drawLines(), drawPolyline(), { TheCoordinate System}3399 \sa drawLines(), drawPolyline(), {Coordinate System} 3387 3400 */ 3388 3401 … … 3431 3444 \endtable 3432 3445 3433 \sa drawRects(), drawPolygon(), { TheCoordinate System}3446 \sa drawRects(), drawPolygon(), {Coordinate System} 3434 3447 */ 3435 3448 … … 3595 3608 pen's color. 3596 3609 3597 \sa { TheCoordinate System}3610 \sa {Coordinate System} 3598 3611 */ 3599 3612 … … 3617 3630 the current pen's color. 3618 3631 3619 \sa { TheCoordinate System}3632 \sa {Coordinate System} 3620 3633 */ 3621 3634 void QPainter::drawPoints(const QPointF *points, int pointCount) … … 4223 4236 \endtable 4224 4237 4225 \sa drawPie(), { TheCoordinate System}4238 \sa drawPie(), {Coordinate System} 4226 4239 */ 4227 4240 void QPainter::drawEllipse(const QRectF &r) … … 4237 4250 4238 4251 QRectF rect(r.normalized()); 4239 if (rect.isEmpty())4240 return;4241 4252 4242 4253 if (d->extended) { … … 4280 4291 4281 4292 QRect rect(r.normalized()); 4282 if (rect.isEmpty())4283 return;4284 4293 4285 4294 if (d->extended) { … … 4353 4362 \endtable 4354 4363 4355 \sa drawPie(), drawChord(), { TheCoordinate System}4364 \sa drawPie(), drawChord(), {Coordinate System} 4356 4365 */ 4357 4366 … … 4417 4426 \endtable 4418 4427 4419 \sa drawEllipse(), drawChord(), { TheCoordinate System}4428 \sa drawEllipse(), drawChord(), {Coordinate System} 4420 4429 */ 4421 4430 void QPainter::drawPie(const QRectF &r, int a, int alen) … … 4486 4495 \endtable 4487 4496 4488 \sa drawArc(), drawPie(), { TheCoordinate System}4497 \sa drawArc(), drawPie(), {Coordinate System} 4489 4498 */ 4490 4499 void QPainter::drawChord(const QRectF &r, int a, int alen) … … 4777 4786 \endtable 4778 4787 4779 \sa drawLines(), drawPolygon(), { TheCoordinate System}4788 \sa drawLines(), drawPolygon(), {Coordinate System} 4780 4789 */ 4781 4790 void QPainter::drawPolyline(const QPointF *points, int pointCount) … … 4916 4925 rules. 4917 4926 4918 \sa drawConvexPolygon(), drawPolyline(), { TheCoordinate System}4927 \sa drawConvexPolygon(), drawPolyline(), {Coordinate System} 4919 4928 */ 4920 4929 void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule) … … 5067 5076 be faster than the drawPolygon() function. 5068 5077 5069 \sa drawPolygon(), drawPolyline(), { TheCoordinate System}5078 \sa drawPolygon(), drawPolyline(), {Coordinate System} 5070 5079 */ 5071 5080 … … 5412 5421 setBackgroundMode(Qt::TransparentMode); 5413 5422 setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform); 5414 QBrush brush(d->state->pen.color(), pm); 5423 QBrush brush; 5424 5425 if (sw == pm.width() && sh == pm.height()) 5426 brush = QBrush(d->state->pen.color(), pm); 5427 else 5428 brush = QBrush(d->state->pen.color(), pm.copy(sx, sy, sw, sh)); 5429 5415 5430 setBrush(brush); 5416 5431 setPen(Qt::NoPen); 5417 setBrushOrigin(QPointF(-sx, -sy));5418 5432 5419 5433 drawRect(QRectF(0, 0, sw, sh)); … … 5698 5712 } 5699 5713 5714 5715 void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, const QPointF *positionArray, 5716 int glyphCount) 5717 { 5718 QPainterPrivate *painter_d = QPainterPrivate::get(painter); 5719 painter_d->drawGlyphs(glyphArray, positionArray, glyphCount); 5720 } 5721 5722 void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *positionArray, 5723 int glyphCount) 5724 { 5725 updateState(state); 5726 5727 QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common); 5728 5729 while (fontEngine->type() == QFontEngine::Multi) { 5730 // Pick engine based on first glyph in array if we are using a multi engine. 5731 // (all glyphs must be for same font) 5732 int engineIdx = 0; 5733 if (glyphCount > 0) 5734 engineIdx = glyphArray[0] >> 24; 5735 5736 fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx); 5737 } 5738 5739 QVarLengthArray<QFixedPoint, 128> positions; 5740 for (int i=0; i<glyphCount; ++i) { 5741 QFixedPoint fp = QFixedPoint::fromPointF(positionArray[i]); 5742 positions.append(fp); 5743 } 5744 5745 if (extended != 0) { 5746 QStaticTextItem staticTextItem; 5747 staticTextItem.color = state->pen.color(); 5748 staticTextItem.font = state->font; 5749 staticTextItem.setFontEngine(fontEngine); 5750 staticTextItem.numGlyphs = glyphCount; 5751 staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray)); 5752 staticTextItem.glyphPositions = positions.data(); 5753 5754 extended->drawStaticTextItem(&staticTextItem); 5755 } else { 5756 QTextItemInt textItem; 5757 textItem.f = &state->font; 5758 textItem.fontEngine = fontEngine; 5759 5760 QVarLengthArray<QFixed, 128> advances(glyphCount); 5761 QVarLengthArray<QGlyphJustification, 128> glyphJustifications(glyphCount); 5762 QVarLengthArray<HB_GlyphAttributes, 128> glyphAttributes(glyphCount); 5763 qMemSet(glyphAttributes.data(), 0, glyphAttributes.size() * sizeof(HB_GlyphAttributes)); 5764 qMemSet(advances.data(), 0, advances.size() * sizeof(QFixed)); 5765 qMemSet(glyphJustifications.data(), 0, glyphJustifications.size() * sizeof(QGlyphJustification)); 5766 5767 textItem.glyphs.numGlyphs = glyphCount; 5768 textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray)); 5769 textItem.glyphs.offsets = positions.data(); 5770 textItem.glyphs.advances_x = advances.data(); 5771 textItem.glyphs.advances_y = advances.data(); 5772 textItem.glyphs.justifications = glyphJustifications.data(); 5773 textItem.glyphs.attributes = glyphAttributes.data(); 5774 5775 engine->drawTextItem(QPointF(0, 0), textItem); 5776 } 5777 } 5778 5779 /*! 5780 5781 \fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText) 5782 \since 4.7 5783 \overload 5784 5785 Draws the \a staticText at the \a topLeftPosition. 5786 5787 \note The y-position is used as the top of the font. 5788 5789 */ 5790 5791 /*! 5792 \fn void QPainter::drawStaticText(int left, int top, const QStaticText &staticText) 5793 \since 4.7 5794 \overload 5795 5796 Draws the \a staticText at coordinates \a left and \a top. 5797 5798 \note The y-position is used as the top of the font. 5799 */ 5800 5700 5801 /*! 5701 5802 \fn void QPainter::drawText(const QPointF &position, const QString &text) … … 5721 5822 5722 5823 /*! 5824 \since 4.7 5825 5826 Draws the given \a staticText at the given \a topLeftPosition. 5827 5828 The text will be drawn using the font and the transformation set on the painter. If the 5829 font and/or transformation set on the painter are different from the ones used to initialize 5830 the layout of the QStaticText, then the layout will have to be recalculated. Use 5831 QStaticText::prepare() to initialize \a staticText with the font and transformation with which 5832 it will later be drawn. 5833 5834 If \a topLeftPosition is not the same as when \a staticText was initialized, or when it was 5835 last drawn, then there will be a slight overhead when translating the text to its new position. 5836 5837 \note If the painter's transformation is not affine, then \a staticText will be drawn using 5838 regular calls to drawText(), losing any potential for performance improvement. 5839 5840 \note The y-position is used as the top of the font. 5841 5842 \sa QStaticText 5843 */ 5844 void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText) 5845 { 5846 Q_D(QPainter); 5847 if (!d->engine || staticText.text().isEmpty() || pen().style() == Qt::NoPen) 5848 return; 5849 5850 QStaticTextPrivate *staticText_d = 5851 const_cast<QStaticTextPrivate *>(QStaticTextPrivate::get(&staticText)); 5852 5853 if (font() != staticText_d->font) { 5854 staticText_d->font = font(); 5855 staticText_d->needsRelayout = true; 5856 } 5857 5858 // If we don't have an extended paint engine, or if the painter is projected, 5859 // we go through standard code path 5860 if (d->extended == 0 || !d->state->matrix.isAffine()) { 5861 staticText_d->paintText(topLeftPosition, this); 5862 return; 5863 } 5864 5865 bool paintEngineSupportsTransformations = d->extended->type() == QPaintEngine::OpenGL2 5866 || d->extended->type() == QPaintEngine::OpenVG 5867 || d->extended->type() == QPaintEngine::OpenGL; 5868 5869 if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) { 5870 staticText_d->untransformedCoordinates = true; 5871 staticText_d->needsRelayout = true; 5872 } else if (!paintEngineSupportsTransformations && staticText_d->untransformedCoordinates) { 5873 staticText_d->untransformedCoordinates = false; 5874 staticText_d->needsRelayout = true; 5875 } 5876 5877 // Don't recalculate entire layout because of translation, rather add the dx and dy 5878 // into the position to move each text item the correct distance. 5879 QPointF transformedPosition = topLeftPosition; 5880 if (!staticText_d->untransformedCoordinates) 5881 transformedPosition = transformedPosition * d->state->matrix; 5882 QTransform oldMatrix; 5883 5884 // The translation has been applied to transformedPosition. Remove translation 5885 // component from matrix. 5886 if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) { 5887 qreal m11 = d->state->matrix.m11(); 5888 qreal m12 = d->state->matrix.m12(); 5889 qreal m13 = d->state->matrix.m13(); 5890 qreal m21 = d->state->matrix.m21(); 5891 qreal m22 = d->state->matrix.m22(); 5892 qreal m23 = d->state->matrix.m23(); 5893 qreal m33 = d->state->matrix.m33(); 5894 5895 oldMatrix = d->state->matrix; 5896 d->state->matrix.setMatrix(m11, m12, m13, 5897 m21, m22, m23, 5898 0.0, 0.0, m33); 5899 } 5900 5901 // If the transform is not identical to the text transform, 5902 // we have to relayout the text (for other transformations than plain translation) 5903 bool staticTextNeedsReinit = staticText_d->needsRelayout; 5904 if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) { 5905 staticText_d->matrix = d->state->matrix; 5906 staticTextNeedsReinit = true; 5907 } 5908 5909 // Recreate the layout of the static text because the matrix or font has changed 5910 if (staticTextNeedsReinit) 5911 staticText_d->init(); 5912 5913 if (transformedPosition != staticText_d->position) { // Translate to actual position 5914 QFixed fx = QFixed::fromReal(transformedPosition.x()); 5915 QFixed fy = QFixed::fromReal(transformedPosition.y()); 5916 QFixed oldX = QFixed::fromReal(staticText_d->position.x()); 5917 QFixed oldY = QFixed::fromReal(staticText_d->position.y()); 5918 for (int item=0; item<staticText_d->itemCount;++item) { 5919 QStaticTextItem *textItem = staticText_d->items + item; 5920 for (int i=0; i<textItem->numGlyphs; ++i) { 5921 textItem->glyphPositions[i].x += fx - oldX; 5922 textItem->glyphPositions[i].y += fy - oldY; 5923 } 5924 textItem->userDataNeedsUpdate = true; 5925 } 5926 5927 staticText_d->position = transformedPosition; 5928 } 5929 5930 QPen oldPen = d->state->pen; 5931 QColor currentColor = oldPen.color(); 5932 for (int i=0; i<staticText_d->itemCount; ++i) { 5933 QStaticTextItem *item = staticText_d->items + i; 5934 if (item->color.isValid() && currentColor != item->color) { 5935 setPen(item->color); 5936 currentColor = item->color; 5937 } 5938 d->extended->drawStaticTextItem(item); 5939 5940 drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions, 5941 item->numGlyphs, item->fontEngine(), staticText_d->font, 5942 QTextCharFormat()); 5943 } 5944 if (currentColor != oldPen.color()) 5945 setPen(oldPen); 5946 5947 if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating()) 5948 d->state->matrix = oldMatrix; 5949 } 5950 5951 /*! 5723 5952 \internal 5724 5953 */ … … 5734 5963 if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen) 5735 5964 return; 5965 5966 if (tf & Qt::TextBypassShaping) { 5967 // Skip harfbuzz complex shaping, shape using glyph advances only 5968 int len = str.length(); 5969 int numGlyphs = len; 5970 QVarLengthGlyphLayoutArray glyphs(len); 5971 QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common); 5972 if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) { 5973 glyphs.resize(numGlyphs); 5974 if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) 5975 Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); 5976 } 5977 5978 QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine); 5979 drawTextItem(p, gf); 5980 return; 5981 } 5736 5982 5737 5983 QStackTextEngine engine(str, d->state->font); … … 5940 6186 By default, QPainter draws text anti-aliased. 5941 6187 5942 \note The y-position is used as the baselineof the font.6188 \note The y-position is used as the top of the font. 5943 6189 5944 6190 \sa Qt::AlignmentFlag, Qt::TextFlag … … 6015 6261 const qreal radiusBase = qMax(qreal(1), maxRadius); 6016 6262 6017 QString key = QLatin1String("WaveUnderline-"); 6018 key += pen.color().name(); 6019 key += QLatin1Char('-'); 6020 key += QString::number(radiusBase); 6263 QString key = QLatin1Literal("WaveUnderline-") 6264 % pen.color().name() 6265 % HexString<qreal>(radiusBase); 6021 6266 6022 6267 QPixmap pixmap; … … 6063 6308 } 6064 6309 6065 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti) 6066 { 6067 QTextCharFormat::UnderlineStyle underlineStyle = ti.underlineStyle; 6310 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, 6311 QTextCharFormat::UnderlineStyle underlineStyle, 6312 const QTextItem::RenderFlags flags, qreal width, 6313 const QTextCharFormat &charFormat) 6314 { 6068 6315 if (underlineStyle == QTextCharFormat::NoUnderline 6069 && !(ti.flags & (QTextItem::StrikeOut | QTextItem::Overline))) 6070 return; 6071 6072 QFontEngine *fe = ti.fontEngine; 6316 && !(flags & (QTextItem::StrikeOut | QTextItem::Overline))) 6317 return; 6073 6318 6074 6319 const QPen oldPen = painter->pen(); … … 6080 6325 pen.setCapStyle(Qt::FlatCap); 6081 6326 6082 QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y());6327 QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y()); 6083 6328 6084 6329 const qreal underlineOffset = fe->underlinePosition().toReal(); … … 6095 6340 painter->translate(0, pos.y() + 1); 6096 6341 6097 QColor uc = ti.charFormat.underlineColor();6342 QColor uc = charFormat.underlineColor(); 6098 6343 if (uc.isValid()) 6099 6344 pen.setColor(uc); … … 6101 6346 // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms 6102 6347 const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen); 6103 const int descent = (int) ti.descent.toReal();6348 const int descent = (int) fe->descent().toReal(); 6104 6349 6105 6350 painter->setBrushOrigin(painter->brushOrigin().x(), 0); 6106 painter->fillRect(pos.x(), 0, qCeil( ti.width.toReal()), qMin(wave.height(), descent), wave);6351 painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave); 6107 6352 painter->restore(); 6108 6353 } else if (underlineStyle != QTextCharFormat::NoUnderline) { 6109 6354 QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos); 6110 6355 6111 QColor uc = ti.charFormat.underlineColor();6356 QColor uc = charFormat.underlineColor(); 6112 6357 if (uc.isValid()) 6113 6358 pen.setColor(uc); … … 6121 6366 pen.setColor(oldPen.color()); 6122 6367 6123 if ( ti.flags & QTextItem::StrikeOut) {6368 if (flags & QTextItem::StrikeOut) { 6124 6369 QLineF strikeOutLine = line; 6125 6370 strikeOutLine.translate(0., - fe->ascent().toReal() / 3.); … … 6128 6373 } 6129 6374 6130 if ( ti.flags & QTextItem::Overline) {6375 if (flags & QTextItem::Overline) { 6131 6376 QLineF overLine = line; 6132 6377 overLine.translate(0., - fe->ascent().toReal()); … … 6137 6382 painter->setPen(oldPen); 6138 6383 painter->setBrush(oldBrush); 6384 } 6385 6386 static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, 6387 const QFixedPoint *positions, int glyphCount, 6388 QFontEngine *fontEngine, const QFont &font, 6389 const QTextCharFormat &charFormat) 6390 { 6391 if (!(font.underline() || font.strikeOut() || font.overline())) 6392 return; 6393 6394 QFixed leftMost; 6395 QFixed rightMost; 6396 QFixed baseLine; 6397 for (int i=0; i<glyphCount; ++i) { 6398 glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]); 6399 if (i == 0 || leftMost > positions[i].x) 6400 leftMost = positions[i].x; 6401 6402 // We don't support glyphs that do not share a common baseline. If this turns out to 6403 // be a relevant use case, then we need to find clusters of glyphs that share a baseline 6404 // and do a drawTextItemDecorations call per cluster. 6405 if (i == 0 || baseLine < positions[i].y) 6406 baseLine = positions[i].y; 6407 6408 // We use the advance rather than the actual bounds to match the algorithm in drawText() 6409 if (i == 0 || rightMost < positions[i].x + gm.xoff) 6410 rightMost = positions[i].x + gm.xoff; 6411 } 6412 6413 QFixed width = rightMost - leftMost; 6414 QTextItem::RenderFlags flags = 0; 6415 6416 if (font.underline()) 6417 flags |= QTextItem::Underline; 6418 if (font.overline()) 6419 flags |= QTextItem::Overline; 6420 if (font.strikeOut()) 6421 flags |= QTextItem::StrikeOut; 6422 6423 drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()), 6424 fontEngine, 6425 font.underline() ? QTextCharFormat::SingleUnderline 6426 : QTextCharFormat::NoUnderline, flags, 6427 width.toReal(), charFormat); 6139 6428 } 6140 6429 … … 6269 6558 d->engine->drawTextItem(p, ti); 6270 6559 } 6271 drawTextItemDecoration(this, p, ti); 6560 drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(), 6561 ti.charFormat); 6272 6562 6273 6563 if (d->state->renderHints != oldRenderHints) { … … 6909 7199 rectangle. 6910 7200 6911 \sa window(), viewTransformEnabled(), { TheCoordinate7201 \sa window(), viewTransformEnabled(), {Coordinate 6912 7202 System#Window-Viewport Conversion}{Window-Viewport Conversion} 6913 7203 */ … … 6973 7263 rectangle. 6974 7264 6975 \sa viewport(), viewTransformEnabled() { TheCoordinate7265 \sa viewport(), viewTransformEnabled() {Coordinate 6976 7266 System#Window-Viewport Conversion}{Window-Viewport Conversion} 6977 7267 */ … … 7057 7347 view transformations if \a enable is false. 7058 7348 7059 \sa viewTransformEnabled(), { TheCoordinate System#Window-Viewport7349 \sa viewTransformEnabled(), {Coordinate System#Window-Viewport 7060 7350 Conversion}{Window-Viewport Conversion} 7061 7351 */ … … 7807 8097 QTextLine line = textLayout.lineAt(i); 7808 8098 7809 qreal advance = textLayout.engine()->lines[i].textAdvance.toReal();8099 qreal advance = line.horizontalAdvance(); 7810 8100 if (tf & Qt::AlignRight) 7811 8101 xoff = r.width() - advance; … … 7826 8116 to the specified \a direction. 7827 8117 7828 \sa layoutDirection(), drawText(), {QPainter#Settings}{Settings} 8118 The default is Qt::LayoutDirectionAuto, which will implicitly determine the 8119 direction from the text drawn. 8120 8121 \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings} 7829 8122 */ 7830 8123 void QPainter::setLayoutDirection(Qt::LayoutDirection direction) … … 7838 8131 Returns the layout direction used by the painter when drawing text. 7839 8132 7840 \sa setLayoutDirection(), drawText(), {QPainter#Settings}{Settings}8133 \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings} 7841 8134 */ 7842 8135 Qt::LayoutDirection QPainter::layoutDirection() const 7843 8136 { 7844 8137 Q_D(const QPainter); 7845 return d->state ? d->state->layoutDirection : Qt::L eftToRight;8138 return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto; 7846 8139 } 7847 8140 … … 8506 8799 8507 8800 /*! 8508 Returns w ether clipping is enabled or not in the current paint8801 Returns whether clipping is enabled or not in the current paint 8509 8802 engine state. 8510 8803 … … 8716 9009 } 8717 9010 9011 /*! 9012 \since 4.7 9013 9014 This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, 9015 at multiple positions with different scale, rotation and opacity. \a 9016 fragments is an array of \a fragmentCount elements specifying the 9017 parameters used to draw each pixmap fragment. The \a hints 9018 parameter can be used to pass in drawing hints. 9019 9020 This function is potentially faster than multiple calls to drawPixmap(), 9021 since the backend can optimize state changes. 9022 9023 \sa QPainter::PixmapFragment, QPainter::PixmapFragmentHint 9024 */ 9025 9026 void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, 9027 const QPixmap &pixmap, PixmapFragmentHints hints) 9028 { 9029 Q_D(QPainter); 9030 9031 if (!d->engine || pixmap.isNull()) 9032 return; 9033 9034 #ifndef QT_NO_DEBUG 9035 for (int i = 0; i < fragmentCount; ++i) { 9036 QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop, 9037 fragments[i].width, fragments[i].height); 9038 if (!(QRectF(pixmap.rect()).contains(sourceRect))) 9039 qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle"); 9040 } 9041 #endif 9042 9043 if (d->engine->isExtended()) { 9044 d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); 9045 } else { 9046 qreal oldOpacity = opacity(); 9047 QTransform oldTransform = transform(); 9048 9049 for (int i = 0; i < fragmentCount; ++i) { 9050 QTransform transform = oldTransform; 9051 qreal xOffset = 0; 9052 qreal yOffset = 0; 9053 if (fragments[i].rotation == 0) { 9054 xOffset = fragments[i].x; 9055 yOffset = fragments[i].y; 9056 } else { 9057 transform.translate(fragments[i].x, fragments[i].y); 9058 transform.rotate(fragments[i].rotation); 9059 } 9060 setOpacity(oldOpacity * fragments[i].opacity); 9061 setTransform(transform); 9062 9063 qreal w = fragments[i].scaleX * fragments[i].width; 9064 qreal h = fragments[i].scaleY * fragments[i].height; 9065 QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop, 9066 fragments[i].width, fragments[i].height); 9067 drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, sourceRect); 9068 } 9069 9070 setOpacity(oldOpacity); 9071 setTransform(oldTransform); 9072 } 9073 } 9074 9075 /*! 9076 \since 4.7 9077 \class QPainter::PixmapFragment 9078 9079 \brief This class is used in conjunction with the 9080 QPainter::drawPixmapFragments() function to specify how a pixmap, or 9081 sub-rect of a pixmap, is drawn. 9082 9083 The \a sourceLeft, \a sourceTop, \a width and \a height variables are used 9084 as a source rectangle within the pixmap passed into the 9085 QPainter::drawPixmapFragments() function. The variables \a x, \a y, \a 9086 width and \a height are used to calculate the target rectangle that is 9087 drawn. \a x and \a y denotes the center of the target rectangle. The \a 9088 width and \a height in the target rectangle is scaled by the \a scaleX and 9089 \a scaleY values. The resulting target rectangle is then rotated \a 9090 rotation degrees around the \a x, \a y center point. 9091 9092 \sa QPainter::drawPixmapFragments() 9093 */ 9094 9095 /*! 9096 \since 4.7 9097 9098 This is a convenience function that returns a QPainter::PixmapFragment that is 9099 initialized with the \a pos, \a sourceRect, \a scaleX, \a scaleY, \a 9100 rotation, \a opacity parameters. 9101 */ 9102 9103 QPainter::PixmapFragment QPainter::PixmapFragment::create(const QPointF &pos, const QRectF &sourceRect, 9104 qreal scaleX, qreal scaleY, qreal rotation, 9105 qreal opacity) 9106 { 9107 PixmapFragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(), 9108 sourceRect.height(), scaleX, scaleY, rotation, opacity}; 9109 return fragment; 9110 } 9111 9112 /*! 9113 \variable QPainter::PixmapFragment::x 9114 \brief the x coordinate of center point in the target rectangle. 9115 */ 9116 9117 /*! 9118 \variable QPainter::PixmapFragment::y 9119 \brief the y coordinate of the center point in the target rectangle. 9120 */ 9121 9122 /*! 9123 \variable QPainter::PixmapFragment::sourceLeft 9124 \brief the left coordinate of the source rectangle. 9125 */ 9126 9127 /*! 9128 \variable QPainter::PixmapFragment::sourceTop 9129 \brief the top coordinate of the source rectangle. 9130 */ 9131 9132 /*! 9133 \variable QPainter::PixmapFragment::width 9134 9135 \brief the width of the source rectangle and is used to calculate the width 9136 of the target rectangle. 9137 */ 9138 9139 /*! 9140 \variable QPainter::PixmapFragment::height 9141 9142 \brief the height of the source rectangle and is used to calculate the 9143 height of the target rectangle. 9144 */ 9145 9146 /*! 9147 \variable QPainter::PixmapFragment::scaleX 9148 \brief the horizontal scale of the target rectangle. 9149 */ 9150 9151 /*! 9152 \variable QPainter::PixmapFragment::scaleY 9153 \brief the vertical scale of the target rectangle. 9154 */ 9155 9156 /*! 9157 \variable QPainter::PixmapFragment::rotation 9158 9159 \brief the rotation of the target rectangle in degrees. The target 9160 rectangle is rotated after it has been scaled. 9161 */ 9162 9163 /*! 9164 \variable QPainter::PixmapFragment::opacity 9165 9166 \brief the opacity of the target rectangle, where 0.0 is fully transparent 9167 and 1.0 is fully opaque. 9168 */ 9169 9170 /*! 9171 \since 4.7 9172 9173 \enum QPainter::PixmapFragmentHint 9174 9175 \value OpaqueHint Indicates that the pixmap fragments to be drawn are 9176 opaque. Opaque fragments are potentially faster to draw. 9177 9178 \sa QPainter::drawPixmapFragments(), QPainter::PixmapFragment 9179 */ 9180 8718 9181 void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation) 8719 9182 { -
trunk/src/gui/painting/qpainter.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 79 79 class QMatrix; 80 80 class QTransform; 81 class QStaticText; 81 82 82 83 class QPainterPrivateDeleter; … … 98 99 99 100 Q_DECLARE_FLAGS(RenderHints, RenderHint) 101 102 class PixmapFragment { 103 public: 104 qreal x; 105 qreal y; 106 qreal sourceLeft; 107 qreal sourceTop; 108 qreal width; 109 qreal height; 110 qreal scaleX; 111 qreal scaleY; 112 qreal rotation; 113 qreal opacity; 114 static PixmapFragment Q_GUI_EXPORT create(const QPointF &pos, const QRectF &sourceRect, 115 qreal scaleX = 1, qreal scaleY = 1, 116 qreal rotation = 0, qreal opacity = 1); 117 }; 118 119 enum PixmapFragmentHint { 120 OpaqueHint = 0x01 121 }; 122 123 Q_DECLARE_FLAGS(PixmapFragmentHints, PixmapFragmentHint) 100 124 101 125 QPainter(); … … 351 375 inline void drawPixmap(const QRect &r, const QPixmap &pm); 352 376 inline void drawPixmap(int x, int y, int w, int h, const QPixmap &pm); 377 378 void drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, 379 const QPixmap &pixmap, PixmapFragmentHints hints = 0); 353 380 354 381 void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, … … 369 396 void setLayoutDirection(Qt::LayoutDirection direction); 370 397 Qt::LayoutDirection layoutDirection() const; 398 399 void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText); 400 inline void drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText); 401 inline void drawStaticText(int left, int top, const QStaticText &staticText); 371 402 372 403 void drawText(const QPointF &p, const QString &s); … … 897 928 } 898 929 930 inline void QPainter::drawStaticText(const QPoint &p, const QStaticText &staticText) 931 { 932 drawStaticText(QPointF(p), staticText); 933 } 934 935 inline void QPainter::drawStaticText(int x, int y, const QStaticText &staticText) 936 { 937 drawStaticText(QPointF(x, y), staticText); 938 } 939 899 940 inline void QPainter::drawTextItem(const QPoint &p, const QTextItem &ti) 900 941 { -
trunk/src/gui/painting/qpainter_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 229 229 void drawStretchedGradient(const QPainterPath &path, DrawOperation operation); 230 230 void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation); 231 void drawGlyphs(const quint32 *glyphArray, const QPointF *positionArray, int glyphCount); 231 232 232 233 void updateMatrix(); … … 238 239 239 240 void checkEmulation(); 241 242 static QPainterPrivate *get(QPainter *painter) 243 { 244 return painter->d_ptr.data(); 245 } 240 246 241 247 QTransform viewTransform() const; … … 253 259 254 260 Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation); 261 Q_GUI_EXPORT void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, 262 const QPointF *positionArray, int glyphCount); 255 263 256 264 QString qt_generate_brush_key(const QBrush &brush); -
trunk/src/gui/painting/qpainterpath.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 1197 1197 d->elements += other.d_func()->elements; 1198 1198 1199 d->elements[first].type = LineToElement; 1199 if (first != 0) 1200 d->elements[first].type = LineToElement; 1200 1201 1201 1202 // avoid duplicate points … … 1258 1259 { 1259 1260 ensureData(); 1261 if (d_func()->fillRule == fillRule) 1262 return; 1260 1263 detach(); 1261 1264 … … 1913 1916 case QPainterPath::MoveToElement: 1914 1917 if (i > 0 1915 && qFuzzyCompare(last_pt.x(), last_start. y())1918 && qFuzzyCompare(last_pt.x(), last_start.x()) 1916 1919 && qFuzzyCompare(last_pt.y(), last_start.y()) 1917 1920 && qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(), … … 2306 2309 returns a reference to the \a stream. 2307 2310 2308 \sa { Format of the QDataStream Operators}2311 \sa {Serializing Qt Data Types} 2309 2312 */ 2310 2313 QDataStream &operator<<(QDataStream &s, const QPainterPath &p) … … 2333 2336 and returns a reference to the \a stream. 2334 2337 2335 \sa { Format of the QDataStream Operators}2338 \sa {Serializing Qt Data Types} 2336 2339 */ 2337 2340 QDataStream &operator>>(QDataStream &s, QPainterPath &p) … … 3166 3169 Set operations on paths will treat the paths as areas. Non-closed 3167 3170 paths will be treated as implicitly closed. 3171 Bezier curves may be flattened to line segments due to numerical instability of 3172 doing bezier curve intersections. 3168 3173 3169 3174 \sa intersected(), subtracted() … … 3181 3186 3182 3187 Returns a path which is the intersection of this path's fill area and \a p's fill area. 3188 Bezier curves may be flattened to line segments due to numerical instability of 3189 doing bezier curve intersections. 3183 3190 */ 3184 3191 QPainterPath QPainterPath::intersected(const QPainterPath &p) const … … 3197 3204 Set operations on paths will treat the paths as areas. Non-closed 3198 3205 paths will be treated as implicitly closed. 3199 3206 Bezier curves may be flattened to line segments due to numerical instability of 3207 doing bezier curve intersections. 3200 3208 */ 3201 3209 QPainterPath QPainterPath::subtracted(const QPainterPath &p) const … … 3226 3234 and returning a path containing no intersecting edges. Consecutive parallel lines will also 3227 3235 be merged. The simplified path will always use the default fill rule, Qt::OddEvenFill. 3236 Bezier curves may be flattened to line segments due to numerical instability of 3237 doing bezier curve intersections. 3228 3238 */ 3229 3239 QPainterPath QPainterPath::simplified() const -
trunk/src/gui/painting/qpainterpath.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 289 289 290 290 private: 291 Q_DISABLE_COPY(QPainterPathStroker) 292 291 293 friend class QX11PaintEngine; 292 294 -
trunk/src/gui/painting/qpainterpath_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpathclipper.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include <private/qbezier_p.h> 45 45 #include <private/qdatabuffer_p.h> 46 #include <private/qnumeric_p.h> 46 47 #include <qmath.h> 47 48 … … 86 87 } 87 88 88 static QPointF normalize(const QPointF &p) 89 { 90 return p / qSqrt(p.x() * p.x() + p.y() * p.y()); 89 static void normalize(double &x, double &y) 90 { 91 double reciprocal = 1 / qSqrt(x * x + y * y); 92 x *= reciprocal; 93 y *= reciprocal; 91 94 } 92 95 … … 106 109 107 110 private: 108 void intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections);109 void intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections);110 111 bool beziersIntersect(const QBezier &one, const QBezier &two) const;112 111 bool linesIntersect(const QLineF &a, const QLineF &b) const; 113 112 }; 114 115 bool QIntersectionFinder::beziersIntersect(const QBezier &one, const QBezier &two) const116 {117 return (comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2())118 && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4()))119 || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3())120 && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))121 || QBezier::findIntersections(one, two, 0);122 }123 113 124 114 bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const … … 175 165 } 176 166 177 // if the lines are not parallel and share a common end point, then they178 // don't intersect179 if (p1_equals_q1 || p1_equals_q2 || p2_equals_q1 || p2_equals_q2)180 return false;181 182 167 const qreal invPar = 1 / par; 183 168 … … 194 179 } 195 180 196 void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections) 197 { 198 if ((comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2()) 199 && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4())) 200 || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3()) 201 && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))) { 202 203 return; 204 } 205 206 t.clear(); 207 208 if (!QBezier::findIntersections(one, two, &t)) 209 return; 210 211 int count = t.size(); 212 213 for (int i = 0; i < count; ++i) { 214 qreal alpha_p = t.at(i).first; 215 qreal alpha_q = t.at(i).second; 216 217 QPointF pt; 218 if (qFuzzyIsNull(alpha_p)) { 219 pt = one.pt1(); 220 } else if (qFuzzyIsNull(alpha_p - 1)) { 221 pt = one.pt4(); 222 } else if (qFuzzyIsNull(alpha_q)) { 223 pt = two.pt1(); 224 } else if (qFuzzyIsNull(alpha_q - 1)) { 225 pt = two.pt4(); 181 bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSegments &b) const 182 { 183 if (a.segments() == 0 || b.segments() == 0) 184 return false; 185 186 const QRectF &rb0 = b.elementBounds(0); 187 188 qreal minX = rb0.left(); 189 qreal minY = rb0.top(); 190 qreal maxX = rb0.right(); 191 qreal maxY = rb0.bottom(); 192 193 for (int i = 1; i < b.segments(); ++i) { 194 const QRectF &r = b.elementBounds(i); 195 minX = qMin(minX, r.left()); 196 minY = qMin(minY, r.top()); 197 maxX = qMax(maxX, r.right()); 198 maxY = qMax(maxY, r.bottom()); 199 } 200 201 QRectF rb(minX, minY, maxX - minX, maxY - minY); 202 203 for (int i = 0; i < a.segments(); ++i) { 204 const QRectF &r1 = a.elementBounds(i); 205 206 if (r1.left() > rb.right() || rb.left() > r1.right()) 207 continue; 208 if (r1.top() > rb.bottom() || rb.top() > r1.bottom()) 209 continue; 210 211 for (int j = 0; j < b.segments(); ++j) { 212 const QRectF &r2 = b.elementBounds(j); 213 214 if (r1.left() > r2.right() || r2.left() > r1.right()) 215 continue; 216 if (r1.top() > r2.bottom() || r2.top() > r1.bottom()) 217 continue; 218 219 if (linesIntersect(a.lineAt(i), b.lineAt(j))) 220 return true; 221 } 222 } 223 224 return false; 225 } 226 227 namespace { 228 struct TreeNode 229 { 230 qreal splitLeft; 231 qreal splitRight; 232 bool leaf; 233 234 int lowestLeftIndex; 235 int lowestRightIndex; 236 237 union { 238 struct { 239 int first; 240 int last; 241 } interval; 242 struct { 243 int left; 244 int right; 245 } children; 246 } index; 247 }; 248 249 struct RectF 250 { 251 qreal x1; 252 qreal y1; 253 qreal x2; 254 qreal y2; 255 }; 256 257 class SegmentTree 258 { 259 public: 260 SegmentTree(QPathSegments &segments); 261 262 QRectF boundingRect() const; 263 264 void produceIntersections(int segment); 265 266 private: 267 TreeNode buildTree(int first, int last, int depth, const RectF &bounds); 268 269 void produceIntersectionsLeaf(const TreeNode &node, int segment); 270 void produceIntersections(const TreeNode &node, int segment, const RectF &segmentBounds, const RectF &nodeBounds, int axis); 271 void intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections); 272 273 QPathSegments &m_segments; 274 QVector<int> m_index; 275 276 RectF m_bounds; 277 278 QVector<TreeNode> m_tree; 279 QDataBuffer<QIntersection> m_intersections; 280 }; 281 282 SegmentTree::SegmentTree(QPathSegments &segments) 283 : m_segments(segments), 284 m_intersections(0) 285 { 286 m_bounds.x1 = qt_inf(); 287 m_bounds.y1 = qt_inf(); 288 m_bounds.x2 = -qt_inf(); 289 m_bounds.y2 = -qt_inf(); 290 291 m_index.resize(m_segments.segments()); 292 293 for (int i = 0; i < m_index.size(); ++i) { 294 m_index[i] = i; 295 296 const QRectF &segmentBounds = m_segments.elementBounds(i); 297 298 if (segmentBounds.left() < m_bounds.x1) 299 m_bounds.x1 = segmentBounds.left(); 300 if (segmentBounds.top() < m_bounds.y1) 301 m_bounds.y1 = segmentBounds.top(); 302 if (segmentBounds.right() > m_bounds.x2) 303 m_bounds.x2 = segmentBounds.right(); 304 if (segmentBounds.bottom() > m_bounds.y2) 305 m_bounds.y2 = segmentBounds.bottom(); 306 } 307 308 m_tree.resize(1); 309 310 TreeNode root = buildTree(0, m_index.size(), 0, m_bounds); 311 m_tree[0] = root; 312 } 313 314 QRectF SegmentTree::boundingRect() const 315 { 316 return QRectF(QPointF(m_bounds.x1, m_bounds.y1), 317 QPointF(m_bounds.x2, m_bounds.y2)); 318 } 319 320 static inline qreal coordinate(const QPointF &pos, int axis) 321 { 322 return axis == 0 ? pos.x() : pos.y(); 323 } 324 325 TreeNode SegmentTree::buildTree(int first, int last, int depth, const RectF &bounds) 326 { 327 if (depth >= 24 || (last - first) <= 10) { 328 TreeNode node; 329 node.leaf = true; 330 node.index.interval.first = first; 331 node.index.interval.last = last; 332 333 return node; 334 } 335 336 int splitAxis = (depth & 1); 337 338 TreeNode node; 339 node.leaf = false; 340 341 qreal split = 0.5f * ((&bounds.x1)[splitAxis] + (&bounds.x2)[splitAxis]); 342 343 node.splitLeft = (&bounds.x1)[splitAxis]; 344 node.splitRight = (&bounds.x2)[splitAxis]; 345 346 node.lowestLeftIndex = INT_MAX; 347 node.lowestRightIndex = INT_MAX; 348 349 const int treeSize = m_tree.size(); 350 351 node.index.children.left = treeSize; 352 node.index.children.right = treeSize + 1; 353 354 m_tree.resize(treeSize + 2); 355 356 int l = first; 357 int r = last - 1; 358 359 // partition into left and right sets 360 while (l <= r) { 361 const int index = m_index.at(l); 362 const QRectF &segmentBounds = m_segments.elementBounds(index); 363 364 qreal lowCoordinate = coordinate(segmentBounds.topLeft(), splitAxis); 365 366 if (coordinate(segmentBounds.center(), splitAxis) < split) { 367 qreal highCoordinate = coordinate(segmentBounds.bottomRight(), splitAxis); 368 if (highCoordinate > node.splitLeft) 369 node.splitLeft = highCoordinate; 370 if (index < node.lowestLeftIndex) 371 node.lowestLeftIndex = index; 372 ++l; 226 373 } else { 227 pt = one.pointAt(alpha_p); 228 } 229 230 QIntersection intersection; 231 intersection.alphaA = alpha_p; 232 intersection.alphaB = alpha_q; 233 intersection.pos = pt; 234 intersections.add(intersection); 235 } 236 } 237 238 void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections) 374 if (lowCoordinate < node.splitRight) 375 node.splitRight = lowCoordinate; 376 if (index < node.lowestRightIndex) 377 node.lowestRightIndex = index; 378 qSwap(m_index[l], m_index[r]); 379 --r; 380 } 381 } 382 383 RectF lbounds = bounds; 384 (&lbounds.x2)[splitAxis] = node.splitLeft; 385 386 RectF rbounds = bounds; 387 (&rbounds.x1)[splitAxis] = node.splitRight; 388 389 TreeNode left = buildTree(first, l, depth + 1, lbounds); 390 m_tree[node.index.children.left] = left; 391 392 TreeNode right = buildTree(l, last, depth + 1, rbounds); 393 m_tree[node.index.children.right] = right; 394 395 return node; 396 } 397 398 void SegmentTree::intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections) 239 399 { 240 400 const QPointF p1 = a.p1(); … … 358 518 } 359 519 360 static const QBezier bezierFromLine(const QLineF &line) 361 { 362 const QPointF p1 = line.p1(); 363 const QPointF p2 = line.p2(); 364 const QPointF delta = (p2 - p1) / 3; 365 return QBezier::fromPoints(p1, p1 + delta, p1 + 2 * delta, p2); 366 } 367 368 bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSegments &b) const 369 { 370 QBezier tempA; 371 QBezier tempB; 372 373 if (a.segments() == 0 || b.segments() == 0) 374 return false; 375 376 const QRectF &rb0 = b.elementBounds(0); 377 378 qreal minX = rb0.left(); 379 qreal minY = rb0.top(); 380 qreal maxX = rb0.right(); 381 qreal maxY = rb0.bottom(); 382 383 for (int i = 1; i < b.segments(); ++i) { 384 const QRectF &r = b.elementBounds(i); 385 minX = qMin(minX, r.left()); 386 minY = qMin(minY, r.top()); 387 maxX = qMax(maxX, r.right()); 388 maxY = qMax(maxY, r.bottom()); 389 } 390 391 QRectF rb(minX, minY, maxX - minX, maxY - minY); 392 393 for (int i = 0; i < a.segments(); ++i) { 394 const QBezier *bezierA = a.bezierAt(i); 395 bool isBezierA = bezierA != 0; 396 397 const QRectF &r1 = a.elementBounds(i); 398 399 if (r1.left() > rb.right() || rb.left() > r1.right()) 520 void SegmentTree::produceIntersections(int segment) 521 { 522 const QRectF &segmentBounds = m_segments.elementBounds(segment); 523 524 RectF sbounds; 525 sbounds.x1 = segmentBounds.left(); 526 sbounds.y1 = segmentBounds.top(); 527 sbounds.x2 = segmentBounds.right(); 528 sbounds.y2 = segmentBounds.bottom(); 529 530 produceIntersections(m_tree.at(0), segment, sbounds, m_bounds, 0); 531 } 532 533 void SegmentTree::produceIntersectionsLeaf(const TreeNode &node, int segment) 534 { 535 const QRectF &r1 = m_segments.elementBounds(segment); 536 const QLineF lineA = m_segments.lineAt(segment); 537 538 for (int i = node.index.interval.first; i < node.index.interval.last; ++i) { 539 const int other = m_index.at(i); 540 if (other >= segment) 400 541 continue; 401 if (r1.top() > rb.bottom() || rb.top() > r1.bottom()) 542 543 const QRectF &r2 = m_segments.elementBounds(other); 544 545 if (r1.left() > r2.right() || r2.left() > r1.right()) 402 546 continue; 403 404 for (int j = 0; j < b.segments(); ++j) { 405 const QRectF &r2 = b.elementBounds(j); 406 407 if (r1.left() > r2.right() || r2.left() > r1.right()) 408 continue; 409 if (r1.top() > r2.bottom() || r2.top() > r1.bottom()) 410 continue; 411 412 bool isBezierB = b.bezierAt(j) != 0; 413 414 if (isBezierA || isBezierB) { 415 const QBezier *bezierB; 416 if (isBezierB) { 417 bezierB = b.bezierAt(j); 418 } else { 419 tempB = bezierFromLine(b.lineAt(j)); 420 bezierB = &tempB; 421 } 422 423 if (!bezierA) { 424 tempA = bezierFromLine(a.lineAt(i)); 425 bezierA = &tempA; 426 } 427 428 if (beziersIntersect(*bezierA, *bezierB)) 429 return true; 430 } else { 431 if (linesIntersect(a.lineAt(i), b.lineAt(j))) 432 return true; 433 } 434 } 435 } 436 437 return false; 547 if (r1.top() > r2.bottom() || r2.top() > r1.bottom()) 548 continue; 549 550 m_intersections.reset(); 551 552 const QLineF lineB = m_segments.lineAt(other); 553 554 intersectLines(lineA, lineB, m_intersections); 555 556 for (int k = 0; k < m_intersections.size(); ++k) { 557 QPathSegments::Intersection i_isect, j_isect; 558 i_isect.vertex = j_isect.vertex = m_segments.addPoint(m_intersections.at(k).pos); 559 560 i_isect.t = m_intersections.at(k).alphaA; 561 j_isect.t = m_intersections.at(k).alphaB; 562 563 i_isect.next = 0; 564 j_isect.next = 0; 565 566 m_segments.addIntersection(segment, i_isect); 567 m_segments.addIntersection(other, j_isect); 568 } 569 } 570 } 571 572 void SegmentTree::produceIntersections(const TreeNode &node, int segment, const RectF &segmentBounds, const RectF &nodeBounds, int axis) 573 { 574 if (node.leaf) { 575 produceIntersectionsLeaf(node, segment); 576 return; 577 } 578 579 RectF lbounds = nodeBounds; 580 (&lbounds.x2)[axis] = node.splitLeft; 581 582 RectF rbounds = nodeBounds; 583 (&rbounds.x1)[axis] = node.splitRight; 584 585 if (segment > node.lowestLeftIndex && (&segmentBounds.x1)[axis] <= node.splitLeft) 586 produceIntersections(m_tree.at(node.index.children.left), segment, segmentBounds, lbounds, !axis); 587 588 if (segment > node.lowestRightIndex && (&segmentBounds.x2)[axis] >= node.splitRight) 589 produceIntersections(m_tree.at(node.index.children.right), segment, segmentBounds, rbounds, !axis); 590 } 591 438 592 } 439 593 440 594 void QIntersectionFinder::produceIntersections(QPathSegments &segments) 441 595 { 442 QBezier tempA; 443 QBezier tempB; 444 445 QVector<QPair<qreal, qreal> > t; 446 QDataBuffer<QIntersection> intersections; 447 448 for (int i = 0; i < segments.segments(); ++i) { 449 const QBezier *bezierA = segments.bezierAt(i); 450 bool isBezierA = bezierA != 0; 451 452 const QRectF &r1 = segments.elementBounds(i); 453 454 for (int j = 0; j < i; ++j) { 455 const QRectF &r2 = segments.elementBounds(j); 456 457 if (r1.left() > r2.right() || r2.left() > r1.right()) 458 continue; 459 if (r1.top() > r2.bottom() || r2.top() > r1.bottom()) 460 continue; 461 462 intersections.reset(); 463 464 bool isBezierB = segments.bezierAt(j) != 0; 465 466 if (isBezierA || isBezierB) { 467 const QBezier *bezierB; 468 if (isBezierB) { 469 bezierB = segments.bezierAt(j); 470 } else { 471 tempB = bezierFromLine(segments.lineAt(j)); 472 bezierB = &tempB; 473 } 474 475 if (!bezierA) { 476 tempA = bezierFromLine(segments.lineAt(i)); 477 bezierA = &tempA; 478 } 479 480 intersectBeziers(*bezierA, *bezierB, t, intersections); 481 } else { 482 const QLineF lineA = segments.lineAt(i); 483 const QLineF lineB = segments.lineAt(j); 484 485 intersectLines(lineA, lineB, intersections); 486 } 487 488 for (int k = 0; k < intersections.size(); ++k) { 489 QPathSegments::Intersection i_isect, j_isect; 490 i_isect.vertex = j_isect.vertex = segments.addPoint(intersections.at(k).pos); 491 492 i_isect.t = intersections.at(k).alphaA; 493 j_isect.t = intersections.at(k).alphaB; 494 495 i_isect.next = 0; 496 j_isect.next = 0; 497 498 segments.addIntersection(i, i_isect); 499 segments.addIntersection(j, j_isect); 500 } 501 } 502 } 596 SegmentTree tree(segments); 597 598 for (int i = 0; i < segments.segments(); ++i) 599 tree.produceIntersections(i); 503 600 } 504 601 … … 713 810 addVertex(m_segments.pointAt(i)); 714 811 715 QDataBuffer<QPathSegments::Intersection> intersections ;812 QDataBuffer<QPathSegments::Intersection> intersections(m_segments.segments()); 716 813 for (int i = 0; i < m_segments.segments(); ++i) { 717 814 intersections.reset(); … … 732 829 qSort(intersections.data(), intersections.data() + intersections.size()); 733 830 734 const QBezier *bezier = m_segments.bezierAt(i); 735 if (bezier) { 736 int first = m_segments.segmentAt(i).va; 737 int second = m_segments.segmentAt(i).vb; 738 739 qreal alpha = 0.0; 740 int last = first; 741 for (int j = 0; j < intersections.size(); ++j) { 742 const QPathSegments::Intersection &isect = intersections.at(j); 743 744 addBezierEdge(bezier, last, isect.vertex, alpha, isect.t, pathId); 745 746 alpha = isect.t; 747 last = isect.vertex; 748 } 749 750 addBezierEdge(bezier, last, second, alpha, 1.0, pathId); 751 } else { 752 int first = m_segments.segmentAt(i).va; 753 int second = m_segments.segmentAt(i).vb; 754 755 int last = first; 756 for (int j = 0; j < intersections.size(); ++j) { 757 const QPathSegments::Intersection &isect = intersections.at(j); 758 759 QPathEdge *ep = edge(addEdge(last, isect.vertex)); 760 761 if (ep) { 762 const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(isect.vertex).y() ? 1 : -1; 763 if (pathId == 0) 764 ep->windingA += dir; 765 else 766 ep->windingB += dir; 767 } 768 769 last = isect.vertex; 770 } 771 772 QPathEdge *ep = edge(addEdge(last, second)); 831 int first = m_segments.segmentAt(i).va; 832 int second = m_segments.segmentAt(i).vb; 833 834 int last = first; 835 for (int j = 0; j < intersections.size(); ++j) { 836 const QPathSegments::Intersection &isect = intersections.at(j); 837 838 QPathEdge *ep = edge(addEdge(last, isect.vertex)); 773 839 774 840 if (ep) { 775 const int dir = m_segments.pointAt(last).y() < m_segments.pointAt( second).y() ? 1 : -1;841 const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(isect.vertex).y() ? 1 : -1; 776 842 if (pathId == 0) 777 843 ep->windingA += dir; … … 779 845 ep->windingB += dir; 780 846 } 781 } 782 } 783 } 784 785 QWingedEdge::QWingedEdge() 786 { 787 } 788 789 QWingedEdge::QWingedEdge(const QPainterPath &subject, const QPainterPath &clip) 847 848 last = isect.vertex; 849 } 850 851 QPathEdge *ep = edge(addEdge(last, second)); 852 853 if (ep) { 854 const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(second).y() ? 1 : -1; 855 if (pathId == 0) 856 ep->windingA += dir; 857 else 858 ep->windingB += dir; 859 } 860 } 861 } 862 863 QWingedEdge::QWingedEdge() : 864 m_edges(0), 865 m_vertices(0), 866 m_segments(0) 867 { 868 } 869 870 QWingedEdge::QWingedEdge(const QPainterPath &subject, const QPainterPath &clip) : 871 m_edges(subject.elementCount()), 872 m_vertices(subject.elementCount()), 873 m_segments(subject.elementCount()) 790 874 { 791 875 m_segments.setPath(subject); … … 833 917 { 834 918 m_points.reset(); 835 m_beziers.reset();836 919 m_intersections.reset(); 837 920 m_segments.reset(); … … 880 963 m_segments << Segment(m_pathId, last, current); 881 964 } else { 882 m_segments << Segment(m_pathId, last, current, m_beziers.size()); 883 m_beziers << bezier; 965 QRectF bounds = bezier.bounds(); 966 967 // threshold based on similar algorithm as in qtriangulatingstroker.cpp 968 int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * (2 * qreal(3.14) / 6)); 969 970 if (threshold < 3) threshold = 3; 971 qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1); 972 973 for (int t = 1; t < threshold - 1; ++t) { 974 currentPoint = bezier.pointAt(t * one_over_threshold_minus_1); 975 976 int index = m_points.size(); 977 m_segments << Segment(m_pathId, last, index); 978 last = index; 979 980 m_points << currentPoint; 981 } 982 983 m_segments << Segment(m_pathId, last, current); 884 984 } 885 985 } … … 897 997 898 998 for (int i = firstSegment; i < m_segments.size(); ++i) { 899 const QBezier *bezier = bezierAt(i); 900 if (bezier) { 901 m_segments.at(i).bounds = bezier->bounds(); 902 } else { 903 const QLineF line = lineAt(i); 904 905 qreal x1 = line.p1().x(); 906 qreal y1 = line.p1().y(); 907 qreal x2 = line.p2().x(); 908 qreal y2 = line.p2().y(); 909 910 if (x2 < x1) 911 qSwap(x1, x2); 912 if (y2 < y1) 913 qSwap(y1, y2); 914 915 m_segments.at(i).bounds = QRectF(x1, y1, x2 - x1, y2 - y1); 916 } 999 const QLineF line = lineAt(i); 1000 1001 qreal x1 = line.p1().x(); 1002 qreal y1 = line.p1().y(); 1003 qreal x2 = line.p2().x(); 1004 qreal y2 = line.p2().y(); 1005 1006 if (x2 < x1) 1007 qSwap(x1, x2); 1008 if (y2 < y1) 1009 qSwap(y1, y2); 1010 1011 m_segments.at(i).bounds = QRectF(x1, y1, x2 - x1, y2 - y1); 917 1012 } 918 1013 … … 925 1020 const QPathEdge *bp = edge(b); 926 1021 927 qreala_angle = ap->angle;928 qrealb_angle = bp->angle;1022 double a_angle = ap->angle; 1023 double b_angle = bp->angle; 929 1024 930 1025 if (vertex == ap->second) … … 934 1029 b_angle = bp->invAngle; 935 1030 936 qreal result = b_angle - a_angle; 937 938 if (qFuzzyIsNull(result) || qFuzzyCompare(result, 128)) 939 return 0; 940 941 if (result < 0) 1031 double result = b_angle - a_angle; 1032 1033 if (result >= 128.) 1034 return result - 128.; 1035 else if (result < 0) 942 1036 return result + 128.; 943 1037 else … … 945 1039 } 946 1040 947 static inline QPointF tangentAt(const QWingedEdge &list, int vi, int ei)1041 static inline QPointF midPoint(const QWingedEdge &list, int ei) 948 1042 { 949 1043 const QPathEdge *ep = list.edge(ei); 950 1044 Q_ASSERT(ep); 951 1045 952 qreal t; 953 qreal sign; 954 955 if (ep->first == vi) { 956 t = ep->t0; 957 sign = 1; 958 } else { 959 t = ep->t1; 960 sign = -1; 961 } 962 963 QPointF normal; 964 if (ep->bezier) { 965 normal = ep->bezier->derivedAt(t); 966 967 if (qFuzzyIsNull(normal.x()) && qFuzzyIsNull(normal.y())) 968 normal = ep->bezier->secondDerivedAt(t); 969 } else { 970 const QPointF a = *list.vertex(ep->first); 971 const QPointF b = *list.vertex(ep->second); 972 normal = b - a; 973 } 974 975 return normalize(sign * normal); 976 } 977 978 static inline QPointF midPoint(const QWingedEdge &list, int ei) 979 { 980 const QPathEdge *ep = list.edge(ei); 981 Q_ASSERT(ep); 982 983 if (ep->bezier) { 984 return ep->bezier->pointAt(0.5 * (ep->t0 + ep->t1)); 985 } else { 986 const QPointF a = *list.vertex(ep->first); 987 const QPointF b = *list.vertex(ep->second); 988 return a + 0.5 * (b - a); 989 } 990 } 991 992 static QBezier transform(const QBezier &bezier, const QPointF &xAxis, const QPointF &yAxis, const QPointF &origin) 993 { 994 QPointF points[4] = { 995 bezier.pt1(), 996 bezier.pt2(), 997 bezier.pt3(), 998 bezier.pt4() 999 }; 1000 1001 for (int i = 0; i < 4; ++i) { 1002 const QPointF p = points[i] - origin; 1003 1004 points[i].rx() = dot(xAxis, p); 1005 points[i].ry() = dot(yAxis, p); 1006 } 1007 1008 return QBezier::fromPoints(points[0], points[1], points[2], points[3]); 1009 } 1010 1011 static bool isLeftOf(const QWingedEdge &list, int vi, int ai, int bi) 1012 { 1013 const QPathEdge *ap = list.edge(ai); 1014 const QPathEdge *bp = list.edge(bi); 1015 1016 Q_ASSERT(ap); 1017 Q_ASSERT(bp); 1018 1019 if (!(ap->bezier || bp->bezier)) 1020 return false; 1021 1022 const QPointF tangent = tangentAt(list, vi, ai); 1023 const QPointF normal(tangent.y(), -tangent.x()); 1024 1025 const QPointF origin = *list.vertex(vi); 1026 1027 const QPointF dpA = midPoint(list, ai) - origin; 1028 const QPointF dpB = midPoint(list, bi) - origin; 1029 1030 qreal xA = dot(normal, dpA); 1031 qreal xB = dot(normal, dpB); 1032 1033 if (xA <= 0 && xB >= 0) 1034 return true; 1035 1036 if (xA >= 0 && xB <= 0) 1037 return false; 1038 1039 if (!ap->bezier) 1040 return xB > 0; 1041 1042 if (!bp->bezier) 1043 return xA < 0; 1044 1045 // both are beziers on the same side of the tangent 1046 1047 // transform the beziers into the local coordinate system 1048 // such that positive y is along the tangent, and positive x is along the normal 1049 1050 QBezier bezierA = transform(*ap->bezier, normal, tangent, origin); 1051 QBezier bezierB = transform(*bp->bezier, normal, tangent, origin); 1052 1053 qreal y = qMin(bezierA.pointAt(0.5 * (ap->t0 + ap->t1)).y(), 1054 bezierB.pointAt(0.5 * (bp->t0 + bp->t1)).y()); 1055 1056 xA = bezierA.pointAt(bezierA.tForY(ap->t0, ap->t1, y)).x(); 1057 xB = bezierB.pointAt(bezierB.tForY(bp->t0, bp->t1, y)).x(); 1058 1059 return xA < xB; 1046 const QPointF a = *list.vertex(ep->first); 1047 const QPointF b = *list.vertex(ep->second); 1048 return a + 0.5 * (b - a); 1060 1049 } 1061 1050 … … 1086 1075 1087 1076 Q_ASSERT(edge(status.edge)->vertex(status.direction) == vi); 1088 1089 1077 qreal d2 = delta(vi, ei, status.edge); 1090 1078 … … 1094 1082 #endif 1095 1083 1096 if (!(qFuzzyIsNull(d2) && isLeftOf(*this, vi, status.edge, ei)) 1097 && (d2 < d || (qFuzzyCompare(d2, d) && isLeftOf(*this, vi, status.edge, position)))) { 1084 if (d2 < d) { 1098 1085 position = status.edge; 1099 1086 d = d2; … … 1187 1174 } 1188 1175 1189 static qrealcomputeAngle(const QPointF &v)1176 static double computeAngle(const QPointF &v) 1190 1177 { 1191 1178 #if 1 … … 1196 1183 } 1197 1184 1198 QPointF nv = normalize(v); 1199 if (nv.y() < 0) { 1200 if (nv.x() < 0) { // 0 - 32 1201 return -32. * nv.x(); 1185 double vx = v.x(); 1186 double vy = v.y(); 1187 normalize(vx, vy); 1188 if (vy < 0) { 1189 if (vx < 0) { // 0 - 32 1190 return -32. * vx; 1202 1191 } else { // 96 - 128 1203 return 128. - 32. * nv.x();1192 return 128. - 32. * vx; 1204 1193 } 1205 1194 } else { // 32 - 96 1206 return 64. + 32 * nv.x();1195 return 64. + 32. * vx; 1207 1196 } 1208 1197 #else … … 1212 1201 } 1213 1202 1214 int QWingedEdge::addEdge(const QPointF &a, const QPointF &b , const QBezier *bezier, qreal t0, qreal t1)1203 int QWingedEdge::addEdge(const QPointF &a, const QPointF &b) 1215 1204 { 1216 1205 int fi = insert(a); 1217 1206 int si = insert(b); 1218 1207 1219 return addEdge(fi, si , bezier, t0, t1);1220 } 1221 1222 int QWingedEdge::addEdge(int fi, int si , const QBezier *bezier, qreal t0, qreal t1)1208 return addEdge(fi, si); 1209 } 1210 1211 int QWingedEdge::addEdge(int fi, int si) 1223 1212 { 1224 1213 if (fi == si) … … 1238 1227 QPathEdge *ep = edge(ei); 1239 1228 1240 ep->bezier = bezier; 1241 ep->t0 = t0; 1242 ep->t1 = t1; 1243 1244 if (bezier) { 1245 QPointF aTangent = bezier->derivedAt(t0); 1246 QPointF bTangent = -bezier->derivedAt(t1); 1247 1248 if (qFuzzyIsNull(aTangent.x()) && qFuzzyIsNull(aTangent.y())) 1249 aTangent = bezier->secondDerivedAt(t0); 1250 1251 if (qFuzzyIsNull(bTangent.x()) && qFuzzyIsNull(bTangent.y())) 1252 bTangent = bezier->secondDerivedAt(t1); 1253 1254 ep->angle = computeAngle(aTangent); 1255 ep->invAngle = computeAngle(bTangent); 1256 } else { 1257 const QPointF tangent = QPointF(*sp) - QPointF(*fp); 1258 ep->angle = computeAngle(tangent); 1259 ep->invAngle = ep->angle + 64; 1260 if (ep->invAngle >= 128) 1261 ep->invAngle -= 128; 1262 } 1229 const QPointF tangent = QPointF(*sp) - QPointF(*fp); 1230 ep->angle = computeAngle(tangent); 1231 ep->invAngle = ep->angle + 64; 1232 if (ep->invAngle >= 128) 1233 ep->invAngle -= 128; 1263 1234 1264 1235 QPathVertex *vertices[2] = { fp, sp }; … … 1315 1286 } 1316 1287 1317 void QWingedEdge::addBezierEdge(const QBezier *bezier, int vertexA, int vertexB, qreal alphaA, qreal alphaB, int path)1318 {1319 if (qFuzzyCompare(alphaA, alphaB))1320 return;1321 1322 qreal alphaMid = (alphaA + alphaB) * 0.5;1323 1324 qreal s0 = 0;1325 qreal s1 = 1;1326 int count = bezier->stationaryYPoints(s0, s1);1327 1328 m_splitPoints.clear();1329 m_splitPoints << alphaA;1330 m_splitPoints << alphaMid;1331 m_splitPoints << alphaB;1332 1333 if (count > 0 && !qFuzzyCompare(s0, alphaA) && !qFuzzyCompare(s0, alphaMid) && !qFuzzyCompare(s0, alphaB) && s0 > alphaA && s0 < alphaB)1334 m_splitPoints << s0;1335 1336 if (count > 1 && !qFuzzyCompare(s1, alphaA) && !qFuzzyCompare(s1, alphaMid) && !qFuzzyCompare(s1, alphaB) && s1 > alphaA && s1 < alphaB)1337 m_splitPoints << s1;1338 1339 if (count > 0)1340 qSort(m_splitPoints.begin(), m_splitPoints.end());1341 1342 int last = vertexA;1343 for (int i = 0; i < m_splitPoints.size() - 1; ++i) {1344 const qreal t0 = m_splitPoints[i];1345 const qreal t1 = m_splitPoints[i+1];1346 1347 int current;1348 if ((i + 1) == (m_splitPoints.size() - 1)) {1349 current = vertexB;1350 } else {1351 current = insert(bezier->pointAt(t1));1352 }1353 1354 QPathEdge *ep = edge(addEdge(last, current, bezier, t0, t1));1355 1356 if (ep) {1357 const int dir = m_vertices.at(last).y < m_vertices.at(current).y ? 1 : -1;1358 if (path == 0)1359 ep->windingA += dir;1360 else1361 ep->windingB += dir;1362 }1363 1364 last = current;1365 }1366 }1367 1368 void QWingedEdge::addBezierEdge(const QBezier *bezier, const QPointF &a, const QPointF &b, qreal alphaA, qreal alphaB, int path)1369 {1370 if (qFuzzyCompare(alphaA, alphaB))1371 return;1372 1373 if (comparePoints(a, b)) {1374 int v = insert(a);1375 1376 addBezierEdge(bezier, v, v, alphaA, alphaB, path);1377 } else {1378 int va = insert(a);1379 int vb = insert(b);1380 1381 addBezierEdge(bezier, va, vb, alphaA, alphaB, path);1382 }1383 }1384 1385 1288 int QWingedEdge::insert(const QPathVertex &vertex) 1386 1289 { … … 1431 1334 status.direction = QPathEdge::Forward; 1432 1335 1433 const QBezier *bezier = 0;1434 qreal t0 = 1;1435 qreal t1 = 0;1436 bool forward = true;1437 1438 1336 path.moveTo(*list.vertex(list.edge(edge)->first)); 1439 1337 … … 1441 1339 const QPathEdge *ep = list.edge(status.edge); 1442 1340 1443 if (ep->bezier != bezier || (bezier && t0 != ep->t1 && t1 != ep->t0)) { 1444 if (bezier) { 1445 QBezier sub = bezier->bezierOnInterval(t0, t1); 1446 1447 if (forward) 1448 path.cubicTo(sub.pt2(), sub.pt3(), sub.pt4()); 1449 else 1450 path.cubicTo(sub.pt3(), sub.pt2(), sub.pt1()); 1451 } 1452 1453 bezier = ep->bezier; 1454 t0 = 1; 1455 t1 = 0; 1456 forward = status.direction == QPathEdge::Forward; 1457 } 1458 1459 if (ep->bezier) { 1460 t0 = qMin(t0, ep->t0); 1461 t1 = qMax(t1, ep->t1); 1462 } else 1463 addLineTo(path, *list.vertex(ep->vertex(status.direction))); 1341 addLineTo(path, *list.vertex(ep->vertex(status.direction))); 1464 1342 1465 1343 if (status.traversal == QPathEdge::LeftTraversal) … … 1470 1348 status = list.next(status); 1471 1349 } while (status.edge != edge); 1472 1473 if (bezier) {1474 QBezier sub = bezier->bezierOnInterval(t0, t1);1475 if (forward)1476 path.cubicTo(sub.pt2(), sub.pt3(), sub.pt4());1477 else1478 path.cubicTo(sub.pt3(), sub.pt2(), sub.pt1());1479 }1480 1350 } 1481 1351 … … 1536 1406 return subjectPath.intersects(r2); 1537 1407 1538 QPathSegments a ;1408 QPathSegments a(subjectPath.elementCount()); 1539 1409 a.setPath(subjectPath); 1540 QPathSegments b ;1410 QPathSegments b(clipPath.elementCount()); 1541 1411 b.setPath(clipPath); 1542 1412 … … 1581 1451 return subjectPath.contains(r2); 1582 1452 1583 QPathSegments a ;1453 QPathSegments a(subjectPath.elementCount()); 1584 1454 a.setPath(subjectPath); 1585 QPathSegments b ;1455 QPathSegments b(clipPath.elementCount()); 1586 1456 b.setPath(clipPath); 1587 1457 … … 1705 1575 if (subjectPath == clipPath) 1706 1576 return op == BoolSub ? QPainterPath() : subjectPath; 1577 1578 bool subjectIsRect = pathToRect(subjectPath, 0); 1579 bool clipIsRect = pathToRect(clipPath, 0); 1707 1580 1708 1581 const QRectF clipBounds = clipPath.boundingRect(); … … 1733 1606 1734 1607 if (clipBounds.contains(subjectBounds)) { 1735 QRectF clipRect; 1736 if (pathToRect(clipPath, &clipRect) && clipRect.contains(subjectBounds)) { 1608 if (clipIsRect) { 1737 1609 switch (op) { 1738 1610 case BoolSub: … … 1747 1619 } 1748 1620 } else if (subjectBounds.contains(clipBounds)) { 1749 QRectF subjectRect; 1750 if (pathToRect(subjectPath, &subjectRect) && subjectRect.contains(clipBounds)) { 1621 if (subjectIsRect) { 1751 1622 switch (op) { 1752 1623 case BoolSub: 1753 1624 if (clipPath.fillRule() == Qt::OddEvenFill) { 1754 1625 QPainterPath result = clipPath; 1755 result.addRect(subject Rect);1626 result.addRect(subjectBounds); 1756 1627 return result; 1757 1628 } else { 1758 1629 QPainterPath result = clipPath.simplified(); 1759 result.addRect(subject Rect);1630 result.addRect(subjectBounds); 1760 1631 return result; 1761 1632 } … … 1770 1641 } 1771 1642 } 1643 1644 if (op == BoolAnd) { 1645 if (subjectIsRect) 1646 return intersect(clipPath, subjectBounds); 1647 else if (clipIsRect) 1648 return intersect(subjectPath, clipBounds); 1649 } 1772 1650 } 1773 1651 … … 1931 1809 1932 1810 if ((a.y() < y && b.y() > y) || (a.y() > y && b.y() < y)) { 1933 if (ep->bezier) { 1934 qreal maxX = qMax(a.x(), qMax(b.x(), qMax(ep->bezier->x2, ep->bezier->x3))); 1935 qreal minX = qMin(a.x(), qMin(b.x(), qMin(ep->bezier->x2, ep->bezier->x3))); 1936 1937 if (minX > x) { 1938 winding += w; 1939 } else if (maxX > x) { 1940 const qreal t = ep->bezier->tForY(ep->t0, ep->t1, y); 1941 const qreal intersection = ep->bezier->pointAt(t).x(); 1942 1943 if (intersection > x) 1944 winding += w; 1945 } 1946 } else { 1947 qreal intersectionX = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y()); 1948 1949 if (intersectionX > x) 1950 winding += w; 1951 } 1811 qreal intersectionX = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y()); 1812 1813 if (intersectionX > x) 1814 winding += w; 1952 1815 } 1953 1816 } … … 1965 1828 1966 1829 if ((a.y() < y && b.y() > y) || (a.y() > y && b.y() < y)) { 1967 if (edge->bezier) { 1968 const qreal t = edge->bezier->tForY(edge->t0, edge->t1, y); 1969 const qreal intersection = edge->bezier->pointAt(t).x(); 1970 1971 const QCrossingEdge edge = { i, intersection }; 1972 crossings << edge; 1973 } else { 1974 const qreal intersection = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y()); 1975 const QCrossingEdge edge = { i, intersection }; 1976 crossings << edge; 1977 } 1830 const qreal intersection = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y()); 1831 const QCrossingEdge edge = { i, intersection }; 1832 crossings << edge; 1978 1833 } 1979 1834 } … … 2053 1908 } 2054 1909 1910 namespace { 1911 1912 QList<QPainterPath> toSubpaths(const QPainterPath &path) 1913 { 1914 1915 QList<QPainterPath> subpaths; 1916 if (path.isEmpty()) 1917 return subpaths; 1918 1919 QPainterPath current; 1920 for (int i = 0; i < path.elementCount(); ++i) { 1921 const QPainterPath::Element &e = path.elementAt(i); 1922 switch (e.type) { 1923 case QPainterPath::MoveToElement: 1924 if (current.elementCount() > 1) 1925 subpaths += current; 1926 current = QPainterPath(); 1927 current.moveTo(e); 1928 break; 1929 case QPainterPath::LineToElement: 1930 current.lineTo(e); 1931 break; 1932 case QPainterPath::CurveToElement: { 1933 current.cubicTo(e, path.elementAt(i + 1), path.elementAt(i + 2)); 1934 i+=2; 1935 break; 1936 } 1937 case QPainterPath::CurveToDataElement: 1938 Q_ASSERT(!"toSubpaths(), bad element type"); 1939 break; 1940 } 1941 } 1942 1943 if (current.elementCount() > 1) 1944 subpaths << current; 1945 1946 return subpaths; 1947 } 1948 1949 enum Edge 1950 { 1951 Left, Top, Right, Bottom 1952 }; 1953 1954 static bool isVertical(Edge edge) 1955 { 1956 return edge == Left || edge == Right; 1957 } 1958 1959 template <Edge edge> 1960 bool compare(const QPointF &p, qreal t) 1961 { 1962 switch (edge) 1963 { 1964 case Left: 1965 return p.x() < t; 1966 case Right: 1967 return p.x() > t; 1968 case Top: 1969 return p.y() < t; 1970 default: 1971 return p.y() > t; 1972 } 1973 } 1974 1975 template <Edge edge> 1976 QPointF intersectLine(const QPointF &a, const QPointF &b, qreal t) 1977 { 1978 QLineF line(a, b); 1979 switch (edge) { 1980 case Left: // fall-through 1981 case Right: 1982 return line.pointAt((t - a.x()) / (b.x() - a.x())); 1983 default: 1984 return line.pointAt((t - a.y()) / (b.y() - a.y())); 1985 } 1986 } 1987 1988 void addLine(QPainterPath &path, const QLineF &line) 1989 { 1990 if (path.elementCount() > 0) 1991 path.lineTo(line.p1()); 1992 else 1993 path.moveTo(line.p1()); 1994 1995 path.lineTo(line.p2()); 1996 } 1997 1998 template <Edge edge> 1999 void clipLine(const QPointF &a, const QPointF &b, qreal t, QPainterPath &result) 2000 { 2001 bool outA = compare<edge>(a, t); 2002 bool outB = compare<edge>(b, t); 2003 if (outA && outB) 2004 return; 2005 2006 if (outA) 2007 addLine(result, QLineF(intersectLine<edge>(a, b, t), b)); 2008 else if(outB) 2009 addLine(result, QLineF(a, intersectLine<edge>(a, b, t))); 2010 else 2011 addLine(result, QLineF(a, b)); 2012 } 2013 2014 void addBezier(QPainterPath &path, const QBezier &bezier) 2015 { 2016 if (path.elementCount() > 0) 2017 path.lineTo(bezier.pt1()); 2018 else 2019 path.moveTo(bezier.pt1()); 2020 2021 path.cubicTo(bezier.pt2(), bezier.pt3(), bezier.pt4()); 2022 } 2023 2024 template <Edge edge> 2025 void clipBezier(const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, qreal t, QPainterPath &result) 2026 { 2027 QBezier bezier = QBezier::fromPoints(a, b, c, d); 2028 2029 bool outA = compare<edge>(a, t); 2030 bool outB = compare<edge>(b, t); 2031 bool outC = compare<edge>(c, t); 2032 bool outD = compare<edge>(d, t); 2033 2034 int outCount = int(outA) + int(outB) + int(outC) + int(outD); 2035 2036 if (outCount == 4) 2037 return; 2038 2039 if (outCount == 0) { 2040 addBezier(result, bezier); 2041 return; 2042 } 2043 2044 QTransform flip = isVertical(edge) ? QTransform(0, 1, 1, 0, 0, 0) : QTransform(); 2045 QBezier unflipped = bezier; 2046 QBezier flipped = bezier.mapBy(flip); 2047 2048 qreal t0 = 0, t1 = 1; 2049 int stationary = flipped.stationaryYPoints(t0, t1); 2050 2051 qreal segments[4]; 2052 QPointF points[4]; 2053 points[0] = unflipped.pt1(); 2054 segments[0] = 0; 2055 2056 int segmentCount = 0; 2057 if (stationary > 0) { 2058 ++segmentCount; 2059 segments[segmentCount] = t0; 2060 points[segmentCount] = unflipped.pointAt(t0); 2061 } 2062 if (stationary > 1) { 2063 ++segmentCount; 2064 segments[segmentCount] = t1; 2065 points[segmentCount] = unflipped.pointAt(t1); 2066 } 2067 ++segmentCount; 2068 segments[segmentCount] = 1; 2069 points[segmentCount] = unflipped.pt4(); 2070 2071 qreal lastIntersection = 0; 2072 for (int i = 0; i < segmentCount; ++i) { 2073 outA = compare<edge>(points[i], t); 2074 outB = compare<edge>(points[i+1], t); 2075 2076 if (outA != outB) { 2077 qreal intersection = flipped.tForY(segments[i], segments[i+1], t); 2078 2079 if (outB) 2080 addBezier(result, unflipped.getSubRange(lastIntersection, intersection)); 2081 2082 lastIntersection = intersection; 2083 } 2084 } 2085 2086 if (!outB) 2087 addBezier(result, unflipped.getSubRange(lastIntersection, 1)); 2088 } 2089 2090 // clips a single subpath against a single edge 2091 template <Edge edge> 2092 QPainterPath clip(const QPainterPath &path, qreal t) 2093 { 2094 QPainterPath result; 2095 for (int i = 1; i < path.elementCount(); ++i) { 2096 const QPainterPath::Element &element = path.elementAt(i); 2097 Q_ASSERT(!element.isMoveTo()); 2098 if (element.isLineTo()) { 2099 clipLine<edge>(path.elementAt(i-1), path.elementAt(i), t, result); 2100 } else { 2101 clipBezier<edge>(path.elementAt(i-1), path.elementAt(i), path.elementAt(i+1), path.elementAt(i+2), t, result); 2102 i += 2; 2103 } 2104 } 2105 2106 int last = path.elementCount() - 1; 2107 if (QPointF(path.elementAt(last)) != QPointF(path.elementAt(0))) 2108 clipLine<edge>(path.elementAt(last), path.elementAt(0), t, result); 2109 2110 return result; 2111 } 2112 2113 QPainterPath intersectPath(const QPainterPath &path, const QRectF &rect) 2114 { 2115 QList<QPainterPath> subpaths = toSubpaths(path); 2116 2117 QPainterPath result; 2118 result.setFillRule(path.fillRule()); 2119 for (int i = 0; i < subpaths.size(); ++i) { 2120 QPainterPath subPath = subpaths.at(i); 2121 QRectF bounds = subPath.boundingRect(); 2122 if (bounds.intersects(rect)) { 2123 if (bounds.left() < rect.left()) 2124 subPath = clip<Left>(subPath, rect.left()); 2125 if (bounds.right() > rect.right()) 2126 subPath = clip<Right>(subPath, rect.right()); 2127 2128 bounds = subPath.boundingRect(); 2129 2130 if (bounds.top() < rect.top()) 2131 subPath = clip<Top>(subPath, rect.top()); 2132 if (bounds.bottom() > rect.bottom()) 2133 subPath = clip<Bottom>(subPath, rect.bottom()); 2134 2135 if (subPath.elementCount() > 1) 2136 result.addPath(subPath); 2137 } 2138 } 2139 return result; 2140 } 2141 2142 } 2143 2144 QPainterPath QPathClipper::intersect(const QPainterPath &path, const QRectF &rect) 2145 { 2146 return intersectPath(path, rect); 2147 } 2148 2055 2149 QT_END_NAMESPACE -
trunk/src/gui/painting/qpathclipper_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 88 88 89 89 static bool pathToRect(const QPainterPath &path, QRectF *rect = 0); 90 static QPainterPath intersect(const QPainterPath &path, const QRectF &rect); 90 91 91 92 private: … … 148 149 int second; 149 150 150 qreal angle; 151 qreal invAngle; 152 153 const QBezier *bezier; 154 qreal t0; 155 qreal t1; 151 double angle; 152 double invAngle; 156 153 157 154 int next(Traversal traversal, Direction direction) const; … … 182 179 183 180 struct Segment { 184 Segment(int pathId, int vertexA, int vertexB , int bezierIndex = -1)181 Segment(int pathId, int vertexA, int vertexB) 185 182 : path(pathId) 186 , bezier(bezierIndex)187 183 , va(vertexA) 188 184 , vb(vertexB) … … 192 188 193 189 int path; 194 int bezier;195 190 196 191 // vertices … … 205 200 206 201 207 QPathSegments( );202 QPathSegments(int reserve); 208 203 209 204 void setPath(const QPainterPath &path); … … 216 211 const Segment &segmentAt(int index) const; 217 212 const QLineF lineAt(int index) const; 218 const QBezier *bezierAt(int index) const;219 213 const QRectF &elementBounds(int index) const; 220 214 int pathId(int index) const; … … 231 225 QDataBuffer<QPointF> m_points; 232 226 QDataBuffer<Segment> m_segments; 233 QDataBuffer<QBezier> m_beziers;234 227 QDataBuffer<Intersection> m_intersections; 235 228 … … 272 265 TraversalStatus next(const TraversalStatus &status) const; 273 266 274 int addEdge(const QPointF &a, const QPointF &b , const QBezier *bezier = 0, qreal t0 = 0, qreal t1 = 1);275 int addEdge(int vertexA, int vertexB , const QBezier *bezier = 0, qreal t0 = 0, qreal t1 = 1);267 int addEdge(const QPointF &a, const QPointF &b); 268 int addEdge(int vertexA, int vertexB); 276 269 277 270 bool isInside(qreal x, qreal y) const; … … 285 278 void printNode(int i, FILE *handle); 286 279 287 QBezier bezierFromIndex(int index) const;288 289 280 void removeEdge(int ei); 290 void addBezierEdge(const QBezier *bezier, const QPointF &a, const QPointF &b, qreal alphaA, qreal alphaB, int path);291 void addBezierEdge(const QBezier *bezier, int vertexA, int vertexB, qreal alphaA, qreal alphaB, int path);292 281 293 282 int insert(const QPathVertex &vertex); … … 312 301 , angle(0) 313 302 , invAngle(0) 314 , bezier(0)315 , t0(0)316 , t1(0)317 303 { 318 304 m_next[0][0] = -1; … … 360 346 } 361 347 362 inline QPathSegments::QPathSegments() 348 inline QPathSegments::QPathSegments(int reserve) : 349 m_points(reserve), 350 m_segments(reserve), 351 m_intersections(reserve) 363 352 { 364 353 } … … 394 383 const Segment &segment = m_segments.at(index); 395 384 return QLineF(m_points.at(segment.va), m_points.at(segment.vb)); 396 }397 398 inline const QBezier *QPathSegments::bezierAt(int index) const399 {400 const Segment &segment = m_segments.at(index);401 if (segment.bezier >= 0)402 return &m_beziers.at(segment.bezier);403 else404 return 0;405 385 } 406 386 -
trunk/src/gui/painting/qpdf.cpp
r781 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 917 917 918 918 919 QByteArray QPdf::stripSpecialCharacters(const QByteArray &string)920 {921 QByteArray s = string;922 s.replace(' ', "");923 s.replace('(', "");924 s.replace(')', "");925 s.replace('<', "");926 s.replace('>', "");927 s.replace('[', "");928 s.replace(']', "");929 s.replace('{', "");930 s.replace('}', "");931 s.replace('/', "");932 s.replace('%', "");933 return s;934 }935 936 937 919 // -------------------------- base engine, shared code between PS and PDF ----------------------- 938 920 … … 1409 1391 { 1410 1392 Q_D(QPdfBaseEngine); 1411 switch ( key) {1393 switch (int(key)) { 1412 1394 case PPK_CollateCopies: 1413 1395 d->collate = value.toBool(); … … 1425 1407 d->fullPage = value.toBool(); 1426 1408 break; 1409 case PPK_CopyCount: // fallthrough 1427 1410 case PPK_NumberOfCopies: 1428 1411 d->copies = value.toInt(); … … 1498 1481 1499 1482 QVariant ret; 1500 switch ( key) {1483 switch (int(key)) { 1501 1484 case PPK_CollateCopies: 1502 1485 ret = d->collate; … … 1513 1496 case PPK_FullPage: 1514 1497 ret = d->fullPage; 1498 break; 1499 case PPK_CopyCount: 1500 ret = d->copies; 1501 break; 1502 case PPK_SupportsMultipleCopies: 1503 #if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) 1504 if (QCUPSSupport::isAvailable()) 1505 ret = true; 1506 else 1507 #endif 1508 ret = false; 1515 1509 break; 1516 1510 case PPK_NumberOfCopies: -
trunk/src/gui/painting/qpdf_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 157 157 const char *paperSizeToString(QPrinter::PaperSize paperSize); 158 158 159 160 QByteArray stripSpecialCharacters(const QByteArray &string);161 159 } 162 160 … … 217 215 private: 218 216 void updateClipPath(const QPainterPath & path, Qt::ClipOperation op); 219 220 friend int qt_printerRealNumCopies(QPaintEngine *);221 217 }; 222 218 -
trunk/src/gui/painting/qpen.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 93 93 brush, respectively. Pens may also be compared and streamed. 94 94 95 For more information about painting in general, see \l{ThePaint95 For more information about painting in general, see the \l{Paint 96 96 System} documentation. 97 97 … … 873 873 the \a stream. 874 874 875 \sa { Format of the QDataStream Operators}875 \sa {Serializing Qt Data Types} 876 876 */ 877 877 … … 919 919 returns a reference to the \a stream. 920 920 921 \sa { Format of the QDataStream Operators}921 \sa {Serializing Qt Data Types} 922 922 */ 923 923 -
trunk/src/gui/painting/qpen.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpen_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpolygon.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 720 720 reference to the stream. 721 721 722 \sa { Format of the QDataStream Operators}722 \sa {Serializing Qt Data Types} 723 723 */ 724 724 QDataStream &operator<<(QDataStream &s, const QPolygon &a) … … 736 736 polygon, and returns a reference to the stream. 737 737 738 \sa { Format of the QDataStream Operators}738 \sa {Serializing Qt Data Types} 739 739 */ 740 740 QDataStream &operator>>(QDataStream &s, QPolygon &a) … … 756 756 reference to the stream. 757 757 758 \sa { Format of the QDataStream Operators}758 \sa {Serializing Qt Data Types} 759 759 */ 760 760 … … 777 777 polygon, and returns a reference to the stream. 778 778 779 \sa { Format of the QDataStream Operators}779 \sa {Serializing Qt Data Types} 780 780 */ 781 781 -
trunk/src/gui/painting/qpolygon.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qpolygonclipper_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 63 63 { 64 64 public: 65 QPolygonClipper() 65 QPolygonClipper() : 66 buffer1(0), buffer2(0) 66 67 { 67 68 x1 = y1 = x2 = y2 = 0; -
trunk/src/gui/painting/qprintengine.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 87 87 PPK_CustomPaperSize, 88 88 PPK_PageMargins, 89 PPK_CopyCount, 90 PPK_SupportsMultipleCopies, 89 91 PPK_PaperSize = PPK_PageSize, 90 92 -
trunk/src/gui/painting/qprintengine_mac.mm
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 115 115 if (d->state == QPrinter::Aborted) 116 116 return true; // I was just here a function call ago :) 117 if(d->paintEngine->type() == QPaintEngine::CoreGraphics) 117 if(d->paintEngine->type() == QPaintEngine::CoreGraphics) { 118 // We dont need the paint engine to call restoreGraphicsState() 119 static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->stackCount = 0; 118 120 static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0; 121 } 119 122 d->paintEngine->end(); 120 123 if (d->state != QPrinter::Idle) … … 686 689 d->fullPage = value.toBool(); 687 690 break; 691 case PPK_CopyCount: // fallthrough 688 692 case PPK_NumberOfCopies: 689 693 PMSetCopies(d->settings, value.toInt(), false); … … 787 791 case PPK_NumberOfCopies: 788 792 ret = 1; 793 break; 794 case PPK_CopyCount: { 795 UInt32 copies = 1; 796 PMGetCopies(d->settings, &copies); 797 ret = (uint) copies; 798 break; 799 } 800 case PPK_SupportsMultipleCopies: 801 ret = true; 789 802 break; 790 803 case PPK_Orientation: -
trunk/src/gui/painting/qprintengine_mac_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprintengine_pdf.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 932 932 { 933 933 info = addXrefEntry(-1); 934 935 // The 'text string' type in PDF is encoded either as PDFDocEncoding, or 936 // Unicode UTF-16 with a Unicode byte order mark as the first character 937 // (0xfeff), with the high-order byte first. 938 QByteArray array("<<\n/Title (\xfe\xff"); 939 const ushort *utf16Title = title.utf16(); 940 for (int i=0; i < title.size(); ++i) { 941 array.append((*(utf16Title + i)) >> 8); 942 array.append((*(utf16Title + i)) & 0xff); 943 } 944 array.append(")\n/Creator (\xfe\xff"); 945 const ushort *utf16Creator = creator.utf16(); 946 for (int i=0; i < creator.size(); ++i) { 947 array.append((*(utf16Creator + i)) >> 8); 948 array.append((*(utf16Creator + i)) & 0xff); 949 } 950 array.append(")\n/Producer (Qt " QT_VERSION_STR " (C) 2010 Nokia Corporation and/or its subsidiary(-ies))\n"); 951 write(array); 952 934 xprintf("<<\n/Title "); 935 printString(title); 936 xprintf("\n/Creator "); 937 printString(creator); 938 xprintf("\n/Producer "); 939 printString(QString::fromLatin1("Qt " QT_VERSION_STR " (C) 2010 Nokia Corporation and/or its subsidiary(-ies)")); 953 940 QDateTime now = QDateTime::currentDateTime().toUTC(); 954 941 QTime t = now.time(); 955 942 QDate d = now.date(); 956 xprintf(" /CreationDate (D:%d%02d%02d%02d%02d%02d)\n",943 xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n", 957 944 d.year(), 958 945 d.month(), … … 1231 1218 } 1232 1219 1220 void QPdfEnginePrivate::printString(const QString &string) { 1221 // The 'text string' type in PDF is encoded either as PDFDocEncoding, or 1222 // Unicode UTF-16 with a Unicode byte order mark as the first character 1223 // (0xfeff), with the high-order byte first. 1224 QByteArray array("(\xfe\xff"); 1225 const ushort *utf16 = string.utf16(); 1226 1227 for (int i=0; i < string.size(); ++i) { 1228 char part[2] = {char((*(utf16 + i)) >> 8), char((*(utf16 + i)) & 0xff)}; 1229 for(int j=0; j < 2; ++j) { 1230 if (part[j] == '(' || part[j] == ')' || part[j] == '\\') 1231 array.append('\\'); 1232 array.append(part[j]); 1233 } 1234 } 1235 array.append(")"); 1236 write(array); 1237 } 1238 1233 1239 QT_END_NAMESPACE 1234 1240 -
trunk/src/gui/painting/qprintengine_pdf_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 171 171 172 172 int addXrefEntry(int object, bool printostr = true); 173 void printString(const QString &string); 173 174 void xprintf(const char* fmt, ...); 174 175 inline void write(const QByteArray &data) { -
trunk/src/gui/painting/qprintengine_ps.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 65 65 #include "qregion.h" 66 66 #include "qimagewriter.h" 67 #include <private/qunicodetables_p.h>68 67 #include <private/qpainterpath_p.h> 69 68 #include <qdebug.h> … … 910 909 if (d->clipEnabled && d->allClipped) 911 910 return; 912 // ### Optimi se implementation!911 // ### Optimize implementation! 913 912 qreal yPos = r.y(); 914 913 qreal yOff = p.y(); -
trunk/src/gui/painting/qprintengine_ps_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprintengine_qws.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 269 269 ret = d->fullPage; 270 270 break; 271 case PPK_CopyCount: // fallthrough 271 272 case PPK_NumberOfCopies: 272 273 ret = d->numCopies; 274 break; 275 case PPK_SupportsMultipleCopies: 276 ret = false; 273 277 break; 274 278 case PPK_Orientation: … … 330 334 d->fullPage = value.toBool(); 331 335 break; 336 case PPK_CopyCount: // fallthrough 332 337 case PPK_NumberOfCopies: 333 338 d->numCopies = value.toInt(); -
trunk/src/gui/painting/qprintengine_qws_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprintengine_win.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 369 369 370 370 // We only want to convert the glyphs to text if the entire string is compatible with ASCII 371 bool convertToText = true; 371 // and if we actually have access to the chars. 372 bool convertToText = ti.chars != 0; 372 373 for (int i=0; i < ti.num_chars; ++i) { 373 374 if (ti.chars[i].unicode() >= 0x80) { … … 851 852 HPEN pen = ExtCreatePen(((penWidth == 0) ? PS_COSMETIC : PS_GEOMETRIC) 852 853 | PS_SOLID | capStyle | joinStyle, 853 penWidth, &brush, 0, 0);854 (penWidth == 0) ? 1 : penWidth, &brush, 0, 0); 854 855 855 856 HGDIOBJ old_pen = SelectObject(hdc, pen); … … 1242 1243 break; 1243 1244 1245 case PPK_CopyCount: // fallthrough 1244 1246 case PPK_NumberOfCopies: 1245 1247 if (!d->devMode) … … 1408 1410 break; 1409 1411 1412 case PPK_CopyCount: 1413 value = d->num_copies; 1414 break; 1415 1416 case PPK_SupportsMultipleCopies: 1417 value = true; 1418 break; 1419 1410 1420 case PPK_NumberOfCopies: 1411 1421 value = 1; -
trunk/src/gui/painting/qprintengine_win_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 109 109 friend class QPrintDialog; 110 110 friend class QPageSetupDialog; 111 friend int qt_printerRealNumCopies(QPaintEngine *);112 111 }; 113 112 -
trunk/src/gui/painting/qprinter.cpp
r782 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 159 159 } 160 160 161 162 // returns the actual num copies set on a printer, not163 // the number that is documented in QPrinter::numCopies()164 int qt_printerRealNumCopies(QPaintEngine *engine)165 {166 int numCopies = 1;167 if (engine->type() == QPaintEngine::PostScript168 || engine->type() == QPaintEngine::Pdf)169 {170 QPdfBaseEngine *base = static_cast<QPdfBaseEngine *>(engine);171 numCopies = base->d_func()->copies;172 }173 #ifdef Q_WS_WIN174 else if (engine->type() == QPaintEngine::Windows) {175 QWin32PrintEngine *base = static_cast<QWin32PrintEngine *>(engine);176 numCopies = base->d_func()->num_copies;177 }178 #endif179 return numCopies;180 }181 182 161 void QPrinterPrivate::createDefaultEngines() 183 162 { … … 304 283 \i setFullPage() tells QPrinter whether you want to deal with the 305 284 full page or just with the part the printer can draw on. 306 \i set NumCopies() tells QPrinter how many copies of the document285 \i setCopyCount() tells QPrinter how many copies of the document 307 286 it should print. 308 287 \endlist … … 405 384 \value Selection Only the selection should be printed. 406 385 \value PageRange The specified page range should be printed. 386 \value CurrentPage Only the current page should be printed. 407 387 408 388 \sa QAbstractPrintDialog::PrintRange … … 594 574 \value Selection Only the selection should be printed. 595 575 \value PageRange Print according to the from page and to page options. 576 \value CurrentPage Only the current page should be printed. 596 577 597 578 \sa setPrintRange(), printRange() … … 609 590 \value PrintPageRange Describes if printing page ranges (from, to) should 610 591 be enabled 592 \value PrintCurrentPage if Print Current Page option should be enabled 611 593 612 594 \sa setOptionEnabled(), isOptionEnabled() … … 756 738 757 739 QPrintEngine *oldPrintEngine = d->printEngine; 758 QPaintEngine *oldPaintEngine = d->paintEngine; // same as the above - shouldn't be deleted759 740 const bool def_engine = d->use_default_engine; 760 741 d->printEngine = 0; … … 769 750 // will return 1, disregarding the actual value that was set 770 751 if (key == QPrintEngine::PPK_NumberOfCopies) 771 prop = QVariant( qt_printerRealNumCopies(oldPaintEngine));752 prop = QVariant(copyCount()); 772 753 else 773 754 prop = oldPrintEngine->property(key); … … 1277 1258 1278 1259 /*! 1260 \obsolete 1279 1261 Returns the number of copies to be printed. The default value is 1. 1280 1262 … … 1289 1271 explicit call to the print code for each copy. 1290 1272 1273 Use copyCount() in conjunction with supportsMultipleCopies() instead. 1274 1291 1275 \sa setNumCopies(), actualNumCopies() 1292 1276 */ … … 1300 1284 1301 1285 /*! 1286 \obsolete 1302 1287 \since 4.6 1303 1288 … … 1308 1293 dialog or using setNumCopies(). 1309 1294 1295 Use copyCount() instead. 1296 1310 1297 \sa setNumCopies(), numCopies() 1311 1298 */ 1312 1299 int QPrinter::actualNumCopies() const 1313 1300 { 1314 Q_D(const QPrinter);1315 return qt_printerRealNumCopies(d->paintEngine); 1316 } 1317 1318 1319 1320 /*! 1301 return copyCount(); 1302 } 1303 1304 1305 1306 /*! 1307 \obsolete 1321 1308 Sets the number of copies to be printed to \a numCopies. 1322 1309 1323 1310 The printer driver reads this setting and prints the specified 1324 1311 number of copies. 1312 1313 Use setCopyCount() instead. 1325 1314 1326 1315 \sa numCopies() … … 1335 1324 } 1336 1325 1326 /*! 1327 \since 4.7 1328 1329 Sets the number of copies to be printed to \a count. 1330 1331 The printer driver reads this setting and prints the specified number of 1332 copies. 1333 1334 \sa copyCount(), supportsMultipleCopies() 1335 */ 1336 1337 void QPrinter::setCopyCount(int count) 1338 { 1339 Q_D(QPrinter); 1340 ABORT_IF_ACTIVE("QPrinter::setCopyCount;"); 1341 d->printEngine->setProperty(QPrintEngine::PPK_CopyCount, count); 1342 d->addToManualSetList(QPrintEngine::PPK_CopyCount); 1343 } 1344 1345 /*! 1346 \since 4.7 1347 1348 Returns the number of copies that will be printed. The default value is 1. 1349 1350 \sa setCopyCount(), supportsMultipleCopies() 1351 */ 1352 1353 int QPrinter::copyCount() const 1354 { 1355 Q_D(const QPrinter); 1356 return d->printEngine->property(QPrintEngine::PPK_CopyCount).toInt(); 1357 } 1358 1359 /*! 1360 \since 4.7 1361 1362 Returns true if the printer supports printing multiple copies of the same 1363 document in one job; otherwise false is returned. 1364 1365 On most systems this function will return true. However, on X11 systems 1366 that do not support CUPS, this function will return false. That means the 1367 application has to handle the number of copies by printing the same 1368 document the required number of times. 1369 1370 \sa setCopyCount(), copyCount() 1371 */ 1372 1373 bool QPrinter::supportsMultipleCopies() const 1374 { 1375 Q_D(const QPrinter); 1376 return d->printEngine->property(QPrintEngine::PPK_SupportsMultipleCopies).toBool(); 1377 } 1337 1378 1338 1379 /*! … … 2276 2317 full page or not. 2277 2318 2278 \value PPK_NumberOfCopies An integer specifying the number of2279 copies 2319 \value PPK_NumberOfCopies Obsolete. An integer specifying the number of 2320 copies. Use PPK_CopyCount instead. 2280 2321 2281 2322 \value PPK_Orientation Specifies a QPrinter::Orientation value. … … 2323 2364 \value PPK_PageMargins A QList<QVariant> containing the left, top, 2324 2365 right and bottom margin values. 2366 2367 \value PPK_CopyCount An integer specifying the number of copies to print. 2368 2369 \value PPK_SupportsMultipleCopies A boolean value indicating whether or not 2370 the printer supports printing multiple copies in one job. 2325 2371 2326 2372 \value PPK_CustomBase Basis for extension. -
trunk/src/gui/painting/qprinter.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 125 125 126 126 // ### Qt 5: Merge with QAbstractPrintDialog::PrintRange 127 enum PrintRange { AllPages, Selection, PageRange };127 enum PrintRange { AllPages, Selection, PageRange, CurrentPage }; 128 128 129 129 enum Unit { … … 199 199 200 200 int actualNumCopies() const; 201 202 void setCopyCount(int); 203 int copyCount() const; 204 bool supportsMultipleCopies() const; 201 205 202 206 void setPaperSource(PaperSource); -
trunk/src/gui/painting/qprinter_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprinterinfo.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprinterinfo.qdoc
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 7 7 ** This file is part of the documentation of the Qt Toolkit. 8 8 ** 9 ** $QT_BEGIN_LICENSE: LGPL$9 ** $QT_BEGIN_LICENSE:FDL$ 10 10 ** Commercial Usage 11 11 ** Licensees holding valid Qt Commercial licenses may use this file in 12 12 ** accordance with the Qt Commercial License Agreement provided with the 13 ** Software or, alternatively, in accordance with the terms contained in 14 ** awritten agreement between you and Nokia.13 ** Software or, alternatively, in accordance with the terms contained in a 14 ** written agreement between you and Nokia. 15 15 ** 16 ** GNU Lesser General Public License Usage 17 ** Alternatively, this file may be used under the terms of the GNU Lesser 18 ** General Public License version 2.1 as published by the Free Software 19 ** Foundation and appearing in the file LICENSE.LGPL included in the 20 ** packaging of this file. Please review the following information to 21 ** ensure the GNU Lesser General Public License version 2.1 requirements 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 23 ** 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 ** 28 ** GNU General Public License Usage 29 ** Alternatively, this file may be used under the terms of the GNU 30 ** General Public License version 3.0 as published by the Free Software 31 ** Foundation and appearing in the file LICENSE.GPL included in the 32 ** packaging of this file. Please review the following information to 33 ** ensure the GNU General Public License version 3.0 requirements will be 34 ** met: http://www.gnu.org/copyleft/gpl.html. 16 ** GNU Free Documentation License 17 ** Alternatively, this file may be used under the terms of the GNU Free 18 ** Documentation License version 1.3 as published by the Free Software 19 ** Foundation and appearing in the file included in the packaging of this 20 ** file. 35 21 ** 36 22 ** If you have questions regarding the use of this file, please contact -
trunk/src/gui/painting/qprinterinfo_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprinterinfo_unix.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprinterinfo_unix_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qprinterinfo_win.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qrasterdefs_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 82 82 QT_FT_BEGIN_HEADER 83 83 84 85 84 /*************************************************************************/ 86 85 /* */ … … 102 101 /* pixel coordinates. */ 103 102 /* */ 104 typedef signed longQT_FT_Pos;103 typedef signed int QT_FT_Pos; 105 104 106 105 … … 838 837 /* independently to convert an outline into a bitmap or pixmap. */ 839 838 /* */ 840 typedef struct QT_FT_RasterRec_*QT_FT_Raster;839 typedef struct TRaster_ *QT_FT_Raster; 841 840 842 841 … … 1090 1089 void* user; 1091 1090 QT_FT_BBox clip_box; 1091 int skip_spans; 1092 1092 1093 1093 } QT_FT_Raster_Params; … … 1119 1119 /* */ 1120 1120 typedef int 1121 (*QT_FT_Raster_NewFunc)( void* memory, 1122 QT_FT_Raster* raster ); 1121 (*QT_FT_Raster_NewFunc)( QT_FT_Raster* raster ); 1123 1122 1124 1123 #define QT_FT_Raster_New_Func QT_FT_Raster_NewFunc -
trunk/src/gui/painting/qrasterizer.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 66 66 #define COORD_OFFSET 32 // 26.6, 32 is half a pixel 67 67 68 static inline QT_FT_Vector PointToVector(const QPointF &p) 69 { 70 QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; 71 return result; 72 } 73 68 74 class QSpanBuffer { 69 75 public: … … 199 205 200 206 QScanConverter::QScanConverter() 201 : m_alloc(0) 207 : m_lines(0) 208 , m_alloc(0) 202 209 , m_size(0) 203 210 , m_intersections(0) 211 , m_active(0) 204 212 { 205 213 } … … 311 319 void qScanConvert(QScanConverter &d, T allVertical) 312 320 { 321 if (!d.m_lines.size()) { 322 d.m_active.reset(); 323 return; 324 } 313 325 qSort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), QT_PREPEND_NAMESPACE(topOrder)); 314 326 int line = 0; … … 688 700 } 689 701 690 static inline bool q 16Dot16Compare(qreal p1, qreal p2)691 { 692 return FloatToQ16Dot16(p2 - p1) == 0;702 static inline bool q26Dot6Compare(qreal p1, qreal p2) 703 { 704 return int((p2 - p1) * 64.) == 0; 693 705 } 694 706 … … 703 715 } 704 716 717 static inline QPointF snapTo26Dot6Grid(const QPointF &p) 718 { 719 return QPointF(qFloorF(p.x() * 64) * (1 / qreal(64)), 720 qFloorF(p.y() * 64) * (1 / qreal(64))); 721 } 722 705 723 void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap) 706 724 { … … 713 731 QPointF pb = b; 714 732 715 QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5; 716 if (squareCap) 717 offs += QPointF(offs.y(), offs.x()); 733 if (squareCap) { 734 QPointF delta = pb - pa; 735 pa -= (0.5f * width) * delta; 736 pb += (0.5f * width) * delta; 737 } 738 739 QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5; 718 740 const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs); 719 741 720 if (!clip.contains( a) || !clip.contains(b)) {742 if (!clip.contains(pa) || !clip.contains(pb)) { 721 743 qreal t1 = 0; 722 744 qreal t2 = 1; 723 745 724 const qreal o[2] = { a.x(),a.y() };725 const qreal d[2] = { b.x() - a.x(), b.y() -a.y() };746 const qreal o[2] = { pa.x(), pa.y() }; 747 const qreal d[2] = { pb.x() - pa.x(), pb.y() - pa.y() }; 726 748 727 749 const qreal low[2] = { clip.left(), clip.top() }; … … 746 768 return; 747 769 } 748 pa = a + (b - a) * t1; 749 pb = a + (b - a) * t2; 770 771 QPointF npa = pa + (pb - pa) * t1; 772 QPointF npb = pa + (pb - pa) * t2; 773 774 pa = npa; 775 pb = npb; 750 776 } 751 777 … … 758 784 759 785 { 760 const qreal gridResolution = 64;761 const qreal reciprocal = 1 / gridResolution;762 763 // snap to grid to prevent large slopes764 pa.rx() = qFloorF(pa.rx() * gridResolution) * reciprocal;765 pa.ry() = qFloorF(pa.ry() * gridResolution) * reciprocal;766 pb.rx() = qFloorF(pb.rx() * gridResolution) * reciprocal;767 pb.ry() = qFloorF(pb.ry() * gridResolution) * reciprocal;768 769 786 // old delta 770 787 const QPointF d0 = a - b; … … 784 801 QSpanBuffer buffer(d->blend, d->data, d->clipRect); 785 802 786 if (q 16Dot16Compare(pa.y(), pb.y())) {803 if (q26Dot6Compare(pa.y(), pb.y())) { 787 804 const qreal x = (pa.x() + pb.x()) * 0.5f; 788 805 const qreal dx = qAbs(pb.x() - pa.x()) * 0.5f; … … 794 811 pb = QPointF(x, y + dy); 795 812 796 if (squareCap) 797 width = 1 / width + 1.0f; 798 else 799 width = 1 / width; 800 801 squareCap = false; 802 } 803 804 if (q16Dot16Compare(pa.x(), pb.x())) { 813 width = 1 / width; 814 } 815 816 if (q26Dot6Compare(pa.x(), pb.x())) { 805 817 if (pa.y() > pb.y()) 806 818 qSwap(pa, pb); … … 809 821 const qreal halfWidth = 0.5f * width * dy; 810 822 811 if (squareCap) {812 pa.ry() -= halfWidth;813 pb.ry() += halfWidth;814 }815 816 823 qreal left = pa.x() - halfWidth; 817 824 qreal right = pa.x() + halfWidth; … … 823 830 pb.ry() = qBound(qreal(d->clipRect.top()), pb.y(), qreal(d->clipRect.bottom() + 1)); 824 831 825 if (q 16Dot16Compare(left, right) || q16Dot16Compare(pa.y(), pb.y()))832 if (q26Dot6Compare(left, right) || q26Dot6Compare(pa.y(), pb.y())) 826 833 return; 827 834 … … 894 901 const QPointF perp(delta.y(), -delta.x()); 895 902 896 if (squareCap) {897 pa -= delta;898 pb += delta;899 }900 901 903 QPointF top; 902 904 QPointF left; … … 916 918 } 917 919 920 top = snapTo26Dot6Grid(top); 921 bottom = snapTo26Dot6Grid(bottom); 922 left = snapTo26Dot6Grid(left); 923 right = snapTo26Dot6Grid(right); 924 918 925 const qreal topBound = qBound(qreal(d->clipRect.top()), top.y(), qreal(d->clipRect.bottom())); 919 926 const qreal bottomBound = qBound(qreal(d->clipRect.top()), bottom.y(), qreal(d->clipRect.bottom())); 920 927 921 const qreal leftSlope = (left.x() - top.x()) / (left.y() - top.y()); 922 const qreal rightSlope = -1.0f / leftSlope; 923 924 const Q16Dot16 leftSlopeFP = FloatToQ16Dot16(leftSlope); 925 const Q16Dot16 rightSlopeFP = FloatToQ16Dot16(rightSlope); 928 const QPointF topLeftEdge = left - top; 929 const QPointF topRightEdge = right - top; 930 const QPointF bottomLeftEdge = bottom - left; 931 const QPointF bottomRightEdge = bottom - right; 932 933 const qreal topLeftSlope = topLeftEdge.x() / topLeftEdge.y(); 934 const qreal bottomLeftSlope = bottomLeftEdge.x() / bottomLeftEdge.y(); 935 936 const qreal topRightSlope = topRightEdge.x() / topRightEdge.y(); 937 const qreal bottomRightSlope = bottomRightEdge.x() / bottomRightEdge.y(); 938 939 const Q16Dot16 topLeftSlopeFP = FloatToQ16Dot16(topLeftSlope); 940 const Q16Dot16 topRightSlopeFP = FloatToQ16Dot16(topRightSlope); 941 942 const Q16Dot16 bottomLeftSlopeFP = FloatToQ16Dot16(bottomLeftSlope); 943 const Q16Dot16 bottomRightSlopeFP = FloatToQ16Dot16(bottomRightSlope); 944 945 const Q16Dot16 invTopLeftSlopeFP = FloatToQ16Dot16(1 / topLeftSlope); 946 const Q16Dot16 invTopRightSlopeFP = FloatToQ16Dot16(1 / topRightSlope); 947 948 const Q16Dot16 invBottomLeftSlopeFP = FloatToQ16Dot16(1 / bottomLeftSlope); 949 const Q16Dot16 invBottomRightSlopeFP = FloatToQ16Dot16(1 / bottomRightSlope); 926 950 927 951 if (d->antialiased) { … … 931 955 const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound)); 932 956 933 Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * leftSlope);934 Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * rightSlope);957 Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope); 958 Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope); 935 959 Q16Dot16 leftIntersectBf = 0; 936 960 Q16Dot16 rightIntersectBf = 0; 937 961 938 962 if (iLeftFP < iTopFP) 939 leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * rightSlope);963 leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope); 940 964 941 965 if (iRightFP < iTopFP) 942 rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * leftSlope);966 rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope); 943 967 944 968 Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom; … … 955 979 rowTop = qMax(iTopFP, yTopFP); 956 980 topLeftIntersectAf = leftIntersectAf + 957 Q16Dot16Multiply( leftSlopeFP, rowTop - iTopFP);981 Q16Dot16Multiply(topLeftSlopeFP, rowTop - iTopFP); 958 982 topRightIntersectAf = rightIntersectAf + 959 Q16Dot16Multiply( rightSlopeFP, rowTop - iTopFP);983 Q16Dot16Multiply(topRightSlopeFP, rowTop - iTopFP); 960 984 961 985 Q16Dot16 yFP = iTopFP; … … 969 993 if (yFP == iLeftFP) { 970 994 const int y = Q16Dot16ToInt(yFP); 971 leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * rightSlope);972 topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply( rightSlopeFP, rowTopLeft - yFP);973 bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply( leftSlopeFP, rowBottomLeft - yFP);995 leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope); 996 topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP); 997 bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP); 974 998 } else { 975 999 topLeftIntersectBf = leftIntersectBf; 976 bottomLeftIntersectAf = leftIntersectAf + leftSlopeFP;1000 bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP; 977 1001 } 978 1002 979 1003 if (yFP == iRightFP) { 980 1004 const int y = Q16Dot16ToInt(yFP); 981 rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * leftSlope);982 topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply( leftSlopeFP, rowTopRight - yFP);983 bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply( rightSlopeFP, rowBottomRight - yFP);1005 rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope); 1006 topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP); 1007 bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP); 984 1008 } else { 985 1009 topRightIntersectBf = rightIntersectBf; 986 bottomRightIntersectAf = rightIntersectAf + rightSlopeFP;1010 bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP; 987 1011 } 988 1012 989 1013 if (yFP == iBottomFP) { 990 bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply( rightSlopeFP, rowBottom - yFP);991 bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply( leftSlopeFP, rowBottom - yFP);1014 bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP); 1015 bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP); 992 1016 } else { 993 bottomLeftIntersectBf = leftIntersectBf + rightSlopeFP;994 bottomRightIntersectBf = rightIntersectBf + leftSlopeFP;1017 bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP; 1018 bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP; 995 1019 } 996 1020 … … 1037 1061 excluded += intersectPixelFP(x, rowTop, rowBottomLeft, 1038 1062 bottomLeftIntersectAf, topLeftIntersectAf, 1039 leftSlopeFP, -rightSlopeFP);1063 topLeftSlopeFP, invTopLeftSlopeFP); 1040 1064 if (yFP >= iLeftFP) 1041 1065 excluded += intersectPixelFP(x, rowTopLeft, rowBottom, 1042 1066 topLeftIntersectBf, bottomLeftIntersectBf, 1043 rightSlopeFP, -leftSlopeFP);1067 bottomLeftSlopeFP, invBottomLeftSlopeFP); 1044 1068 1045 1069 if (x >= rightMin) { … … 1047 1071 excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, 1048 1072 topRightIntersectAf, bottomRightIntersectAf, 1049 rightSlopeFP, -leftSlopeFP);1073 topRightSlopeFP, invTopRightSlopeFP); 1050 1074 if (yFP >= iRightFP) 1051 1075 excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, 1052 1076 bottomRightIntersectBf, topRightIntersectBf, 1053 leftSlopeFP, -rightSlopeFP);1077 bottomRightSlopeFP, invBottomRightSlopeFP); 1054 1078 } 1055 1079 … … 1069 1093 excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, 1070 1094 topRightIntersectAf, bottomRightIntersectAf, 1071 rightSlopeFP, -leftSlopeFP);1095 topRightSlopeFP, invTopRightSlopeFP); 1072 1096 if (yFP >= iRightFP) 1073 1097 excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, 1074 1098 bottomRightIntersectBf, topRightIntersectBf, 1075 leftSlopeFP, -rightSlopeFP);1099 bottomRightSlopeFP, invBottomRightSlopeFP); 1076 1100 1077 1101 Q16Dot16 coverage = rowHeight - excluded; … … 1081 1105 } 1082 1106 1083 leftIntersectAf += leftSlopeFP;1084 leftIntersectBf += rightSlopeFP;1085 rightIntersectAf += rightSlopeFP;1086 rightIntersectBf += leftSlopeFP;1107 leftIntersectAf += topLeftSlopeFP; 1108 leftIntersectBf += bottomLeftSlopeFP; 1109 rightIntersectAf += topRightSlopeFP; 1110 rightIntersectBf += bottomRightSlopeFP; 1087 1111 topLeftIntersectAf = leftIntersectAf; 1088 1112 topRightIntersectAf = rightIntersectAf; … … 1098 1122 int iMiddle = qMin(iLeft, iRight); 1099 1123 1100 Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * leftSlope);1101 Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * rightSlope);1102 Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * rightSlope);1103 Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * leftSlope);1124 Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope); 1125 Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope); 1126 Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope); 1127 Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope); 1104 1128 1105 1129 int ny; … … 1123 1147 } 1124 1148 1125 DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, leftSlopeFP, rightSlopeFP)1126 DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, rightSlopeFP, rightSlopeFP)1127 DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, leftSlopeFP, leftSlopeFP)1128 DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, rightSlopeFP, leftSlopeFP)1149 DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, topLeftSlopeFP, topRightSlopeFP) 1150 DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, bottomLeftSlopeFP, topRightSlopeFP) 1151 DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, topLeftSlopeFP, bottomRightSlopeFP); 1152 DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, bottomLeftSlopeFP, bottomRightSlopeFP); 1129 1153 #undef DO_SEGMENT 1130 1154 } … … 1176 1200 1177 1201 d->scanConverter.end(); 1178 }1179 1180 static inline QT_FT_Vector PointToVector(const QPointF &p)1181 {1182 QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) };1183 return result;1184 1202 } 1185 1203 -
trunk/src/gui/painting/qrasterizer_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qregion.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 712 712 713 713 /*! 714 \fn bool QRegion::intersects(const QRect &rect) const 714 715 \since 4.2 715 716 … … 717 718 returns false. 718 719 */ 719 bool QRegion::intersects(const QRect &rect) const 720 { 721 if (isEmpty() || rect.isNull()) 722 return false; 723 724 const QRect r = rect.normalized(); 725 if (!rect_intersects(boundingRect(), r)) 726 return false; 727 if (rectCount() == 1) 728 return true; 729 730 const QVector<QRect> myRects = rects(); 731 for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it) 732 if (rect_intersects(r, *it)) 733 return true; 734 return false; 735 } 720 736 721 737 722 #if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN) && !defined (Q_WS_PM) … … 1726 1711 QT_END_INCLUDE_NAMESPACE 1727 1712 1728 /* 1 if two BOX s overlap.1729 * 0 if two BOX s do not overlap.1713 /* 1 if two BOXes overlap. 1714 * 0 if two BOXes do not overlap. 1730 1715 * Remember, x2 and y2 are not in the region 1731 1716 */ … … 4376 4361 } 4377 4362 4363 bool QRegion::intersects(const QRect &rect) const 4364 { 4365 if (isEmptyHelper(d->qt_rgn) || rect.isNull()) 4366 return false; 4367 4368 const QRect r = rect.normalized(); 4369 if (!rect_intersects(d->qt_rgn->extents, r)) 4370 return false; 4371 if (d->qt_rgn->numRects == 1) 4372 return true; 4373 4374 const QVector<QRect> myRects = rects(); 4375 for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it) 4376 if (rect_intersects(r, *it)) 4377 return true; 4378 return false; 4379 } 4380 4381 4378 4382 #endif 4379 4383 QT_END_NAMESPACE -
trunk/src/gui/painting/qregion.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 213 213 void *xrectangles; 214 214 #elif defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) 215 mutable RgnHandle unused; // Here for binary compat ability reasons. ### Qt 5 remove.215 mutable RgnHandle unused; // Here for binary compatibility reasons. ### Qt 5 remove. 216 216 #endif 217 217 #if defined(Q_WS_QWS) || defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM) -
trunk/src/gui/painting/qregion_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qregion_qws.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qregion_s60.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qregion_win.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qregion_x11.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qrgb.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 65 65 66 66 Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb) // get alpha part of RGBA 67 { return ((rgb >> 24) & 0xff); }67 { return rgb >> 24; } 68 68 69 69 Q_GUI_EXPORT_INLINE QRgb qRgb(int r, int g, int b)// set RGB value -
trunk/src/gui/painting/qstroker.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 121 121 { 122 122 public: 123 QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path )124 : m_path(path), m_pos(0), m_curve_index(-1) { }123 QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path, qreal threshold) 124 : m_path(path), m_pos(0), m_curve_index(-1), m_curve_threshold(threshold) { } 125 125 126 126 inline bool hasNext() const { return m_curve_index >= 0 || m_pos < m_path->size(); } … … 153 153 qt_fixed_to_real(m_path->at(m_pos+1).y)), 154 154 QPointF(qt_fixed_to_real(m_path->at(m_pos+2).x), 155 qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon( );155 qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon(m_curve_threshold); 156 156 m_curve_index = 1; 157 157 e.type = QPainterPath::LineToElement; … … 170 170 QPolygonF m_curve; 171 171 int m_curve_index; 172 qreal m_curve_threshold; 172 173 }; 173 174 … … 188 189 189 190 QStrokerOps::QStrokerOps() 190 : m_customData(0), m_moveTo(0), m_lineTo(0), m_cubicTo(0) 191 : m_elements(0) 192 , m_curveThreshold(qt_real_to_fixed(0.25)) 193 , m_dashThreshold(qt_real_to_fixed(0.25)) 194 , m_customData(0) 195 , m_moveTo(0) 196 , m_lineTo(0) 197 , m_cubicTo(0) 191 198 { 192 199 } … … 195 202 { 196 203 } 197 198 204 199 205 /*! … … 239 245 return; 240 246 247 setCurveThresholdFromTransform(QTransform()); 241 248 begin(customData); 242 249 int count = path.elementCount(); … … 309 316 if (!pointCount) 310 317 return; 318 319 setCurveThresholdFromTransform(QTransform()); 311 320 begin(data); 312 321 if (matrix.isIdentity()) { … … 349 358 } 350 359 360 setCurveThresholdFromTransform(QTransform()); 351 361 begin(data); 352 362 moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y())); … … 367 377 m_strokeWidth = qt_real_to_fixed(1); 368 378 m_miterLimit = qt_real_to_fixed(2); 369 m_curveThreshold = qt_real_to_fixed(0.25);370 379 } 371 380 372 381 QStroker::~QStroker() 373 382 { 374 375 383 } 376 384 … … 603 611 QLineF miterLine(QPointF(qt_fixed_to_real(focal_x), 604 612 qt_fixed_to_real(focal_y)), isect); 605 if ( miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) {613 if (type == QLineF::NoIntersection || miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) { 606 614 emitLineTo(qt_real_to_fixed(nextLine.x1()), 607 615 qt_real_to_fixed(nextLine.y1())); … … 1044 1052 } 1045 1053 1054 static inline bool lineRectIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) 1055 { 1056 return ((p1.x > tl.x || p2.x > tl.x) && (p1.x < br.x || p2.x < br.x) 1057 && (p1.y > tl.y || p2.y > tl.y) && (p1.y < br.y || p2.y < br.y)); 1058 } 1059 1060 // If the line intersects the rectangle, this function will return true. 1061 static bool lineIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) 1062 { 1063 if (!lineRectIntersectsRect(p1, p2, tl, br)) 1064 return false; 1065 if (p1.x == p2.x || p1.y == p2.y) 1066 return true; 1067 1068 if (p1.y > p2.y) 1069 qSwap(p1, p2); // make p1 above p2 1070 qfixed2d u; 1071 qfixed2d v; 1072 qfixed2d w = {p2.x - p1.x, p2.y - p1.y}; 1073 if (p1.x < p2.x) { 1074 // backslash 1075 u.x = tl.x - p1.x; u.y = br.y - p1.y; 1076 v.x = br.x - p1.x; v.y = tl.y - p1.y; 1077 } else { 1078 // slash 1079 u.x = tl.x - p1.x; u.y = tl.y - p1.y; 1080 v.x = br.x - p1.x; v.y = br.y - p1.y; 1081 } 1082 #if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16) 1083 qint64 val1 = qint64(u.x) * qint64(w.y) - qint64(u.y) * qint64(w.x); 1084 qint64 val2 = qint64(v.x) * qint64(w.y) - qint64(v.y) * qint64(w.x); 1085 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); 1086 #elif defined(QFIXED_IS_32_32) 1087 // Cannot do proper test because it may overflow. 1088 return true; 1089 #else 1090 qreal val1 = u.x * w.y - u.y * w.x; 1091 qreal val2 = v.x * w.y - v.y * w.x; 1092 return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); 1093 #endif 1094 } 1046 1095 1047 1096 void QDashStroker::processCurrentSubpath() … … 1068 1117 return; 1069 1118 1119 qreal invSumLength = qreal(1) / sumLength; 1120 1070 1121 Q_ASSERT(dashCount > 0); 1071 1122 1072 dashCount = (dashCount / 2) *2; // Round down to even number1123 dashCount = dashCount & -2; // Round down to even number 1073 1124 1074 1125 int idash = 0; // Index to current dash … … 1078 1129 1079 1130 // make sure doffset is in range [0..sumLength) 1080 doffset -= qFloor(doffset / sumLength) * sumLength;1131 doffset -= qFloor(doffset * invSumLength) * sumLength; 1081 1132 1082 1133 while (doffset >= dashes[idash]) { 1083 1134 doffset -= dashes[idash]; 1084 idash = (idash + 1) % dashCount; 1135 if (++idash >= dashCount) 1136 idash = 0; 1085 1137 } 1086 1138 … … 1092 1144 QPainterPath dashPath; 1093 1145 1094 QSubpathFlatIterator it(&m_elements );1146 QSubpathFlatIterator it(&m_elements, m_dashThreshold); 1095 1147 qfixed2d prev = it.next(); 1096 1148 … … 1120 1172 1121 1173 bool done = pos >= estop; 1174 1175 if (clipping) { 1176 // Check if the entire line can be clipped away. 1177 if (!lineIntersectsRect(prev, e, clip_tl, clip_br)) { 1178 // Cut away full dash sequences. 1179 elen -= qFloor(elen * invSumLength) * sumLength; 1180 // Update dash offset. 1181 while (!done) { 1182 qreal dpos = pos + dashes[idash] - doffset - estart; 1183 1184 Q_ASSERT(dpos >= 0); 1185 1186 if (dpos > elen) { // dash extends this line 1187 doffset = dashes[idash] - (dpos - elen); // subtract the part already used 1188 pos = estop; // move pos to next path element 1189 done = true; 1190 } else { // Dash is on this line 1191 pos = dpos + estart; 1192 done = pos >= estop; 1193 if (++idash >= dashCount) 1194 idash = 0; 1195 doffset = 0; // full segment so no offset on next. 1196 } 1197 } 1198 hasMoveTo = false; 1199 move_to_pos = e; 1200 } 1201 } 1202 1122 1203 // Dash away... 1123 1204 while (!done) { 1124 1205 QPointF p2; 1125 1206 1126 int idash_incr = 0;1127 1207 bool has_offset = doffset > 0; 1208 bool evenDash = (idash & 1) == 0; 1128 1209 qreal dpos = pos + dashes[idash] - doffset - estart; 1129 1210 … … 1139 1220 pos = dpos + estart; 1140 1221 done = pos >= estop; 1141 idash_incr = 1; 1222 if (++idash >= dashCount) 1223 idash = 0; 1142 1224 doffset = 0; // full segment so no offset on next. 1143 1225 } 1144 1226 1145 if ( idash % 2 == 0) {1227 if (evenDash) { 1146 1228 line_to_pos.x = qt_real_to_fixed(p2.x()); 1147 1229 line_to_pos.y = qt_real_to_fixed(p2.y()); 1148 1230 1149 // If we have an offset, we're continuing a dash 1150 // from a previous element and should only 1151 // continue the current dash, without starting a 1152 // new subpath. 1153 if (!has_offset || !hasMoveTo) { 1154 emitMoveTo(move_to_pos.x, move_to_pos.y); 1155 hasMoveTo = true; 1231 if (!clipping 1232 || lineRectIntersectsRect(move_to_pos, line_to_pos, clip_tl, clip_br)) 1233 { 1234 // If we have an offset, we're continuing a dash 1235 // from a previous element and should only 1236 // continue the current dash, without starting a 1237 // new subpath. 1238 if (!has_offset || !hasMoveTo) { 1239 emitMoveTo(move_to_pos.x, move_to_pos.y); 1240 hasMoveTo = true; 1241 } 1242 1243 emitLineTo(line_to_pos.x, line_to_pos.y); 1244 } else { 1245 hasMoveTo = false; 1156 1246 } 1157 1158 if (!clipping 1159 // if move_to is inside... 1160 || (move_to_pos.x > clip_tl.x && move_to_pos.x < clip_br.x 1161 && move_to_pos.y > clip_tl.y && move_to_pos.y < clip_br.y) 1162 // Or if line_to is inside... 1163 || (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x 1164 && line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y)) 1165 { 1166 emitLineTo(line_to_pos.x, line_to_pos.y); 1167 } 1247 move_to_pos = line_to_pos; 1168 1248 } else { 1169 1249 move_to_pos.x = qt_real_to_fixed(p2.x()); 1170 1250 move_to_pos.y = qt_real_to_fixed(p2.y()); 1171 1251 } 1172 1173 idash = (idash + idash_incr) % dashCount;1174 1252 } 1175 1253 -
trunk/src/gui/painting/qstroker_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 125 125 void *data); 126 126 127 // qtransform.cpp 128 Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); 129 127 130 class Q_GUI_EXPORT QStrokerOps 128 131 { … … 162 165 void setClipRect(const QRectF &clip) { m_clip_rect = clip; } 163 166 167 void setCurveThresholdFromTransform(const QTransform &transform) 168 { 169 qreal scale; 170 qt_scaleForTransform(transform, &scale); 171 m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale); 172 } 173 174 void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; } 175 qfixed curveThreshold() const { return m_curveThreshold; } 176 164 177 protected: 165 178 inline void emitMoveTo(qfixed x, qfixed y); … … 171 184 172 185 QRectF m_clip_rect; 186 qfixed m_curveThreshold; 187 qfixed m_dashThreshold; 173 188 174 189 void *m_customData; … … 209 224 qfixed miterLimit() const { return m_miterLimit; } 210 225 211 void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }212 qfixed curveThreshold() const { return m_curveThreshold; }213 214 226 void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join); 215 227 inline void emitMoveTo(qfixed x, qfixed y); … … 228 240 qfixed m_strokeWidth; 229 241 qfixed m_miterLimit; 230 qfixed m_curveThreshold;231 242 232 243 LineJoinMode m_capStyle; -
trunk/src/gui/painting/qstylepainter.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qstylepainter.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qtessellator.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qtessellator_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qtextureglyphcache.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 48 48 #include "private/qfontengine_ft_p.h" 49 49 50 #ifndef QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH51 #define QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH 25652 #endif53 54 50 QT_BEGIN_NAMESPACE 55 51 56 52 // #define CACHE_DEBUG 57 53 58 void QTextureGlyphCache::populate(const QTextItemInt &ti, 59 const QVarLengthArray<glyph_t> &glyphs, 60 const QVarLengthArray<QFixedPoint> &) 54 // returns the highest number closest to v, which is a power of 2 55 // NB! assumes 32 bit ints 56 static inline int qt_next_power_of_two(int v) 57 { 58 v--; 59 v |= v >> 1; 60 v |= v >> 2; 61 v |= v >> 4; 62 v |= v >> 8; 63 v |= v >> 16; 64 ++v; 65 return v; 66 } 67 68 bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs, 69 const QFixedPoint *) 61 70 { 62 71 #ifdef CACHE_DEBUG 63 printf("Populating with '%s'\n", QString::fromRawData(ti.chars, ti.num_chars).toLatin1().data());72 printf("Populating with %d glyphs\n", numGlyphs); 64 73 qDebug() << " -> current transformation: " << m_transform; 65 74 #endif 66 75 67 m_current_ textitem = &ti;76 m_current_fontengine = fontEngine; 68 77 const int margin = glyphMargin(); 78 const int paddingDoubled = glyphPadding() * 2; 69 79 70 80 QHash<glyph_t, Coord> listItemCoordinates; … … 72 82 73 83 // check each glyph for its metrics and get the required rowHeight. 74 for (int i=0; i < glyphs.size(); ++i) {84 for (int i=0; i < numGlyphs; ++i) { 75 85 const glyph_t glyph = glyphs[i]; 76 86 if (coords.contains(glyph)) … … 78 88 if (listItemCoordinates.contains(glyph)) 79 89 continue; 80 glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyph, m_transform);90 glyph_metrics_t metrics = fontEngine->boundingBox(glyph, m_transform); 81 91 82 92 #ifdef CACHE_DEBUG 83 printf("'%c' (%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f, ti.ascent=%.2f, ti.descent=%.2f\n", 84 ti.chars[i].toLatin1(), 93 printf("(%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n", 85 94 glyph, 86 95 metrics.width.toReal(), … … 89 98 metrics.yoff.toReal(), 90 99 metrics.x.toReal(), 91 metrics.y.toReal(), 92 ti.ascent.toReal(), 93 ti.descent.toReal()); 100 metrics.y.toReal()); 94 101 #endif 95 102 int glyph_width = metrics.width.ceil().toInt(); … … 113 120 } 114 121 if (listItemCoordinates.isEmpty()) 115 return ;116 117 rowHeight += margin * 2 ;122 return true; 123 124 rowHeight += margin * 2 + paddingDoubled; 118 125 if (isNull()) 119 createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, rowHeight);126 createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, qt_next_power_of_two(rowHeight)); 120 127 121 128 // now actually use the coords and paint the wanted glyps into cache. … … 124 131 Coord c = iter.value(); 125 132 133 m_currentRowHeight = qMax(m_currentRowHeight, c.h + margin * 2); 134 126 135 if (m_cx + c.w > m_w) { 127 // no room on the current line, start new glyph strip 128 m_cx = 0; 129 m_cy = m_h; 136 int new_width = m_w*2; 137 while (new_width < m_cx + c.w) 138 new_width *= 2; 139 if (new_width <= maxTextureWidth()) { 140 resizeTextureData(new_width, m_h); 141 m_w = new_width; 142 } else { 143 // no room on the current line, start new glyph strip 144 m_cx = 0; 145 m_cy += m_currentRowHeight + paddingDoubled; 146 m_currentRowHeight = c.h + margin * 2; // New row 147 } 130 148 } 131 149 if (m_cy + c.h > m_h) { 132 int new_height; 133 if (m_cx == 0) { // add a whole row 134 new_height = m_h + rowHeight; 135 m_cy = m_h; 136 } else { // just extend row 137 new_height = m_cy + rowHeight; 138 } 150 int new_height = m_h*2; 151 while (new_height < m_cy + c.h) 152 new_height *= 2; 153 154 if (maxTextureHeight() > 0 && new_height > maxTextureHeight()) { 155 // We can't make a new texture of the required size, so 156 // bail out 157 return false; 158 } 159 139 160 // if no room in the current texture - realloc a larger texture 140 161 resizeTextureData(m_w, new_height); … … 148 169 coords.insert(iter.key(), c); 149 170 150 if (m_cx + c.w > m_w) { 151 m_cx = 0; 152 m_cy += rowHeight; 153 } else { 154 // for the Mono case, glyph_width is 8-bit aligned, 155 // and therefore so will m_cx 156 m_cx += c.w; 157 } 171 m_cx += c.w + paddingDoubled; 158 172 ++iter; 159 173 } 160 174 161 175 return true; 162 176 } 163 177 … … 183 197 }; 184 198 185 QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_ textitem->fontEngine);199 QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_fontengine); 186 200 QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform); 187 201 188 202 if (gset && ft->loadGlyphs(gset, &g, 1, format)) { 189 QFontEngineFT::Glyph *glyph = gset->g lyph_data.value(g);203 QFontEngineFT::Glyph *glyph = gset->getGlyph(g); 190 204 const int bytesPerLine = (format == QFontEngineFT::Format_Mono ? ((glyph->width + 31) & ~31) >> 3 191 205 : (glyph->width + 3) & ~3); … … 195 209 #endif 196 210 if (m_type == QFontEngineGlyphCache::Raster_RGBMask) 197 return m_current_ textitem->fontEngine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform);211 return m_current_fontengine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform); 198 212 else 199 return m_current_ textitem->fontEngine->alphaMapForGlyph(g, m_transform);213 return m_current_fontengine->alphaMapForGlyph(g, m_transform); 200 214 201 215 return QImage(); … … 253 267 #endif 254 268 255 if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { 256 QPainter p(&m_image); 269 if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { 270 QImage ref(m_image.bits() + (c.x * 4 + c.y * m_image.bytesPerLine()), 271 qMax(mask.width(), c.w), qMax(mask.height(), c.h), m_image.bytesPerLine(), 272 m_image.format()); 273 QPainter p(&ref); 257 274 p.setCompositionMode(QPainter::CompositionMode_Source); 258 p.fillRect( c.x, c.y, c.w, c.h, QColor(0,0,0,0)); // TODO optimize this259 p.drawImage( c.x, c.y, mask);275 p.fillRect(0, 0, c.w, c.h, QColor(0,0,0,0)); // TODO optimize this 276 p.drawImage(0, 0, mask); 260 277 p.end(); 261 278 } else if (m_type == QFontEngineGlyphCache::Raster_Mono) { … … 325 342 if (m_image.rect().contains(base)) 326 343 m_image.setPixel(base, 255); 327 m_image.save(QString::fromLatin1("cache-%1-%2-%3.png") 328 .arg(m_current_textitem->font().family()) 329 .arg(m_current_textitem->font().pointSize()) 330 .arg(m_transform.type())); 344 m_image.save(QString::fromLatin1("cache-%1.png").arg(int(this))); 331 345 #endif 332 346 } -
trunk/src/gui/painting/qtextureglyphcache_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 65 65 #endif 66 66 67 #ifndef QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH 68 #define QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH 256 69 #endif 70 67 71 struct glyph_metrics_t; 68 72 typedef unsigned int glyph_t; … … 77 81 public: 78 82 QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix) 79 : QFontEngineGlyphCache(matrix, type), m_w(0), m_h(0), m_cx(0), m_cy(0) { } 83 : QFontEngineGlyphCache(matrix, type), m_current_fontengine(0), 84 m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0) 85 { } 80 86 81 87 virtual ~QTextureGlyphCache() { } … … 91 97 }; 92 98 93 void populate(const QTextItemInt &ti, 94 const QVarLengthArray<glyph_t> &glyphs, 95 const QVarLengthArray<QFixedPoint> &positions); 99 bool populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs, 100 const QFixedPoint *positions); 96 101 97 102 virtual void createTextureData(int width, int height) = 0; 98 103 virtual void resizeTextureData(int width, int height) = 0; 99 104 virtual int glyphMargin() const { return 0; } 105 virtual int glyphPadding() const { return 0; } 100 106 101 107 virtual void fillTexture(const Coord &coord, glyph_t glyph) = 0; … … 112 118 113 119 QImage textureMapForGlyph(glyph_t g) const; 120 virtual int maxTextureWidth() const { return QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH; } 121 virtual int maxTextureHeight() const { return -1; } 114 122 115 123 protected: 116 const QTextItemInt *m_current_textitem;124 QFontEngine *m_current_fontengine; 117 125 118 126 int m_w; // image width … … 120 128 int m_cx; // current x 121 129 int m_cy; // current y 130 int m_currentRowHeight; // Height of last row 122 131 }; 123 132 124 133 125 class Q ImageTextureGlyphCache : public QTextureGlyphCache134 class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache 126 135 { 127 136 public: -
trunk/src/gui/painting/qtransform.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 48 48 #include "qvariant.h" 49 49 #include <qmath.h> 50 #include <qnumeric.h> 50 51 51 52 #include <private/qbezier_p.h> … … 148 149 QPaintDevice has its origin located at the top-left position. The 149 150 \e x values increase to the right; \e y values increase 150 downward. For a complete description, see the \l { TheCoordinate151 System} {coordinate system} documentation.151 downward. For a complete description, see the \l {Coordinate 152 System} {coordinate system} documentation. 152 153 153 154 QPainter has functions to translate, scale, shear and rotate the … … 223 224 \endtable 224 225 225 \sa QPainter, { TheCoordinate System}, {demos/affine}{Affine226 \sa QPainter, {Coordinate System}, {demos/affine}{Affine 226 227 Transformations Demo}, {Transformations Example} 227 228 */ … … 411 412 if (dx == 0 && dy == 0) 412 413 return *this; 414 #ifndef QT_NO_DEBUG 415 if (qIsNaN(dx) | qIsNaN(dy)) { 416 qWarning() << "QTransform::translate with NaN called"; 417 return *this; 418 } 419 #endif 413 420 414 421 switch(inline_type()) { … … 448 455 QTransform QTransform::fromTranslate(qreal dx, qreal dy) 449 456 { 457 #ifndef QT_NO_DEBUG 458 if (qIsNaN(dx) | qIsNaN(dy)) { 459 qWarning() << "QTransform::fromTranslate with NaN called"; 460 return QTransform(); 461 } 462 #endif 450 463 QTransform transform(1, 0, 0, 0, 1, 0, dx, dy, 1, true); 451 464 if (dx == 0 && dy == 0) … … 467 480 if (sx == 1 && sy == 1) 468 481 return *this; 482 #ifndef QT_NO_DEBUG 483 if (qIsNaN(sx) | qIsNaN(sy)) { 484 qWarning() << "QTransform::scale with NaN called"; 485 return *this; 486 } 487 #endif 469 488 470 489 switch(inline_type()) { … … 502 521 QTransform QTransform::fromScale(qreal sx, qreal sy) 503 522 { 523 #ifndef QT_NO_DEBUG 524 if (qIsNaN(sx) | qIsNaN(sy)) { 525 qWarning() << "QTransform::fromScale with NaN called"; 526 return QTransform(); 527 } 528 #endif 504 529 QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1, true); 505 530 if (sx == 1. && sy == 1.) … … 521 546 if (sh == 0 && sv == 0) 522 547 return *this; 548 #ifndef QT_NO_DEBUG 549 if (qIsNaN(sh) | qIsNaN(sv)) { 550 qWarning() << "QTransform::shear with NaN called"; 551 return *this; 552 } 553 #endif 523 554 524 555 switch(inline_type()) { … … 576 607 if (a == 0) 577 608 return *this; 609 #ifndef QT_NO_DEBUG 610 if (qIsNaN(a)) { 611 qWarning() << "QTransform::rotate with NaN called"; 612 return *this; 613 } 614 #endif 578 615 579 616 qreal sina = 0; … … 661 698 QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis) 662 699 { 700 #ifndef QT_NO_DEBUG 701 if (qIsNaN(a)) { 702 qWarning() << "QTransform::rotateRadians with NaN called"; 703 return *this; 704 } 705 #endif 663 706 qreal sina = qSin(a); 664 707 qreal cosa = qCos(a); … … 986 1029 reference to the stream. 987 1030 988 \sa { Format of the QDataStream Operators}1031 \sa {Serializing Qt Data Types} 989 1032 */ 990 1033 QDataStream & operator<<(QDataStream &s, const QTransform &m) … … 1010 1053 reference to the stream. 1011 1054 1012 \sa { Format of the QDataStream Operators}1055 \sa {Serializing Qt Data Types} 1013 1056 */ 1014 1057 QDataStream & operator>>(QDataStream &s, QTransform &t) … … 1038 1081 QDebug operator<<(QDebug dbg, const QTransform &m) 1039 1082 { 1040 dbg.nospace() << "QTransform(" 1041 << "11=" << m.m11() 1083 static const char *typeStr[] = 1084 { 1085 "TxNone", 1086 "TxTranslate", 1087 "TxScale", 1088 "TxRotate", 1089 "TxShear", 1090 "TxProject" 1091 }; 1092 1093 dbg.nospace() << "QTransform(type=" << typeStr[m.type()] << ',' 1094 << " 11=" << m.m11() 1042 1095 << " 12=" << m.m12() 1043 1096 << " 13=" << m.m13() … … 1049 1102 << " 33=" << m.m33() 1050 1103 << ')'; 1104 1051 1105 return dbg.space(); 1052 1106 } … … 1492 1546 return true; 1493 1547 } 1548 Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); 1494 1549 1495 1550 static inline bool cubicTo_clipped(QPainterPath &path, const QTransform &transform, const QPointF &a, const QPointF &b, const QPointF &c, const QPointF &d, bool needsMoveTo) … … 1497 1552 // Convert projective xformed curves to line 1498 1553 // segments so they can be transformed more accurately 1499 QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon(); 1554 1555 qreal scale; 1556 qt_scaleForTransform(transform, &scale); 1557 1558 qreal curveThreshold = scale == 0 ? qreal(0.25) : (qreal(0.25) / scale); 1559 1560 QPolygonF segment = QBezier::fromPoints(a, b, c, d).toPolygon(curveThreshold); 1500 1561 1501 1562 for (int i = 0; i < segment.size() - 1; ++i) … … 1566 1627 { 1567 1628 TransformationType t = inline_type(); 1568 if (t == TxNone || path. isEmpty())1629 if (t == TxNone || path.elementCount() == 0) 1569 1630 return path; 1570 1631 -
trunk/src/gui/painting/qtransform.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 65 65 class Q_GUI_EXPORT QTransform 66 66 { 67 Q_ENUMS(TransformationType)68 67 public: 69 68 enum TransformationType { -
trunk/src/gui/painting/qvectorpath_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include <private/qwidget_p.h> 45 45 #include <private/qbackingstore_p.h> 46 #include <private/qapplication_p.h> 46 47 47 48 QT_BEGIN_NAMESPACE … … 50 51 { 51 52 public: 52 QWindowSurfacePrivate(QWidget *w) : window(w), staticContentsSupport(false) {} 53 QWindowSurfacePrivate(QWidget *w) 54 : window(w) 55 , staticContentsSupport(0) 56 , partialUpdateSupport(1) 57 { 58 } 53 59 54 60 QWidget *window; … … 56 62 QRegion staticContents; 57 63 QList<QImage*> bufferImages; 58 bool staticContentsSupport; 64 uint staticContentsSupport : 1; 65 uint partialUpdateSupport : 1; 59 66 }; 60 67 … … 111 118 : d_ptr(new QWindowSurfacePrivate(window)) 112 119 { 113 if (window) 114 window->setWindowSurface(this); 120 if (!QApplicationPrivate::runtime_graphics_system) { 121 if(window) 122 window->setWindowSurface(this); 123 } 115 124 } 116 125 … … 285 294 void QWindowSurface::setStaticContentsSupport(bool enable) 286 295 { 296 if (enable && !d_ptr->partialUpdateSupport) { 297 qWarning("QWindowSurface::setStaticContentsSupport: static contents support requires partial update support"); 298 return; 299 } 287 300 d_ptr->staticContentsSupport = enable; 288 301 } … … 301 314 { 302 315 return d_ptr->staticContentsSupport && !d_ptr->staticContents.isEmpty(); 316 } 317 318 bool QWindowSurface::hasPartialUpdateSupport() const 319 { 320 return d_ptr->partialUpdateSupport; 321 } 322 323 void QWindowSurface::setPartialUpdateSupport(bool enable) 324 { 325 if (!enable && d_ptr->staticContentsSupport) { 326 qWarning("QWindowSurface::setPartialUpdateSupport: static contents support requires partial update support"); 327 return; 328 } 329 d_ptr->partialUpdateSupport = enable; 303 330 } 304 331 -
trunk/src/gui/painting/qwindowsurface_mac.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface_mac_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 74 74 75 75 virtual QPaintDevice *paintDevice() = 0; 76 virtual void flush(QWidget *widget, const QRegion ®ion, 77 const QPoint &offset) = 0; 76 77 // 'widget' can be a child widget, in which case 'region' is in child widget coordinates and 78 // offset is the (child) widget's offset in relation to the window surface. On QWS, 'offset' 79 // can be larger than just the offset from the top-level widget as there may also be window 80 // decorations which are painted into the window surface. 81 virtual void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) = 0; 78 82 virtual void setGeometry(const QRect &rect); 79 83 QRect geometry() const; … … 91 95 92 96 bool hasStaticContentsSupport() const; 97 bool hasPartialUpdateSupport() const; 93 98 94 99 void setStaticContents(const QRegion ®ion); … … 98 103 bool hasStaticContents() const; 99 104 void setStaticContentsSupport(bool enable); 105 void setPartialUpdateSupport(bool enable); 100 106 101 107 private: -
trunk/src/gui/painting/qwindowsurface_qws.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 883 883 const QColor blank = Qt::transparent; 884 884 for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { 885 p.fillRect(*it, blank); 885 QRect r = *it; 886 #ifdef Q_BACKINGSTORE_SUBSURFACES 887 r.translate(painterOffset()); 888 #endif 889 p.fillRect(r, blank); 886 890 } 887 891 } -
trunk/src/gui/painting/qwindowsurface_qws_p.h
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface_raster.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface_raster_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface_s60.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 44 44 #include <QtGui/qpaintdevice.h> 45 45 #include <private/qwidget_p.h> 46 #include "qwindowsurface_s60_p.h" 47 #include "qpixmap_s60_p.h" 48 #include "qt_s60_p.h" 49 #include "private/qdrawhelper_p.h" 46 #include <private/qwindowsurface_s60_p.h> 47 #include <private/qpixmap_s60_p.h> 48 #include <private/qt_s60_p.h> 49 #include <private/qapplication_p.h> 50 #include <private/qdrawhelper_p.h> 51 52 #ifdef QT_GRAPHICSSYSTEM_RUNTIME 53 #include <private/qgraphicssystem_runtime_p.h> 54 #endif 50 55 51 56 QT_BEGIN_NAMESPACE … … 57 62 }; 58 63 64 TDisplayMode displayMode(bool opaque) 65 { 66 67 TDisplayMode mode = S60->screenDevice()->DisplayMode(); 68 if (opaque) { 69 mode = EColor16MU; 70 } else { 71 if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3) 72 mode = Q_SYMBIAN_ECOLOR16MAP; // Symbian^3 WServ has support for ARGB32_PRE 73 else 74 mode = EColor16MA; // Symbian prior to Symbian^3 sw accelerates EColor16MA 75 } 76 return mode; 77 } 78 59 79 QS60WindowSurface::QS60WindowSurface(QWidget* widget) 60 80 : QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate) 61 81 { 62 63 TDisplayMode mode = S60->screenDevice()->DisplayMode(); 64 bool isOpaque = qt_widget_private(widget)->isOpaque; 65 if (mode == EColor16MA && isOpaque) 66 mode = EColor16MU; // Faster since 16MU -> 16MA is typically accelerated 67 else if (mode == EColor16MU && !isOpaque) 68 mode = EColor16MA; // Try for transparency anyway 69 82 TDisplayMode mode = displayMode(qt_widget_private(widget)->isOpaque); 70 83 // We create empty CFbsBitmap here -> it will be resized in setGeometry 71 84 CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new … … 80 93 setStaticContentsSupport(true); 81 94 } 95 82 96 QS60WindowSurface::~QS60WindowSurface() 83 97 { 98 #if defined(QT_GRAPHICSSYSTEM_RUNTIME) && defined(Q_SYMBIAN_SUPPORTS_SURFACES) 99 if(QApplicationPrivate::runtime_graphics_system) { 100 QRuntimeGraphicsSystem *runtimeGraphicsSystem = 101 static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system); 102 if(runtimeGraphicsSystem->graphicsSystemName() == QLatin1String("openvg")) { 103 104 // Graphics system has been switched from raster to openvg. 105 // Issue empty redraw to clear the UI surface 106 107 QWidget *w = window(); 108 if (w->testAttribute(Qt::WA_WState_Created)) { 109 RWindow *const window = static_cast<RWindow *>(w->winId()->DrawableWindow()); 110 window->BeginRedraw(); 111 window->EndRedraw(); 112 } 113 } 114 } 115 #endif 116 84 117 delete d_ptr; 85 118 } … … 87 120 void QS60WindowSurface::beginPaint(const QRegion &rgn) 88 121 { 122 #ifdef Q_SYMBIAN_SUPPORTS_SURFACES 123 S60->wsSession().Finish(); 124 #endif 125 89 126 if (!qt_widget_private(window())->isOpaque) { 90 127 QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data()); 128 129 TDisplayMode mode = displayMode(false); 130 if (pixmapData->cfbsBitmap->DisplayMode() != mode) 131 pixmapData->convertToDisplayMode(mode); 132 91 133 pixmapData->beginDataAccess(); 92 134 -
trunk/src/gui/painting/qwindowsurface_s60_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface_x11.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwindowsurface_x11_p.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) -
trunk/src/gui/painting/qwmatrix.h
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com)
Note:
See TracChangeset
for help on using the changeset viewer.