summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
commit30fd22b9574def54726e7b193127cc0c901c1b4c (patch)
tree96dfc923044db0515064ba39d052d9ed577e3e40 /src/gui
parentd7b0581c1c2ef60c08d238dae39298af6904918f (diff)
parent6aa09bbce59828d028f6d1e81d2bfc6ba537aae1 (diff)
Merge remote-tracking branch 'origin/dev' into stable
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessiblecache.cpp2
-rw-r--r--src/gui/doc/snippets/image/supportedformat.cpp8
-rw-r--r--src/gui/doc/src/coordsys.qdoc2
-rw-r--r--src/gui/doc/src/paintsystem.qdoc4
-rw-r--r--src/gui/gui.pro4
-rw-r--r--src/gui/image/image.pri15
-rw-r--r--src/gui/image/qbmphandler.cpp107
-rw-r--r--src/gui/image/qimage.cpp2509
-rw-r--r--src/gui/image/qimage.h29
-rw-r--r--src/gui/image/qimage_compat.cpp (renamed from src/gui/painting/qdrawhelper_avx.cpp)46
-rw-r--r--src/gui/image/qimage_conversions.cpp2183
-rw-r--r--src/gui/image/qimage_neon.cpp4
-rw-r--r--src/gui/image/qimage_p.h13
-rw-r--r--src/gui/image/qimage_sse2.cpp2
-rw-r--r--src/gui/image/qimagereader.cpp29
-rw-r--r--src/gui/image/qjpeghandler.cpp10
-rw-r--r--src/gui/image/qpixmap.cpp22
-rw-r--r--src/gui/image/qpixmap.h7
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/image/qpixmap_raster.cpp13
-rw-r--r--src/gui/image/qpixmap_raster_p.h1
-rw-r--r--src/gui/image/qplatformpixmap.h9
-rw-r--r--src/gui/image/qpnghandler.pri2
-rw-r--r--src/gui/image/qxbmhandler.cpp24
-rw-r--r--src/gui/kernel/kernel.pri3
-rw-r--r--src/gui/kernel/qdrag.cpp6
-rw-r--r--src/gui/kernel/qevent.cpp32
-rw-r--r--src/gui/kernel/qevent.h3
-rw-r--r--src/gui/kernel/qguiapplication.cpp174
-rw-r--r--src/gui/kernel/qguiapplication.h4
-rw-r--r--src/gui/kernel/qguiapplication_p.h16
-rw-r--r--src/gui/kernel/qguivariant.cpp2
-rw-r--r--src/gui/kernel/qinputmethod.cpp25
-rw-r--r--src/gui/kernel/qinputmethod.h3
-rw-r--r--src/gui/kernel/qkeysequence.cpp2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp59
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp88
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h120
-rw-r--r--src/gui/kernel/qplatformintegration.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.h6
-rw-r--r--src/gui/kernel/qplatformmenu.cpp (renamed from src/gui/image/qimage_avx.cpp)24
-rw-r--r--src/gui/kernel/qplatformmenu.h2
-rw-r--r--src/gui/kernel/qplatformsessionmanager.h6
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.h2
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon_qpa.cpp16
-rw-r--r--src/gui/kernel/qplatformtheme.cpp65
-rw-r--r--src/gui/kernel/qplatformtheme.h6
-rw-r--r--src/gui/kernel/qplatformwindow.cpp41
-rw-r--r--src/gui/kernel/qplatformwindow.h3
-rw-r--r--src/gui/kernel/qscreen.cpp11
-rw-r--r--src/gui/kernel/qshortcutmap.cpp2
-rw-r--r--src/gui/kernel/qstylehints.cpp117
-rw-r--r--src/gui/kernel/qstylehints.h8
-rw-r--r--src/gui/kernel/qsurface.cpp16
-rw-r--r--src/gui/kernel/qsurface.h4
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp124
-rw-r--r--src/gui/kernel/qsurfaceformat.h12
-rw-r--r--src/gui/kernel/qwindow.cpp53
-rw-r--r--src/gui/kernel/qwindow_p.h4
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp20
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h16
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h11
-rw-r--r--src/gui/math3d/qvector2d.h82
-rw-r--r--src/gui/math3d/qvector3d.h86
-rw-r--r--src/gui/math3d/qvector4d.h90
-rw-r--r--src/gui/opengl/opengl.pri10
-rw-r--r--src/gui/opengl/qopengl.h10
-rw-r--r--src/gui/opengl/qopenglbuffer.cpp16
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp5
-rw-r--r--src/gui/opengl/qopenglengineshadersource_p.h8
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp228
-rw-r--r--src/gui/opengl/qopenglframebufferobject.h13
-rw-r--r--src/gui/opengl/qopenglframebufferobject_p.h13
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp318
-rw-r--r--src/gui/opengl/qopenglfunctions.h11
-rw-r--r--src/gui/opengl/qopenglgradientcache.cpp10
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp123
-rw-r--r--src/gui/opengl/qopenglproxy_win.cpp4600
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp28
-rw-r--r--src/gui/opengl/qopengltexture.cpp734
-rw-r--r--src/gui/opengl/qopengltexture.h44
-rw-r--r--src/gui/opengl/qopengltexture_p.h4
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp393
-rw-r--r--src/gui/opengl/qopengltextureblitter_p.h86
-rw-r--r--src/gui/opengl/qopengltextureglyphcache.cpp21
-rw-r--r--src/gui/opengl/qopengltexturehelper.cpp450
-rw-r--r--src/gui/opengl/qopengltexturehelper_p.h641
-rw-r--r--src/gui/opengl/qopengltimerquery.cpp6
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp8
-rw-r--r--src/gui/painting/painting.pri13
-rw-r--r--src/gui/painting/qbrush.cpp81
-rw-r--r--src/gui/painting/qcolor.cpp55
-rw-r--r--src/gui/painting/qdrawhelper.cpp884
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp6
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h4
-rw-r--r--src/gui/painting/qdrawhelper_p.h36
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp38
-rw-r--r--src/gui/painting/qdrawhelper_x86_p.h27
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h4
-rw-r--r--src/gui/painting/qemulationpaintengine.cpp2
-rw-r--r--src/gui/painting/qpaintbuffer.cpp6
-rw-r--r--src/gui/painting/qpaintengine.cpp1
-rw-r--r--src/gui/painting/qpaintengine.h1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp38
-rw-r--r--src/gui/painting/qpainter.cpp12
-rw-r--r--src/gui/painting/qpainterpath.cpp24
-rw-r--r--src/gui/painting/qpainterpath.h2
-rw-r--r--src/gui/painting/qpen.cpp4
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp247
-rw-r--r--src/gui/painting/qplatformbackingstore.h34
-rw-r--r--src/gui/painting/qrgb.h43
-rw-r--r--src/gui/text/qdistancefield.cpp14
-rw-r--r--src/gui/text/qfont.cpp18
-rw-r--r--src/gui/text/qfont.h2
-rw-r--r--src/gui/text/qfont_p.h17
-rw-r--r--src/gui/text/qfontdatabase.h2
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp17
-rw-r--r--src/gui/text/qfontengine.cpp221
-rw-r--r--src/gui/text/qfontengine_ft.cpp35
-rw-r--r--src/gui/text/qfontengine_p.h1
-rw-r--r--src/gui/text/qfontengine_qpa.cpp8
-rw-r--r--src/gui/text/qfontmetrics.cpp163
-rw-r--r--src/gui/text/qfontsubset.cpp18
-rw-r--r--src/gui/text/qharfbuzzng.cpp39
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp6
-rw-r--r--src/gui/text/qplatformfontdatabase.h2
-rw-r--r--src/gui/text/qrawfont.cpp21
-rw-r--r--src/gui/text/qtextcursor.cpp1
-rw-r--r--src/gui/text/qtextdocument.cpp94
-rw-r--r--src/gui/text/qtextdocument.h8
-rw-r--r--src/gui/text/qtextdocument_p.h1
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp2
-rw-r--r--src/gui/text/qtextengine.cpp208
-rw-r--r--src/gui/text/qtextengine_p.h46
-rw-r--r--src/gui/text/qtextformat.cpp127
-rw-r--r--src/gui/text/qtextformat.h11
-rw-r--r--src/gui/text/qtextformat_p.h6
-rw-r--r--src/gui/text/qtexthtmlparser.cpp28
-rw-r--r--src/gui/text/qtextlayout.cpp29
-rw-r--r--src/gui/text/qtextobject.cpp50
-rw-r--r--src/gui/text/qtextobject.h4
-rw-r--r--src/gui/util/qabstractlayoutstyleinfo.cpp53
-rw-r--r--src/gui/util/qabstractlayoutstyleinfo_p.h97
-rw-r--r--src/gui/util/qgridlayoutengine.cpp1635
-rw-r--r--src/gui/util/qgridlayoutengine_p.h473
-rw-r--r--src/gui/util/qlayoutpolicy.cpp136
-rw-r--r--src/gui/util/qlayoutpolicy_p.h185
-rw-r--r--src/gui/util/qvalidator.cpp22
-rw-r--r--src/gui/util/util.pri10
149 files changed, 14872 insertions, 4693 deletions
diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp
index a9a880e71f..fe66c6e19d 100644
--- a/src/gui/accessible/qaccessiblecache.cpp
+++ b/src/gui/accessible/qaccessiblecache.cpp
@@ -90,7 +90,7 @@ QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface *
Q_ASSERT(object == obj);
if (obj) {
objectToId.insert(obj, id);
- connect(obj, SIGNAL(destroyed(QObject *)), this, SLOT(objectDestroyed(QObject *)));
+ connect(obj, &QObject::destroyed, this, &QAccessibleCache::objectDestroyed);
}
idToInterface.insert(id, iface);
return id;
diff --git a/src/gui/doc/snippets/image/supportedformat.cpp b/src/gui/doc/snippets/image/supportedformat.cpp
index f4d2606728..0b52156b80 100644
--- a/src/gui/doc/snippets/image/supportedformat.cpp
+++ b/src/gui/doc/snippets/image/supportedformat.cpp
@@ -43,10 +43,10 @@
int main(int argv, char **args)
{
//! [0]
- QImageWriter writer;
- writer.setFormat("png");
- if (writer.supportsOption(QImageIOHandler::Description))
- qDebug() << "Png supports embedded text";
+ QImageWriter writer;
+ writer.setFormat("png");
+ if (writer.supportsOption(QImageIOHandler::Description))
+ qDebug() << "Png supports embedded text";
//! [0]
return 0;
}
diff --git a/src/gui/doc/src/coordsys.qdoc b/src/gui/doc/src/coordsys.qdoc
index e66afcfe55..d9c7c7e3c1 100644
--- a/src/gui/doc/src/coordsys.qdoc
+++ b/src/gui/doc/src/coordsys.qdoc
@@ -29,7 +29,7 @@
\page coordsys.html
\title Coordinate System
\ingroup qt-graphics
- \ingroup best-practices
+ \ingroup best-practices
\brief Information about the coordinate system used by the paint
system.
diff --git a/src/gui/doc/src/paintsystem.qdoc b/src/gui/doc/src/paintsystem.qdoc
index cd208e9e18..1006d2ef65 100644
--- a/src/gui/doc/src/paintsystem.qdoc
+++ b/src/gui/doc/src/paintsystem.qdoc
@@ -93,8 +93,8 @@
\page paintsystem-devices.html
\title Paint Devices and Backends
- \contentspage The Paint System
- \nextpage Drawing and Filling
+ \contentspage The Paint System
+ \nextpage Drawing and Filling
\section1 Creating a Paint Device
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index f4c35a36c5..9bd33d1f57 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -13,11 +13,13 @@ MODULE_PLUGIN_TYPES = \
imageformats
# This is here only because the platform plugin is no module, obviously.
-win32:contains(QT_CONFIG, angle) {
+win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
MODULE_AUX_INCLUDES = \
\$\$QT_MODULE_INCLUDE_BASE/QtANGLE
}
+contains(QT_CONFIG, dynamicgl): DEFINES += QT_OPENGL_DYNAMIC_IN_GUI
+
load(qt_module)
# Code coverage with TestCocoon
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index bf4b5ddf01..bbdd0f3da7 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -32,6 +32,7 @@ HEADERS += \
SOURCES += \
image/qbitmap.cpp \
image/qimage.cpp \
+ image/qimage_conversions.cpp \
image/qimageiohandler.cpp \
image/qimagereader.cpp \
image/qimagewriter.cpp \
@@ -54,6 +55,9 @@ SOURCES += \
win32:!winrt: SOURCES += image/qpixmap_win.cpp
+NO_PCH_SOURCES += image/qimage_compat.cpp
+false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator
+
# Built-in image format support
HEADERS += \
image/qbmphandler_p.h \
@@ -74,9 +78,12 @@ contains(QT_CONFIG, jpeg):include($$PWD/qjpeghandler.pri)
contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri)
# SIMD
-NEON_SOURCES += image/qimage_neon.cpp
-SSE2_SOURCES += image/qimage_sse2.cpp
-SSSE3_SOURCES += image/qimage_ssse3.cpp
-AVX_SOURCES += image/qimage_avx.cpp
+contains(QT_CPU_FEATURES.$$QT_ARCH, neon) {
+ SOURCES += image/qimage_neon.cpp
+}
+contains(QT_CPU_FEATURES.$$QT_ARCH, sse2) {
+ SOURCES += image/qimage_sse2.cpp
+ SSSE3_SOURCES += image/qimage_ssse3.cpp
+}
MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index c03d9b8e5d..bb79a139b3 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -210,54 +210,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
uint red_mask = 0;
uint green_mask = 0;
uint blue_mask = 0;
+ uint alpha_mask = 0;
int red_shift = 0;
int green_shift = 0;
int blue_shift = 0;
+ int alpha_shift = 0;
int red_scale = 0;
int green_scale = 0;
int blue_scale = 0;
-
- int ncols = 0;
- int depth = 0;
- QImage::Format format;
- switch (nbits) {
- case 32:
- case 24:
- case 16:
- depth = 32;
- format = QImage::Format_RGB32;
- break;
- case 8:
- case 4:
- depth = 8;
- format = QImage::Format_Indexed8;
- break;
- default:
- depth = 1;
- format = QImage::Format_Mono;
- }
-
- if (bi.biHeight < 0)
- h = -h; // support images with negative height
-
- if (image.size() != QSize(w, h) || image.format() != format) {
- image = QImage(w, h, format);
- if (image.isNull()) // could not create image
- return false;
- }
-
- if (depth != 32) {
- ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
- if (ncols > 256) // sanity check - don't run out of mem if color table is broken
- return false;
- image.setColorCount(ncols);
- }
-
- image.setDotsPerMeterX(bi.biXPelsPerMeter);
- image.setDotsPerMeterY(bi.biYPelsPerMeter);
-
- if (!d->isSequential())
- d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
+ int alpha_scale = 0;
if (bi.biSize >= BMP_WIN4 || (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32))) {
if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))
@@ -269,7 +230,6 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
// Read BMP v4+ header
if (bi.biSize >= BMP_WIN4) {
- int alpha_mask = 0;
int CSType = 0;
int gamma_red = 0;
int gamma_green = 0;
@@ -307,6 +267,49 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
}
}
+ bool transp = (comp == BMP_BITFIELDS) && alpha_mask;
+ int ncols = 0;
+ int depth = 0;
+ QImage::Format format;
+ switch (nbits) {
+ case 32:
+ case 24:
+ case 16:
+ depth = 32;
+ format = transp ? QImage::Format_ARGB32 : QImage::Format_RGB32;
+ break;
+ case 8:
+ case 4:
+ depth = 8;
+ format = QImage::Format_Indexed8;
+ break;
+ default:
+ depth = 1;
+ format = QImage::Format_Mono;
+ }
+
+ if (bi.biHeight < 0)
+ h = -h; // support images with negative height
+
+ if (image.size() != QSize(w, h) || image.format() != format) {
+ image = QImage(w, h, format);
+ if (image.isNull()) // could not create image
+ return false;
+ }
+
+ if (depth != 32) {
+ ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
+ if (ncols > 256) // sanity check - don't run out of mem if color table is broken
+ return false;
+ image.setColorCount(ncols);
+ }
+
+ image.setDotsPerMeterX(bi.biXPelsPerMeter);
+ image.setDotsPerMeterY(bi.biYPelsPerMeter);
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
+
if (ncols > 0) { // read color table
uchar rgb[4];
int rgb_len = t == BMP_OLD ? 3 : 4;
@@ -324,6 +327,8 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
green_scale = 256 / ((green_mask >> green_shift) + 1);
blue_shift = calc_shift(blue_mask);
blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
+ alpha_shift = calc_shift(alpha_mask);
+ alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
} else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
blue_mask = 0x000000ff;
green_mask = 0x0000ff00;
@@ -344,6 +349,13 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
blue_scale = 8;
}
+#if 0
+ qDebug("Rmask: %08x Rshift: %08x Rscale:%08x", red_mask, red_shift, red_scale);
+ qDebug("Gmask: %08x Gshift: %08x Gscale:%08x", green_mask, green_shift, green_scale);
+ qDebug("Bmask: %08x Bshift: %08x Bscale:%08x", blue_mask, blue_shift, blue_scale);
+ qDebug("Amask: %08x Ashift: %08x Ascale:%08x", alpha_mask, alpha_shift, alpha_scale);
+#endif
+
// offset can be bogus, be careful
if (offset>=0 && startpos + offset > d->pos()) {
if (!d->isSequential())
@@ -535,11 +547,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
b = buf24;
while (p < end) {
c = *(uchar*)b | (*(uchar*)(b+1)<<8);
- if (nbits != 16)
+ if (nbits > 16)
c |= *(uchar*)(b+2)<<16;
- *p++ = qRgb(((c & red_mask) >> red_shift) * red_scale,
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+ *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
((c & green_mask) >> green_shift) * green_scale,
- ((c & blue_mask) >> blue_shift) * blue_scale);
+ ((c & blue_mask) >> blue_shift) * blue_scale,
+ transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
b += nbits/8;
}
}
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 0b2211defc..48c262ae7a 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -715,42 +715,6 @@ bool QImageData::checkForAlphaPixels() const
QImage member functions
*****************************************************************************/
-// table to flip bits
-static const uchar bitflip[256] = {
- /*
- open OUT, "| fmt";
- for $i (0..255) {
- print OUT (($i >> 7) & 0x01) | (($i >> 5) & 0x02) |
- (($i >> 3) & 0x04) | (($i >> 1) & 0x08) |
- (($i << 7) & 0x80) | (($i << 5) & 0x40) |
- (($i << 3) & 0x20) | (($i << 1) & 0x10), ", ";
- }
- close OUT;
- */
- 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
- 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
- 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
- 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
- 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
- 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
- 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
- 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
- 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
- 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
- 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
- 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
- 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
- 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
- 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
- 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
-};
-
-const uchar *qt_get_bitflip_array() // called from QPixmap code
-{
- return bitflip;
-}
-
-
/*!
Constructs a null image.
@@ -1105,8 +1069,7 @@ void QImage::detach()
if (d->ref.load() != 1 || d->ro_data)
*this = copy();
- if (d)
- ++d->detach_no;
+ ++d->detach_no;
}
}
@@ -1756,7 +1719,7 @@ void QImage::fill(const QColor &color)
if (d->depth == 32) {
uint pixel = color.rgba();
if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied)
- pixel = PREMUL(pixel);
+ pixel = qPremultiply(pixel);
fill((uint) pixel);
} else if (d->format == QImage::Format_RGB16) {
@@ -1898,2101 +1861,9 @@ QImage::Format QImage::format() const
return d ? d->format : Format_Invalid;
}
-
-
-/*****************************************************************************
- Internal routines for converting image depth.
- *****************************************************************************/
-
-typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
-
-typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags);
-
-static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = PREMUL(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_ARGB32);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- QRgb *rgb_data = (QRgb *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const QRgb *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = PREMUL(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
- data->format = QImage::Format_ARGB32_Premultiplied;
- return true;
-}
-
-static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32);
- Q_ASSERT(dest->format == QImage::Format_RGBX8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(0xff000000 | *src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- quint32 *rgb_data = (quint32 *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const quint32 *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = ARGB2RGBA(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
- if (data->format == QImage::Format_ARGB32)
- data->format = QImage::Format_RGBA8888;
- else
- data->format = QImage::Format_RGBA8888_Premultiplied;
- return true;
-}
-
-static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32);
- Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(PREMUL(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = RGBA2ARGB(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888 || data->format == QImage::Format_RGBA8888_Premultiplied);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- QRgb *rgb_data = (QRgb *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const QRgb *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = RGBA2ARGB(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
- if (data->format == QImage::Format_RGBA8888_Premultiplied)
- data->format = QImage::Format_ARGB32_Premultiplied;
- else if (data->format == QImage::Format_RGBX8888)
- data->format = QImage::Format_RGB32;
- else
- data->format = QImage::Format_ARGB32;
- return true;
-}
-
-static void convert_RGBA_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = PREMUL(RGBA2ARGB(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGBA8888);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- QRgb *rgb_data = (QRgb *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const QRgb *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = PREMUL(RGBA2ARGB(*rgb_data));
- ++rgb_data;
- }
- rgb_data += pad;
- }
- data->format = QImage::Format_ARGB32_Premultiplied;
- return true;
-}
-
-static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_Indexed8);
- const int depth = 32;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, nbytes);
- if (!newData)
- return false;
-
- data->data = newData;
-
- // start converting from the end because the end image is bigger than the source
- uchar *src_data = newData + data->nbytes; // end of src
- quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src
- const int width = data->width;
- const int src_pad = data->bytes_per_line - width;
- const int dest_pad = (dst_bytes_per_line >> 2) - width;
- if (data->colortable.size() == 0) {
- data->colortable.resize(256);
- for (int i = 0; i < 256; ++i)
- data->colortable[i] = qRgb(i, i, i);
- } else {
- for (int i = 0; i < data->colortable.size(); ++i)
- data->colortable[i] = PREMUL(data->colortable.at(i));
-
- // Fill the rest of the table in case src_data > colortable.size()
- const int oldSize = data->colortable.size();
- const QRgb lastColor = data->colortable.at(oldSize - 1);
- data->colortable.insert(oldSize, 256 - oldSize, lastColor);
- }
-
- for (int i = 0; i < data->height; ++i) {
- src_data -= src_pad;
- dest_data -= dest_pad;
- for (int pixI = 0; pixI < width; ++pixI) {
- --src_data;
- --dest_data;
- *dest_data = data->colortable.at(*src_data);
- }
- }
-
- data->colortable = QVector<QRgb>();
- data->format = QImage::Format_ARGB32_Premultiplied;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = nbytes;
-
- return true;
-}
-
-static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_Indexed8);
- const int depth = 32;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, nbytes);
- if (!newData)
- return false;
-
- data->data = newData;
-
- // start converting from the end because the end image is bigger than the source
- uchar *src_data = newData + data->nbytes;
- quint32 *dest_data = (quint32 *) (newData + nbytes);
- const int width = data->width;
- const int src_pad = data->bytes_per_line - width;
- const int dest_pad = (dst_bytes_per_line >> 2) - width;
- if (data->colortable.size() == 0) {
- data->colortable.resize(256);
- for (int i = 0; i < 256; ++i)
- data->colortable[i] = qRgb(i, i, i);
- } else {
- // Fill the rest of the table in case src_data > colortable.size()
- const int oldSize = data->colortable.size();
- const QRgb lastColor = data->colortable.at(oldSize - 1);
- data->colortable.insert(oldSize, 256 - oldSize, lastColor);
- }
-
- for (int i = 0; i < data->height; ++i) {
- src_data -= src_pad;
- dest_data -= dest_pad;
- for (int pixI = 0; pixI < width; ++pixI) {
- --src_data;
- --dest_data;
- *dest_data = (quint32) data->colortable.at(*src_data);
- }
- }
-
- data->colortable = QVector<QRgb>();
- data->format = QImage::Format_RGB32;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = nbytes;
-
- return true;
-}
-
-static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_Indexed8);
- const int depth = 16;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, nbytes);
- if (!newData)
- return false;
-
- data->data = newData;
-
- // start converting from the end because the end image is bigger than the source
- uchar *src_data = newData + data->nbytes;
- quint16 *dest_data = (quint16 *) (newData + nbytes);
- const int width = data->width;
- const int src_pad = data->bytes_per_line - width;
- const int dest_pad = (dst_bytes_per_line >> 1) - width;
-
- quint16 colorTableRGB16[256];
- if (data->colortable.isEmpty()) {
- for (int i = 0; i < 256; ++i)
- colorTableRGB16[i] = qConvertRgb32To16(qRgb(i, i, i));
- } else {
- // 1) convert the existing colors to RGB16
- const int tableSize = data->colortable.size();
- for (int i = 0; i < tableSize; ++i)
- colorTableRGB16[i] = qConvertRgb32To16(data->colortable.at(i));
- data->colortable = QVector<QRgb>();
-
- // 2) fill the rest of the table in case src_data > colortable.size()
- const quint16 lastColor = colorTableRGB16[tableSize - 1];
- for (int i = tableSize; i < 256; ++i)
- colorTableRGB16[i] = lastColor;
- }
-
- for (int i = 0; i < data->height; ++i) {
- src_data -= src_pad;
- dest_data -= dest_pad;
- for (int pixI = 0; pixI < width; ++pixI) {
- --src_data;
- --dest_data;
- *dest_data = colorTableRGB16[*src_data];
- }
- }
-
- data->format = QImage::Format_RGB16;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = nbytes;
-
- return true;
-}
-
-static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB32);
- const int depth = 16;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int src_bytes_per_line = data->bytes_per_line;
- quint32 *src_data = (quint32 *) data->data;
- quint16 *dst_data = (quint16 *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- for (int j = 0; j < data->width; ++j)
- dst_data[j] = qConvertRgb32To16(src_data[j]);
- src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line);
- dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line);
- }
- data->format = QImage::Format_RGB16;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, data->nbytes);
- if (newData) {
- data->data = newData;
- return true;
- } else {
- return false;
- }
-}
-
-static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_RGBA8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = INV_PREMUL(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_RGBX8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = 0xff000000 | INV_PREMUL(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_PM_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGBX8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(0xff000000 | INV_PREMUL(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_PM_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGBA8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(INV_PREMUL(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBX8888);
- Q_ASSERT(dest->format == QImage::Format_RGB32);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = RGBA2ARGB(*src_data) | 0xff000000;
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB32);
- Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(*src_data | 0xff000000);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = INV_PREMUL(RGBA2ARGB(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB32);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = 0xff000000 | INV_PREMUL(RGBA2ARGB(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void swap_bit_order(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
- Q_ASSERT(dest->format == QImage::Format_Mono || dest->format == QImage::Format_MonoLSB);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
- Q_ASSERT(src->nbytes == dest->nbytes);
- Q_ASSERT(src->bytes_per_line == dest->bytes_per_line);
-
- dest->colortable = src->colortable;
-
- const uchar *src_data = src->data;
- const uchar *end = src->data + src->nbytes;
- uchar *dest_data = dest->data;
- while (src_data < end) {
- *dest_data = bitflip[*src_data];
- ++src_data;
- ++dest_data;
- }
-}
-
-static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = *src_data | 0xff000000;
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
-{
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- return mask_alpha_converter(dest, src, flags);
-#else
- Q_UNUSED(flags);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = *src_data | 0x000000ff;
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-#endif
-}
-
-static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
-{
- QVector<QRgb> colorTable = ctbl;
- if (format == QImage::Format_RGB32) {
- // check if the color table has alpha
- for (int i = 0; i < colorTable.size(); ++i)
- if (qAlpha(colorTable.at(i) != 0xff))
- colorTable[i] = colorTable.at(i) | 0xff000000;
- } else if (format == QImage::Format_ARGB32_Premultiplied) {
- // check if the color table has alpha
- for (int i = 0; i < colorTable.size(); ++i)
- colorTable[i] = PREMUL(colorTable.at(i));
- }
- return colorTable;
-}
-
-//
-// dither_to_1: Uses selected dithering algorithm.
-//
-
-static void dither_to_Mono(QImageData *dst, const QImageData *src,
- Qt::ImageConversionFlags flags, bool fromalpha)
-{
- Q_ASSERT(src->width == dst->width);
- Q_ASSERT(src->height == dst->height);
- Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
-
- dst->colortable.clear();
- dst->colortable.append(0xffffffff);
- dst->colortable.append(0xff000000);
-
- enum { Threshold, Ordered, Diffuse } dithermode;
-
- if (fromalpha) {
- if ((flags & Qt::AlphaDither_Mask) == Qt::DiffuseAlphaDither)
- dithermode = Diffuse;
- else if ((flags & Qt::AlphaDither_Mask) == Qt::OrderedAlphaDither)
- dithermode = Ordered;
- else
- dithermode = Threshold;
- } else {
- if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither)
- dithermode = Threshold;
- else if ((flags & Qt::Dither_Mask) == Qt::OrderedDither)
- dithermode = Ordered;
- else
- dithermode = Diffuse;
- }
-
- int w = src->width;
- int h = src->height;
- int d = src->depth;
- uchar gray[256]; // gray map for 8 bit images
- bool use_gray = (d == 8);
- if (use_gray) { // make gray map
- if (fromalpha) {
- // Alpha 0x00 -> 0 pixels (white)
- // Alpha 0xFF -> 1 pixels (black)
- for (int i = 0; i < src->colortable.size(); i++)
- gray[i] = (255 - (src->colortable.at(i) >> 24));
- } else {
- // Pixel 0x00 -> 1 pixels (black)
- // Pixel 0xFF -> 0 pixels (white)
- for (int i = 0; i < src->colortable.size(); i++)
- gray[i] = qGray(src->colortable.at(i));
- }
- }
-
- uchar *dst_data = dst->data;
- int dst_bpl = dst->bytes_per_line;
- const uchar *src_data = src->data;
- int src_bpl = src->bytes_per_line;
-
- switch (dithermode) {
- case Diffuse: {
- QScopedArrayPointer<int> lineBuffer(new int[w * 2]);
- int *line1 = lineBuffer.data();
- int *line2 = lineBuffer.data() + w;
- int bmwidth = (w+7)/8;
-
- int *b1, *b2;
- int wbytes = w * (d/8);
- const uchar *p = src->data;
- const uchar *end = p + wbytes;
- b2 = line2;
- if (use_gray) { // 8 bit image
- while (p < end)
- *b2++ = gray[*p++];
- } else { // 32 bit image
- if (fromalpha) {
- while (p < end) {
- *b2++ = 255 - (*(uint*)p >> 24);
- p += 4;
- }
- } else {
- while (p < end) {
- *b2++ = qGray(*(uint*)p);
- p += 4;
- }
- }
- }
- for (int y=0; y<h; y++) { // for each scan line...
- int *tmp = line1; line1 = line2; line2 = tmp;
- bool not_last_line = y < h - 1;
- if (not_last_line) { // calc. grayvals for next line
- p = src->data + (y+1)*src->bytes_per_line;
- end = p + wbytes;
- b2 = line2;
- if (use_gray) { // 8 bit image
- while (p < end)
- *b2++ = gray[*p++];
- } else { // 24 bit image
- if (fromalpha) {
- while (p < end) {
- *b2++ = 255 - (*(uint*)p >> 24);
- p += 4;
- }
- } else {
- while (p < end) {
- *b2++ = qGray(*(uint*)p);
- p += 4;
- }
- }
- }
- }
-
- int err;
- uchar *p = dst->data + y*dst->bytes_per_line;
- memset(p, 0, bmwidth);
- b1 = line1;
- b2 = line2;
- int bit = 7;
- for (int x=1; x<=w; x++) {
- if (*b1 < 128) { // black pixel
- err = *b1++;
- *p |= 1 << bit;
- } else { // white pixel
- err = *b1++ - 255;
- }
- if (bit == 0) {
- p++;
- bit = 7;
- } else {
- bit--;
- }
- if (x < w)
- *b1 += (err*7)>>4; // spread error to right pixel
- if (not_last_line) {
- b2[0] += (err*5)>>4; // pixel below
- if (x > 1)
- b2[-1] += (err*3)>>4; // pixel below left
- if (x < w)
- b2[1] += err>>4; // pixel below right
- }
- b2++;
- }
- }
- } break;
- case Ordered: {
-
- memset(dst->data, 0, dst->nbytes);
- if (d == 32) {
- for (int i=0; i<h; i++) {
- const uint *p = (const uint *)src_data;
- const uint *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- int j = 0;
- if (fromalpha) {
- while (p < end) {
- if ((*p++ >> 24) >= qt_bayer_matrix[j++&15][i&15])
- *m |= 1 << bit;
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- } else {
- while (p < end) {
- if ((uint)qGray(*p++) < qt_bayer_matrix[j++&15][i&15])
- *m |= 1 << bit;
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- } else
- /* (d == 8) */ {
- for (int i=0; i<h; i++) {
- const uchar *p = src_data;
- const uchar *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- int j = 0;
- while (p < end) {
- if ((uint)gray[*p++] < qt_bayer_matrix[j++&15][i&15])
- *m |= 1 << bit;
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- }
- } break;
- default: { // Threshold:
- memset(dst->data, 0, dst->nbytes);
- if (d == 32) {
- for (int i=0; i<h; i++) {
- const uint *p = (const uint *)src_data;
- const uint *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- if (fromalpha) {
- while (p < end) {
- if ((*p++ >> 24) >= 128)
- *m |= 1 << bit; // Set mask "on"
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- } else {
- while (p < end) {
- if (qGray(*p++) < 128)
- *m |= 1 << bit; // Set pixel "black"
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- } else
- if (d == 8) {
- for (int i=0; i<h; i++) {
- const uchar *p = src_data;
- const uchar *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- while (p < end) {
- if (gray[*p++] < 128)
- *m |= 1 << bit; // Set mask "on"/ pixel "black"
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- }
- }
- }
-
- if (dst->format == QImage::Format_MonoLSB) {
- // need to swap bit order
- uchar *sl = dst->data;
- int bpl = (dst->width + 7) * dst->depth / 8;
- int pad = dst->bytes_per_line - bpl;
- for (int y=0; y<dst->height; ++y) {
- for (int x=0; x<bpl; ++x) {
- *sl = bitflip[*sl];
- ++sl;
- }
- sl += pad;
- }
- }
-}
-
-static void convert_X_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- dither_to_Mono(dst, src, flags, false);
-}
-
-static void convert_ARGB_PM_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
- convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
- dither_to_Mono(dst, tmp.data(), flags, false);
-}
-
-//
-// convert_32_to_8: Converts a 32 bits depth (true color) to an 8 bit
-// image with a colormap. If the 32 bit image has more than 256 colors,
-// we convert the red,green and blue bytes into a single byte encoded
-// as 6 shades of each of red, green and blue.
-//
-// if dithering is needed, only 1 color at most is available for alpha.
-//
-struct QRgbMap {
- inline QRgbMap() : used(0) { }
- uchar pix;
- uchar used;
- QRgb rgb;
-};
-
-static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32);
- Q_ASSERT(dst->format == QImage::Format_Indexed8);
- Q_ASSERT(src->width == dst->width);
- Q_ASSERT(src->height == dst->height);
-
- bool do_quant = (flags & Qt::DitherMode_Mask) == Qt::PreferDither
- || src->format == QImage::Format_ARGB32;
- uint alpha_mask = src->format == QImage::Format_RGB32 ? 0xff000000 : 0;
-
- const int tablesize = 997; // prime
- QRgbMap table[tablesize];
- int pix=0;
-
- if (!dst->colortable.isEmpty()) {
- QVector<QRgb> ctbl = dst->colortable;
- dst->colortable.resize(256);
- // Preload palette into table.
- // Almost same code as pixel insertion below
- for (int i = 0; i < dst->colortable.size(); ++i) {
- // Find in table...
- QRgb p = ctbl.at(i) | alpha_mask;
- int hash = p % tablesize;
- for (;;) {
- if (table[hash].used) {
- if (table[hash].rgb == p) {
- // Found previous insertion - use it
- break;
- } else {
- // Keep searching...
- if (++hash == tablesize) hash = 0;
- }
- } else {
- // Cannot be in table
- Q_ASSERT (pix != 256); // too many colors
- // Insert into table at this unused position
- dst->colortable[pix] = p;
- table[hash].pix = pix++;
- table[hash].rgb = p;
- table[hash].used = 1;
- break;
- }
- }
- }
- }
-
- if ((flags & Qt::DitherMode_Mask) != Qt::PreferDither) {
- dst->colortable.resize(256);
- const uchar *src_data = src->data;
- uchar *dest_data = dst->data;
- for (int y = 0; y < src->height; y++) { // check if <= 256 colors
- const QRgb *s = (const QRgb *)src_data;
- uchar *b = dest_data;
- for (int x = 0; x < src->width; ++x) {
- QRgb p = s[x] | alpha_mask;
- int hash = p % tablesize;
- for (;;) {
- if (table[hash].used) {
- if (table[hash].rgb == (p)) {
- // Found previous insertion - use it
- break;
- } else {
- // Keep searching...
- if (++hash == tablesize) hash = 0;
- }
- } else {
- // Cannot be in table
- if (pix == 256) { // too many colors
- do_quant = true;
- // Break right out
- x = src->width;
- y = src->height;
- } else {
- // Insert into table at this unused position
- dst->colortable[pix] = p;
- table[hash].pix = pix++;
- table[hash].rgb = p;
- table[hash].used = 1;
- }
- break;
- }
- }
- *b++ = table[hash].pix; // May occur once incorrectly
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- }
- int numColors = do_quant ? 256 : pix;
-
- dst->colortable.resize(numColors);
-
- if (do_quant) { // quantization needed
-
-#define MAX_R 5
-#define MAX_G 5
-#define MAX_B 5
-#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
-
- for (int rc=0; rc<=MAX_R; rc++) // build 6x6x6 color cube
- for (int gc=0; gc<=MAX_G; gc++)
- for (int bc=0; bc<=MAX_B; bc++)
- dst->colortable[INDEXOF(rc,gc,bc)] = 0xff000000 | qRgb(rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B);
-
- const uchar *src_data = src->data;
- uchar *dest_data = dst->data;
- if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither) {
- for (int y = 0; y < src->height; y++) {
- const QRgb *p = (const QRgb *)src_data;
- const QRgb *end = p + src->width;
- uchar *b = dest_data;
-
- while (p < end) {
-#define DITHER(p,m) ((uchar) ((p * (m) + 127) / 255))
- *b++ =
- INDEXOF(
- DITHER(qRed(*p), MAX_R),
- DITHER(qGreen(*p), MAX_G),
- DITHER(qBlue(*p), MAX_B)
- );
-#undef DITHER
- p++;
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- } else if ((flags & Qt::Dither_Mask) == Qt::DiffuseDither) {
- int* line1[3];
- int* line2[3];
- int* pv[3];
- QScopedArrayPointer<int> lineBuffer(new int[src->width * 9]);
- line1[0] = lineBuffer.data();
- line2[0] = lineBuffer.data() + src->width;
- line1[1] = lineBuffer.data() + src->width * 2;
- line2[1] = lineBuffer.data() + src->width * 3;
- line1[2] = lineBuffer.data() + src->width * 4;
- line2[2] = lineBuffer.data() + src->width * 5;
- pv[0] = lineBuffer.data() + src->width * 6;
- pv[1] = lineBuffer.data() + src->width * 7;
- pv[2] = lineBuffer.data() + src->width * 8;
-
- int endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian);
- for (int y = 0; y < src->height; y++) {
- const uchar* q = src_data;
- const uchar* q2 = y < src->height - 1 ? q + src->bytes_per_line : src->data;
- uchar *b = dest_data;
- for (int chan = 0; chan < 3; chan++) {
- int *l1 = (y&1) ? line2[chan] : line1[chan];
- int *l2 = (y&1) ? line1[chan] : line2[chan];
- if (y == 0) {
- for (int i = 0; i < src->width; i++)
- l1[i] = q[i*4+chan+endian];
- }
- if (y+1 < src->height) {
- for (int i = 0; i < src->width; i++)
- l2[i] = q2[i*4+chan+endian];
- }
- // Bi-directional error diffusion
- if (y&1) {
- for (int x = 0; x < src->width; x++) {
- int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
- int err = l1[x] - pix * 255 / 5;
- pv[chan][x] = pix;
-
- // Spread the error around...
- if (x + 1< src->width) {
- l1[x+1] += (err*7)>>4;
- l2[x+1] += err>>4;
- }
- l2[x]+=(err*5)>>4;
- if (x>1)
- l2[x-1]+=(err*3)>>4;
- }
- } else {
- for (int x = src->width; x-- > 0;) {
- int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
- int err = l1[x] - pix * 255 / 5;
- pv[chan][x] = pix;
-
- // Spread the error around...
- if (x > 0) {
- l1[x-1] += (err*7)>>4;
- l2[x-1] += err>>4;
- }
- l2[x]+=(err*5)>>4;
- if (x + 1 < src->width)
- l2[x+1]+=(err*3)>>4;
- }
- }
- }
- if (endian) {
- for (int x = 0; x < src->width; x++) {
- *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
- }
- } else {
- for (int x = 0; x < src->width; x++) {
- *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
- }
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- } else { // OrderedDither
- for (int y = 0; y < src->height; y++) {
- const QRgb *p = (const QRgb *)src_data;
- const QRgb *end = p + src->width;
- uchar *b = dest_data;
-
- int x = 0;
- while (p < end) {
- uint d = qt_bayer_matrix[y & 15][x & 15] << 8;
-
-#define DITHER(p, d, m) ((uchar) ((((256 * (m) + (m) + 1)) * (p) + (d)) >> 16))
- *b++ =
- INDEXOF(
- DITHER(qRed(*p), d, MAX_R),
- DITHER(qGreen(*p), d, MAX_G),
- DITHER(qBlue(*p), d, MAX_B)
- );
-#undef DITHER
-
- p++;
- x++;
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- }
-
- if (src->format != QImage::Format_RGB32
- && src->format != QImage::Format_RGB16) {
- const int trans = 216;
- Q_ASSERT(dst->colortable.size() > trans);
- dst->colortable[trans] = 0;
- QScopedPointer<QImageData> mask(QImageData::create(QSize(src->width, src->height), QImage::Format_Mono));
- dither_to_Mono(mask.data(), src, flags, true);
- uchar *dst_data = dst->data;
- const uchar *mask_data = mask->data;
- for (int y = 0; y < src->height; y++) {
- for (int x = 0; x < src->width ; x++) {
- if (!(mask_data[x>>3] & (0x80 >> (x & 7))))
- dst_data[x] = trans;
- }
- mask_data += mask->bytes_per_line;
- dst_data += dst->bytes_per_line;
- }
- dst->has_alpha_clut = true;
- }
-
-#undef MAX_R
-#undef MAX_G
-#undef MAX_B
-#undef INDEXOF
-
- }
-}
-
-static void convert_ARGB_PM_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
- convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
- convert_RGB_to_Indexed8(dst, tmp.data(), flags);
-}
-
-static void convert_ARGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- convert_RGB_to_Indexed8(dst, src, flags);
-}
-
-static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Indexed8);
- Q_ASSERT(dest->format == QImage::Format_RGB32
- || dest->format == QImage::Format_ARGB32
- || dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
- if (colorTable.size() == 0) {
- colorTable.resize(256);
- for (int i=0; i<256; ++i)
- colorTable[i] = qRgb(i, i, i);
- }
-
- int w = src->width;
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
- int tableSize = colorTable.size() - 1;
- for (int y = 0; y < src->height; y++) {
- uint *p = (uint *)dest_data;
- const uchar *b = src_data;
- uint *end = p + w;
-
- while (p < end)
- *p++ = colorTable.at(qMin<int>(tableSize, *b++));
-
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
-}
-
-static void convert_Mono_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
- Q_ASSERT(dest->format == QImage::Format_RGB32
- || dest->format == QImage::Format_ARGB32
- || dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
-
- // Default to black / white colors
- if (colorTable.size() < 2) {
- if (colorTable.size() == 0)
- colorTable << 0xff000000;
- colorTable << 0xffffffff;
- }
-
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
- if (src->format == QImage::Format_Mono) {
- for (int y = 0; y < dest->height; y++) {
- uint *p = (uint *)dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = colorTable.at((src_data[x>>3] >> (7 - (x & 7))) & 1);
-
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- } else {
- for (int y = 0; y < dest->height; y++) {
- uint *p = (uint *)dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = colorTable.at((src_data[x>>3] >> (x & 7)) & 1);
-
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- }
-}
-
-
-static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
- Q_ASSERT(dest->format == QImage::Format_Indexed8);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- QVector<QRgb> ctbl = src->colortable;
- if (ctbl.size() > 2) {
- ctbl.resize(2);
- } else if (ctbl.size() < 2) {
- if (ctbl.size() == 0)
- ctbl << 0xff000000;
- ctbl << 0xffffffff;
- }
- dest->colortable = ctbl;
- dest->has_alpha_clut = src->has_alpha_clut;
-
-
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
- if (src->format == QImage::Format_Mono) {
- for (int y = 0; y < dest->height; y++) {
- uchar *p = dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = (src_data[x>>3] >> (7 - (x & 7))) & 1;
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- } else {
- for (int y = 0; y < dest->height; y++) {
- uchar *p = dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = (src_data[x>>3] >> (x & 7)) & 1;
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- }
-}
-
-// Cannot be used with indexed formats.
-static void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- const int buffer_size = 2048;
- uint buffer[buffer_size];
- const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
- const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
- const uchar *srcData = src->data;
- uchar *destData = dest->data;
-
- FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
- StorePixelsFunc store = qStorePixels[destLayout->bpp];
-
- for (int y = 0; y < src->height; ++y) {
- int x = 0;
- while (x < src->width) {
- int l = qMin(src->width - x, buffer_size);
- const uint *ptr = fetch(buffer, srcData, x, l);
- ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
- ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
- store(destData, ptr, x, l);
- x += l;
- }
- srcData += src->bytes_per_line;
- destData += dest->bytes_per_line;
- }
-}
-
-
-// first index source, second dest
-static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] =
-{
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0,
- 0,
- swap_bit_order,
- convert_Mono_to_Indexed8,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_Mono
-
- {
- 0,
- swap_bit_order,
- 0,
- convert_Mono_to_Indexed8,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_MonoLSB
-
- {
- 0,
- convert_X_to_Mono,
- convert_X_to_Mono,
- 0,
- convert_Indexed8_to_X32,
- convert_Indexed8_to_X32,
- convert_Indexed8_to_X32,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_Indexed8
-
- {
- 0,
- convert_X_to_Mono,
- convert_X_to_Mono,
- convert_RGB_to_Indexed8,
- 0,
- mask_alpha_converter,
- mask_alpha_converter,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_RGB_to_RGBA,
- convert_RGB_to_RGBA,
- convert_RGB_to_RGBA
- }, // Format_RGB32
-
- {
- 0,
- convert_X_to_Mono,
- convert_X_to_Mono,
- convert_ARGB_to_Indexed8,
- mask_alpha_converter,
- 0,
- convert_ARGB_to_ARGB_PM,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_ARGB_to_RGBx,
- convert_ARGB_to_RGBA,
- convert_ARGB_to_RGBA_PM,
- }, // Format_ARGB32
-
- {
- 0,
- convert_ARGB_PM_to_Mono,
- convert_ARGB_PM_to_Mono,
- convert_ARGB_PM_to_Indexed8,
- convert_ARGB_PM_to_RGB,
- convert_ARGB_PM_to_ARGB,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_PM_to_RGBx,
- convert_ARGB_PM_to_RGBA,
- convert_ARGB_to_RGBA,
- }, // Format_ARGB32_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
-#if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16)
- convert_generic,
-#else
- 0,
-#endif
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB16
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB8565_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB666
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB6666_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
-#if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16)
- convert_generic,
-#else
- 0,
-#endif
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB555
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB8555_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB888
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB444
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB4444_Premultiplied
- {
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_RGB,
- convert_RGBA_to_ARGB,
- convert_RGBA_to_ARGB,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- mask_alpha_converter_RGBx,
- mask_alpha_converter_RGBx,
- }, // Format_RGBX8888
- {
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_RGB,
- convert_RGBA_to_ARGB,
- convert_RGBA_to_ARGB_PM,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- mask_alpha_converter_RGBx,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- 0,
- convert_ARGB_to_ARGB_PM,
-#else
- 0,
- 0
-#endif
- }, // Format_RGBA8888
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_PM_to_RGB,
- convert_RGBA_PM_to_ARGB,
- convert_RGBA_to_ARGB,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- convert_ARGB_PM_to_RGB,
- convert_ARGB_PM_to_ARGB,
- 0,
-#else
- 0,
- 0,
- 0
-#endif
- } // Format_RGBA8888_Premultiplied
-};
-
-static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
-{
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_Mono
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_MonoLSB
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_indexed8_to_RGB_inplace,
- convert_indexed8_to_ARGB_PM_inplace,
- convert_indexed8_to_RGB16_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_Indexed8
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGB_to_RGB16_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_RGB32
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_to_ARGB_PM_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_to_RGBA_inplace,
- 0,
- }, // Format_ARGB32
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_to_RGBA_inplace
- }, // Format_ARGB32_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB16
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB8565_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB666
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB6666_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB555
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB8555_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB888
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB444
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB4444_Premultiplied
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_ARGB_inplace,
- convert_RGBA_to_ARGB_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_RGBX8888
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_ARGB_inplace,
- convert_RGBA_to_ARGB_PM_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_RGBA8888
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_ARGB_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- } // Format_RGBA8888_Premultiplied
-};
-
-void qInitImageConversions()
-{
-#ifdef QT_COMPILER_SUPPORTS_AVX
- if (qCpuHasFeature(AVX)) {
- extern bool convert_ARGB_to_ARGB_PM_inplace_avx(QImageData *data, Qt::ImageConversionFlags);
- inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_avx;
-
- extern void convert_RGB888_to_RGB32_avx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_avx;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_avx;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_avx;
- return;
- }
-#endif
-
-#if defined(QT_COMPILER_SUPPORTS_SSE2) && !defined(__AVX__)
- if (qCpuHasFeature(SSE2)) {
- extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
- inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2;
-#ifdef QT_COMPILER_SUPPORTS_SSSE3
- if (qCpuHasFeature(SSSE3)) {
- extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
- }
-#endif
- return;
- }
-#endif // SSE2
-
-#ifdef QT_COMPILER_SUPPORTS_NEON
- if (qCpuHasFeature(NEON)) {
- extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon;
- return;
- }
-#endif
-
-#ifdef QT_COMPILER_SUPPORTS_MIPS_DSPR2
- extern bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConversionFlags);
- inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_mips_dspr2;
- return;
-#endif
-}
-
-extern const uchar *qt_pow_rgb_gamma();
-
-void qGamma_correct_back_to_linear_cs(QImage *image)
-{
- const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
- if (!tables)
- return;
- const uchar *gamma = tables->qt_pow_rgb_gamma;
- // gamma correct the pixels back to linear color space...
- int h = image->height();
- int w = image->width();
-
- for (int y=0; y<h; ++y) {
- uint *pixels = (uint *) image->scanLine(y);
- for (int x=0; x<w; ++x) {
- uint p = pixels[x];
- uint r = gamma[qRed(p)];
- uint g = gamma[qGreen(p)];
- uint b = gamma[qBlue(p)];
- pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
- }
- }
-}
-
/*!
+ \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const
+
Returns a copy of the image in the given \a format.
The specified image conversion \a flags control how the image data
@@ -4000,7 +1871,11 @@ void qGamma_correct_back_to_linear_cs(QImage *image)
\sa {Image Formats}
*/
-QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const
+
+/*!
+ \internal
+*/
+QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const
{
if (!d || d->format == format)
return *this;
@@ -4008,8 +1883,9 @@ QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) co
if (format == Format_Invalid || d->format == Format_Invalid)
return QImage();
- const Image_Converter *converterPtr = &converter_map[d->format][format];
- Image_Converter converter = *converterPtr;
+ Image_Converter converter = qimage_converter_map[d->format][format];
+ if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8)
+ converter = convert_generic;
if (converter) {
QImage image(d->width, d->height, format);
@@ -4025,14 +1901,20 @@ QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) co
return image;
}
+ // Convert indexed formats over ARGB32 to the final format.
Q_ASSERT(format != QImage::Format_ARGB32);
Q_ASSERT(d->format != QImage::Format_ARGB32);
- QImage image = convertToFormat(Format_ARGB32, flags);
- return image.convertToFormat(format, flags);
+ return convertToFormat(Format_ARGB32, flags).convertToFormat(format, flags);
}
-
+/*!
+ \internal
+*/
+bool QImage::convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags)
+{
+ return d && d->convertInPlace(format, flags);
+}
static inline int pixel_distance(QRgb p1, QRgb p2) {
int r1 = qRed(p1);
@@ -4131,7 +2013,7 @@ QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Q
return convertWithPalette(*this, format, colorTable);
}
- const Image_Converter *converterPtr = &converter_map[d->format][format];
+ const Image_Converter *converterPtr = &qimage_converter_map[d->format][format];
Image_Converter converter = *converterPtr;
if (!converter)
return QImage();
@@ -4240,6 +2122,7 @@ QRgb QImage::pixel(int x, int y) const
case Format_Indexed8:
return d->colortable.at((int)s[x]);
case Format_RGB32:
+ return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x];
case Format_ARGB32: // Keep old behaviour.
case Format_ARGB32_Premultiplied:
return reinterpret_cast<const QRgb *>(s)[x];
@@ -4321,17 +2204,17 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
case Format_RGB32:
//make sure alpha is 255, we depend on it in qdrawhelper for cases
// when image is set as a texture pattern on a qbrush
- ((uint *)s)[x] = uint(255 << 24) | index_or_rgb;
+ ((uint *)s)[x] = 0xff000000 | index_or_rgb;
return;
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
((uint *)s)[x] = index_or_rgb;
return;
case Format_RGB16:
- ((quint16 *)s)[x] = qConvertRgb32To16(INV_PREMUL(index_or_rgb));
+ ((quint16 *)s)[x] = qConvertRgb32To16(qUnpremultiply(index_or_rgb));
return;
case Format_RGBX8888:
- ((uint *)s)[x] = ARGB2RGBA(index_or_rgb | 0xff000000);
+ ((uint *)s)[x] = ARGB2RGBA(0xff000000 | index_or_rgb);
return;
case Format_RGBA8888:
case Format_RGBA8888_Premultiplied:
@@ -4810,6 +2693,7 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
*/
/*!
+ \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const
Returns a mirror of the image, mirrored in the horizontal and/or
the vertical direction depending on whether \a horizontal and \a
vertical are set to true or false.
@@ -4818,7 +2702,70 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
\sa {QImage#Image Transformations}{Image Transformations}
*/
-QImage QImage::mirrored(bool horizontal, bool vertical) const
+
+template<typename T>
+inline void mirrored_helper_loop(int w, int h, int dxi, int dxs, int dyi, int dy, const uchar* sdata, uchar* ddata, int sbpl, int dbpl)
+{
+ for (int sy = 0; sy < h; sy++, dy += dyi) {
+ const T* ssl = (T*)(sdata + sy*sbpl);
+ T* dsl = (T*)(ddata + dy*dbpl);
+ int dx = dxs;
+ for (int sx = 0; sx < w; sx++, dx += dxi)
+ dsl[dx] = ssl[sx];
+ }
+}
+
+template<typename T>
+inline void mirrored_helper_loop_inplace(int w, int h, int dxi, int dxs, int dyi, int dy, uchar* sdata, int sbpl)
+{
+ for (int sy = 0; sy < h; sy++, dy += dyi) {
+ T* ssl = (T*)(sdata + sy*sbpl);
+ T* dsl = (T*)(sdata + dy*sbpl);
+ int dx = dxs;
+ for (int sx = 0; sx < w; sx++, dx += dxi)
+ std::swap(dsl[dx], ssl[sx]);
+ }
+}
+
+inline void mirror_horizonal_bitmap(int w, int h, int dxs, uchar* data, int bpl, bool monolsb)
+{
+ int shift = w % 8;
+ const uchar* bitflip = qt_get_bitflip_array();
+ for (int y = h-1; y >= 0; y--) {
+ quint8* a0 = (quint8*)(data + y*bpl);
+ // Swap bytes
+ quint8* a = a0+dxs;
+ while (a >= a0) {
+ *a = bitflip[*a];
+ a--;
+ }
+ // Shift bits if unaligned
+ if (shift != 0) {
+ a = a0+dxs;
+ quint8 c = 0;
+ if (monolsb) {
+ while (a >= a0) {
+ quint8 nc = *a << shift;
+ *a = (*a >> (8-shift)) | c;
+ --a;
+ c = nc;
+ }
+ } else {
+ while (a >= a0) {
+ quint8 nc = *a >> shift;
+ *a = (*a << (8-shift)) | c;
+ --a;
+ c = nc;
+ }
+ }
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
{
if (!d)
return QImage();
@@ -4840,92 +2787,80 @@ QImage QImage::mirrored(bool horizontal, bool vertical) const
result.d->has_alpha_clut = d->has_alpha_clut;
result.d->devicePixelRatio = d->devicePixelRatio;
- if (depth() == 1)
+ if (d->depth == 1)
w = (w+7)/8;
int dxi = horizontal ? -1 : 1;
int dxs = horizontal ? w-1 : 0;
int dyi = vertical ? -1 : 1;
- int dy = vertical ? h-1: 0;
+ int dys = vertical ? h-1 : 0;
// 1 bit, 8 bit
- if (d->depth == 1 || d->depth == 8) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint8* ssl = (quint8*)(d->data + sy*d->bytes_per_line);
- quint8* dsl = (quint8*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ if (d->depth == 1 || d->depth == 8)
+ mirrored_helper_loop<quint8>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// 16 bit
- else if (d->depth == 16) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint16* ssl = (quint16*)(d->data + sy*d->bytes_per_line);
- quint16* dsl = (quint16*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ else if (d->depth == 16)
+ mirrored_helper_loop<quint16>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// 24 bit
- else if (d->depth == 24) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint24* ssl = (quint24*)(d->data + sy*d->bytes_per_line);
- quint24* dsl = (quint24*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ else if (d->depth == 24)
+ mirrored_helper_loop<quint24>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// 32 bit
- else if (d->depth == 32) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint32* ssl = (quint32*)(d->data + sy*d->bytes_per_line);
- quint32* dsl = (quint32*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ else if (d->depth == 32)
+ mirrored_helper_loop<quint32>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// special handling of 1 bit images for horizontal mirroring
- if (horizontal && d->depth == 1) {
- int shift = width() % 8;
- for (int y = h-1; y >= 0; y--) {
- quint8* a0 = (quint8*)(result.d->data + y*d->bytes_per_line);
- // Swap bytes
- quint8* a = a0+dxs;
- while (a >= a0) {
- *a = bitflip[*a];
- a--;
- }
- // Shift bits if unaligned
- if (shift != 0) {
- a = a0+dxs;
- quint8 c = 0;
- if (format() == Format_MonoLSB) {
- while (a >= a0) {
- quint8 nc = *a << shift;
- *a = (*a >> (8-shift)) | c;
- --a;
- c = nc;
- }
- } else {
- while (a >= a0) {
- quint8 nc = *a >> shift;
- *a = (*a << (8-shift)) | c;
- --a;
- c = nc;
- }
- }
- }
- }
- }
-
+ if (horizontal && d->depth == 1)
+ mirror_horizonal_bitmap(d->width, d->height, dxs, result.d->data, result.d->bytes_per_line, d->format == Format_MonoLSB);
return result;
}
/*!
+ \internal
+*/
+void QImage::mirrored_inplace(bool horizontal, bool vertical)
+{
+ if (!d)
+ return;
+
+ if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
+ return;
+
+ detach();
+
+ int w = d->width;
+ int h = d->height;
+
+ if (d->depth == 1)
+ w = (w+7)/8;
+ int dxi = horizontal ? -1 : 1;
+ int dxs = horizontal ? w-1 : 0;
+ int dyi = vertical ? -1 : 1;
+ int dys = vertical ? h-1 : 0;
+
+ if (vertical)
+ h = h/2;
+ else if (horizontal)
+ w = w/2;
+
+ // 1 bit, 8 bit
+ if (d->depth == 1 || d->depth == 8)
+ mirrored_helper_loop_inplace<quint8>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+ // 16 bit
+ else if (d->depth == 16)
+ mirrored_helper_loop_inplace<quint16>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+ // 24 bit
+ else if (d->depth == 24)
+ mirrored_helper_loop_inplace<quint24>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+ // 32 bit
+ else if (d->depth == 32)
+ mirrored_helper_loop_inplace<quint32>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+
+ // special handling of 1 bit images for horizontal mirroring
+ if (horizontal && d->depth == 1)
+ mirror_horizonal_bitmap(d->width, d->height, dxs, d->data, d->bytes_per_line, d->format == Format_MonoLSB);
+}
+
+/*!
+ \fn QImage QImage::rgbSwapped() const
Returns a QImage in which the values of the red and blue
components of all pixels have been swapped, effectively converting
an RGB image to an BGR image.
@@ -4934,16 +2869,54 @@ QImage QImage::mirrored(bool horizontal, bool vertical) const
\sa {QImage#Image Transformations}{Image Transformations}
*/
-QImage QImage::rgbSwapped() const
+
+inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
+{
+ Q_ASSERT(layout->redWidth == layout->blueWidth);
+ FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
+ StorePixelsFunc store = qStorePixels[layout->bpp];
+
+ const uint redBlueMask = (1 << layout->redWidth) - 1;
+ const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift)
+ | (((1 << layout->greenWidth) - 1) << layout->greenShift);
+
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ for (int i = 0; i < height; ++i) {
+ uchar *q = dst->scanLine(i);
+ const uchar *p = src->constScanLine(i);
+ int x = 0;
+ while (x < width) {
+ int l = qMin(width - x, buffer_size);
+ const uint *ptr = fetch(buffer, p, x, l);
+ for (int j = 0; j < l; ++j) {
+ uint red = (ptr[j] >> layout->redShift) & redBlueMask;
+ uint blue = (ptr[j] >> layout->blueShift) & redBlueMask;
+ buffer[j] = (ptr[j] & alphaGreenMask)
+ | (red << layout->blueShift)
+ | (blue << layout->redShift);
+ }
+ store(q, buffer, x, l);
+ x += l;
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+QImage QImage::rgbSwapped_helper() const
{
if (isNull())
return *this;
+
QImage res;
+
switch (d->format) {
case Format_Invalid:
case NImageFormats:
Q_ASSERT(false);
- return res;
+ break;
case Format_Mono:
case Format_MonoLSB:
case Format_Indexed8:
@@ -4952,7 +2925,7 @@ QImage QImage::rgbSwapped() const
QRgb c = res.d->colortable.at(i);
res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
}
- return res;
+ break;
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
@@ -4965,15 +2938,16 @@ QImage QImage::rgbSwapped() const
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
uint *q = (uint*)res.scanLine(i);
- uint *p = (uint*)constScanLine(i);
- uint *end = p + d->width;
+ const uint *p = (const uint*)constScanLine(i);
+ const uint *end = p + d->width;
while (p < end) {
- *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
+ uint c = *p;
+ *q = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
p++;
q++;
}
}
- return res;
+ break;
case Format_RGB16:
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
@@ -4982,48 +2956,77 @@ QImage QImage::rgbSwapped() const
const ushort *p = (const ushort*)constScanLine(i);
const ushort *end = p + d->width;
while (p < end) {
- *q = ((*p << 11) & 0xf800) | ((*p >> 11) & 0x1f) | (*p & 0x07e0);
+ ushort c = *p;
+ *q = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
p++;
q++;
}
}
- return res;
+ break;
default:
+ res = QImage(d->width, d->height, d->format);
+ rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]);
break;
}
+ return res;
+}
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- const QPixelLayout *layout = &qPixelLayouts[d->format];
- Q_ASSERT(layout->redWidth == layout->blueWidth);
- FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
- StorePixelsFunc store = qStorePixels[layout->bpp];
+/*!
+ \internal
+*/
+void QImage::rgbSwapped_inplace()
+{
+ if (isNull())
+ return;
- const uint redBlueMask = (1 << layout->redWidth) - 1;
- const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift)
- | (((1 << layout->greenWidth) - 1) << layout->greenShift);
+ detach();
- const int buffer_size = 2048;
- uint buffer[buffer_size];
- for (int i = 0; i < d->height; ++i) {
- uchar *q = res.scanLine(i);
- const uchar *p = constScanLine(i);
- int x = 0;
- while (x < d->width) {
- int l = qMin(d->width - x, buffer_size);
- const uint *ptr = fetch(buffer, p, x, l);
- for (int j = 0; j < l; ++j) {
- uint red = (ptr[j] >> layout->redShift) & redBlueMask;
- uint blue = (ptr[j] >> layout->blueShift) & redBlueMask;
- buffer[j] = (ptr[j] & alphaGreenMask)
- | (red << layout->blueShift)
- | (blue << layout->redShift);
+ switch (d->format) {
+ case Format_Invalid:
+ case NImageFormats:
+ Q_ASSERT(false);
+ break;
+ case Format_Mono:
+ case Format_MonoLSB:
+ case Format_Indexed8:
+ for (int i = 0; i < d->colortable.size(); i++) {
+ QRgb c = d->colortable.at(i);
+ d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
+ }
+ break;
+ case Format_RGB32:
+ case Format_ARGB32:
+ case Format_ARGB32_Premultiplied:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ case Format_RGBX8888:
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+#endif
+ for (int i = 0; i < d->height; i++) {
+ uint *p = (uint*)scanLine(i);
+ uint *end = p + d->width;
+ while (p < end) {
+ uint c = *p;
+ *p = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
+ p++;
}
- store(q, buffer, x, l);
- x += l;
}
+ break;
+ case Format_RGB16:
+ for (int i = 0; i < d->height; i++) {
+ ushort *p = (ushort*)scanLine(i);
+ ushort *end = p + d->width;
+ while (p < end) {
+ ushort c = *p;
+ *p = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
+ p++;
+ }
+ }
+ break;
+ default:
+ rgbSwapped_generic(d->width, d->height, this, this, &qPixelLayouts[d->format]);
+ break;
}
- return res;
}
/*!
@@ -6433,10 +4436,12 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla
if (ref.load() > 1)
return false;
- const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat];
+ const InPlace_Image_Converter *const converterPtr = &qimage_inplace_converter_map[format][newFormat];
InPlace_Image_Converter converter = *converterPtr;
if (converter)
return converter(this, flags);
+ else if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8)
+ return convert_generic_inplace(this, newFormat, flags);
else
return false;
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index bc7f3729ad..4326d5dbbc 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -172,7 +172,19 @@ public:
Format format() const;
+#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QIMAGE_COMPAT_CPP)
+ QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) const & Q_REQUIRED_RESULT
+ { return convertToFormat_helper(f, flags); }
+ QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) && Q_REQUIRED_RESULT
+ {
+ if (convertToFormat_inplace(f, flags))
+ return std::move(*this);
+ else
+ return convertToFormat_helper(f, flags);
+ }
+#else
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) const Q_REQUIRED_RESULT;
+#endif
QImage convertToFormat(Format f, const QVector<QRgb> &colorTable, Qt::ImageConversionFlags flags = Qt::AutoColor) const Q_REQUIRED_RESULT;
int width() const;
@@ -245,8 +257,19 @@ public:
static QMatrix trueMatrix(const QMatrix &, int w, int h);
QImage transformed(const QTransform &matrix, Qt::TransformationMode mode = Qt::FastTransformation) const;
static QTransform trueMatrix(const QTransform &, int w, int h);
+#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QIMAGE_COMPAT_CPP)
+ QImage mirrored(bool horizontally = false, bool vertically = true) const &
+ { return mirrored_helper(horizontally, vertically); }
+ QImage &&mirrored(bool horizontally = false, bool vertically = true) &&
+ { mirrored_inplace(horizontally, vertically); return qMove(*this); }
+ QImage rgbSwapped() const &
+ { return rgbSwapped_helper(); }
+ QImage &&rgbSwapped() &&
+ { rgbSwapped_inplace(); return qMove(*this); }
+#else
QImage mirrored(bool horizontally = false, bool vertically = true) const;
QImage rgbSwapped() const;
+#endif
void invertPixels(InvertMode = InvertRgb);
@@ -298,6 +321,12 @@ public:
protected:
virtual int metric(PaintDeviceMetric metric) const;
+ QImage mirrored_helper(bool horizontal, bool vertical) const;
+ QImage rgbSwapped_helper() const;
+ void mirrored_inplace(bool horizontal, bool vertical);
+ void rgbSwapped_inplace();
+ QImage convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const;
+ bool convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags);
private:
friend class QWSOnScreenSurface;
diff --git a/src/gui/painting/qdrawhelper_avx.cpp b/src/gui/image/qimage_compat.cpp
index 7da6ce6a20..9acf5c18fa 100644
--- a/src/gui/painting/qdrawhelper_avx.cpp
+++ b/src/gui/image/qimage_compat.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Intel Corporation
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -39,32 +39,30 @@
**
****************************************************************************/
-#include <private/qsimd_p.h>
+#ifdef QIMAGE_H
+# error "This file cannot be used with precompiled headers"
+#endif
+#define QT_COMPILING_QIMAGE_COMPAT_CPP
-#ifdef QT_COMPILER_SUPPORTS_AVX
-#define QDRAWHELPER_AVX
+#include "qimage.h"
-#ifndef __AVX__
-#error "AVX not enabled in this file, cannot proceed"
-#endif
+QT_BEGIN_NAMESPACE
-#define qt_blend_argb32_on_argb32_ssse3 qt_blend_argb32_on_argb32_avx
-#include "qdrawhelper_ssse3.cpp"
+// These implementations must be the same as the inline versions in qimage.h
-//#define qt_blend_argb32_on_argb32_sse2 qt_blend_argb32_on_argb32_avx
-#define qt_blend_rgb32_on_rgb32_sse2 qt_blend_rgb32_on_rgb32_avx
-#define comp_func_SourceOver_sse2 comp_func_SourceOver_avx
-#define comp_func_Plus_sse2 comp_func_Plus_avx
-#define comp_func_Source_sse2 comp_func_Source_avx
-#define comp_func_solid_SourceOver_sse2 comp_func_solid_SourceOver_avx
-#define qt_memfill32_sse2 qt_memfill32_avx
-#define qt_memfill16_sse2 qt_memfill16_avx
-#define qt_bitmapblit32_sse2 qt_bitmapblit32_avx
-#define qt_bitmapblit16_sse2 qt_bitmapblit16_avx
-#define QSimdSse2 QSimdAvx
-#define qt_fetch_radial_gradient_sse2 qt_fetch_radial_gradient_avx
-#define qt_scale_image_argb32_on_argb32_sse2 qt_scale_image_argb32_on_argb32_avx
+QImage QImage::convertToFormat(Format f, Qt::ImageConversionFlags flags) const
+{
+ return convertToFormat_helper(f, flags);
+}
-#include "qdrawhelper_sse2.cpp"
+QImage QImage::mirrored(bool horizontally, bool vertically) const
+{
+ return mirrored_helper(horizontally, vertically);
+}
-#endif
+QImage QImage::rgbSwapped() const
+{
+ return rgbSwapped_helper();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
new file mode 100644
index 0000000000..629a7c9b69
--- /dev/null
+++ b/src/gui/image/qimage_conversions.cpp
@@ -0,0 +1,2183 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qdrawhelper_p.h>
+#include <private/qguiapplication_p.h>
+#include <private/qsimd_p.h>
+
+#include <private/qimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// table to flip bits
+static const uchar bitflip[256] = {
+ /*
+ open OUT, "| fmt";
+ for $i (0..255) {
+ print OUT (($i >> 7) & 0x01) | (($i >> 5) & 0x02) |
+ (($i >> 3) & 0x04) | (($i >> 1) & 0x08) |
+ (($i << 7) & 0x80) | (($i << 5) & 0x40) |
+ (($i << 3) & 0x20) | (($i << 1) & 0x10), ", ";
+ }
+ close OUT;
+ */
+ 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
+ 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
+ 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
+ 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
+ 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
+ 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
+ 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
+ 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
+ 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
+ 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
+ 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
+ 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
+ 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
+ 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
+ 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
+ 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
+};
+
+const uchar *qt_get_bitflip_array()
+{
+ return bitflip;
+}
+
+void qGamma_correct_back_to_linear_cs(QImage *image)
+{
+ const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
+ if (!tables)
+ return;
+ const uchar *gamma = tables->qt_pow_rgb_gamma;
+ // gamma correct the pixels back to linear color space...
+ int h = image->height();
+ int w = image->width();
+
+ for (int y=0; y<h; ++y) {
+ uint *pixels = (uint *) image->scanLine(y);
+ for (int x=0; x<w; ++x) {
+ uint p = pixels[x];
+ uint r = gamma[qRed(p)];
+ uint g = gamma[qGreen(p)];
+ uint b = gamma[qBlue(p)];
+ pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
+ }
+ }
+}
+
+/*****************************************************************************
+ Internal routines for converting image depth.
+ *****************************************************************************/
+
+// Cannot be used with indexed formats.
+void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(dest->format > QImage::Format_Indexed8);
+ Q_ASSERT(src->format > QImage::Format_Indexed8);
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
+ const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
+ const uchar *srcData = src->data;
+ uchar *destData = dest->data;
+
+ FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
+ StorePixelsFunc store = qStorePixels[destLayout->bpp];
+
+ for (int y = 0; y < src->height; ++y) {
+ int x = 0;
+ while (x < src->width) {
+ int l = qMin(src->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, srcData, x, l);
+ ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
+ ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
+ store(destData, ptr, x, l);
+ x += l;
+ }
+ srcData += src->bytes_per_line;
+ destData += dest->bytes_per_line;
+ }
+}
+
+// Cannot be used with indexed formats or between formats with different pixel depths.
+bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(dst_format > QImage::Format_Indexed8);
+ Q_ASSERT(data->format > QImage::Format_Indexed8);
+ if (data->depth != qt_depthForFormat(dst_format))
+ return false;
+
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ const QPixelLayout *srcLayout = &qPixelLayouts[data->format];
+ const QPixelLayout *destLayout = &qPixelLayouts[dst_format];
+
+ uchar *srcData = data->data;
+
+ FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
+ StorePixelsFunc store = qStorePixels[destLayout->bpp];
+
+ for (int y = 0; y < data->height; ++y) {
+ int x = 0;
+ while (x < data->width) {
+ int l = qMin(data->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, srcData, x, l);
+ ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
+ ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
+ store(srcData, ptr, x, l);
+ x += l;
+ }
+ srcData += data->bytes_per_line;
+ }
+ data->format = dst_format;
+ return true;
+}
+
+static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qPremultiply(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
+
+#ifndef __SSE2__
+static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = PREMUL(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ return true;
+}
+#endif
+
+static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | *src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ quint32 *rgb_data = (quint32 *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const quint32 *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = ARGB2RGBA(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_ARGB32)
+ data->format = QImage::Format_RGBA8888;
+ else
+ data->format = QImage::Format_RGBA8888_Premultiplied;
+ return true;
+}
+
+static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(qPremultiply(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888 || data->format == QImage::Format_RGBA8888_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = RGBA2ARGB(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_RGBA8888_Premultiplied)
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ else if (data->format == QImage::Format_RGBX8888)
+ data->format = QImage::Format_RGB32;
+ else
+ data->format = QImage::Format_ARGB32;
+ return true;
+}
+
+static void convert_RGBA_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qPremultiply(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBA8888);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = qPremultiply(RGBA2ARGB(*rgb_data));
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ return true;
+}
+
+static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 32;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes; // end of src
+ quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 2) - width;
+ if (data->colortable.size() == 0) {
+ data->colortable.resize(256);
+ for (int i = 0; i < 256; ++i)
+ data->colortable[i] = qRgb(i, i, i);
+ } else {
+ for (int i = 0; i < data->colortable.size(); ++i)
+ data->colortable[i] = qPremultiply(data->colortable.at(i));
+
+ // Fill the rest of the table in case src_data > colortable.size()
+ const int oldSize = data->colortable.size();
+ const QRgb lastColor = data->colortable.at(oldSize - 1);
+ data->colortable.insert(oldSize, 256 - oldSize, lastColor);
+ }
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ *dest_data = data->colortable.at(*src_data);
+ }
+ }
+
+ data->colortable = QVector<QRgb>();
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 32;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes;
+ quint32 *dest_data = (quint32 *) (newData + nbytes);
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 2) - width;
+ if (data->colortable.size() == 0) {
+ data->colortable.resize(256);
+ for (int i = 0; i < 256; ++i)
+ data->colortable[i] = qRgb(i, i, i);
+ } else {
+ // Fill the rest of the table in case src_data > colortable.size()
+ const int oldSize = data->colortable.size();
+ const QRgb lastColor = data->colortable.at(oldSize - 1);
+ data->colortable.insert(oldSize, 256 - oldSize, lastColor);
+ }
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ *dest_data = (quint32) data->colortable.at(*src_data);
+ }
+ }
+
+ data->colortable = QVector<QRgb>();
+ data->format = QImage::Format_RGB32;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 16;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes;
+ quint16 *dest_data = (quint16 *) (newData + nbytes);
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 1) - width;
+
+ quint16 colorTableRGB16[256];
+ if (data->colortable.isEmpty()) {
+ for (int i = 0; i < 256; ++i)
+ colorTableRGB16[i] = qConvertRgb32To16(qRgb(i, i, i));
+ } else {
+ // 1) convert the existing colors to RGB16
+ const int tableSize = data->colortable.size();
+ for (int i = 0; i < tableSize; ++i)
+ colorTableRGB16[i] = qConvertRgb32To16(data->colortable.at(i));
+ data->colortable = QVector<QRgb>();
+
+ // 2) fill the rest of the table in case src_data > colortable.size()
+ const quint16 lastColor = colorTableRGB16[tableSize - 1];
+ for (int i = tableSize; i < 256; ++i)
+ colorTableRGB16[i] = lastColor;
+ }
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ *dest_data = colorTableRGB16[*src_data];
+ }
+ }
+
+ data->format = QImage::Format_RGB16;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGB32);
+ const int depth = 16;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int src_bytes_per_line = data->bytes_per_line;
+ quint32 *src_data = (quint32 *) data->data;
+ quint16 *dst_data = (quint16 *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ for (int j = 0; j < data->width; ++j)
+ dst_data[j] = qConvertRgb32To16(src_data[j]);
+ src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line);
+ dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line);
+ }
+ data->format = QImage::Format_RGB16;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, data->nbytes);
+ if (newData) {
+ data->data = newData;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qUnpremultiply(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | qUnpremultiply(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | qUnpremultiply(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(qUnpremultiply(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBX8888);
+ Q_ASSERT(dest->format == QImage::Format_RGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data) | 0xff000000;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data | 0xff000000);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qUnpremultiply(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | qUnpremultiply(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void swap_bit_order(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
+ Q_ASSERT(dest->format == QImage::Format_Mono || dest->format == QImage::Format_MonoLSB);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+ Q_ASSERT(src->nbytes == dest->nbytes);
+ Q_ASSERT(src->bytes_per_line == dest->bytes_per_line);
+
+ dest->colortable = src->colortable;
+
+ const uchar *src_data = src->data;
+ const uchar *end = src->data + src->nbytes;
+ uchar *dest_data = dest->data;
+ while (src_data < end) {
+ *dest_data = bitflip[*src_data];
+ ++src_data;
+ ++dest_data;
+ }
+}
+
+static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = *src_data | 0xff000000;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ return mask_alpha_converter(dest, src, flags);
+#else
+ Q_UNUSED(flags);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = *src_data | 0x000000ff;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+#endif
+}
+
+static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
+{
+ QVector<QRgb> colorTable = ctbl;
+ if (format == QImage::Format_RGB32) {
+ // check if the color table has alpha
+ for (int i = 0; i < colorTable.size(); ++i)
+ if (qAlpha(colorTable.at(i) != 0xff))
+ colorTable[i] = colorTable.at(i) | 0xff000000;
+ } else if (format == QImage::Format_ARGB32_Premultiplied) {
+ // check if the color table has alpha
+ for (int i = 0; i < colorTable.size(); ++i)
+ colorTable[i] = qPremultiply(colorTable.at(i));
+ }
+ return colorTable;
+}
+
+//
+// dither_to_1: Uses selected dithering algorithm.
+//
+
+void dither_to_Mono(QImageData *dst, const QImageData *src,
+ Qt::ImageConversionFlags flags, bool fromalpha)
+{
+ Q_ASSERT(src->width == dst->width);
+ Q_ASSERT(src->height == dst->height);
+ Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
+
+ dst->colortable.clear();
+ dst->colortable.append(0xffffffff);
+ dst->colortable.append(0xff000000);
+
+ enum { Threshold, Ordered, Diffuse } dithermode;
+
+ if (fromalpha) {
+ if ((flags & Qt::AlphaDither_Mask) == Qt::DiffuseAlphaDither)
+ dithermode = Diffuse;
+ else if ((flags & Qt::AlphaDither_Mask) == Qt::OrderedAlphaDither)
+ dithermode = Ordered;
+ else
+ dithermode = Threshold;
+ } else {
+ if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither)
+ dithermode = Threshold;
+ else if ((flags & Qt::Dither_Mask) == Qt::OrderedDither)
+ dithermode = Ordered;
+ else
+ dithermode = Diffuse;
+ }
+
+ int w = src->width;
+ int h = src->height;
+ int d = src->depth;
+ uchar gray[256]; // gray map for 8 bit images
+ bool use_gray = (d == 8);
+ if (use_gray) { // make gray map
+ if (fromalpha) {
+ // Alpha 0x00 -> 0 pixels (white)
+ // Alpha 0xFF -> 1 pixels (black)
+ for (int i = 0; i < src->colortable.size(); i++)
+ gray[i] = (255 - (src->colortable.at(i) >> 24));
+ } else {
+ // Pixel 0x00 -> 1 pixels (black)
+ // Pixel 0xFF -> 0 pixels (white)
+ for (int i = 0; i < src->colortable.size(); i++)
+ gray[i] = qGray(src->colortable.at(i));
+ }
+ }
+
+ uchar *dst_data = dst->data;
+ int dst_bpl = dst->bytes_per_line;
+ const uchar *src_data = src->data;
+ int src_bpl = src->bytes_per_line;
+
+ switch (dithermode) {
+ case Diffuse: {
+ QScopedArrayPointer<int> lineBuffer(new int[w * 2]);
+ int *line1 = lineBuffer.data();
+ int *line2 = lineBuffer.data() + w;
+ int bmwidth = (w+7)/8;
+
+ int *b1, *b2;
+ int wbytes = w * (d/8);
+ const uchar *p = src->data;
+ const uchar *end = p + wbytes;
+ b2 = line2;
+ if (use_gray) { // 8 bit image
+ while (p < end)
+ *b2++ = gray[*p++];
+ } else { // 32 bit image
+ if (fromalpha) {
+ while (p < end) {
+ *b2++ = 255 - (*(uint*)p >> 24);
+ p += 4;
+ }
+ } else {
+ while (p < end) {
+ *b2++ = qGray(*(uint*)p);
+ p += 4;
+ }
+ }
+ }
+ for (int y=0; y<h; y++) { // for each scan line...
+ int *tmp = line1; line1 = line2; line2 = tmp;
+ bool not_last_line = y < h - 1;
+ if (not_last_line) { // calc. grayvals for next line
+ p = src->data + (y+1)*src->bytes_per_line;
+ end = p + wbytes;
+ b2 = line2;
+ if (use_gray) { // 8 bit image
+ while (p < end)
+ *b2++ = gray[*p++];
+ } else { // 24 bit image
+ if (fromalpha) {
+ while (p < end) {
+ *b2++ = 255 - (*(uint*)p >> 24);
+ p += 4;
+ }
+ } else {
+ while (p < end) {
+ *b2++ = qGray(*(uint*)p);
+ p += 4;
+ }
+ }
+ }
+ }
+
+ int err;
+ uchar *p = dst->data + y*dst->bytes_per_line;
+ memset(p, 0, bmwidth);
+ b1 = line1;
+ b2 = line2;
+ int bit = 7;
+ for (int x=1; x<=w; x++) {
+ if (*b1 < 128) { // black pixel
+ err = *b1++;
+ *p |= 1 << bit;
+ } else { // white pixel
+ err = *b1++ - 255;
+ }
+ if (bit == 0) {
+ p++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ if (x < w)
+ *b1 += (err*7)>>4; // spread error to right pixel
+ if (not_last_line) {
+ b2[0] += (err*5)>>4; // pixel below
+ if (x > 1)
+ b2[-1] += (err*3)>>4; // pixel below left
+ if (x < w)
+ b2[1] += err>>4; // pixel below right
+ }
+ b2++;
+ }
+ }
+ } break;
+ case Ordered: {
+
+ memset(dst->data, 0, dst->nbytes);
+ if (d == 32) {
+ for (int i=0; i<h; i++) {
+ const uint *p = (const uint *)src_data;
+ const uint *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ int j = 0;
+ if (fromalpha) {
+ while (p < end) {
+ if ((*p++ >> 24) >= qt_bayer_matrix[j++&15][i&15])
+ *m |= 1 << bit;
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ } else {
+ while (p < end) {
+ if ((uint)qGray(*p++) < qt_bayer_matrix[j++&15][i&15])
+ *m |= 1 << bit;
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ } else
+ /* (d == 8) */ {
+ for (int i=0; i<h; i++) {
+ const uchar *p = src_data;
+ const uchar *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ int j = 0;
+ while (p < end) {
+ if ((uint)gray[*p++] < qt_bayer_matrix[j++&15][i&15])
+ *m |= 1 << bit;
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ }
+ } break;
+ default: { // Threshold:
+ memset(dst->data, 0, dst->nbytes);
+ if (d == 32) {
+ for (int i=0; i<h; i++) {
+ const uint *p = (const uint *)src_data;
+ const uint *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ if (fromalpha) {
+ while (p < end) {
+ if ((*p++ >> 24) >= 128)
+ *m |= 1 << bit; // Set mask "on"
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ } else {
+ while (p < end) {
+ if (qGray(*p++) < 128)
+ *m |= 1 << bit; // Set pixel "black"
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ } else
+ if (d == 8) {
+ for (int i=0; i<h; i++) {
+ const uchar *p = src_data;
+ const uchar *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ while (p < end) {
+ if (gray[*p++] < 128)
+ *m |= 1 << bit; // Set mask "on"/ pixel "black"
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ }
+ }
+ }
+
+ if (dst->format == QImage::Format_MonoLSB) {
+ // need to swap bit order
+ uchar *sl = dst->data;
+ int bpl = (dst->width + 7) * dst->depth / 8;
+ int pad = dst->bytes_per_line - bpl;
+ for (int y=0; y<dst->height; ++y) {
+ for (int x=0; x<bpl; ++x) {
+ *sl = bitflip[*sl];
+ ++sl;
+ }
+ sl += pad;
+ }
+ }
+}
+
+static void convert_X_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ dither_to_Mono(dst, src, flags, false);
+}
+
+static void convert_ARGB_PM_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
+ convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
+ dither_to_Mono(dst, tmp.data(), flags, false);
+}
+
+//
+// convert_32_to_8: Converts a 32 bits depth (true color) to an 8 bit
+// image with a colormap. If the 32 bit image has more than 256 colors,
+// we convert the red,green and blue bytes into a single byte encoded
+// as 6 shades of each of red, green and blue.
+//
+// if dithering is needed, only 1 color at most is available for alpha.
+//
+struct QRgbMap {
+ inline QRgbMap() : used(0) { }
+ uchar pix;
+ uchar used;
+ QRgb rgb;
+};
+
+static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dst->format == QImage::Format_Indexed8);
+ Q_ASSERT(src->width == dst->width);
+ Q_ASSERT(src->height == dst->height);
+
+ bool do_quant = (flags & Qt::DitherMode_Mask) == Qt::PreferDither
+ || src->format == QImage::Format_ARGB32;
+ uint alpha_mask = src->format == QImage::Format_RGB32 ? 0xff000000 : 0;
+
+ const int tablesize = 997; // prime
+ QRgbMap table[tablesize];
+ int pix=0;
+
+ if (!dst->colortable.isEmpty()) {
+ QVector<QRgb> ctbl = dst->colortable;
+ dst->colortable.resize(256);
+ // Preload palette into table.
+ // Almost same code as pixel insertion below
+ for (int i = 0; i < dst->colortable.size(); ++i) {
+ // Find in table...
+ QRgb p = ctbl.at(i) | alpha_mask;
+ int hash = p % tablesize;
+ for (;;) {
+ if (table[hash].used) {
+ if (table[hash].rgb == p) {
+ // Found previous insertion - use it
+ break;
+ } else {
+ // Keep searching...
+ if (++hash == tablesize) hash = 0;
+ }
+ } else {
+ // Cannot be in table
+ Q_ASSERT (pix != 256); // too many colors
+ // Insert into table at this unused position
+ dst->colortable[pix] = p;
+ table[hash].pix = pix++;
+ table[hash].rgb = p;
+ table[hash].used = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ if ((flags & Qt::DitherMode_Mask) != Qt::PreferDither) {
+ dst->colortable.resize(256);
+ const uchar *src_data = src->data;
+ uchar *dest_data = dst->data;
+ for (int y = 0; y < src->height; y++) { // check if <= 256 colors
+ const QRgb *s = (const QRgb *)src_data;
+ uchar *b = dest_data;
+ for (int x = 0; x < src->width; ++x) {
+ QRgb p = s[x] | alpha_mask;
+ int hash = p % tablesize;
+ for (;;) {
+ if (table[hash].used) {
+ if (table[hash].rgb == (p)) {
+ // Found previous insertion - use it
+ break;
+ } else {
+ // Keep searching...
+ if (++hash == tablesize) hash = 0;
+ }
+ } else {
+ // Cannot be in table
+ if (pix == 256) { // too many colors
+ do_quant = true;
+ // Break right out
+ x = src->width;
+ y = src->height;
+ } else {
+ // Insert into table at this unused position
+ dst->colortable[pix] = p;
+ table[hash].pix = pix++;
+ table[hash].rgb = p;
+ table[hash].used = 1;
+ }
+ break;
+ }
+ }
+ *b++ = table[hash].pix; // May occur once incorrectly
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ }
+ int numColors = do_quant ? 256 : pix;
+
+ dst->colortable.resize(numColors);
+
+ if (do_quant) { // quantization needed
+
+#define MAX_R 5
+#define MAX_G 5
+#define MAX_B 5
+#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
+
+ for (int rc=0; rc<=MAX_R; rc++) // build 6x6x6 color cube
+ for (int gc=0; gc<=MAX_G; gc++)
+ for (int bc=0; bc<=MAX_B; bc++)
+ dst->colortable[INDEXOF(rc,gc,bc)] = 0xff000000 | qRgb(rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B);
+
+ const uchar *src_data = src->data;
+ uchar *dest_data = dst->data;
+ if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither) {
+ for (int y = 0; y < src->height; y++) {
+ const QRgb *p = (const QRgb *)src_data;
+ const QRgb *end = p + src->width;
+ uchar *b = dest_data;
+
+ while (p < end) {
+#define DITHER(p,m) ((uchar) ((p * (m) + 127) / 255))
+ *b++ =
+ INDEXOF(
+ DITHER(qRed(*p), MAX_R),
+ DITHER(qGreen(*p), MAX_G),
+ DITHER(qBlue(*p), MAX_B)
+ );
+#undef DITHER
+ p++;
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ } else if ((flags & Qt::Dither_Mask) == Qt::DiffuseDither) {
+ int* line1[3];
+ int* line2[3];
+ int* pv[3];
+ QScopedArrayPointer<int> lineBuffer(new int[src->width * 9]);
+ line1[0] = lineBuffer.data();
+ line2[0] = lineBuffer.data() + src->width;
+ line1[1] = lineBuffer.data() + src->width * 2;
+ line2[1] = lineBuffer.data() + src->width * 3;
+ line1[2] = lineBuffer.data() + src->width * 4;
+ line2[2] = lineBuffer.data() + src->width * 5;
+ pv[0] = lineBuffer.data() + src->width * 6;
+ pv[1] = lineBuffer.data() + src->width * 7;
+ pv[2] = lineBuffer.data() + src->width * 8;
+
+ int endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian);
+ for (int y = 0; y < src->height; y++) {
+ const uchar* q = src_data;
+ const uchar* q2 = y < src->height - 1 ? q + src->bytes_per_line : src->data;
+ uchar *b = dest_data;
+ for (int chan = 0; chan < 3; chan++) {
+ int *l1 = (y&1) ? line2[chan] : line1[chan];
+ int *l2 = (y&1) ? line1[chan] : line2[chan];
+ if (y == 0) {
+ for (int i = 0; i < src->width; i++)
+ l1[i] = q[i*4+chan+endian];
+ }
+ if (y+1 < src->height) {
+ for (int i = 0; i < src->width; i++)
+ l2[i] = q2[i*4+chan+endian];
+ }
+ // Bi-directional error diffusion
+ if (y&1) {
+ for (int x = 0; x < src->width; x++) {
+ int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
+ int err = l1[x] - pix * 255 / 5;
+ pv[chan][x] = pix;
+
+ // Spread the error around...
+ if (x + 1< src->width) {
+ l1[x+1] += (err*7)>>4;
+ l2[x+1] += err>>4;
+ }
+ l2[x]+=(err*5)>>4;
+ if (x>1)
+ l2[x-1]+=(err*3)>>4;
+ }
+ } else {
+ for (int x = src->width; x-- > 0;) {
+ int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
+ int err = l1[x] - pix * 255 / 5;
+ pv[chan][x] = pix;
+
+ // Spread the error around...
+ if (x > 0) {
+ l1[x-1] += (err*7)>>4;
+ l2[x-1] += err>>4;
+ }
+ l2[x]+=(err*5)>>4;
+ if (x + 1 < src->width)
+ l2[x+1]+=(err*3)>>4;
+ }
+ }
+ }
+ if (endian) {
+ for (int x = 0; x < src->width; x++) {
+ *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
+ }
+ } else {
+ for (int x = 0; x < src->width; x++) {
+ *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
+ }
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ } else { // OrderedDither
+ for (int y = 0; y < src->height; y++) {
+ const QRgb *p = (const QRgb *)src_data;
+ const QRgb *end = p + src->width;
+ uchar *b = dest_data;
+
+ int x = 0;
+ while (p < end) {
+ uint d = qt_bayer_matrix[y & 15][x & 15] << 8;
+
+#define DITHER(p, d, m) ((uchar) ((((256 * (m) + (m) + 1)) * (p) + (d)) >> 16))
+ *b++ =
+ INDEXOF(
+ DITHER(qRed(*p), d, MAX_R),
+ DITHER(qGreen(*p), d, MAX_G),
+ DITHER(qBlue(*p), d, MAX_B)
+ );
+#undef DITHER
+
+ p++;
+ x++;
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ }
+
+ if (src->format != QImage::Format_RGB32
+ && src->format != QImage::Format_RGB16) {
+ const int trans = 216;
+ Q_ASSERT(dst->colortable.size() > trans);
+ dst->colortable[trans] = 0;
+ QScopedPointer<QImageData> mask(QImageData::create(QSize(src->width, src->height), QImage::Format_Mono));
+ dither_to_Mono(mask.data(), src, flags, true);
+ uchar *dst_data = dst->data;
+ const uchar *mask_data = mask->data;
+ for (int y = 0; y < src->height; y++) {
+ for (int x = 0; x < src->width ; x++) {
+ if (!(mask_data[x>>3] & (0x80 >> (x & 7))))
+ dst_data[x] = trans;
+ }
+ mask_data += mask->bytes_per_line;
+ dst_data += dst->bytes_per_line;
+ }
+ dst->has_alpha_clut = true;
+ }
+
+#undef MAX_R
+#undef MAX_G
+#undef MAX_B
+#undef INDEXOF
+
+ }
+}
+
+static void convert_ARGB_PM_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
+ convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
+ convert_RGB_to_Indexed8(dst, tmp.data(), flags);
+}
+
+static void convert_ARGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ convert_RGB_to_Indexed8(dst, src, flags);
+}
+
+static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Indexed8);
+ Q_ASSERT(dest->format == QImage::Format_RGB32
+ || dest->format == QImage::Format_ARGB32
+ || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
+ if (colorTable.size() == 0) {
+ colorTable.resize(256);
+ for (int i=0; i<256; ++i)
+ colorTable[i] = qRgb(i, i, i);
+ }
+
+ int w = src->width;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+ int tableSize = colorTable.size() - 1;
+ for (int y = 0; y < src->height; y++) {
+ uint *p = (uint *)dest_data;
+ const uchar *b = src_data;
+ uint *end = p + w;
+
+ while (p < end)
+ *p++ = colorTable.at(qMin<int>(tableSize, *b++));
+
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+}
+
+static void convert_Mono_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
+ Q_ASSERT(dest->format == QImage::Format_RGB32
+ || dest->format == QImage::Format_ARGB32
+ || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
+
+ // Default to black / white colors
+ if (colorTable.size() < 2) {
+ if (colorTable.size() == 0)
+ colorTable << 0xff000000;
+ colorTable << 0xffffffff;
+ }
+
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+ if (src->format == QImage::Format_Mono) {
+ for (int y = 0; y < dest->height; y++) {
+ uint *p = (uint *)dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = colorTable.at((src_data[x>>3] >> (7 - (x & 7))) & 1);
+
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ } else {
+ for (int y = 0; y < dest->height; y++) {
+ uint *p = (uint *)dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = colorTable.at((src_data[x>>3] >> (x & 7)) & 1);
+
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ }
+}
+
+
+static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
+ Q_ASSERT(dest->format == QImage::Format_Indexed8);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ QVector<QRgb> ctbl = src->colortable;
+ if (ctbl.size() > 2) {
+ ctbl.resize(2);
+ } else if (ctbl.size() < 2) {
+ if (ctbl.size() == 0)
+ ctbl << 0xff000000;
+ ctbl << 0xffffffff;
+ }
+ dest->colortable = ctbl;
+ dest->has_alpha_clut = src->has_alpha_clut;
+
+
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+ if (src->format == QImage::Format_Mono) {
+ for (int y = 0; y < dest->height; y++) {
+ uchar *p = dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = (src_data[x>>3] >> (7 - (x & 7))) & 1;
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ } else {
+ for (int y = 0; y < dest->height; y++) {
+ uchar *p = dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = (src_data[x>>3] >> (x & 7)) & 1;
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ }
+}
+
+// first index source, second dest
+Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
+{
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ {
+ 0,
+ 0,
+ swap_bit_order,
+ convert_Mono_to_Indexed8,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_Mono
+
+ {
+ 0,
+ swap_bit_order,
+ 0,
+ convert_Mono_to_Indexed8,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_MonoLSB
+
+ {
+ 0,
+ convert_X_to_Mono,
+ convert_X_to_Mono,
+ 0,
+ convert_Indexed8_to_X32,
+ convert_Indexed8_to_X32,
+ convert_Indexed8_to_X32,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_Indexed8
+
+ {
+ 0,
+ convert_X_to_Mono,
+ convert_X_to_Mono,
+ convert_RGB_to_Indexed8,
+ 0,
+ mask_alpha_converter,
+ mask_alpha_converter,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA
+ }, // Format_RGB32
+
+ {
+ 0,
+ convert_X_to_Mono,
+ convert_X_to_Mono,
+ convert_ARGB_to_Indexed8,
+ mask_alpha_converter,
+ 0,
+ convert_ARGB_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBx,
+ convert_ARGB_to_RGBA,
+ convert_ARGB_to_RGBA_PM,
+ }, // Format_ARGB32
+
+ {
+ 0,
+ convert_ARGB_PM_to_Mono,
+ convert_ARGB_PM_to_Mono,
+ convert_ARGB_PM_to_Indexed8,
+ convert_ARGB_PM_to_RGB,
+ convert_ARGB_PM_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_PM_to_RGBx,
+ convert_ARGB_PM_to_RGBA,
+ convert_ARGB_to_RGBA,
+ }, // Format_ARGB32_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB16
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB8565_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB666
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB6666_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB555
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB8555_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB888
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB444
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB4444_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+ mask_alpha_converter_RGBx,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ 0,
+ convert_ARGB_to_ARGB_PM,
+#else
+ 0,
+ 0
+#endif
+ }, // Format_RGBA8888
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_PM_to_RGB,
+ convert_RGBA_PM_to_ARGB,
+ convert_RGBA_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_ARGB_PM_to_RGB,
+ convert_ARGB_PM_to_ARGB,
+ 0,
+#else
+ 0,
+ 0,
+ 0
+#endif
+ } // Format_RGBA8888_Premultiplied
+};
+
+InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
+{
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_Mono
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_MonoLSB
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_indexed8_to_RGB_inplace,
+ convert_indexed8_to_ARGB_PM_inplace,
+ convert_indexed8_to_RGB16_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_Indexed8
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGB_to_RGB16_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGB32
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#ifdef __SSE2__
+ convert_ARGB_to_ARGB_PM_inplace_sse2,
+#else
+ convert_ARGB_to_ARGB_PM_inplace,
+#endif
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBA_inplace,
+ 0,
+ }, // Format_ARGB32
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBA_inplace
+ }, // Format_ARGB32_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB16
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB8565_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB666
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB6666_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB555
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB8555_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB888
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB444
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB4444_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_PM_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBA8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ } // Format_RGBA8888_Premultiplied
+};
+
+void qInitImageConversions()
+{
+#if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSSE3)
+ if (qCpuHasFeature(SSSE3)) {
+ extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
+ }
+#endif
+
+#ifdef __ARM_NEON__
+ extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon;
+#endif
+
+#ifdef QT_COMPILER_SUPPORTS_MIPS_DSPR2
+ extern bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConversionFlags);
+ inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_mips_dspr2;
+ return;
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp
index 1ac0a87272..60c2da6a58 100644
--- a/src/gui/image/qimage_neon.cpp
+++ b/src/gui/image/qimage_neon.cpp
@@ -43,7 +43,7 @@
#include <private/qimage_p.h>
#include <private/qsimd_p.h>
-#ifdef QT_COMPILER_SUPPORTS_NEON
+#ifdef __ARM_NEON__
QT_BEGIN_NAMESPACE
@@ -111,4 +111,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I
QT_END_NAMESPACE
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 36f117df60..81730b92f2 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -108,7 +108,20 @@ struct Q_GUI_EXPORT QImageData { // internal image data
QPaintEngine *paintEngine;
};
+typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags);
+
+extern Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats];
+extern InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats];
+
+void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags);
+
+void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha);
+
void qInitImageConversions();
+
+const uchar *qt_get_bitflip_array();
Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image);
inline int qt_depthForFormat(QImage::Format format)
diff --git a/src/gui/image/qimage_sse2.cpp b/src/gui/image/qimage_sse2.cpp
index 0d6eac4ea2..037846c9aa 100644
--- a/src/gui/image/qimage_sse2.cpp
+++ b/src/gui/image/qimage_sse2.cpp
@@ -94,7 +94,7 @@ bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionF
if (*p < 0x00ffffff)
*p = 0;
else if (*p < 0xff000000)
- *p = PREMUL(*p);
+ *p = qPremultiply(*p);
}
d = reinterpret_cast<__m128i*>(p+pad);
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 636d86991b..091837b8b4 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -190,37 +190,36 @@ enum _qt_BuiltInFormatType {
struct _qt_BuiltInFormatStruct
{
- _qt_BuiltInFormatType type;
const char *extension;
const char *mimeType;
};
static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
#ifndef QT_NO_IMAGEFORMAT_PNG
- {_qt_PngFormat, "png", "image/png"},
+ {"png", "image/png"},
#endif
#ifndef QT_NO_IMAGEFORMAT_JPEG
- {_qt_JpgFormat, "jpg", "image/jpeg"},
- {_qt_JpegFormat, "jpeg", "image/jpeg"},
+ {"jpg", "image/jpeg"},
+ {"jpeg", "image/jpeg"},
#endif
#ifdef QT_BUILTIN_GIF_READER
- {_qt_GifFormat, "gif", "image/gif"},
+ {"gif", "image/gif"},
#endif
#ifndef QT_NO_IMAGEFORMAT_BMP
- {_qt_BmpFormat, "bmp", "image/bmp"},
+ {"bmp", "image/bmp"},
#endif
#ifndef QT_NO_IMAGEFORMAT_PPM
- {_qt_PpmFormat, "ppm", "image/x-portable-pixmap"},
- {_qt_PgmFormat, "pgm", "image/x-portable-graymap"},
- {_qt_PbmFormat, "pbm", "image/x-portable-bitmap"},
+ {"ppm", "image/x-portable-pixmap"},
+ {"pgm", "image/x-portable-graymap"},
+ {"pbm", "image/x-portable-bitmap"},
#endif
#ifndef QT_NO_IMAGEFORMAT_XBM
- {_qt_XbmFormat, "xbm", "image/x-xbitmap"},
+ {"xbm", "image/x-xbitmap"},
#endif
#ifndef QT_NO_IMAGEFORMAT_XPM
- {_qt_XpmFormat, "xpm", "image/x-xpixmap"},
+ {"xpm", "image/x-xpixmap"},
#endif
- {_qt_NoFormat, "", ""}
+ {"", ""}
};
static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
@@ -423,10 +422,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray subType;
int numFormats = _qt_NumFormats;
while (device && numFormats >= 0) {
- const _qt_BuiltInFormatStruct *formatStruct = &_qt_BuiltInFormats[currentFormat];
-
const qint64 pos = device->pos();
- switch (formatStruct->type) {
+ switch (currentFormat) {
#ifndef QT_NO_IMAGEFORMAT_PNG
case _qt_PngFormat:
if (QPngHandler::canRead(device))
@@ -482,7 +479,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (handler) {
#ifdef QIMAGEREADER_DEBUG
- qDebug() << "QImageReader::createReadHandler: the" << formatStruct->extension
+ qDebug() << "QImageReader::createReadHandler: the" << _qt_BuiltInFormats[currentFormat].extension
<< "built-in handler can read this data";
#endif
break;
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index 3f90bb42f0..bd358b7228 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -861,24 +861,18 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_avx(quint32 *dst, const
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
-#if defined(QT_COMPILER_SUPPORTS_NEON)
+#if defined(__ARM_NEON__)
// from qimage_neon.cpp
if (qCpuHasFeature(NEON))
rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
#if defined(QT_COMPILER_SUPPORTS_SSSE3)
// from qimage_ssse3.cpp
if (false) {
-# if defined(QT_COMPILER_SUPPORTS_AVX)
- } else if (qCpuHasFeature(AVX)) {
- rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_avx;
-# endif
-# ifndef __AVX__
} else if (qCpuHasFeature(SSSE3)) {
rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_ssse3;
-# endif
}
#endif // QT_COMPILER_SUPPORTS_SSSE3
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 6dced54d20..86c4dfbdca 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1617,6 +1617,28 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
}
/*!
+ \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
+ \since 5.3
+ \overload
+
+ Converts the given \a image to a pixmap without copying if possible.
+*/
+
+
+/*!
+ \internal
+*/
+QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
+{
+ if (image.isNull())
+ return QPixmap();
+
+ QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
+ data->fromImageInPlace(image, flags);
+ return QPixmap(data.take());
+}
+
+/*!
\fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
Create a QPixmap from an image read directly from an \a imageReader.
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index f1fce03c80..0efd606283 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -131,6 +131,12 @@ public:
QImage toImage() const;
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);
static QPixmap fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags = Qt::AutoColor);
+#ifdef Q_COMPILER_RVALUE_REFS
+ static QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags = Qt::AutoColor)
+ {
+ return fromImageInPlace(image, flags);
+ }
+#endif
bool load(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
bool loadFromData(const uchar *buf, uint len, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
@@ -167,6 +173,7 @@ public:
protected:
int metric(PaintDeviceMetric) const;
+ static QPixmap fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);
private:
QExplicitlySharedDataPointer<QPlatformPixmap> data;
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index 4c1b30a6d8..839a7a709f 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -148,7 +148,7 @@ void QBlittablePlatformPixmap::fill(const QColor &color)
m_alpha = true;
}
- uint pixel = PREMUL(color.rgba());
+ uint pixel = qPremultiply(color.rgba());
const QPixelLayout *layout = &qPixelLayouts[blittable()->lock()->format()];
Q_ASSERT(layout->convertFromARGB32PM);
layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index f9a017c281..1465fea8b9 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -135,11 +135,16 @@ bool QRasterPlatformPixmap::fromData(const uchar *buffer, uint len, const char *
void QRasterPlatformPixmap::fromImage(const QImage &sourceImage,
Qt::ImageConversionFlags flags)
{
- Q_UNUSED(flags);
QImage image = sourceImage;
createPixmapForImage(image, flags, /* inplace = */false);
}
+void QRasterPlatformPixmap::fromImageInPlace(QImage &sourceImage,
+ Qt::ImageConversionFlags flags)
+{
+ createPixmapForImage(sourceImage, flags, /* inplace = */true);
+}
+
void QRasterPlatformPixmap::fromImageReader(QImageReader *imageReader,
Qt::ImageConversionFlags flags)
{
@@ -182,7 +187,7 @@ void QRasterPlatformPixmap::fill(const QColor &color)
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
QImage::Format toFormat;
-#if !(defined(QT_COMPILER_SUPPORTS_NEON) || defined(__SSE2__))
+#if !(defined(__ARM_NEON__) || defined(__SSE2__))
if (image.format() == QImage::Format_RGB16)
toFormat = QImage::Format_ARGB8565_Premultiplied;
else if (image.format() == QImage::Format_RGB666)
@@ -203,7 +208,7 @@ void QRasterPlatformPixmap::fill(const QColor &color)
}
}
}
- pixel = PREMUL(color.rgba());
+ pixel = qPremultiply(color.rgba());
const QPixelLayout *layout = &qPixelLayouts[image.format()];
layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
} else {
@@ -311,7 +316,7 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC
QImage::Format opaqueFormat = QNativeImage::systemFormat();
QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-#if !defined(QT_COMPILER_SUPPORTS_NEON) && !defined(__SSE2__)
+#if !defined(__ARM_NEON__) && !defined(__SSE2__)
switch (opaqueFormat) {
case QImage::Format_RGB16:
alphaFormat = QImage::Format_ARGB8565_Premultiplied;
diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h
index cef8821888..b273d65c9f 100644
--- a/src/gui/image/qpixmap_raster_p.h
+++ b/src/gui/image/qpixmap_raster_p.h
@@ -69,6 +69,7 @@ public:
void resize(int width, int height);
bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags);
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+ void fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags);
void fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags);
void copy(const QPlatformPixmap *data, const QRect &rect);
diff --git a/src/gui/image/qplatformpixmap.h b/src/gui/image/qplatformpixmap.h
index 08e03f10bd..435811eb84 100644
--- a/src/gui/image/qplatformpixmap.h
+++ b/src/gui/image/qplatformpixmap.h
@@ -69,7 +69,8 @@ public:
};
enum ClassId { RasterClass, DirectFBClass,
- BlitterClass, CustomClass = 1024 };
+ BlitterClass, Direct2DClass,
+ CustomClass = 1024 };
QPlatformPixmap(PixelType pixelType, int classId);
virtual ~QPlatformPixmap();
@@ -79,6 +80,12 @@ public:
virtual void resize(int width, int height) = 0;
virtual void fromImage(const QImage &image,
Qt::ImageConversionFlags flags) = 0;
+ virtual void fromImageInPlace(QImage &image,
+ Qt::ImageConversionFlags flags)
+ {
+ fromImage(image, flags);
+ }
+
virtual void fromImageReader(QImageReader *imageReader,
Qt::ImageConversionFlags flags);
diff --git a/src/gui/image/qpnghandler.pri b/src/gui/image/qpnghandler.pri
index bedf23ff12..aca7e2c568 100644
--- a/src/gui/image/qpnghandler.pri
+++ b/src/gui/image/qpnghandler.pri
@@ -2,7 +2,7 @@ INCLUDEPATH *= $$PWD
HEADERS += $$PWD/qpnghandler_p.h
SOURCES += $$PWD/qpnghandler.cpp
contains(QT_CONFIG, system-png) {
- if(unix|win32-g++*): LIBS_PRIVATE += -lpng
+ if(unix|mingw): LIBS_PRIVATE += -lpng
else:win32: LIBS += libpng.lib
} else {
diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp
index aceb6623ea..5311afd745 100644
--- a/src/gui/image/qxbmhandler.cpp
+++ b/src/gui/image/qxbmhandler.cpp
@@ -103,7 +103,7 @@ static bool read_xbm_header(QIODevice *device, int& w, int& h)
// "#define .._height <num>"
readBytes = device->readLine(buf, buflen);
if (readBytes <= 0)
- return false;
+ return false;
buf[readBytes - 1] = '\0';
sbuf = QString::fromLatin1(buf);
@@ -183,9 +183,9 @@ static bool read_xbm_image(QIODevice *device, QImage *outImage)
static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const QString &fileName)
{
QImage image = sourceImage;
- int w = image.width();
- int h = image.height();
- int i;
+ int w = image.width();
+ int h = image.height();
+ int i;
QString s = fileName; // get file base name
int msize = s.length() + 100;
char *buf = new char[msize];
@@ -203,16 +203,16 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const
bool invert = qGray(image.color(0)) < qGray(image.color(1));
char hexrep[16];
for (i=0; i<10; i++)
- hexrep[i] = '0' + i;
+ hexrep[i] = '0' + i;
for (i=10; i<16; i++)
- hexrep[i] = 'a' -10 + i;
+ hexrep[i] = 'a' -10 + i;
if (invert) {
- char t;
- for (i=0; i<8; i++) {
- t = hexrep[15-i];
- hexrep[15-i] = hexrep[i];
- hexrep[i] = t;
- }
+ char t;
+ for (i=0; i<8; i++) {
+ t = hexrep[15-i];
+ hexrep[15-i] = hexrep[i];
+ hexrep[i] = t;
+ }
}
int bcnt = 0;
char *p = buf;
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index d9bcbf316f..e9e4a1d818 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -121,7 +121,8 @@ SOURCES += \
kernel/qplatformservices.cpp \
kernel/qplatformscreenpageflipper.cpp \
kernel/qplatformsystemtrayicon_qpa.cpp \
- kernel/qplatformsessionmanager.cpp
+ kernel/qplatformsessionmanager.cpp \
+ kernel/qplatformmenu.cpp
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index 91aae94730..465c04cdc8 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -103,7 +103,7 @@ QT_BEGIN_NAMESPACE
\sa {Drag and Drop}, QClipboard, QMimeData, QWindowsMime, QMacPasteboardMime,
{Draggable Icons Example}, {Draggable Text Example}, {Drop Site Example},
- {Fridge Magnets Example}
+ {Fridge Magnets Example}
*/
/*!
@@ -253,8 +253,8 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
loop. Other events are still delivered to the application while
the operation is performed. On Windows, the Qt event loop is
blocked during the operation. However, QDrag::exec() on
- Windows causes processEvents() to be called frequently to keep the GUI responsive.
- If any loops or operations are called while a drag operation is active, it will block the drag operation.
+ Windows causes processEvents() to be called frequently to keep the GUI responsive.
+ If any loops or operations are called while a drag operation is active, it will block the drag operation.
*/
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defaultDropAction)
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 131f1863a5..7759e812cb 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -274,6 +274,38 @@ QMouseEvent::~QMouseEvent()
{
}
+/*!
+ \since 5.3
+
+ Returns information about the mouse event source.
+
+ The mouse event source can be used to distinguish between genuine
+ and artificial mouse events. The latter are events that are
+ synthesized from touch events by the operating system or Qt itself.
+
+ \note Many platforms provide no such information. On such platforms
+ \l Qt::MouseEventNotSynthesized is returned always.
+
+ \sa Qt::MouseEventSource
+ */
+Qt::MouseEventSource QMouseEvent::source() const
+{
+ return QGuiApplicationPrivate::mouseEventSource(this);
+}
+
+/*!
+ \since 5.3
+
+ Returns the mouse event flags.
+
+ The mouse event flags provide additional information about a mouse event.
+
+ \sa Qt::MouseEventFlag
+ */
+Qt::MouseEventFlags QMouseEvent::flags() const
+{
+ return QGuiApplicationPrivate::mouseEventFlags(this);
+}
/*!
\fn QPointF QMouseEvent::localPos() const
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index d22e423248..0a826284c9 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -135,6 +135,9 @@ public:
QT_DEPRECATED inline QPointF posF() const { return l; }
#endif
+ Qt::MouseEventSource source() const;
+ Qt::MouseEventFlags flags() const;
+
protected:
QPointF l, w, s;
Qt::MouseButton b;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index c935a45085..c587e51299 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -59,6 +59,7 @@
#include <QtCore/qmutex.h>
#include <QtCore/private/qthread_p.h>
#include <QtCore/qdir.h>
+#include <QtCore/qlibraryinfo.h>
#include <QtCore/qnumeric.h>
#include <QtDebug>
#ifndef QT_NO_ACCESSIBILITY
@@ -132,6 +133,8 @@ enum ApplicationResourceFlags
static unsigned applicationResourceFlags = 0;
+QIcon *QGuiApplicationPrivate::app_icon = 0;
+
QString *QGuiApplicationPrivate::platform_name = 0;
QString *QGuiApplicationPrivate::displayName = 0;
@@ -490,6 +493,8 @@ static QWindowGeometrySpecification windowGeometrySpecification;
Qt::RightToLeft
\li \c{-session} \e session, restores the application from an earlier
\l{Session Management}{session}.
+ \li -qwindowgeometry, sets the geometry of the first window
+ \li -qwindowtitle, sets the title of the first window
\endlist
The following standard command line options are available for X11:
@@ -565,6 +570,8 @@ QGuiApplication::~QGuiApplication()
d->cursor_list.clear();
#endif
+ delete QGuiApplicationPrivate::app_icon;
+ QGuiApplicationPrivate::app_icon = 0;
delete QGuiApplicationPrivate::platform_name;
QGuiApplicationPrivate::platform_name = 0;
delete QGuiApplicationPrivate::displayName;
@@ -960,11 +967,14 @@ QString QGuiApplication::platformName()
*QGuiApplicationPrivate::platform_name : QString();
}
-static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, int &argc, char **argv)
+static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv)
{
// Split into platform name and arguments
QStringList arguments = pluginArgument.split(QLatin1Char(':'));
const QString name = arguments.takeFirst().toLower();
+ QString argumentsKey = name;
+ argumentsKey[0] = argumentsKey.at(0).toUpper();
+ arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey));
// Create the platform integration.
QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
@@ -991,15 +1001,21 @@ static void init_platform(const QString &pluginArgument, const QString &platform
}
// Create the platform theme:
- // 1) Ask the platform integration for a list of names.
- const QStringList themeNames = QGuiApplicationPrivate::platform_integration->themeNames();
+
+ // 1) Fetch the platform name from the environment if present.
+ QStringList themeNames;
+ if (!platformThemeName.isEmpty())
+ themeNames.append(platformThemeName);
+
+ // 2) Ask the platform integration for a list of names and try loading them.
+ themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
foreach (const QString &themeName, themeNames) {
QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(themeName, platformPluginPath);
if (QGuiApplicationPrivate::platform_theme)
break;
}
- // 2) If none found, look for a theme plugin. Theme plugins are located in the
+ // 3) If none found, look for a theme plugin. Theme plugins are located in the
// same directory as platform plugins.
if (!QGuiApplicationPrivate::platform_theme) {
foreach (const QString &themeName, themeNames) {
@@ -1010,7 +1026,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
// No error message; not having a theme plugin is allowed.
}
- // 3) Fall back on the built-in "null" platform theme.
+ // 4) Fall back on the built-in "null" platform theme.
if (!QGuiApplicationPrivate::platform_theme)
QGuiApplicationPrivate::platform_theme = new QPlatformTheme;
@@ -1070,6 +1086,8 @@ void QGuiApplicationPrivate::createPlatformIntegration()
platformName = platformNameEnv;
}
+ QString platformThemeName = QString::fromLocal8Bit(qgetenv("QT_QPA_PLATFORMTHEME"));
+
// Get command line params
int j = argc ? 1 : 0;
@@ -1079,15 +1097,23 @@ void QGuiApplicationPrivate::createPlatformIntegration()
continue;
}
QByteArray arg = argv[i];
+ if (arg.startsWith("--"))
+ arg.remove(0, 1);
if (arg == "-platformpluginpath") {
if (++i < argc)
platformPluginPath = QLatin1String(argv[i]);
} else if (arg == "-platform") {
if (++i < argc)
platformName = argv[i];
+ } else if (arg == "-platformtheme") {
+ if (++i < argc)
+ platformThemeName = QString::fromLocal8Bit(argv[i]);
} else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) {
if (++i < argc)
windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
+ } else if (arg == "-qwindowtitle" || (platformName == "xcb" && arg == "-title")) {
+ if (++i < argc)
+ firstWindowTitle = QString::fromLocal8Bit(argv[i]);
} else {
argv[j++] = argv[i];
}
@@ -1098,7 +1124,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
argc = j;
}
- init_platform(QLatin1String(platformName), platformPluginPath, argc, argv);
+ init_platform(QLatin1String(platformName), platformPluginPath, platformThemeName, argc, argv);
}
@@ -1156,6 +1182,8 @@ void QGuiApplicationPrivate::init()
continue;
}
QByteArray arg = argv[i];
+ if (arg.startsWith("--"))
+ arg.remove(0, 1);
if (arg == "-plugin") {
if (++i < argc)
pluginList << argv[i];
@@ -1644,6 +1672,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
ev.setTimestamp(e->timestamp);
+ setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
if (!e->synthetic) {
if (const QScreen *screen = window->screen())
@@ -1657,6 +1686,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
return;
}
+ if (doubleClick && (ev.type() == QEvent::MouseButtonPress)) {
+ // QtBUG-25831, used to suppress delivery in qwidgetwindow.cpp
+ setMouseEventFlags(&ev, ev.flags() | Qt::MouseEventCreatedDoubleClick);
+ }
+
QGuiApplication::sendSpontaneousEvent(window, &ev);
if (!e->synthetic && !ev.isAccepted()
&& !frameStrut
@@ -1694,11 +1728,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
}
if (doubleClick) {
mousePressButton = Qt::NoButton;
- const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
- QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
- button, buttons, e->modifiers);
- dblClickEvent.setTimestamp(e->timestamp);
- QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
+ if (!e->window.isNull()) { // QTBUG-36364, check if window closed in response to press
+ const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
+ QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
+ button, buttons, e->modifiers);
+ dblClickEvent.setTimestamp(e->timestamp);
+ setMouseEventSource(&dblClickEvent, e->source);
+ QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
+ }
}
}
@@ -2114,7 +2151,8 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
synthIt->pos,
synthIt->screenPos,
Qt::NoButton,
- e->modifiers);
+ e->modifiers,
+ Qt::MouseEventSynthesizedByQt);
fake.synthetic = true;
processMouseEvent(&fake);
}
@@ -2634,6 +2672,35 @@ void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
{
}
+/*!
+ \property QGuiApplication::windowIcon
+ \brief the default window icon
+
+ \sa QWindow::setIcon(), {Setting the Application Icon}
+*/
+QIcon QGuiApplication::windowIcon()
+{
+ return QGuiApplicationPrivate::app_icon ? *QGuiApplicationPrivate::app_icon : QIcon();
+}
+
+void QGuiApplication::setWindowIcon(const QIcon &icon)
+{
+ if (!QGuiApplicationPrivate::app_icon)
+ QGuiApplicationPrivate::app_icon = new QIcon();
+ *QGuiApplicationPrivate::app_icon = icon;
+ if (QGuiApplicationPrivate::is_app_running && !QGuiApplicationPrivate::is_app_closing)
+ QGuiApplicationPrivate::self->notifyWindowIconChanged();
+}
+
+void QGuiApplicationPrivate::notifyWindowIconChanged()
+{
+ QEvent ev(QEvent::ApplicationWindowIconChange);
+ const QWindowList list = QGuiApplication::topLevelWindows();
+ for (int i = 0; i < list.size(); ++i)
+ QCoreApplication::sendEvent(list.at(i), &ev);
+}
+
+
/*!
\property QGuiApplication::quitOnLastWindowClosed
@@ -2701,6 +2768,27 @@ bool QGuiApplicationPrivate::shouldQuitInternal(const QWindowList &processedWind
return true;
}
+bool QGuiApplicationPrivate::tryCloseAllWindows()
+{
+ return tryCloseRemainingWindows(QWindowList());
+}
+
+bool QGuiApplicationPrivate::tryCloseRemainingWindows(QWindowList processedWindows)
+{
+ QWindowList list = QGuiApplication::topLevelWindows();
+ for (int i = 0; i < list.size(); ++i) {
+ QWindow *w = list.at(i);
+ if (w->isVisible() && !processedWindows.contains(w)) {
+ if (!w->close())
+ return false;
+ processedWindows.append(w);
+ list = QGuiApplication::topLevelWindows();
+ i = -1;
+ }
+ }
+ return true;
+}
+
/*!
\since 5.2
\fn Qt::ApplicationState QGuiApplication::applicationState()
@@ -2907,23 +2995,8 @@ void QGuiApplicationPrivate::commitData()
Q_Q(QGuiApplication);
is_saving_session = true;
emit q->commitDataRequest(*session_manager);
- if (session_manager->allowsInteraction()) {
- QWindowList done;
- QWindowList list = QGuiApplication::topLevelWindows();
- bool cancelled = false;
- for (int i = 0; !cancelled && i < list.size(); ++i) {
- QWindow* w = list.at(i);
- if (w->isVisible() && !done.contains(w)) {
- cancelled = !w->close();
- if (!cancelled)
- done.append(w);
- list = QGuiApplication::topLevelWindows();
- i = -1;
- }
- }
- if (cancelled)
- session_manager->cancel();
- }
+ if (session_manager->allowsInteraction() && !tryCloseAllWindows())
+ session_manager->cancel();
is_saving_session = false;
}
@@ -3219,9 +3292,18 @@ void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object)
emit q->focusObjectChanged(object);
}
+enum {
+ MouseCapsMask = 0xFF,
+ MouseSourceMaskDst = 0xFF00,
+ MouseSourceMaskSrc = MouseCapsMask,
+ MouseSourceShift = 8,
+ MouseFlagsCapsMask = 0xFF0000,
+ MouseFlagsShift = 16
+};
+
int QGuiApplicationPrivate::mouseEventCaps(QMouseEvent *event)
{
- return event->caps;
+ return event->caps & MouseCapsMask;
}
QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event)
@@ -3231,16 +3313,40 @@ QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event)
void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity)
{
- event->caps = caps;
+ Q_ASSERT(caps <= MouseCapsMask);
+ event->caps &= ~MouseCapsMask;
+ event->caps |= caps & MouseCapsMask;
event->velocity = velocity;
}
-void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other)
+Qt::MouseEventSource QGuiApplicationPrivate::mouseEventSource(const QMouseEvent *event)
+{
+ return Qt::MouseEventSource((event->caps & MouseSourceMaskDst) >> MouseSourceShift);
+}
+
+void QGuiApplicationPrivate::setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source)
+{
+ // Mouse event synthesization status is encoded in the caps field because
+ // QTouchDevice::CapabilityFlag uses only 6 bits from it.
+ int value = source;
+ Q_ASSERT(value <= MouseSourceMaskSrc);
+ event->caps &= ~MouseSourceMaskDst;
+ event->caps |= (value & MouseSourceMaskSrc) << MouseSourceShift;
+}
+
+Qt::MouseEventFlags QGuiApplicationPrivate::mouseEventFlags(const QMouseEvent *event)
{
- event->caps = other->caps;
- event->velocity = other->velocity;
+ return Qt::MouseEventFlags((event->caps & MouseFlagsCapsMask) >> MouseFlagsShift);
}
+void QGuiApplicationPrivate::setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags)
+{
+ // use the 0x00FF0000 byte from caps (containing up to 7 mouse event flags)
+ unsigned int value = flags;
+ Q_ASSERT(value <= Qt::MouseEventFlagMask);
+ event->caps &= ~MouseFlagsCapsMask;
+ event->caps |= (value & Qt::MouseEventFlagMask) << MouseFlagsShift;
+}
#include "moc_qguiapplication.cpp"
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index 0089d48fa6..6d9a4b2376 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -73,6 +73,7 @@ class QStyleHints;
class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
{
Q_OBJECT
+ Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
Q_PROPERTY(QString applicationDisplayName READ applicationDisplayName WRITE setApplicationDisplayName)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection)
Q_PROPERTY(QString platformName READ platformName STORED false)
@@ -93,6 +94,9 @@ public:
static QWindowList topLevelWindows();
static QWindow *topLevelAt(const QPoint &pos);
+ static void setWindowIcon(const QIcon &icon);
+ static QIcon windowIcon();
+
static QString platformName();
static QWindow *modalWindow();
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 218036033e..1ec808ec27 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -92,6 +92,7 @@ public:
virtual bool shouldQuit();
bool shouldQuitInternal(const QWindowList &processedWindows);
+ virtual bool tryCloseAllWindows();
static Qt::KeyboardModifiers modifier_buttons;
static Qt::MouseButtons mouse_buttons;
@@ -171,7 +172,7 @@ public:
{
if (!(alignment & Qt::AlignHorizontal_Mask))
alignment |= Qt::AlignLeft;
- if ((alignment & Qt::AlignAbsolute) == 0 && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
+ if (!(alignment & Qt::AlignAbsolute) && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
if (direction == Qt::RightToLeft)
alignment ^= (Qt::AlignLeft | Qt::AlignRight);
alignment |= Qt::AlignAbsolute;
@@ -187,6 +188,7 @@ public:
static QGuiApplicationPrivate *instance() { return self; }
+ static QIcon *app_icon;
static QString *platform_name;
static QString *displayName;
@@ -231,6 +233,8 @@ public:
static bool noGrab;
QInputMethod *inputMethod;
+ QString firstWindowTitle;
+
static QList<QObject *> generic_plugin_list;
#ifndef QT_NO_SHORTCUT
QShortcutMap shortcutMap;
@@ -268,19 +272,27 @@ public:
static int mouseEventCaps(QMouseEvent *event);
static QVector2D mouseEventVelocity(QMouseEvent *event);
static void setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity);
- static void setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other);
+
+ static Qt::MouseEventSource mouseEventSource(const QMouseEvent *event);
+ static void setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source);
+
+ static Qt::MouseEventFlags mouseEventFlags(const QMouseEvent *event);
+ static void setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags);
const QDrawHelperGammaTables *gammaTables();
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
+ virtual void notifyWindowIconChanged();
+
static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
static void setApplicationState(Qt::ApplicationState state);
protected:
virtual void notifyThemeChanged();
+ bool tryCloseRemainingWindows(QWindowList processedWindows);
#ifndef QT_NO_DRAGANDDROP
virtual void notifyDragStarted(const QDrag *);
#endif // QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index b4e936f818..1739e8c6fd 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -165,7 +165,7 @@ public:
#ifndef QT_NO_ICON
bool delegate(const QIcon *)
{
- return false;
+ return v_cast<QIcon>(Base::m_a)->cacheKey() == v_cast<QIcon>(Base::m_b)->cacheKey();
}
#endif
bool delegate(const void *p) { return Base::delegate(p); }
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp
index 438c169f71..495ea8f6e7 100644
--- a/src/gui/kernel/qinputmethod.cpp
+++ b/src/gui/kernel/qinputmethod.cpp
@@ -45,6 +45,8 @@
#include <qtimer.h>
#include <qpa/qplatforminputcontext_p.h>
+#include <QDebug>
+
QT_BEGIN_NAMESPACE
/*!
@@ -365,6 +367,29 @@ bool QInputMethodPrivate::objectAcceptsInputMethod(QObject *object)
return enabled;
}
+/*!
+ Send \a query to the current focus object with parameters \a argument and return the result.
+ */
+QVariant QInputMethod::queryFocusObject(Qt::InputMethodQuery query, QVariant argument)
+{
+ QVariant retval;
+ QObject *focusObject = qGuiApp->focusObject();
+ if (!focusObject)
+ return retval;
+
+ bool newMethodWorks = QMetaObject::invokeMethod(focusObject, "inputMethodQuery",
+ Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, retval),
+ Q_ARG(Qt::InputMethodQuery, query),
+ Q_ARG(QVariant, argument));
+ if (newMethodWorks)
+ return retval;
+
+ QInputMethodQueryEvent queryEvent(query);
+ QCoreApplication::sendEvent(focusObject, &queryEvent);
+ return queryEvent.value(query);
+}
+
QT_END_NAMESPACE
#include "moc_qinputmethod.cpp"
diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h
index fe6cc3f331..b155b5c0ca 100644
--- a/src/gui/kernel/qinputmethod.h
+++ b/src/gui/kernel/qinputmethod.h
@@ -50,6 +50,7 @@ class QInputMethodPrivate;
class QWindow;
class QRectF;
class QTransform;
+class QInputMethodQueryEvent;
class Q_GUI_EXPORT QInputMethod : public QObject
{
@@ -89,6 +90,8 @@ public:
QLocale locale() const;
Qt::LayoutDirection inputDirection() const;
+ static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument);
+
public Q_SLOTS:
void show();
void hide();
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 5770b76f1f..4569457a20 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1567,7 +1567,7 @@ QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
*/
QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
{
- qAtomicDetach(keysequence.d);
+ qAtomicDetach(keysequence.d);
QList<quint32> list;
s >> list;
for (int i = 0; i < 4; ++i)
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 39dd2a2dfa..7257663799 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -337,31 +337,32 @@ int QOpenGLContextPrivate::maxTextureSize()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
-#if defined(QT_OPENGL_ES)
- return max_texture_size;
-#else
- GLenum proxy = GL_PROXY_TEXTURE_2D;
-
- GLint size;
- GLint next = 64;
- glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
- if (size == 0) {
- return max_texture_size;
- }
- do {
- size = next;
- next = size * 2;
+#ifndef QT_OPENGL_ES
+ if (!QOpenGLFunctions::isES()) {
+ GLenum proxy = GL_PROXY_TEXTURE_2D;
- if (next > max_texture_size)
- break;
+ GLint size;
+ GLint next = 64;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
- } while (next > size);
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
+ if (size == 0) {
+ return max_texture_size;
+ }
+ do {
+ size = next;
+ next = size * 2;
+
+ if (next > max_texture_size)
+ break;
+ glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
+ } while (next > size);
+
+ max_texture_size = size;
+ }
+#endif // QT_OPENGL_ES
- max_texture_size = size;
return max_texture_size;
-#endif
}
/*!
@@ -641,6 +642,13 @@ QOpenGLFunctions *QOpenGLContext::functions() const
*/
QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const
{
+#ifndef QT_OPENGL_ES_2
+ if (QOpenGLFunctions::isES()) {
+ qWarning("versionFunctions: Not supported on dynamic GL ES");
+ return 0;
+ }
+#endif // QT_OPENGL_ES_2
+
Q_D(const QOpenGLContext);
const QSurfaceFormat f = format();
@@ -761,8 +769,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
if (!surface->surfaceHandle())
return false;
-
- if (surface->surfaceType() != QSurface::OpenGLSurface) {
+ if (!surface->supportsOpenGL()) {
qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface" << surface;
return false;
}
@@ -837,9 +844,9 @@ void QOpenGLContext::swapBuffers(QSurface *surface)
return;
}
- if (surface->surfaceType() != QSurface::OpenGLSurface) {
- qWarning() << "QOpenGLContext::swapBuffers() called with non-opengl surface";
- return;
+ if (!surface->supportsOpenGL()) {
+ qWarning() << "QOpenGLContext::swapBuffers() called with non-opengl surface";
+ return;
}
if (surface->surfaceClass() == QSurface::Window
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 5ddd718e69..66a2fdff96 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -62,6 +62,70 @@ QT_BEGIN_NAMESPACE
*/
+static const int buttonRoleLayouts[2][5][14] =
+{
+ // Qt::Horizontal
+ {
+ // WinLayout
+ { QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole,
+ QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::NoRole,
+ QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::ApplyRole,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // MacLayout
+ { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
+ QPlatformDialogHelper::Stretch, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // KdeLayout
+ { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::YesRole,
+ QPlatformDialogHelper::NoRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole,
+ QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::EOL },
+
+ // GnomeLayout
+ { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole,
+ QPlatformDialogHelper::ApplyRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL },
+
+ // MacModelessLayout
+ { QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::Stretch,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL,
+ QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
+ },
+
+ // Qt::Vertical
+ {
+ // WinLayout
+ { QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole,
+ QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ResetRole,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // MacLayout
+ { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::RejectRole,
+ QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole,
+ QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // KdeLayout
+ { QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
+ QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ResetRole,
+ QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL },
+
+ // GnomeLayout
+ { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::RejectRole,
+ QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::Stretch,
+ QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // MacModelessLayout
+ { QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL,
+ QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
+ }
+};
+
QPlatformDialogHelper::QPlatformDialogHelper()
{
}
@@ -603,7 +667,7 @@ class QMessageDialogOptionsPrivate : public QSharedData
public:
QMessageDialogOptionsPrivate() :
icon(QMessageDialogOptions::NoIcon),
- buttons(QMessageDialogOptions::Ok)
+ buttons(QPlatformDialogHelper::Ok)
{}
QString windowTitle;
@@ -611,7 +675,7 @@ public:
QString text;
QString informativeText;
QString detailedText;
- QMessageDialogOptions::StandardButtons buttons;
+ QPlatformDialogHelper::StandardButtons buttons;
};
QMessageDialogOptions::QMessageDialogOptions() : d(new QMessageDialogOptionsPrivate)
@@ -683,17 +747,17 @@ void QMessageDialogOptions::setDetailedText(const QString &detailedText)
d->detailedText = detailedText;
}
-void QMessageDialogOptions::setStandardButtons(StandardButtons buttons)
+void QMessageDialogOptions::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons)
{
d->buttons = buttons;
}
-QMessageDialogOptions::StandardButtons QMessageDialogOptions::standardButtons() const
+QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons() const
{
return d->buttons;
}
-QMessageDialogOptions::ButtonRole QMessageDialogOptions::buttonRole(QMessageDialogOptions::StandardButton button)
+QPlatformDialogHelper::ButtonRole QPlatformDialogHelper::buttonRole(QPlatformDialogHelper::StandardButton button)
{
switch (button) {
case Ok:
@@ -736,6 +800,20 @@ QMessageDialogOptions::ButtonRole QMessageDialogOptions::buttonRole(QMessageDial
return InvalidRole;
}
+const int *QPlatformDialogHelper::buttonLayout(Qt::Orientation orientation, ButtonLayout policy)
+{
+ if (policy == UnknownLayout) {
+#if defined (Q_OS_OSX)
+ policy = MacLayout;
+#elif defined (Q_OS_LINUX) || defined (Q_OS_UNIX)
+ policy = KdeLayout;
+#else
+ policy = WinLayout;
+#endif
+ }
+ return buttonRoleLayouts[orientation == Qt::Vertical][policy];
+}
+
/*!
\class QPlatformMessageDialogHelper
\since 5.0
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 9eeb0a6da4..731440723b 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -82,6 +82,71 @@ public:
};
enum DialogCode { Rejected, Accepted };
+ enum StandardButton {
+ // keep this in sync with QDialogButtonBox::StandardButton and QMessageBox::StandardButton
+ NoButton = 0x00000000,
+ Ok = 0x00000400,
+ Save = 0x00000800,
+ SaveAll = 0x00001000,
+ Open = 0x00002000,
+ Yes = 0x00004000,
+ YesToAll = 0x00008000,
+ No = 0x00010000,
+ NoToAll = 0x00020000,
+ Abort = 0x00040000,
+ Retry = 0x00080000,
+ Ignore = 0x00100000,
+ Close = 0x00200000,
+ Cancel = 0x00400000,
+ Discard = 0x00800000,
+ Help = 0x01000000,
+ Apply = 0x02000000,
+ Reset = 0x04000000,
+ RestoreDefaults = 0x08000000,
+
+
+ FirstButton = Ok, // internal
+ LastButton = RestoreDefaults, // internal
+ LowestBit = 10, // internal: log2(FirstButton)
+ HighestBit = 27 // internal: log2(LastButton)
+ };
+
+ Q_DECLARE_FLAGS(StandardButtons, StandardButton)
+
+ enum ButtonRole {
+ // keep this in sync with QDialogButtonBox::ButtonRole and QMessageBox::ButtonRole
+ // TODO Qt 6: make the enum copies explicit, and make InvalidRole == 0 so that
+ // AcceptRole can be or'ed with flags, and EOL can be the same as InvalidRole (null-termination)
+ InvalidRole = -1,
+ AcceptRole,
+ RejectRole,
+ DestructiveRole,
+ ActionRole,
+ HelpRole,
+ YesRole,
+ NoRole,
+ ResetRole,
+ ApplyRole,
+
+ NRoles,
+
+ RoleMask = 0x0FFFFFFF,
+ AlternateRole = 0x10000000,
+ Stretch = 0x20000000,
+ Reverse = 0x40000000,
+ EOL = InvalidRole
+ };
+
+ enum ButtonLayout {
+ // keep this in sync with QDialogButtonBox::ButtonLayout and QMessageBox::ButtonLayout
+ UnknownLayout = -1,
+ WinLayout,
+ MacLayout,
+ KdeLayout,
+ GnomeLayout,
+ MacModelessLayout
+ };
+
QPlatformDialogHelper();
virtual ~QPlatformDialogHelper();
@@ -95,6 +160,9 @@ public:
static QVariant defaultStyleHint(QPlatformDialogHelper::StyleHint hint);
+ static const int *buttonLayout(Qt::Orientation orientation = Qt::Horizontal, ButtonLayout policy = UnknownLayout);
+ static ButtonRole buttonRole(StandardButton button);
+
Q_SIGNALS:
void accept();
void reject();
@@ -332,50 +400,6 @@ public:
// Keep in sync with QMessageBox::Icon
enum Icon { NoIcon, Information, Warning, Critical, Question };
- enum StandardButton {
- // keep this in sync with QDialogButtonBox::StandardButton and QMessageBox::StandardButton
- NoButton = 0x00000000,
- Ok = 0x00000400,
- Save = 0x00000800,
- SaveAll = 0x00001000,
- Open = 0x00002000,
- Yes = 0x00004000,
- YesToAll = 0x00008000,
- No = 0x00010000,
- NoToAll = 0x00020000,
- Abort = 0x00040000,
- Retry = 0x00080000,
- Ignore = 0x00100000,
- Close = 0x00200000,
- Cancel = 0x00400000,
- Discard = 0x00800000,
- Help = 0x01000000,
- Apply = 0x02000000,
- Reset = 0x04000000,
- RestoreDefaults = 0x08000000,
-
-
- FirstButton = Ok, // internal
- LastButton = RestoreDefaults // internal
- };
-
- Q_DECLARE_FLAGS(StandardButtons, StandardButton)
-
- enum ButtonRole {
- InvalidRole = -1,
- AcceptRole,
- RejectRole,
- DestructiveRole,
- ActionRole,
- HelpRole,
- YesRole,
- NoRole,
- ResetRole,
- ApplyRole,
-
- NRoles
- };
-
QMessageDialogOptions();
QMessageDialogOptions(const QMessageDialogOptions &rhs);
QMessageDialogOptions &operator=(const QMessageDialogOptions &rhs);
@@ -398,10 +422,8 @@ public:
void setDetailedText(const QString &text);
QString detailedText() const;
- void setStandardButtons(StandardButtons buttons);
- StandardButtons standardButtons() const;
-
- static ButtonRole buttonRole(StandardButton button);
+ void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons);
+ QPlatformDialogHelper::StandardButtons standardButtons() const;
private:
QSharedDataPointer<QMessageDialogOptionsPrivate> d;
@@ -417,7 +439,7 @@ public:
void setOptions(const QSharedPointer<QMessageDialogOptions> &options);
Q_SIGNALS:
- void clicked(QMessageDialogOptions::StandardButton button, QMessageDialogOptions::ButtonRole role);
+ void clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
private:
QSharedPointer<QMessageDialogOptions> m_options;
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 26aaf931b3..bec201f3f7 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -359,6 +359,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return true;
case SetFocusOnTouchRelease:
return QVariant(false);
+ case MousePressAndHoldInterval:
+ return QPlatformTheme::defaultThemeHint(QPlatformTheme::MousePressAndHoldInterval);
}
return 0;
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 580fc15233..35ef88949f 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -95,7 +95,8 @@ public:
NonFullScreenWindows,
NativeWidgets,
WindowManagement,
- SyncState
+ SyncState,
+ RasterGLSurface
};
virtual ~QPlatformIntegration() { }
@@ -148,7 +149,8 @@ public:
SynthesizeMouseFromTouchEvents,
PasswordMaskCharacter,
SetFocusOnTouchRelease,
- ShowIsMaximized
+ ShowIsMaximized,
+ MousePressAndHoldInterval
};
virtual QVariant styleHint(StyleHint hint) const;
diff --git a/src/gui/image/qimage_avx.cpp b/src/gui/kernel/qplatformmenu.cpp
index d04ec5b3de..54c340abf9 100644
--- a/src/gui/image/qimage_avx.cpp
+++ b/src/gui/kernel/qplatformmenu.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2012 Intel Corporation
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Martin Graesslin <mgraesslin@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -39,19 +40,16 @@
**
****************************************************************************/
-#include <private/qsimd_p.h>
+#include "qplatformmenu.h"
-#ifdef QT_COMPILER_SUPPORTS_AVX
+#include <qpa/qplatformtheme.h>
+#include <private/qguiapplication_p.h>
-#ifndef __AVX__
-#error "AVX not enabled in this file, cannot proceed"
-#endif
+QT_BEGIN_NAMESPACE
-#define convert_ARGB_to_ARGB_PM_inplace_sse2 convert_ARGB_to_ARGB_PM_inplace_avx
-#include "qimage_sse2.cpp"
+QPlatformMenuItem *QPlatformMenu::createMenuItem() const
+{
+ return QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem();
+}
-#define qt_convert_rgb888_to_rgb32_ssse3 qt_convert_rgb888_to_rgb32_avx
-#define convert_RGB888_to_RGB32_ssse3 convert_RGB888_to_RGB32_avx
-#include "qimage_ssse3.cpp"
-
-#endif
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 3485cc58dd..9326a2b3a1 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -116,6 +116,8 @@ public:
virtual QPlatformMenuItem *menuItemAt(int position) const = 0;
virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0;
+
+ virtual QPlatformMenuItem *createMenuItem() const;
Q_SIGNALS:
void aboutToShow();
void aboutToHide();
diff --git a/src/gui/kernel/qplatformsessionmanager.h b/src/gui/kernel/qplatformsessionmanager.h
index 23b7a62436..80f1bcbaa0 100644
--- a/src/gui/kernel/qplatformsessionmanager.h
+++ b/src/gui/kernel/qplatformsessionmanager.h
@@ -91,10 +91,10 @@ public:
virtual bool isPhase2() const;
virtual void requestPhase2();
-protected:
- virtual void appCommitData();
- virtual void appSaveState();
+ void appCommitData();
+ void appSaveState();
+protected:
QString m_sessionId;
QString m_sessionKey;
diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h
index 2c05b1a7fa..6bad643c7c 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.h
+++ b/src/gui/kernel/qplatformsystemtrayicon.h
@@ -83,6 +83,8 @@ public:
virtual bool isSystemTrayAvailable() const = 0;
virtual bool supportsMessages() const = 0;
+ virtual QPlatformMenu *createMenu() const;
+
Q_SIGNALS:
void activated(QPlatformSystemTrayIcon::ActivationReason reason);
void messageClicked();
diff --git a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp b/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp
index c4cec40a10..bc37f99210 100644
--- a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp
+++ b/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp
@@ -159,6 +159,22 @@ QPlatformSystemTrayIcon::~QPlatformSystemTrayIcon()
\sa activated()
*/
+/*!
+ This method is called in case there is no QPlatformMenu available when
+ updating the menu. This allows the abstraction to provide a menu for the
+ system tray icon even if normally a non-native menu is used.
+
+ The default implementation returns a null pointer.
+
+ \sa updateMenu()
+ \since 5.3
+ */
+
+QPlatformMenu *QPlatformSystemTrayIcon::createMenu() const
+{
+ return Q_NULLPTR;
+}
+
QT_END_NAMESPACE
#include "moc_qplatformsystemtrayicon.cpp"
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 3548ec0199..e12eb318dc 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -51,6 +51,7 @@
#include <private/qiconloader_p.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformdialoghelper.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,9 @@ QT_BEGIN_NAMESPACE
\value MouseDoubleClickInterval (int) Mouse double click interval in ms,
overriding QPlatformIntegration::styleHint.
+ \value MousePressAndHoldInterval (int) Mouse press and hold interval in ms,
+ overriding QPlatformIntegration::styleHint.
+
\value StartDragDistance (int) Start drag distance,
overriding QPlatformIntegration::styleHint.
@@ -425,6 +429,8 @@ QVariant QPlatformTheme::themeHint(ThemeHint hint) const
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::PasswordMaskDelay);
case QPlatformTheme::PasswordMaskCharacter:
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::PasswordMaskCharacter);
+ case QPlatformTheme::MousePressAndHoldInterval:
+ return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::MousePressAndHoldInterval);
default:
return QPlatformTheme::defaultThemeHint(hint);
}
@@ -491,6 +497,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
case DialogSnapToDefaultButton:
case ContextMenuOnMouseRelease:
return QVariant(false);
+ case MousePressAndHoldInterval:
+ return QVariant(800);
}
return QVariant();
}
@@ -620,6 +628,63 @@ QList<QKeySequence> QPlatformTheme::keyBindings(QKeySequence::StandardKey key) c
return list;
}
+/*!
+ Returns the text of a standard \a button.
+
+ \since 5.3
+ \sa QPlatformDialogHelper::StandardButton
+ */
+
+QString QPlatformTheme::standardButtonText(int button) const
+{
+ return QPlatformTheme::defaultStandardButtonText(button);
+}
+
+QString QPlatformTheme::defaultStandardButtonText(int button)
+{
+ switch (button) {
+ case QPlatformDialogHelper::Ok:
+ return QCoreApplication::translate("QPlatformTheme", "OK");
+ case QPlatformDialogHelper::Save:
+ return QCoreApplication::translate("QPlatformTheme", "Save");
+ case QPlatformDialogHelper::SaveAll:
+ return QCoreApplication::translate("QPlatformTheme", "Save All");
+ case QPlatformDialogHelper::Open:
+ return QCoreApplication::translate("QPlatformTheme", "Open");
+ case QPlatformDialogHelper::Yes:
+ return QCoreApplication::translate("QPlatformTheme", "&Yes");
+ case QPlatformDialogHelper::YesToAll:
+ return QCoreApplication::translate("QPlatformTheme", "Yes to &All");
+ case QPlatformDialogHelper::No:
+ return QCoreApplication::translate("QPlatformTheme", "&No");
+ case QPlatformDialogHelper::NoToAll:
+ return QCoreApplication::translate("QPlatformTheme", "N&o to All");
+ case QPlatformDialogHelper::Abort:
+ return QCoreApplication::translate("QPlatformTheme", "Abort");
+ case QPlatformDialogHelper::Retry:
+ return QCoreApplication::translate("QPlatformTheme", "Retry");
+ case QPlatformDialogHelper::Ignore:
+ return QCoreApplication::translate("QPlatformTheme", "Ignore");
+ case QPlatformDialogHelper::Close:
+ return QCoreApplication::translate("QPlatformTheme", "Close");
+ case QPlatformDialogHelper::Cancel:
+ return QCoreApplication::translate("QPlatformTheme", "Cancel");
+ case QPlatformDialogHelper::Discard:
+ return QCoreApplication::translate("QPlatformTheme", "Discard");
+ case QPlatformDialogHelper::Help:
+ return QCoreApplication::translate("QPlatformTheme", "Help");
+ case QPlatformDialogHelper::Apply:
+ return QCoreApplication::translate("QPlatformTheme", "Apply");
+ case QPlatformDialogHelper::Reset:
+ return QCoreApplication::translate("QPlatformTheme", "Reset");
+ case QPlatformDialogHelper::RestoreDefaults:
+ return QCoreApplication::translate("QPlatformTheme", "Restore Defaults");
+ default:
+ break;
+ }
+ return QString();
+}
+
unsigned QPlatformThemePrivate::currentKeyPlatforms()
{
const uint keyboardScheme = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt();
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 5cdec48ca3..205a5bab69 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -107,7 +107,8 @@ public:
IconPixmapSizes,
PasswordMaskCharacter,
DialogSnapToDefaultButton,
- ContextMenuOnMouseRelease
+ ContextMenuOnMouseRelease,
+ MousePressAndHoldInterval
};
enum DialogType {
@@ -295,7 +296,10 @@ public:
virtual QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const;
+ virtual QString standardButtonText(int button) const;
+
static QVariant defaultThemeHint(ThemeHint hint);
+ static QString defaultStandardButtonText(int button);
protected:
explicit QPlatformTheme(QPlatformThemePrivate *priv);
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 954d47f18c..faaf418522 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -127,6 +127,18 @@ QRect QPlatformWindow::geometry() const
return d->rect;
}
+/*!
+ Returns the geometry of a window in 'normal' state
+ (neither maximized, fullscreen nor minimized) for saving geometries to
+ application settings.
+
+ \since 5.3
+*/
+QRect QPlatformWindow::normalGeometry() const
+{
+ return QRect();
+}
+
QMargins QPlatformWindow::frameMargins() const
{
return QMargins();
@@ -509,6 +521,20 @@ static inline const QScreen *effectiveScreen(const QWindow *window)
}
/*!
+ Invalidates the window's surface by releasing its surface buffers.
+
+ Many platforms do not support releasing the surface memory,
+ and the default implementation does nothing.
+
+ The platform window is expected to recreate the surface again if
+ it is needed. For instance, if an OpenGL context is made current
+ on this window.
+ */
+void QPlatformWindow::invalidateSurface()
+{
+}
+
+/*!
Helper function to get initial geometry on windowing systems which do not
do smart positioning and also do not provide a means of centering a
transient window w.r.t. its parent. For example this is useful on Windows
@@ -521,14 +547,13 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
QRect rect(initialGeometry);
- if (rect.isNull()) {
- QSize minimumSize = w->minimumSize();
- if (minimumSize.width() > 0 || minimumSize.height() > 0) {
- rect.setSize(minimumSize);
- } else {
- rect.setWidth(defaultWidth);
- rect.setHeight(defaultHeight);
- }
+ if (rect.width() == 0) {
+ const int minWidth = w->minimumWidth();
+ rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
+ }
+ if (rect.height() == 0) {
+ const int minHeight = w->minimumHeight();
+ rect.setHeight(minHeight > 0 ? minHeight : defaultHeight);
}
if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
&& w->type() != Qt::Popup) {
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 7dfbae036f..39bd8324a0 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -84,6 +84,7 @@ public:
virtual void setGeometry(const QRect &rect);
virtual QRect geometry() const;
+ virtual QRect normalGeometry() const;
virtual QMargins frameMargins() const;
@@ -131,6 +132,8 @@ public:
virtual void setAlertState(bool enabled);
virtual bool isAlertState() const;
+ virtual void invalidateSurface();
+
static QRect initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 2573f76374..70ee631fc8 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -401,8 +401,8 @@ Qt::ScreenOrientations QScreen::orientationUpdateMask() const
The screen orientation represents the physical orientation
of the display. For example, the screen orientation of a mobile device
- will change based on the device is being held, and a desktop display
- might be rotated so that it's in portrait mode.
+ will change based on how it is being held. A change to the orientation
+ might or might not trigger a change to the primary orientation of the screen.
Changes to this property will be filtered by orientationUpdateMask(),
so in order to receive orientation updates the application must first
@@ -435,7 +435,12 @@ qreal QScreen::refreshRate() const
The primary screen orientation is Qt::LandscapeOrientation
if the screen geometry's width is greater than or equal to its
- height, or Qt::PortraitOrientation otherwise.
+ height, or Qt::PortraitOrientation otherwise. This property might
+ change when the screen orientation was changed (i.e. when the
+ display is rotated).
+ The behavior is however platform dependent and can often be specified in
+ an application manifest file.
+
*/
Qt::ScreenOrientation QScreen::primaryOrientation() const
{
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 513e21937e..c915ed3928 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -359,7 +359,7 @@ bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
resetState();
dispatchEvent(e);
default:
- break;
+ break;
}
// If nextState is QKeySequence::ExactMatch && identicals.count == 0
// we've only found disabled shortcuts
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 68eb724454..e1468942af 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -62,6 +62,25 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th,
return QGuiApplicationPrivate::platformIntegration()->styleHint(ih);
}
+class QStyleHintsPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QStyleHints)
+public:
+ inline QStyleHintsPrivate()
+ : m_mouseDoubleClickInterval(-1)
+ , m_startDragDistance(-1)
+ , m_startDragTime(-1)
+ , m_keyboardInputInterval(-1)
+ , m_cursorFlashTime(-1)
+ {}
+
+ int m_mouseDoubleClickInterval;
+ int m_startDragDistance;
+ int m_startDragTime;
+ int m_keyboardInputInterval;
+ int m_cursorFlashTime;
+};
+
/*!
\class QStyleHints
\since 5.0
@@ -80,17 +99,55 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th,
\sa QGuiApplication::styleHints(), QPlatformTheme
*/
QStyleHints::QStyleHints()
- : QObject()
+ : QObject(*new QStyleHintsPrivate(), 0)
{
}
/*!
+ Sets the \a mouseDoubleClickInterval.
+ \internal
+ \sa mouseDoubleClickInterval()
+ \since 5.3
+*/
+void QStyleHints::setMouseDoubleClickInterval(int mouseDoubleClickInterval)
+{
+ Q_D(QStyleHints);
+ d->m_mouseDoubleClickInterval = mouseDoubleClickInterval;
+}
+
+/*!
Returns the time limit in milliseconds that distinguishes a double click
from two consecutive mouse clicks.
*/
int QStyleHints::mouseDoubleClickInterval() const
{
- return themeableHint(QPlatformTheme::MouseDoubleClickInterval, QPlatformIntegration::MouseDoubleClickInterval).toInt();
+ Q_D(const QStyleHints);
+ return d->m_mouseDoubleClickInterval >= 0 ?
+ d->m_mouseDoubleClickInterval :
+ themeableHint(QPlatformTheme::MouseDoubleClickInterval, QPlatformIntegration::MouseDoubleClickInterval).toInt();
+}
+
+/*!
+ Returns the time limit in milliseconds that activates
+ a press and hold.
+
+ \since 5.3
+*/
+int QStyleHints::mousePressAndHoldInterval() const
+{
+ return themeableHint(QPlatformTheme::MousePressAndHoldInterval, QPlatformIntegration::MousePressAndHoldInterval).toInt();
+}
+
+/*!
+ Sets the \a startDragDistance.
+ \internal
+ \sa startDragDistance()
+ \since 5.3
+*/
+void QStyleHints::setStartDragDistance(int startDragDistance)
+{
+ Q_D(QStyleHints);
+ d->m_startDragDistance = startDragDistance;
}
/*!
@@ -112,7 +169,22 @@ int QStyleHints::mouseDoubleClickInterval() const
*/
int QStyleHints::startDragDistance() const
{
- return themeableHint(QPlatformTheme::StartDragDistance, QPlatformIntegration::StartDragDistance).toInt();
+ Q_D(const QStyleHints);
+ return d->m_startDragDistance >= 0 ?
+ d->m_startDragDistance :
+ themeableHint(QPlatformTheme::StartDragDistance, QPlatformIntegration::StartDragDistance).toInt();
+}
+
+/*!
+ Sets the \a startDragDragTime.
+ \internal
+ \sa startDragTime()
+ \since 5.3
+*/
+void QStyleHints::setStartDragTime(int startDragTime)
+{
+ Q_D(QStyleHints);
+ d->m_startDragTime = startDragTime;
}
/*!
@@ -127,7 +199,10 @@ int QStyleHints::startDragDistance() const
*/
int QStyleHints::startDragTime() const
{
- return themeableHint(QPlatformTheme::StartDragTime, QPlatformIntegration::StartDragTime).toInt();
+ Q_D(const QStyleHints);
+ return d->m_startDragTime >= 0 ?
+ d->m_startDragTime :
+ themeableHint(QPlatformTheme::StartDragTime, QPlatformIntegration::StartDragTime).toInt();
}
/*!
@@ -143,12 +218,27 @@ int QStyleHints::startDragVelocity() const
}
/*!
+ Sets the \a keyboardInputInterval.
+ \internal
+ \sa keyboardInputInterval()
+ \since 5.3
+*/
+void QStyleHints::setKeyboardInputInterval(int keyboardInputInterval)
+{
+ Q_D(QStyleHints);
+ d->m_keyboardInputInterval = keyboardInputInterval;
+}
+
+/*!
Returns the time limit, in milliseconds, that distinguishes a key press
from two consecutive key presses.
*/
int QStyleHints::keyboardInputInterval() const
{
- return themeableHint(QPlatformTheme::KeyboardInputInterval, QPlatformIntegration::KeyboardInputInterval).toInt();
+ Q_D(const QStyleHints);
+ return d->m_keyboardInputInterval >= 0 ?
+ d->m_keyboardInputInterval :
+ themeableHint(QPlatformTheme::KeyboardInputInterval, QPlatformIntegration::KeyboardInputInterval).toInt();
}
/*!
@@ -161,6 +251,18 @@ int QStyleHints::keyboardAutoRepeatRate() const
}
/*!
+ Sets the \a cursorFlashTime.
+ \internal
+ \sa cursorFlashTime()
+ \since 5.3
+*/
+void QStyleHints::setCursorFlashTime(int cursorFlashTime)
+{
+ Q_D(QStyleHints);
+ d->m_cursorFlashTime = cursorFlashTime;
+}
+
+/*!
Returns the text cursor's flash (blink) time in milliseconds.
The flash time is the time used to display, invert and restore the
@@ -169,7 +271,10 @@ int QStyleHints::keyboardAutoRepeatRate() const
*/
int QStyleHints::cursorFlashTime() const
{
- return themeableHint(QPlatformTheme::CursorFlashTime, QPlatformIntegration::CursorFlashTime).toInt();
+ Q_D(const QStyleHints);
+ return d->m_cursorFlashTime >= 0 ?
+ d->m_cursorFlashTime :
+ themeableHint(QPlatformTheme::CursorFlashTime, QPlatformIntegration::CursorFlashTime).toInt();
}
/*!
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index a0facd5f94..33fbe2965e 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -48,17 +48,25 @@ QT_BEGIN_NAMESPACE
class QPlatformIntegration;
+class QStyleHintsPrivate;
class Q_GUI_EXPORT QStyleHints : public QObject
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QStyleHints)
public:
+ void setMouseDoubleClickInterval(int mouseDoubleClickInterval);
int mouseDoubleClickInterval() const;
+ int mousePressAndHoldInterval() const;
+ void setStartDragDistance(int startDragDistance);
int startDragDistance() const;
+ void setStartDragTime(int startDragTime);
int startDragTime() const;
int startDragVelocity() const;
+ void setKeyboardInputInterval(int keyboardInputInterval);
int keyboardInputInterval() const;
int keyboardAutoRepeatRate() const;
+ void setCursorFlashTime(int cursorFlashTime);
int cursorFlashTime() const;
bool showIsFullScreen() const;
int passwordMaskDelay() const;
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index a943639d5f..a27bdaccde 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -74,6 +74,9 @@ QT_BEGIN_NAMESPACE
a software rasterizer like Qt's raster paint engine.
\value OpenGLSurface The surface is an OpenGL compatible surface and can be used
in conjunction with QOpenGLContext.
+ \value RasterGLSurface The surface can be rendered to using a software rasterizer,
+ and also supports OpenGL. This surface type is intended for internal Qt use, and
+ requires the use of private API.
*/
@@ -84,6 +87,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ Returns true if the surface is OpenGL compatible and can be used in
+ conjunction with QOpenGLContext; otherwise returns false.
+
+ \since 5.3
+*/
+
+bool QSurface::supportsOpenGL() const
+{
+ SurfaceType type = surfaceType();
+ return type == OpenGLSurface || type == RasterGLSurface;
+}
+
+/*!
\fn QPlatformSurface *QSurface::surfaceHandle() const
Returns a handle to the platform-specific implementation of the surface.
diff --git a/src/gui/kernel/qsurface.h b/src/gui/kernel/qsurface.h
index 8dbc230c10..c4a3276372 100644
--- a/src/gui/kernel/qsurface.h
+++ b/src/gui/kernel/qsurface.h
@@ -64,7 +64,8 @@ public:
enum SurfaceType {
RasterSurface,
- OpenGLSurface
+ OpenGLSurface,
+ RasterGLSurface
};
virtual ~QSurface();
@@ -75,6 +76,7 @@ public:
virtual QPlatformSurface *surfaceHandle() const = 0;
virtual SurfaceType surfaceType() const = 0;
+ bool supportsOpenGL() const;
virtual QSize size() const = 0;
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index fe5615d394..2b6cb2d949 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -72,6 +72,7 @@ public:
, profile(QSurfaceFormat::NoProfile)
, major(2)
, minor(0)
+ , swapInterval(1) // default to vsync
{
}
@@ -89,7 +90,8 @@ public:
renderableType(other->renderableType),
profile(other->profile),
major(other->major),
- minor(other->minor)
+ minor(other->minor),
+ swapInterval(other->swapInterval)
{
}
@@ -107,6 +109,7 @@ public:
QSurfaceFormat::OpenGLContextProfile profile;
int major;
int minor;
+ int swapInterval;
};
/*!
@@ -311,9 +314,15 @@ void QSurfaceFormat::setSamples(int numSamples)
}
/*!
- Sets the format option to \a opt.
+ \obsolete
+ \overload
- \sa testOption()
+ Use setOption(QSurfaceFormat::FormatOption, bool) or setOptions() instead.
+
+ Sets the format options to the OR combination of \a opt and the
+ current format options.
+
+ \sa options(), testOption()
*/
void QSurfaceFormat::setOption(QSurfaceFormat::FormatOptions opt)
{
@@ -325,7 +334,13 @@ void QSurfaceFormat::setOption(QSurfaceFormat::FormatOptions opt)
}
/*!
- Returns \c true if format option \a opt is set; otherwise returns \c false.
+ \obsolete
+ \overload
+
+ Use testOption(QSurfaceFormat::FormatOption) instead.
+
+ Returns \c true if any of the options in \a opt is currently set
+ on this object; otherwise returns false.
\sa setOption()
*/
@@ -335,6 +350,63 @@ bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const
}
/*!
+ \since 5.3
+
+ Sets the format options to \a options.
+
+ \sa options(), testOption()
+*/
+void QSurfaceFormat::setOptions(QSurfaceFormat::FormatOptions options)
+{
+ if (int(d->opts) != int(options)) {
+ detach();
+ d->opts = options;
+ }
+}
+
+/*!
+ \since 5.3
+
+ Sets the format option \a option if \a on is true; otherwise, clears the option.
+
+ \sa setOptions(), options(), testOption()
+*/
+void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on)
+{
+ if (testOption(option) == on)
+ return;
+ detach();
+ if (on)
+ d->opts |= option;
+ else
+ d->opts &= ~option;
+}
+
+/*!
+ \since 5.3
+
+ Returns true if the format option \a option is set; otherwise returns false.
+
+ \sa options(), testOption()
+*/
+bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const
+{
+ return d->opts & option;
+}
+
+/*!
+ \since 5.3
+
+ Returns the currently set format options.
+
+ \sa setOption(), setOptions(), testOption()
+*/
+QSurfaceFormat::FormatOptions QSurfaceFormat::options() const
+{
+ return d->opts;
+}
+
+/*!
Set the minimum depth buffer size to \a size.
\sa depthBufferSize()
@@ -607,6 +679,46 @@ void QSurfaceFormat::setVersion(int major, int minor)
}
/*!
+ Sets the preferred swap interval. The swap interval specifies the
+ minimum number of video frames that are displayed before a buffer
+ swap occurs. This can be used to sync the GL drawing into a window
+ to the vertical refresh of the screen.
+
+ Setting an \a interval value of 0 will turn the vertical refresh
+ syncing off, any value higher than 0 will turn the vertical
+ syncing on. Setting \a interval to a higher value, for example 10,
+ results in having 10 vertical retraces between every buffer swap.
+
+ The default interval is 1.
+
+ Changing the swap interval may not be supported by the underlying
+ platform. In this case, the request will be silently ignored.
+
+ \since 5.3
+
+ \sa swapInterval()
+ */
+void QSurfaceFormat::setSwapInterval(int interval)
+{
+ if (d->swapInterval != interval) {
+ detach();
+ d->swapInterval = interval;
+ }
+}
+
+/*!
+ Returns the swap interval.
+
+ \since 5.3
+
+ \sa setSwapInterval()
+*/
+int QSurfaceFormat::swapInterval() const
+{
+ return d->swapInterval;
+}
+
+/*!
Returns \c true if all the options of the two QSurfaceFormat objects
\a a and \a b are equal.
@@ -625,7 +737,8 @@ bool operator==(const QSurfaceFormat& a, const QSurfaceFormat& b)
&& a.d->swapBehavior == b.d->swapBehavior
&& a.d->profile == b.d->profile
&& a.d->major == b.d->major
- && a.d->minor == b.d->minor);
+ && a.d->minor == b.d->minor
+ && a.d->swapInterval == b.d->swapInterval);
}
/*!
@@ -655,6 +768,7 @@ QDebug operator<<(QDebug dbg, const QSurfaceFormat &f)
<< ", stencilBufferSize " << d->stencilSize
<< ", samples " << d->numSamples
<< ", swapBehavior " << d->swapBehavior
+ << ", swapInterval " << d->swapInterval
<< ", profile " << d->profile
<< ')';
diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h
index 7c3c846df3..453beac5cd 100644
--- a/src/gui/kernel/qsurfaceformat.h
+++ b/src/gui/kernel/qsurfaceformat.h
@@ -127,8 +127,16 @@ public:
bool stereo() const;
void setStereo(bool enable);
- void setOption(QSurfaceFormat::FormatOptions opt);
- bool testOption(QSurfaceFormat::FormatOptions opt) const;
+ QT_DEPRECATED void setOption(QSurfaceFormat::FormatOptions opt);
+ QT_DEPRECATED bool testOption(QSurfaceFormat::FormatOptions opt) const;
+
+ void setOptions(QSurfaceFormat::FormatOptions options);
+ void setOption(FormatOption option, bool on = true);
+ bool testOption(FormatOption option) const;
+ QSurfaceFormat::FormatOptions options() const;
+
+ int swapInterval() const;
+ void setSwapInterval(int interval);
private:
QSurfaceFormatPrivate *d;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 19bd947c2c..51548aa371 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -163,9 +163,7 @@ QWindow::QWindow(QScreen *targetScreen)
//if your applications aborts here, then chances are your creating a QWindow before the
//screen list is populated.
Q_ASSERT(d->screen);
-
- connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
- QGuiApplicationPrivate::window_list.prepend(this);
+ d->init();
}
/*!
@@ -188,8 +186,7 @@ QWindow::QWindow(QWindow *parent)
d->screen = parent->screen();
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
- connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
- QGuiApplicationPrivate::window_list.prepend(this);
+ d->init();
}
/*!
@@ -214,8 +211,7 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent)
d->screen = parent->screen();
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
- connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
- QGuiApplicationPrivate::window_list.prepend(this);
+ d->init();
}
/*!
@@ -233,6 +229,13 @@ QWindow::~QWindow()
destroy();
}
+void QWindowPrivate::init()
+{
+ Q_Q(QWindow);
+ QObject::connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*)));
+ QGuiApplicationPrivate::window_list.prepend(q);
+}
+
/*!
\enum QWindow::Visibility
\since 5.1
@@ -429,6 +432,14 @@ void QWindow::setVisible(bool visible)
// remove posted quit events when showing a new window
QCoreApplication::removePostedEvents(qApp, QEvent::Quit);
+ if (type() == Qt::Window) {
+ QString &firstWindowTitle = QGuiApplicationPrivate::instance()->firstWindowTitle;
+ if (!firstWindowTitle.isEmpty()) {
+ setTitle(firstWindowTitle);
+ firstWindowTitle = QString();
+ }
+ }
+
QShowEvent showEvent;
QGuiApplication::sendEvent(this, &showEvent);
}
@@ -765,6 +776,8 @@ void QWindow::setIcon(const QIcon &icon)
d->windowIcon = icon;
if (d->platformWindow)
d->platformWindow->setWindowIcon(icon);
+ QEvent e(QEvent::WindowIconChange);
+ QCoreApplication::sendEvent(this, &e);
}
/*!
@@ -775,6 +788,8 @@ void QWindow::setIcon(const QIcon &icon)
QIcon QWindow::icon() const
{
Q_D(const QWindow);
+ if (d->windowIcon.isNull())
+ return QGuiApplication::windowIcon();
return d->windowIcon;
}
@@ -1929,6 +1944,10 @@ bool QWindow::event(QEvent *ev)
hideEvent(static_cast<QHideEvent *>(ev));
break;
+ case QEvent::ApplicationWindowIconChange:
+ setIcon(icon());
+ break;
+
case QEvent::WindowStateChange: {
Q_D(QWindow);
emit windowStateChanged(d->windowState);
@@ -2147,6 +2166,26 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed()
}
+QWindow *QWindowPrivate::topLevelWindow() const
+{
+ Q_Q(const QWindow);
+
+ QWindow *window = const_cast<QWindow *>(q);
+
+ while (window) {
+ QWindow *parent = window->parent();
+ if (!parent)
+ parent = window->transientParent();
+
+ if (!parent)
+ break;
+
+ window = parent;
+ }
+
+ return window;
+}
+
/*!
Creates a local representation of a window created by another process or by
using native libraries below Qt.
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 8d8fca3ce6..4305edea51 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -108,6 +108,8 @@ public:
{
}
+ void init();
+
void maybeQuitOnLastWindowClosed();
#ifndef QT_NO_CURSOR
void setCursor(const QCursor *c = 0);
@@ -122,6 +124,8 @@ public:
return offset;
}
+ QWindow *topLevelWindow() const;
+
virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; }
void updateVisibility();
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 8ef275a27c..49ff8bcb0d 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -164,31 +164,35 @@ void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted)
\a w == 0 means that the event is in global coords only, \a local will be ignored in this case
*/
-void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleMouseEvent(w, time, local, global, b, mods);
+ handleMouseEvent(w, time, local, global, b, mods, source);
}
-void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
- new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods);
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleFrameStrutMouseEvent(w, time, local, global, b, mods);
+ handleFrameStrutMouseEvent(w, time, local, global, b, mods, source);
}
-void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
QWindowSystemInterfacePrivate::FrameStrutMouse,
- local, global, b, mods);
+ local, global, b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index d1c3c8e249..71feb1bcb7 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -73,10 +73,18 @@ class QPlatformDropQtResponse;
class Q_GUI_EXPORT QWindowSystemInterface
{
public:
- static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
+ static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
+ static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
+ static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
+ static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
static bool tryHandleShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
const QString & text = QString(), bool autorep = false, ushort count = 1);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 42dbe7509e..8e503bbf3d 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -209,14 +209,17 @@ public:
class MouseEvent : public InputEvent {
public:
MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global,
- Qt::MouseButtons b, Qt::KeyboardModifiers mods)
- : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b) { }
+ Qt::MouseButtons b, Qt::KeyboardModifiers mods,
+ Qt::MouseEventSource src = Qt::MouseEventNotSynthesized)
+ : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b), source(src) { }
MouseEvent(QWindow * w, ulong time, EventType t, const QPointF & local, const QPointF & global,
- Qt::MouseButtons b, Qt::KeyboardModifiers mods)
- : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b) { }
+ Qt::MouseButtons b, Qt::KeyboardModifiers mods,
+ Qt::MouseEventSource src = Qt::MouseEventNotSynthesized)
+ : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b), source(src) { }
QPointF localPos;
QPointF globalPos;
Qt::MouseButtons buttons;
+ Qt::MouseEventSource source;
};
class WheelEvent : public InputEvent {
diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h
index 55e606ec35..649d45d477 100644
--- a/src/gui/math3d/qvector2d.h
+++ b/src/gui/math3d/qvector2d.h
@@ -57,10 +57,10 @@ class QVariant;
class Q_GUI_EXPORT QVector2D
{
public:
- QVector2D();
- QVector2D(float xpos, float ypos);
- explicit QVector2D(const QPoint& point);
- explicit QVector2D(const QPointF& point);
+ Q_DECL_CONSTEXPR QVector2D();
+ Q_DECL_CONSTEXPR QVector2D(float xpos, float ypos);
+ Q_DECL_CONSTEXPR explicit QVector2D(const QPoint& point);
+ Q_DECL_CONSTEXPR explicit QVector2D(const QPointF& point);
#ifndef QT_NO_VECTOR3D
explicit QVector2D(const QVector3D& vector);
#endif
@@ -70,8 +70,8 @@ public:
bool isNull() const;
- float x() const;
- float y() const;
+ Q_DECL_CONSTEXPR float x() const;
+ Q_DECL_CONSTEXPR float y() const;
void setX(float x);
void setY(float y);
@@ -80,7 +80,12 @@ public:
float operator[](int i) const;
float length() const;
+#ifdef QT_BUILD_GUI_LIB
float lengthSquared() const;
+#else
+ Q_DECL_CONSTEXPR inline float lengthSquared() const
+ { return xp * xp + yp * yp; }
+#endif
QVector2D normalized() const;
void normalize();
@@ -94,19 +99,24 @@ public:
QVector2D &operator*=(const QVector2D &vector);
QVector2D &operator/=(float divisor);
+#ifdef QT_BUILD_GUI_LIB
static float dotProduct(const QVector2D& v1, const QVector2D& v2);
+#else
+ Q_DECL_CONSTEXPR inline static float dotProduct(const QVector2D& v1, const QVector2D& v2)
+ { return v1.xp * v2.xp + v1.yp * v2.yp; }
+#endif
- friend inline bool operator==(const QVector2D &v1, const QVector2D &v2);
- friend inline bool operator!=(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator*(float factor, const QVector2D &vector);
- friend inline const QVector2D operator*(const QVector2D &vector, float factor);
- friend inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator-(const QVector2D &vector);
- friend inline const QVector2D operator/(const QVector2D &vector, float divisor);
+ Q_DECL_CONSTEXPR friend inline bool operator==(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline bool operator!=(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator*(float factor, const QVector2D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator*(const QVector2D &vector, float factor);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator-(const QVector2D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator/(const QVector2D &vector, float divisor);
- friend inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2);
+ Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2);
#ifndef QT_NO_VECTOR3D
QVector3D toVector3D() const;
@@ -115,8 +125,8 @@ public:
QVector4D toVector4D() const;
#endif
- QPoint toPoint() const;
- QPointF toPointF() const;
+ Q_DECL_CONSTEXPR QPoint toPoint() const;
+ Q_DECL_CONSTEXPR QPointF toPointF() const;
operator QVariant() const;
@@ -129,21 +139,21 @@ private:
Q_DECLARE_TYPEINFO(QVector2D, Q_MOVABLE_TYPE);
-inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {}
-inline QVector2D::QVector2D(float xpos, float ypos) : xp(xpos), yp(ypos) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(float xpos, float ypos) : xp(xpos), yp(ypos) {}
-inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {}
-inline QVector2D::QVector2D(const QPointF& point) : xp(point.x()), yp(point.y()) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPointF& point) : xp(point.x()), yp(point.y()) {}
inline bool QVector2D::isNull() const
{
return qIsNull(xp) && qIsNull(yp);
}
-inline float QVector2D::x() const { return xp; }
-inline float QVector2D::y() const { return yp; }
+Q_DECL_CONSTEXPR inline float QVector2D::x() const { return xp; }
+Q_DECL_CONSTEXPR inline float QVector2D::y() const { return yp; }
inline void QVector2D::setX(float aX) { xp = aX; }
inline void QVector2D::setY(float aY) { yp = aY; }
@@ -195,62 +205,62 @@ inline QVector2D &QVector2D::operator/=(float divisor)
return *this;
}
-inline bool operator==(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline bool operator==(const QVector2D &v1, const QVector2D &v2)
{
return v1.xp == v2.xp && v1.yp == v2.yp;
}
-inline bool operator!=(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline bool operator!=(const QVector2D &v1, const QVector2D &v2)
{
return v1.xp != v2.xp || v1.yp != v2.yp;
}
-inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
{
return QVector2D(v1.xp + v2.xp, v1.yp + v2.yp);
}
-inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
{
return QVector2D(v1.xp - v2.xp, v1.yp - v2.yp);
}
-inline const QVector2D operator*(float factor, const QVector2D &vector)
+Q_DECL_CONSTEXPR inline const QVector2D operator*(float factor, const QVector2D &vector)
{
return QVector2D(vector.xp * factor, vector.yp * factor);
}
-inline const QVector2D operator*(const QVector2D &vector, float factor)
+Q_DECL_CONSTEXPR inline const QVector2D operator*(const QVector2D &vector, float factor)
{
return QVector2D(vector.xp * factor, vector.yp * factor);
}
-inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
{
return QVector2D(v1.xp * v2.xp, v1.yp * v2.yp);
}
-inline const QVector2D operator-(const QVector2D &vector)
+Q_DECL_CONSTEXPR inline const QVector2D operator-(const QVector2D &vector)
{
return QVector2D(-vector.xp, -vector.yp);
}
-inline const QVector2D operator/(const QVector2D &vector, float divisor)
+Q_DECL_CONSTEXPR inline const QVector2D operator/(const QVector2D &vector, float divisor)
{
return QVector2D(vector.xp / divisor, vector.yp / divisor);
}
-inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)
+Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)
{
return qFuzzyCompare(v1.xp, v2.xp) && qFuzzyCompare(v1.yp, v2.yp);
}
-inline QPoint QVector2D::toPoint() const
+Q_DECL_CONSTEXPR inline QPoint QVector2D::toPoint() const
{
return QPoint(qRound(xp), qRound(yp));
}
-inline QPointF QVector2D::toPointF() const
+Q_DECL_CONSTEXPR inline QPointF QVector2D::toPointF() const
{
return QPointF(qreal(xp), qreal(yp));
}
diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h
index c880930935..c5506bf1ac 100644
--- a/src/gui/math3d/qvector3d.h
+++ b/src/gui/math3d/qvector3d.h
@@ -57,10 +57,11 @@ class QVector4D;
class Q_GUI_EXPORT QVector3D
{
public:
- QVector3D();
- QVector3D(float xpos, float ypos, float zpos);
- explicit QVector3D(const QPoint& point);
- explicit QVector3D(const QPointF& point);
+ Q_DECL_CONSTEXPR QVector3D();
+ Q_DECL_CONSTEXPR QVector3D(float xpos, float ypos, float zpos) : xp(xpos), yp(ypos), zp(zpos) {}
+
+ Q_DECL_CONSTEXPR explicit QVector3D(const QPoint& point);
+ Q_DECL_CONSTEXPR explicit QVector3D(const QPointF& point);
#ifndef QT_NO_VECTOR2D
QVector3D(const QVector2D& vector);
QVector3D(const QVector2D& vector, float zpos);
@@ -71,9 +72,9 @@ public:
bool isNull() const;
- float x() const;
- float y() const;
- float z() const;
+ Q_DECL_CONSTEXPR float x() const;
+ Q_DECL_CONSTEXPR float y() const;
+ Q_DECL_CONSTEXPR float z() const;
void setX(float x);
void setY(float y);
@@ -94,8 +95,17 @@ public:
QVector3D &operator*=(const QVector3D& vector);
QVector3D &operator/=(float divisor);
+#ifdef QT_BUILD_GUI_LIB
static float dotProduct(const QVector3D& v1, const QVector3D& v2);
static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2);
+#else
+ Q_DECL_CONSTEXPR inline static float dotProduct(const QVector3D& v1, const QVector3D& v2)
+ { return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; }
+ Q_DECL_CONSTEXPR inline static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2)
+ { return QVector3D(v1.yp * v2.zp - v1.zp * v2.yp,
+ v1.zp * v2.xp - v1.xp * v2.zp,
+ v1.xp * v2.yp - v1.yp * v2.xp); }
+#endif
static QVector3D normal(const QVector3D& v1, const QVector3D& v2);
static QVector3D normal
(const QVector3D& v1, const QVector3D& v2, const QVector3D& v3);
@@ -105,17 +115,17 @@ public:
float distanceToPlane(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const;
float distanceToLine(const QVector3D& point, const QVector3D& direction) const;
- friend inline bool operator==(const QVector3D &v1, const QVector3D &v2);
- friend inline bool operator!=(const QVector3D &v1, const QVector3D &v2);
- friend inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2);
- friend inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2);
- friend inline const QVector3D operator*(float factor, const QVector3D &vector);
- friend inline const QVector3D operator*(const QVector3D &vector, float factor);
- friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2);
- friend inline const QVector3D operator-(const QVector3D &vector);
- friend inline const QVector3D operator/(const QVector3D &vector, float divisor);
+ Q_DECL_CONSTEXPR friend inline bool operator==(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline bool operator!=(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator*(float factor, const QVector3D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator*(const QVector3D &vector, float factor);
+ Q_DECL_CONSTEXPR friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator-(const QVector3D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator/(const QVector3D &vector, float divisor);
- friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2);
+ Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2);
#ifndef QT_NO_VECTOR2D
QVector2D toVector2D() const;
@@ -124,8 +134,8 @@ public:
QVector4D toVector4D() const;
#endif
- QPoint toPoint() const;
- QPointF toPointF() const;
+ Q_DECL_CONSTEXPR QPoint toPoint() const;
+ Q_DECL_CONSTEXPR QPointF toPointF() const;
operator QVariant() const;
@@ -142,22 +152,20 @@ private:
Q_DECLARE_TYPEINFO(QVector3D, Q_MOVABLE_TYPE);
-inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {}
-
-inline QVector3D::QVector3D(float xpos, float ypos, float zpos) : xp(xpos), yp(ypos), zp(zpos) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {}
-inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
-inline QVector3D::QVector3D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
inline bool QVector3D::isNull() const
{
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp);
}
-inline float QVector3D::x() const { return xp; }
-inline float QVector3D::y() const { return yp; }
-inline float QVector3D::z() const { return zp; }
+Q_DECL_CONSTEXPR inline float QVector3D::x() const { return xp; }
+Q_DECL_CONSTEXPR inline float QVector3D::y() const { return yp; }
+Q_DECL_CONSTEXPR inline float QVector3D::z() const { return zp; }
inline void QVector3D::setX(float aX) { xp = aX; }
inline void QVector3D::setY(float aY) { yp = aY; }
@@ -215,64 +223,64 @@ inline QVector3D &QVector3D::operator/=(float divisor)
return *this;
}
-inline bool operator==(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline bool operator==(const QVector3D &v1, const QVector3D &v2)
{
return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp;
}
-inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
{
return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp;
}
-inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
{
return QVector3D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp);
}
-inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
{
return QVector3D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp);
}
-inline const QVector3D operator*(float factor, const QVector3D &vector)
+Q_DECL_CONSTEXPR inline const QVector3D operator*(float factor, const QVector3D &vector)
{
return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
}
-inline const QVector3D operator*(const QVector3D &vector, float factor)
+Q_DECL_CONSTEXPR inline const QVector3D operator*(const QVector3D &vector, float factor)
{
return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
}
-inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
+Q_DECL_CONSTEXPR inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
{
return QVector3D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp);
}
-inline const QVector3D operator-(const QVector3D &vector)
+Q_DECL_CONSTEXPR inline const QVector3D operator-(const QVector3D &vector)
{
return QVector3D(-vector.xp, -vector.yp, -vector.zp);
}
-inline const QVector3D operator/(const QVector3D &vector, float divisor)
+Q_DECL_CONSTEXPR inline const QVector3D operator/(const QVector3D &vector, float divisor)
{
return QVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor);
}
-inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)
+Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)
{
return qFuzzyCompare(v1.xp, v2.xp) &&
qFuzzyCompare(v1.yp, v2.yp) &&
qFuzzyCompare(v1.zp, v2.zp);
}
-inline QPoint QVector3D::toPoint() const
+Q_DECL_CONSTEXPR inline QPoint QVector3D::toPoint() const
{
return QPoint(qRound(xp), qRound(yp));
}
-inline QPointF QVector3D::toPointF() const
+Q_DECL_CONSTEXPR inline QPointF QVector3D::toPointF() const
{
return QPointF(qreal(xp), qreal(yp));
}
diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h
index 810380b805..1256f384a0 100644
--- a/src/gui/math3d/qvector4d.h
+++ b/src/gui/math3d/qvector4d.h
@@ -57,10 +57,10 @@ class QVector3D;
class Q_GUI_EXPORT QVector4D
{
public:
- QVector4D();
- QVector4D(float xpos, float ypos, float zpos, float wpos);
- explicit QVector4D(const QPoint& point);
- explicit QVector4D(const QPointF& point);
+ Q_DECL_CONSTEXPR QVector4D();
+ Q_DECL_CONSTEXPR QVector4D(float xpos, float ypos, float zpos, float wpos);
+ Q_DECL_CONSTEXPR explicit QVector4D(const QPoint& point);
+ Q_DECL_CONSTEXPR explicit QVector4D(const QPointF& point);
#ifndef QT_NO_VECTOR2D
QVector4D(const QVector2D& vector);
QVector4D(const QVector2D& vector, float zpos, float wpos);
@@ -72,10 +72,10 @@ public:
bool isNull() const;
- float x() const;
- float y() const;
- float z() const;
- float w() const;
+ Q_DECL_CONSTEXPR float x() const;
+ Q_DECL_CONSTEXPR float y() const;
+ Q_DECL_CONSTEXPR float z() const;
+ Q_DECL_CONSTEXPR float w() const;
void setX(float x);
void setY(float y);
@@ -86,7 +86,12 @@ public:
float operator[](int i) const;
float length() const;
+#ifdef QT_BUILD_GUI_LIB
float lengthSquared() const;
+#else
+ Q_DECL_CONSTEXPR inline float lengthSquared() const
+ { return xp * xp + yp * yp + zp * zp + wp * wp; }
+#endif
QVector4D normalized() const;
void normalize();
@@ -97,19 +102,24 @@ public:
QVector4D &operator*=(const QVector4D &vector);
QVector4D &operator/=(float divisor);
+#ifdef QT_BUILD_GUI_LIB
static float dotProduct(const QVector4D& v1, const QVector4D& v2);
+#else
+ static float dotProduct(const QVector4D& v1, const QVector4D& v2)
+ { return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp; }
+#endif
- friend inline bool operator==(const QVector4D &v1, const QVector4D &v2);
- friend inline bool operator!=(const QVector4D &v1, const QVector4D &v2);
- friend inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2);
- friend inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2);
- friend inline const QVector4D operator*(float factor, const QVector4D &vector);
- friend inline const QVector4D operator*(const QVector4D &vector, float factor);
- friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2);
- friend inline const QVector4D operator-(const QVector4D &vector);
- friend inline const QVector4D operator/(const QVector4D &vector, float divisor);
+ Q_DECL_CONSTEXPR friend inline bool operator==(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline bool operator!=(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator*(float factor, const QVector4D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator*(const QVector4D &vector, float factor);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator-(const QVector4D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator/(const QVector4D &vector, float divisor);
- friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2);
+ Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2);
#ifndef QT_NO_VECTOR2D
QVector2D toVector2D() const;
@@ -120,8 +130,8 @@ public:
QVector3D toVector3DAffine() const;
#endif
- QPoint toPoint() const;
- QPointF toPointF() const;
+ Q_DECL_CONSTEXPR QPoint toPoint() const;
+ Q_DECL_CONSTEXPR QPointF toPointF() const;
operator QVariant() const;
@@ -138,23 +148,23 @@ private:
Q_DECLARE_TYPEINFO(QVector4D, Q_MOVABLE_TYPE);
-inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {}
-inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {}
-inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
-inline QVector4D::QVector4D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
inline bool QVector4D::isNull() const
{
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp);
}
-inline float QVector4D::x() const { return xp; }
-inline float QVector4D::y() const { return yp; }
-inline float QVector4D::z() const { return zp; }
-inline float QVector4D::w() const { return wp; }
+Q_DECL_CONSTEXPR inline float QVector4D::x() const { return xp; }
+Q_DECL_CONSTEXPR inline float QVector4D::y() const { return yp; }
+Q_DECL_CONSTEXPR inline float QVector4D::z() const { return zp; }
+Q_DECL_CONSTEXPR inline float QVector4D::w() const { return wp; }
inline void QVector4D::setX(float aX) { xp = aX; }
inline void QVector4D::setY(float aY) { yp = aY; }
@@ -218,52 +228,52 @@ inline QVector4D &QVector4D::operator/=(float divisor)
return *this;
}
-inline bool operator==(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline bool operator==(const QVector4D &v1, const QVector4D &v2)
{
return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp && v1.wp == v2.wp;
}
-inline bool operator!=(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline bool operator!=(const QVector4D &v1, const QVector4D &v2)
{
return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp || v1.wp != v2.wp;
}
-inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
{
return QVector4D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp, v1.wp + v2.wp);
}
-inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
{
return QVector4D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp, v1.wp - v2.wp);
}
-inline const QVector4D operator*(float factor, const QVector4D &vector)
+Q_DECL_CONSTEXPR inline const QVector4D operator*(float factor, const QVector4D &vector)
{
return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
}
-inline const QVector4D operator*(const QVector4D &vector, float factor)
+Q_DECL_CONSTEXPR inline const QVector4D operator*(const QVector4D &vector, float factor)
{
return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
}
-inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
+Q_DECL_CONSTEXPR inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
{
return QVector4D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp, v1.wp * v2.wp);
}
-inline const QVector4D operator-(const QVector4D &vector)
+Q_DECL_CONSTEXPR inline const QVector4D operator-(const QVector4D &vector)
{
return QVector4D(-vector.xp, -vector.yp, -vector.zp, -vector.wp);
}
-inline const QVector4D operator/(const QVector4D &vector, float divisor)
+Q_DECL_CONSTEXPR inline const QVector4D operator/(const QVector4D &vector, float divisor)
{
return QVector4D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, vector.wp / divisor);
}
-inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
+Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
{
return qFuzzyCompare(v1.xp, v2.xp) &&
qFuzzyCompare(v1.yp, v2.yp) &&
@@ -271,12 +281,12 @@ inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
qFuzzyCompare(v1.wp, v2.wp);
}
-inline QPoint QVector4D::toPoint() const
+Q_DECL_CONSTEXPR inline QPoint QVector4D::toPoint() const
{
return QPoint(qRound(xp), qRound(yp));
}
-inline QPointF QVector4D::toPointF() const
+Q_DECL_CONSTEXPR inline QPointF QVector4D::toPointF() const
{
return QPointF(qreal(xp), qreal(yp));
}
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri
index d249b855f5..56aecd49e2 100644
--- a/src/gui/opengl/opengl.pri
+++ b/src/gui/opengl/opengl.pri
@@ -31,7 +31,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
opengl/qopenglversionfunctions.h \
opengl/qopenglversionfunctionsfactory_p.h \
opengl/qopenglvertexarrayobject.h \
- opengl/qopengldebug.h
+ opengl/qopengldebug.h \
+ opengl/qopengltextureblitter_p.h
SOURCES += opengl/qopengl.cpp \
opengl/qopenglfunctions.cpp \
@@ -51,7 +52,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
opengl/qopenglversionfunctions.cpp \
opengl/qopenglversionfunctionsfactory.cpp \
opengl/qopenglvertexarrayobject.cpp \
- opengl/qopengldebug.cpp
+ opengl/qopengldebug.cpp \
+ opengl/qopengltextureblitter.cpp
!wince* {
HEADERS += opengl/qopengltexture.h \
@@ -120,4 +122,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
SOURCES += opengl/qopenglfunctions_es2.cpp
}
+
+ contains(QT_CONFIG, dynamicgl) {
+ win32: SOURCES += opengl/qopenglproxy_win.cpp
+ }
}
diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h
index 6eb656cd09..025f8b823c 100644
--- a/src/gui/opengl/qopengl.h
+++ b/src/gui/opengl/qopengl.h
@@ -107,7 +107,17 @@ typedef GLfloat GLdouble;
# include <OpenGL/glext.h>
# else
# define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h
+ // In dynamic GL builds qopenglproxy will export the GL functions that are
+ // called also in QtGui itself. To prevent linker warnings (msvc) or errors (mingw)
+ // we need to make sure the prototypes do not have dllimport.
+# ifdef QT_OPENGL_DYNAMIC_IN_GUI
+# undef WINGDIAPI
+# define WINGDIAPI
+# endif // QT_OPENGL_DYNAMIC_IN_GUI
# include <GL/gl.h>
+# ifdef QT_OPENGL_DYNAMIC_IN_GUI
+# undef WINGDIAPI
+# endif // QT_OPENGL_DYNAMIC_IN_GUI
# include <QtGui/qopenglext.h>
# endif // Q_OS_MAC
#endif
diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp
index b832cefd70..a4c1e538ee 100644
--- a/src/gui/opengl/qopenglbuffer.cpp
+++ b/src/gui/opengl/qopenglbuffer.cpp
@@ -333,18 +333,20 @@ void QOpenGLBuffer::destroy()
bool QOpenGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
- Q_D(QOpenGLBuffer);
- if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
- return false;
- while (glGetError() != GL_NO_ERROR) ; // Clear error state.
- d->funcs->glGetBufferSubData(d->type, offset, count, data);
- return glGetError() == GL_NO_ERROR;
+ if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) {
+ Q_D(QOpenGLBuffer);
+ if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
+ return false;
+ while (glGetError() != GL_NO_ERROR) ; // Clear error state.
+ d->funcs->glGetBufferSubData(d->type, offset, count, data);
+ return glGetError() == GL_NO_ERROR;
+ }
#else
Q_UNUSED(offset);
Q_UNUSED(data);
Q_UNUSED(count);
- return false;
#endif
+ return false;
}
/*!
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
index 7c3c309ea5..95bafb07d9 100644
--- a/src/gui/opengl/qopenglengineshadermanager.cpp
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -164,7 +164,10 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader;
code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader;
- code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader;
+ if (QOpenGLFunctions::isES())
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_ES;
+ else
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop;
code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader;
code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader;
code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader;
diff --git a/src/gui/opengl/qopenglengineshadersource_p.h b/src/gui/opengl/qopenglengineshadersource_p.h
index ba72de3fb0..5bb0bc4704 100644
--- a/src/gui/opengl/qopenglengineshadersource_p.h
+++ b/src/gui/opengl/qopenglengineshadersource_p.h
@@ -305,25 +305,23 @@ static const char* const qopenglslPositionWithTextureBrushVertexShader = "\n\
static const char* const qopenglslAffinePositionWithTextureBrushVertexShader
= qopenglslPositionWithTextureBrushVertexShader;
-#if defined(QT_OPENGL_ES_2)
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
-static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
+static const char* const qopenglslTextureBrushSrcFragmentShader_ES = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() { \n\
return texture2D(brushTexture, fract(brushTextureCoords)); \n\
}\n";
-#else
-static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
+
+static const char* const qopenglslTextureBrushSrcFragmentShader_desktop = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
return texture2D(brushTexture, brushTextureCoords); \n\
}\n";
-#endif
static const char* const qopenglslTextureBrushSrcWithPatternFragmentShader = "\n\
varying highp vec2 brushTextureCoords; \n\
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 14d7fac9f7..9953b4e889 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -72,8 +72,6 @@ QT_BEGIN_NAMESPACE
#define QT_CHECK_GLERROR() {}
#endif
-// ####TODO Properly #ifdef this class to use #define symbols actually defined
-// by OpenGL/ES includes
#ifndef GL_MAX_SAMPLES
#define GL_MAX_SAMPLES 0x8D57
#endif
@@ -448,42 +446,12 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
funcs.glGenFramebuffers(1, &fbo);
funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- GLuint texture = 0;
GLuint color_buffer = 0;
QT_CHECK_GLERROR();
// init texture
if (samples == 0) {
- glGenTextures(1, &texture);
- glBindTexture(target, texture);
-
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- if (mipmap) {
- int width = size.width();
- int height = size.height();
- int level = 0;
- while (width > 1 || height > 1) {
- width = qMax(1, width >> 1);
- height = qMax(1, height >> 1);
- ++level;
- glTexImage2D(target, level, internal_format, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
- funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- target, texture, 0);
-
- QT_CHECK_GLERROR();
- valid = checkFramebufferStatus(ctx);
- glBindTexture(target, 0);
-
- color_buffer = 0;
+ initTexture(texture_target, internal_format, size, mipmap);
} else {
mipmap = false;
funcs.glGenRenderbuffers(1, &color_buffer);
@@ -494,8 +462,10 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
QT_CHECK_GLERROR();
valid = checkFramebufferStatus(ctx);
- if (valid)
+ if (valid) {
funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
+ color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
+ }
}
format.setTextureTarget(target);
@@ -508,20 +478,59 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
if (valid) {
fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
- if (color_buffer)
- color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
- else
- texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
} else {
- if (color_buffer)
- funcs.glDeleteRenderbuffers(1, &color_buffer);
- else
- glDeleteTextures(1, &texture);
+ if (color_buffer_guard) {
+ color_buffer_guard->free();
+ color_buffer_guard = 0;
+ } else if (texture_guard) {
+ texture_guard->free();
+ texture_guard = 0;
+ }
funcs.glDeleteFramebuffers(1, &fbo);
}
QT_CHECK_GLERROR();
}
+void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal_format,
+ const QSize &size, bool mipmap)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ GLuint texture = 0;
+
+ glGenTextures(1, &texture);
+ glBindTexture(target, texture);
+
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ if (mipmap) {
+ int width = size.width();
+ int height = size.height();
+ int level = 0;
+ while (width > 1 || height > 1) {
+ width = qMax(1, width >> 1);
+ height = qMax(1, height >> 1);
+ ++level;
+ glTexImage2D(target, level, internal_format, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+ }
+ funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ target, texture, 0);
+
+ QT_CHECK_GLERROR();
+ glBindTexture(target, 0);
+ valid = checkFramebufferStatus(ctx);
+ if (valid)
+ texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
+ else
+ glDeleteTextures(1, &texture);
+}
+
void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment)
{
int samples = format.samples();
@@ -581,30 +590,29 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
-#ifdef QT_OPENGL_ES
- if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT24, size.width(), size.height());
+ if (QOpenGLFunctions::isES()) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT24, size.width(), size.height());
+ else
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT16, size.width(), size.height());
} else {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT16, size.width(), size.height());
+ GL_DEPTH_COMPONENT, size.width(), size.height());
}
-#else
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT, size.width(), size.height());
-#endif
} else {
-#ifdef QT_OPENGL_ES
- if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
- size.width(), size.height());
+ if (QOpenGLFunctions::isES()) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
+ size.width(), size.height());
+ } else {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+ size.width(), size.height());
+ }
} else {
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
- size.width(), size.height());
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
}
-#else
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
-#endif
}
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_buffer);
@@ -619,23 +627,18 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
funcs.glGenRenderbuffers(1, &stencil_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
- if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
-#ifdef QT_OPENGL_ES
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_STENCIL_INDEX8, size.width(), size.height());
-#else
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_STENCIL_INDEX, size.width(), size.height());
-#endif
- } else {
+
#ifdef QT_OPENGL_ES
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
- size.width(), size.height());
+ GLenum storage = GL_STENCIL_INDEX8;
#else
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
- size.width(), size.height());
+ GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
#endif
- }
+
+ if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
+ else
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
+
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
valid = checkFramebufferStatus(ctx);
@@ -768,7 +771,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, size, NoAttachment, target,
+#ifndef QT_OPENGL_ES_2
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#else
+ GL_RGBA
+#endif
+ );
}
/*! \overload
@@ -782,7 +791,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, QSize(width, height), NoAttachment, target,
+#ifndef QT_OPENGL_ES_2
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#else
+ GL_RGBA
+#endif
+ );
}
/*! \overload
@@ -831,6 +846,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
+ if (!internal_format)
+#ifdef QT_OPENGL_ES_2
+ internal_format = GL_RGBA;
+#else
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#endif
d->init(this, QSize(width, height), attachment, target, internal_format);
}
@@ -852,6 +873,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
+ if (!internal_format)
+#ifdef QT_OPENGL_ES_2
+ internal_format = GL_RGBA;
+#else
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#endif
d->init(this, size, attachment, target, internal_format);
}
@@ -907,12 +934,16 @@ bool QOpenGLFramebufferObject::isValid() const
framebuffer to this framebuffer object.
Returns \c true upon success, false otherwise.
+ \note If takeTexture() was called, a new texture is created and associated
+ with the framebuffer object. This is potentially expensive and changes the
+ context state (the currently bound texture).
+
\sa release()
*/
bool QOpenGLFramebufferObject::bind()
{
if (!isValid())
- return false;
+ return false;
Q_D(QOpenGLFramebufferObject);
QOpenGLContext *current = QOpenGLContext::currentContext();
if (!current)
@@ -922,7 +953,10 @@ bool QOpenGLFramebufferObject::bind()
qWarning("QOpenGLFramebufferObject::bind() called from incompatible context");
#endif
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
- d->valid = d->checkFramebufferStatus(current);
+ if (d->texture_guard || d->format.samples() != 0)
+ d->valid = d->checkFramebufferStatus(current);
+ else
+ d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap());
if (d->valid && current)
current->d_func()->current_fbo = d->fbo();
return d->valid;
@@ -940,7 +974,7 @@ bool QOpenGLFramebufferObject::bind()
bool QOpenGLFramebufferObject::release()
{
if (!isValid())
- return false;
+ return false;
QOpenGLContext *current = QOpenGLContext::currentContext();
if (!current)
@@ -969,6 +1003,8 @@ bool QOpenGLFramebufferObject::release()
If a multisample framebuffer object is used then the value returned
from this function will be invalid.
+
+ \sa takeTexture()
*/
GLuint QOpenGLFramebufferObject::texture() const
{
@@ -977,6 +1013,40 @@ GLuint QOpenGLFramebufferObject::texture() const
}
/*!
+ \fn GLuint QOpenGLFramebufferObject::takeTexture()
+
+ Returns the texture id for the texture attached to this framebuffer
+ object. The ownership of the texture is transferred to the caller.
+
+ If the framebuffer object is currently bound, an implicit release()
+ will be done. During the next call to bind() a new texture will be
+ created.
+
+ If a multisample framebuffer object is used, then there is no
+ texture and the return value from this function will be invalid.
+ Similarly, incomplete framebuffer objects will also return 0.
+
+ \since 5.3
+
+ \sa texture(), bind(), release()
+ */
+GLuint QOpenGLFramebufferObject::takeTexture()
+{
+ Q_D(QOpenGLFramebufferObject);
+ GLuint id = 0;
+ if (isValid() && d->texture_guard) {
+ QOpenGLContext *current = QOpenGLContext::currentContext();
+ if (current && current->shareGroup() == d->fbo_guard->group() && current->d_func()->current_fbo == d->fbo())
+ release();
+ id = d->texture_guard->id();
+ // Do not call free() on texture_guard, just null it out.
+ // This way the texture will not be deleted when the guard is destroyed.
+ d->texture_guard = 0;
+ }
+ return id;
+}
+
+/*!
\fn QSize QOpenGLFramebufferObject::size() const
Returns the size of the texture attached to this framebuffer
diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h
index 215d3701ca..3df929c210 100644
--- a/src/gui/opengl/qopenglframebufferobject.h
+++ b/src/gui/opengl/qopenglframebufferobject.h
@@ -69,17 +69,11 @@ public:
explicit QOpenGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
-#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
- QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
- QOpenGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
-#else
+
QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QOpenGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
-#endif
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format);
QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format);
@@ -97,6 +91,7 @@ public:
int height() const { return size().height(); }
GLuint texture() const;
+ GLuint takeTexture();
QSize size() const;
QImage toImage() const;
Attachment attachment() const;
diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h
index c8c69c4b3e..f0e07f2119 100644
--- a/src/gui/opengl/qopenglframebufferobject_p.h
+++ b/src/gui/opengl/qopenglframebufferobject_p.h
@@ -59,12 +59,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_OPENGL_ES
-#define DEFAULT_FORMAT GL_RGBA8
-#else
-#define DEFAULT_FORMAT GL_RGBA
-#endif
-
class QOpenGLFramebufferObjectFormatPrivate
{
public:
@@ -73,9 +67,13 @@ public:
samples(0),
attachment(QOpenGLFramebufferObject::NoAttachment),
target(GL_TEXTURE_2D),
- internal_format(DEFAULT_FORMAT),
mipmap(false)
{
+#ifndef QT_OPENGL_ES_2
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#else
+ internal_format = GL_RGBA;
+#endif
}
QOpenGLFramebufferObjectFormatPrivate
(const QOpenGLFramebufferObjectFormatPrivate *other)
@@ -116,6 +114,7 @@ public:
QOpenGLFramebufferObject::Attachment attachment,
GLenum internal_format, GLenum texture_target,
GLint samples = 0, bool mipmap = false);
+ void initTexture(GLenum target, GLenum internal_format, const QSize &size, bool mipmap);
void initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment);
bool checkFramebufferStatus(QOpenGLContext *ctx) const;
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 0e5a1327b0..150e7dcb32 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -249,98 +249,98 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
static int qt_gl_resolve_features()
{
-#if defined(QT_OPENGL_ES_2)
- int features = QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::Shaders |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::Framebuffers |
- QOpenGLFunctions::BlendColor |
- QOpenGLFunctions::BlendEquation |
- QOpenGLFunctions::BlendEquationSeparate |
- QOpenGLFunctions::BlendFuncSeparate |
- QOpenGLFunctions::BlendSubtract |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample |
- QOpenGLFunctions::StencilSeparate;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures |
- QOpenGLFunctions::NPOTTextureRepeat;
- return features;
-#elif defined(QT_OPENGL_ES)
- int features = QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_OES_framebuffer_object"))
- features |= QOpenGLFunctions::Framebuffers;
- if (extensions.match("GL_OES_blend_equation_separate"))
- features |= QOpenGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_OES_blend_func_separate"))
- features |= QOpenGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_OES_blend_subtract"))
- features |= QOpenGLFunctions::BlendSubtract;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- return features;
-#else
- int features = 0;
- QSurfaceFormat format = QOpenGLContext::currentContext()->format();
- QOpenGLExtensionMatcher extensions;
-
- // Recognize features by extension name.
- if (extensions.match("GL_ARB_multitexture"))
- features |= QOpenGLFunctions::Multitexture;
- if (extensions.match("GL_ARB_shader_objects"))
- features |= QOpenGLFunctions::Shaders;
- if (extensions.match("GL_EXT_framebuffer_object") ||
+ if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) {
+ int features = QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::Shaders |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::Framebuffers |
+ QOpenGLFunctions::BlendColor |
+ QOpenGLFunctions::BlendEquation |
+ QOpenGLFunctions::BlendEquationSeparate |
+ QOpenGLFunctions::BlendFuncSeparate |
+ QOpenGLFunctions::BlendSubtract |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample |
+ QOpenGLFunctions::StencilSeparate;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures |
+ QOpenGLFunctions::NPOTTextureRepeat;
+ return features;
+ } else if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) {
+ int features = QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_OES_framebuffer_object"))
+ features |= QOpenGLFunctions::Framebuffers;
+ if (extensions.match("GL_OES_blend_equation_separate"))
+ features |= QOpenGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_OES_blend_func_separate"))
+ features |= QOpenGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_OES_blend_subtract"))
+ features |= QOpenGLFunctions::BlendSubtract;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ return features;
+ } else {
+ int features = 0;
+ QSurfaceFormat format = QOpenGLContext::currentContext()->format();
+ QOpenGLExtensionMatcher extensions;
+
+ // Recognize features by extension name.
+ if (extensions.match("GL_ARB_multitexture"))
+ features |= QOpenGLFunctions::Multitexture;
+ if (extensions.match("GL_ARB_shader_objects"))
+ features |= QOpenGLFunctions::Shaders;
+ if (extensions.match("GL_EXT_framebuffer_object") ||
extensions.match("GL_ARB_framebuffer_object"))
- features |= QOpenGLFunctions::Framebuffers;
- if (extensions.match("GL_EXT_blend_color"))
- features |= QOpenGLFunctions::BlendColor;
- if (extensions.match("GL_EXT_blend_equation_separate"))
- features |= QOpenGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_EXT_blend_func_separate"))
- features |= QOpenGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_EXT_blend_subtract"))
- features |= QOpenGLFunctions::BlendSubtract;
- if (extensions.match("GL_ARB_texture_compression"))
- features |= QOpenGLFunctions::CompressedTextures;
- if (extensions.match("GL_ARB_multisample"))
- features |= QOpenGLFunctions::Multisample;
- if (extensions.match("GL_ARB_texture_non_power_of_two"))
- features |= QOpenGLFunctions::NPOTTextures;
-
- // assume version 2.0 or higher
- features |= QOpenGLFunctions::BlendColor |
- QOpenGLFunctions::BlendEquation |
- QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample |
- QOpenGLFunctions::BlendFuncSeparate |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::Shaders |
- QOpenGLFunctions::StencilSeparate |
- QOpenGLFunctions::BlendEquationSeparate |
- QOpenGLFunctions::NPOTTextures;
-
- if (format.majorVersion() >= 3)
- features |= QOpenGLFunctions::Framebuffers;
-
- const QPair<int, int> version = format.version();
- if (version < qMakePair(3, 0)
+ features |= QOpenGLFunctions::Framebuffers;
+ if (extensions.match("GL_EXT_blend_color"))
+ features |= QOpenGLFunctions::BlendColor;
+ if (extensions.match("GL_EXT_blend_equation_separate"))
+ features |= QOpenGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_EXT_blend_func_separate"))
+ features |= QOpenGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_EXT_blend_subtract"))
+ features |= QOpenGLFunctions::BlendSubtract;
+ if (extensions.match("GL_ARB_texture_compression"))
+ features |= QOpenGLFunctions::CompressedTextures;
+ if (extensions.match("GL_ARB_multisample"))
+ features |= QOpenGLFunctions::Multisample;
+ if (extensions.match("GL_ARB_texture_non_power_of_two"))
+ features |= QOpenGLFunctions::NPOTTextures;
+
+ // assume version 2.0 or higher
+ features |= QOpenGLFunctions::BlendColor |
+ QOpenGLFunctions::BlendEquation |
+ QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample |
+ QOpenGLFunctions::BlendFuncSeparate |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::Shaders |
+ QOpenGLFunctions::StencilSeparate |
+ QOpenGLFunctions::BlendEquationSeparate |
+ QOpenGLFunctions::NPOTTextures;
+
+ if (format.majorVersion() >= 3)
+ features |= QOpenGLFunctions::Framebuffers;
+
+ const QPair<int, int> version = format.version();
+ if (version < qMakePair(3, 0)
|| (version == qMakePair(3, 0) && format.testOption(QSurfaceFormat::DeprecatedFunctions))
|| (version == qMakePair(3, 1) && extensions.match("GL_ARB_compatibility"))
|| (version >= qMakePair(3, 2) && format.profile() == QSurfaceFormat::CompatibilityProfile)) {
- features |= QOpenGLFunctions::FixedFunctionPipeline;
+ features |= QOpenGLFunctions::FixedFunctionPipeline;
+ }
+ return features;
}
- return features;
-#endif
}
static int qt_gl_resolve_extensions()
@@ -350,38 +350,38 @@ static int qt_gl_resolve_extensions()
if (extensionMatcher.match("GL_EXT_bgra"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
-#if defined(QT_OPENGL_ES)
- if (extensionMatcher.match("GL_OES_mapbuffer"))
- extensions |= QOpenGLExtensions::MapBuffer;
- if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
- extensions |= QOpenGLExtensions::PackedDepthStencil;
- if (extensionMatcher.match("GL_OES_element_index_uint"))
- extensions |= QOpenGLExtensions::ElementIndexUint;
- if (extensionMatcher.match("GL_OES_depth24"))
- extensions |= QOpenGLExtensions::Depth24;
- // TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
- if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
- extensions |= QOpenGLExtensions::BGRATextureFormat;
-#else
- QSurfaceFormat format = QOpenGLContext::currentContext()->format();
- extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
-
- // Recognize features by extension name.
- if (format.majorVersion() >= 3
- || extensionMatcher.match("GL_ARB_framebuffer_object"))
- {
- extensions |= QOpenGLExtensions::FramebufferMultisample |
- QOpenGLExtensions::FramebufferBlit |
- QOpenGLExtensions::PackedDepthStencil;
- } else {
- if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
- extensions |= QOpenGLExtensions::FramebufferMultisample;
- if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
- extensions |= QOpenGLExtensions::FramebufferBlit;
- if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
+ if (QOpenGLFunctions::isES()) {
+ if (extensionMatcher.match("GL_OES_mapbuffer"))
+ extensions |= QOpenGLExtensions::MapBuffer;
+ if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
extensions |= QOpenGLExtensions::PackedDepthStencil;
+ if (extensionMatcher.match("GL_OES_element_index_uint"))
+ extensions |= QOpenGLExtensions::ElementIndexUint;
+ if (extensionMatcher.match("GL_OES_depth24"))
+ extensions |= QOpenGLExtensions::Depth24;
+ // TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
+ if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
+ extensions |= QOpenGLExtensions::BGRATextureFormat;
+ } else {
+ QSurfaceFormat format = QOpenGLContext::currentContext()->format();
+ extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
+
+ // Recognize features by extension name.
+ if (format.majorVersion() >= 3
+ || extensionMatcher.match("GL_ARB_framebuffer_object"))
+ {
+ extensions |= QOpenGLExtensions::FramebufferMultisample |
+ QOpenGLExtensions::FramebufferBlit |
+ QOpenGLExtensions::PackedDepthStencil;
+ } else {
+ if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
+ extensions |= QOpenGLExtensions::FramebufferMultisample;
+ if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
+ extensions |= QOpenGLExtensions::FramebufferBlit;
+ if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
+ extensions |= QOpenGLExtensions::PackedDepthStencil;
+ }
}
-#endif
return extensions;
}
@@ -2509,4 +2509,88 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
GetBufferSubData = qopenglfResolveGetBufferSubData;
}
+#if defined(QT_OPENGL_DYNAMIC)
+extern int qgl_proxyLibraryType(void);
+extern HMODULE qgl_glHandle(void);
+#endif
+
+/*!
+ \enum QOpenGLFunctions::PlatformGLType
+ This enum defines the type of the underlying GL implementation.
+
+ \value DesktopGL Desktop OpenGL
+ \value GLES2 OpenGL ES 2.0 or higher
+ \value GLES1 OpenGL ES 1.x
+
+ \since 5.3
+ */
+
+/*!
+ \fn QOpenGLFunctions::isES()
+
+ On platforms where the OpenGL implementation is dynamically loaded
+ this function returns true if the underlying GL implementation is
+ Open GL ES.
+
+ On platforms that do not use runtime loading of the GL the return
+ value is based on Qt's compile-time configuration and will never
+ change during runtime.
+
+ \sa platformGLType()
+
+ \since 5.3
+ */
+
+/*!
+ Returns the underlying GL implementation type.
+
+ On platforms where the OpenGL implementation is not dynamically
+ loaded, the return value is determined during compile time and never
+ changes.
+
+ Platforms that use dynamic GL loading (e.g. Windows) cannot rely on
+ compile-time defines for differentiating between desktop and ES
+ OpenGL code. Instead, they rely on this function to query, during
+ runtime, the type of the loaded graphics library.
+
+ \since 5.3
+ */
+QOpenGLFunctions::PlatformGLType QOpenGLFunctions::platformGLType()
+{
+#if defined(QT_OPENGL_DYNAMIC)
+ return PlatformGLType(qgl_proxyLibraryType());
+#elif defined(QT_OPENGL_ES_2)
+ return GLES2;
+#elif defined(QT_OPENGL_ES)
+ return GLES1;
+#else
+ return DesktopGL;
+#endif
+}
+
+/*!
+ Returns the platform-specific handle for the OpenGL implementation that
+ is currently in use. (for example, a HMODULE on Windows)
+
+ On platforms that do not use dynamic GL switch the return value is null.
+
+ The library might be GL-only, meaning that windowing system interface
+ functions (for example EGL) may live in another, separate library.
+
+ Always use platformGLType() before resolving any functions to check if the
+ library implements desktop OpenGL or OpenGL ES.
+
+ \sa platformGLType()
+
+ \since 5.3
+ */
+void *QOpenGLFunctions::platformGLHandle()
+{
+#if defined(QT_OPENGL_DYNAMIC)
+ return qgl_glHandle();
+#else
+ return 0;
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index 9d8da209ad..6d3f038004 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -311,6 +311,15 @@ public:
void glVertexAttrib4fv(GLuint indx, const GLfloat* values);
void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+ enum PlatformGLType {
+ DesktopGL = 0,
+ GLES2,
+ GLES1
+ };
+ static PlatformGLType platformGLType();
+ static void *platformGLHandle();
+ static bool isES() { return platformGLType() != DesktopGL; }
+
protected:
QOpenGLFunctionsPrivate *d_ptr;
static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
@@ -322,7 +331,6 @@ struct QOpenGLFunctionsPrivate
{
QOpenGLFunctionsPrivate(QOpenGLContext *ctx);
-#ifndef QT_OPENGL_ES_2
void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
void (QOPENGLF_APIENTRYP AttachShader)(GLuint program, GLuint shader);
void (QOPENGLF_APIENTRYP BindAttribLocation)(GLuint program, GLuint index, const char* name);
@@ -418,7 +426,6 @@ struct QOpenGLFunctionsPrivate
void (QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint indx, const GLfloat* values);
void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
-#endif
};
inline void QOpenGLFunctions::glActiveTexture(GLenum texture)
diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp
index 9c4fbbe013..9c312808a2 100644
--- a/src/gui/opengl/qopenglgradientcache.cpp
+++ b/src/gui/opengl/qopenglgradientcache.cpp
@@ -168,7 +168,7 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);
qreal incr = 1.0 / qreal(size);
qreal fpos = 1.5 * incr;
- colorTable[pos++] = ARGB2RGBA(PREMUL(current_color));
+ colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color));
while (fpos <= s.first().first) {
colorTable[pos] = colorTable[pos - 1];
@@ -177,13 +177,13 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
}
if (colorInterpolation)
- current_color = PREMUL(current_color);
+ current_color = qPremultiply(current_color);
for (int i = 0; i < s.size() - 1; ++i) {
qreal delta = 1/(s[i+1].first - s[i].first);
uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
if (colorInterpolation)
- next_color = PREMUL(next_color);
+ next_color = qPremultiply(next_color);
while (fpos < s[i+1].first && pos < size) {
int dist = int(256 * ((fpos - s[i].first) * delta));
@@ -191,7 +191,7 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
if (colorInterpolation)
colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
else
- colorTable[pos] = ARGB2RGBA(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
+ colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
++pos;
fpos += incr;
}
@@ -200,7 +200,7 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
Q_ASSERT(s.size() > 0);
- uint last_color = ARGB2RGBA(PREMUL(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
+ uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
for (;pos < size; ++pos)
colorTable[pos] = last_color;
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 05135519f8..e91ada7b3a 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -220,14 +220,14 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size)
currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
-#if defined(QT_OPENGL_ES_2)
- // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
- // we emulate GL_REPEAT by only taking the fractional part of the texture coords
- // in the qopenglslTextureBrushSrcFragmentShader program.
- GLuint wrapMode = GL_CLAMP_TO_EDGE;
-#else
GLuint wrapMode = GL_REPEAT;
-#endif
+ if (QOpenGLFunctions::isES()) {
+ // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
+ // we emulate GL_REPEAT by only taking the fractional part of the texture coords
+ // in the qopenglslTextureBrushSrcFragmentShader program.
+ wrapMode = GL_CLAMP_TO_EDGE;
+ }
+
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushPixmap);
updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
@@ -542,36 +542,38 @@ void QOpenGL2PaintEngineEx::beginNativePainting()
d->funcs.glDisableVertexAttribArray(i);
#ifndef QT_OPENGL_ES_2
- Q_ASSERT(QOpenGLContext::currentContext());
- const QOpenGLContext *ctx = d->ctx;
- const QSurfaceFormat &fmt = d->device->context()->format();
- if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
- || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
- || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
- {
- // be nice to people who mix OpenGL 1.x code with QPainter commands
- // by setting modelview and projection matrices to mirror the GL 1
- // paint engine
- const QTransform& mtx = state()->matrix;
-
- float mv_matrix[4][4] =
+ if (!QOpenGLFunctions::isES()) {
+ Q_ASSERT(QOpenGLContext::currentContext());
+ const QOpenGLContext *ctx = d->ctx;
+ const QSurfaceFormat &fmt = d->device->context()->format();
+ if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
+ || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
+ || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
{
- { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
- { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
- { 0, 0, 1, 0 },
- { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
- };
-
- const QSize sz = d->device->size();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(&mv_matrix[0][0]);
+ // be nice to people who mix OpenGL 1.x code with QPainter commands
+ // by setting modelview and projection matrices to mirror the GL 1
+ // paint engine
+ const QTransform& mtx = state()->matrix;
+
+ float mv_matrix[4][4] =
+ {
+ { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
+ { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
+ { 0, 0, 1, 0 },
+ { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
+ };
+
+ const QSize sz = d->device->size();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(&mv_matrix[0][0]);
+ }
}
-#endif
+#endif // QT_OPENGL_ES_2
d->lastTextureUsed = GLuint(-1);
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
@@ -598,11 +600,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState()
setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
-#ifndef QT_OPENGL_ES_2
- // gl_Color, corresponding to vertex attribute 3, may have been changed
- float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- funcs.glVertexAttrib4fv(3, color);
-#endif
+ if (!QOpenGLFunctions::isES()) {
+ // gl_Color, corresponding to vertex attribute 3, may have been changed
+ float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ funcs.glVertexAttrib4fv(3, color);
+ }
}
void QOpenGL2PaintEngineEx::endNativePainting()
@@ -1332,13 +1334,15 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
{
state()->renderHintsChanged = true;
-#if !defined(QT_OPENGL_ES_2)
- if ((state()->renderHints & QPainter::Antialiasing)
- || (state()->renderHints & QPainter::HighQualityAntialiasing))
- glEnable(GL_MULTISAMPLE);
- else
- glDisable(GL_MULTISAMPLE);
-#endif
+#ifndef QT_OPENGL_ES_2
+ if (!QOpenGLFunctions::isES()) {
+ if ((state()->renderHints & QPainter::Antialiasing)
+ || (state()->renderHints & QPainter::HighQualityAntialiasing))
+ glEnable(GL_MULTISAMPLE);
+ else
+ glDisable(GL_MULTISAMPLE);
+ }
+#endif // QT_OPENGL_ES_2
Q_D(QOpenGL2PaintEngineEx);
d->lastTextureUsed = GLuint(-1);
@@ -2008,23 +2012,20 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
-#if !defined(QT_OPENGL_ES_2)
- glDisable(GL_MULTISAMPLE);
-#endif
-
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
-#if !defined(QT_OPENGL_ES_2)
+#ifndef QT_OPENGL_ES_2
+ if (!QOpenGLFunctions::isES()) {
+ glDisable(GL_MULTISAMPLE);
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
-#endif
-
-#if defined(QT_OPENGL_ES_2)
- // OpenGL ES can't switch MSAA off, so if the gl paint device is
- // multisampled, it's always multisampled.
- d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
-#else
- d->multisamplingAlwaysEnabled = false;
-#endif
+ d->multisamplingAlwaysEnabled = false;
+ } else
+#endif // QT_OPENGL_ES_2
+ {
+ // OpenGL ES can't switch MSAA off, so if the gl paint device is
+ // multisampled, it's always multisampled.
+ d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
+ }
return true;
}
diff --git a/src/gui/opengl/qopenglproxy_win.cpp b/src/gui/opengl/qopenglproxy_win.cpp
new file mode 100644
index 0000000000..83c3073f63
--- /dev/null
+++ b/src/gui/opengl/qopenglproxy_win.cpp
@@ -0,0 +1,4600 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QByteArray>
+#include <QVector>
+#include <QCoreApplication>
+#include <QLoggingCategory>
+#include <qt_windows.h>
+// Must not include QOpenGLFunctions or anything that pulls in qopengl.h.
+// Otherwise we end up with errors about inconsistent linkage.
+#include <GL/gl.h>
+#include <EGL/egl.h>
+
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
+# error "Proxy GL is not compatible with static ES builds"
+#endif
+
+// This should not be an issue with the compilers used on Windows, but just in case:
+#ifndef Q_COMPILER_VARIADIC_MACROS
+# error "Proxy GL requires variadic macro support"
+#endif
+
+// Disable inconsistent dll linkage warnings. gl.h and egl.h are included and these mark
+// the egl and (w)gl functions as imported. We will mark them as exported.
+#if defined(Q_CC_MSVC)
+# pragma warning(disable : 4273)
+#elif defined(Q_CC_MINGW)
+# pragma GCC diagnostic ignored "-Wattributes"
+#endif
+
+#ifdef Q_OS_WIN64
+typedef signed long long int khronos_intptr_t;
+typedef signed long long int khronos_ssize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef signed long int khronos_ssize_t;
+#endif
+
+typedef char GLchar;
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t GLsizeiptr;
+
+Q_LOGGING_CATEGORY(qglLc, "qt.gui.openglproxy")
+
+class QAbstractWindowsOpenGL
+{
+public:
+ QAbstractWindowsOpenGL();
+ virtual ~QAbstractWindowsOpenGL() { }
+
+ enum LibType { // must match QOpenGLFunctions::PlatformGLType
+ DesktopGL = 0,
+ GLES2
+ };
+
+ LibType libraryType() const { return m_libraryType; }
+ HMODULE libraryHandle() const { return m_lib; }
+ bool functionsReady() const { return m_loaded; }
+
+ // WGL
+ BOOL (WINAPI * CopyContext)(HGLRC src, HGLRC dst, UINT mask);
+ HGLRC (WINAPI * CreateContext)(HDC dc);
+ HGLRC (WINAPI * CreateLayerContext)(HDC dc, int plane);
+ BOOL (WINAPI * DeleteContext)(HGLRC context);
+ HGLRC (WINAPI * GetCurrentContext)();
+ HDC (WINAPI * GetCurrentDC)();
+ PROC (WINAPI * GetProcAddress)(LPCSTR name);
+ BOOL (WINAPI * MakeCurrent)(HDC dc, HGLRC context);
+ BOOL (WINAPI * ShareLists)(HGLRC context1, HGLRC context2);
+ BOOL (WINAPI * UseFontBitmapsW)(HDC dc, DWORD first, DWORD count, DWORD base);
+ BOOL (WINAPI * UseFontOutlinesW)(HDC dc, DWORD first, DWORD count, DWORD base, FLOAT deviation,
+ FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT gmf);
+ BOOL (WINAPI * DescribeLayerPlane)(HDC dc, int pixelFormat, int plane, UINT n,
+ LPLAYERPLANEDESCRIPTOR planeDescriptor);
+ int (WINAPI * SetLayerPaletteEntries)(HDC dc, int plane, int start, int entries,
+ CONST COLORREF *colors);
+ int (WINAPI * GetLayerPaletteEntries)(HDC dc, int plane, int start, int entries,
+ COLORREF *color);
+ BOOL (WINAPI * RealizeLayerPalette)(HDC dc, int plane, BOOL realize);
+ BOOL (WINAPI * SwapLayerBuffers)(HDC dc, UINT planes);
+ DWORD (WINAPI * SwapMultipleBuffers)(UINT n, CONST WGLSWAP *buffers);
+
+ // EGL
+ EGLint (EGLAPIENTRY * EGL_GetError)(void);
+ EGLDisplay (EGLAPIENTRY * EGL_GetDisplay)(EGLNativeDisplayType display_id);
+ EGLBoolean (EGLAPIENTRY * EGL_Initialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+ EGLBoolean (EGLAPIENTRY * EGL_Terminate)(EGLDisplay dpy);
+ const char * (EGLAPIENTRY * EGL_QueryString)(EGLDisplay dpy, EGLint name);
+ EGLBoolean (EGLAPIENTRY * EGL_GetConfigs)(EGLDisplay dpy, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config);
+ EGLBoolean (EGLAPIENTRY * EGL_ChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config);
+ EGLBoolean (EGLAPIENTRY * EGL_GetConfigAttrib)(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value);
+ EGLSurface (EGLAPIENTRY * EGL_CreateWindowSurface)(EGLDisplay dpy, EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list);
+ EGLSurface (EGLAPIENTRY * EGL_CreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list);
+ EGLSurface (EGLAPIENTRY * EGL_CreatePixmapSurface)(EGLDisplay dpy, EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * EGL_DestroySurface)(EGLDisplay dpy, EGLSurface surface);
+ EGLBoolean (EGLAPIENTRY * EGL_QuerySurface)(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint *value);
+ EGLBoolean (EGLAPIENTRY * EGL_BindAPI)(EGLenum api);
+ EGLenum (EGLAPIENTRY * EGL_QueryAPI)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_WaitClient)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_ReleaseThread)(void);
+ EGLSurface (EGLAPIENTRY * EGL_CreatePbufferFromClientBuffer)(EGLDisplay dpy, EGLenum buftype,
+ EGLClientBuffer buffer,
+ EGLConfig config, const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * EGL_SurfaceAttrib)(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint value);
+ EGLBoolean (EGLAPIENTRY * EGL_BindTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ EGLBoolean (EGLAPIENTRY * EGL_ReleaseTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ EGLBoolean (EGLAPIENTRY * EGL_SwapInterval)(EGLDisplay dpy, EGLint interval);
+ EGLContext (EGLAPIENTRY * EGL_CreateContext)(EGLDisplay dpy, EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * EGL_DestroyContext)(EGLDisplay dpy, EGLContext ctx);
+ EGLBoolean (EGLAPIENTRY * EGL_MakeCurrent)(EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx);
+ EGLContext (EGLAPIENTRY * EGL_GetCurrentContext)(void);
+ EGLSurface (EGLAPIENTRY * EGL_GetCurrentSurface)(EGLint readdraw);
+ EGLDisplay (EGLAPIENTRY * EGL_GetCurrentDisplay)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_QueryContext)(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value);
+ EGLBoolean (EGLAPIENTRY * EGL_WaitGL)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_WaitNative)(EGLint engine);
+ EGLBoolean (EGLAPIENTRY * EGL_SwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+ EGLBoolean (EGLAPIENTRY * EGL_CopyBuffers)(EGLDisplay dpy, EGLSurface surface,
+ EGLNativePixmapType target);
+ __eglMustCastToProperFunctionPointerType (EGLAPIENTRY * EGL_GetProcAddress)(const char *procname);
+
+ // OpenGL 1.0
+ void (APIENTRY * Viewport)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * DepthRange)(GLdouble nearVal, GLdouble farVal);
+ GLboolean (APIENTRY * IsEnabled)(GLenum cap);
+ void (APIENTRY * GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetTexParameteriv)(GLenum target, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+ const GLubyte * (APIENTRY * GetString)(GLenum name);
+ void (APIENTRY * GetIntegerv)(GLenum pname, GLint *params);
+ void (APIENTRY * GetFloatv)(GLenum pname, GLfloat *params);
+ GLenum (APIENTRY * GetError)();
+ void (APIENTRY * GetDoublev)(GLenum pname, GLdouble *params);
+ void (APIENTRY * GetBooleanv)(GLenum pname, GLboolean *params);
+ void (APIENTRY * ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+ void (APIENTRY * ReadBuffer)(GLenum mode);
+ void (APIENTRY * PixelStorei)(GLenum pname, GLint param);
+ void (APIENTRY * PixelStoref)(GLenum pname, GLfloat param);
+ void (APIENTRY * DepthFunc)(GLenum func);
+ void (APIENTRY * StencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
+ void (APIENTRY * StencilFunc)(GLenum func, GLint ref, GLuint mask);
+ void (APIENTRY * LogicOp)(GLenum opcode);
+ void (APIENTRY * BlendFunc)(GLenum sfactor, GLenum dfactor);
+ void (APIENTRY * Flush)();
+ void (APIENTRY * Finish)();
+ void (APIENTRY * Enable)(GLenum cap);
+ void (APIENTRY * Disable)(GLenum cap);
+ void (APIENTRY * DepthMask)(GLboolean flag);
+ void (APIENTRY * ColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void (APIENTRY * StencilMask)(GLuint mask);
+ void (APIENTRY * ClearDepth)(GLdouble depth);
+ void (APIENTRY * ClearStencil)(GLint s);
+ void (APIENTRY * ClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void (APIENTRY * Clear)(GLbitfield mask);
+ void (APIENTRY * DrawBuffer)(GLenum mode);
+ void (APIENTRY * TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * TexParameteriv)(GLenum target, GLenum pname, const GLint *params);
+ void (APIENTRY * TexParameteri)(GLenum target, GLenum pname, GLint param);
+ void (APIENTRY * TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params);
+ void (APIENTRY * TexParameterf)(GLenum target, GLenum pname, GLfloat param);
+ void (APIENTRY * Scissor)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * PolygonMode)(GLenum face, GLenum mode);
+ void (APIENTRY * PointSize)(GLfloat size);
+ void (APIENTRY * LineWidth)(GLfloat width);
+ void (APIENTRY * Hint)(GLenum target, GLenum mode);
+ void (APIENTRY * FrontFace)(GLenum mode);
+ void (APIENTRY * CullFace)(GLenum mode);
+
+ void (APIENTRY * Translatef)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Translated)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * Scalef)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Scaled)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * Rotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Rotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * PushMatrix)();
+ void (APIENTRY * PopMatrix)();
+ void (APIENTRY * Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+ void (APIENTRY * MultMatrixd)(const GLdouble *m);
+ void (APIENTRY * MultMatrixf)(const GLfloat *m);
+ void (APIENTRY * MatrixMode)(GLenum mode);
+ void (APIENTRY * LoadMatrixd)(const GLdouble *m);
+ void (APIENTRY * LoadMatrixf)(const GLfloat *m);
+ void (APIENTRY * LoadIdentity)();
+ void (APIENTRY * Frustum)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+ GLboolean (APIENTRY * IsList)(GLuint list);
+ void (APIENTRY * GetTexGeniv)(GLenum coord, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexGenfv)(GLenum coord, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetTexGendv)(GLenum coord, GLenum pname, GLdouble *params);
+ void (APIENTRY * GetTexEnviv)(GLenum target, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexEnvfv)(GLenum target, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetPolygonStipple)(GLubyte *mask);
+ void (APIENTRY * GetPixelMapusv)(GLenum map, GLushort *values);
+ void (APIENTRY * GetPixelMapuiv)(GLenum map, GLuint *values);
+ void (APIENTRY * GetPixelMapfv)(GLenum map, GLfloat *values);
+ void (APIENTRY * GetMaterialiv)(GLenum face, GLenum pname, GLint *params);
+ void (APIENTRY * GetMaterialfv)(GLenum face, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetMapiv)(GLenum target, GLenum query, GLint *v);
+ void (APIENTRY * GetMapfv)(GLenum target, GLenum query, GLfloat *v);
+ void (APIENTRY * GetMapdv)(GLenum target, GLenum query, GLdouble *v);
+ void (APIENTRY * GetLightiv)(GLenum light, GLenum pname, GLint *params);
+ void (APIENTRY * GetLightfv)(GLenum light, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetClipPlane)(GLenum plane, GLdouble *equation);
+ void (APIENTRY * DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * CopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
+ void (APIENTRY * PixelMapusv)(GLenum map, GLint mapsize, const GLushort *values);
+ void (APIENTRY * PixelMapuiv)(GLenum map, GLint mapsize, const GLuint *values);
+ void (APIENTRY * PixelMapfv)(GLenum map, GLint mapsize, const GLfloat *values);
+ void (APIENTRY * PixelTransferi)(GLenum pname, GLint param);
+ void (APIENTRY * PixelTransferf)(GLenum pname, GLfloat param);
+ void (APIENTRY * PixelZoom)(GLfloat xfactor, GLfloat yfactor);
+ void (APIENTRY * AlphaFunc)(GLenum func, GLfloat ref);
+ void (APIENTRY * EvalPoint2)(GLint i, GLint j);
+ void (APIENTRY * EvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
+ void (APIENTRY * EvalPoint1)(GLint i);
+ void (APIENTRY * EvalMesh1)(GLenum mode, GLint i1, GLint i2);
+ void (APIENTRY * EvalCoord2fv)(const GLfloat *u);
+ void (APIENTRY * EvalCoord2f)(GLfloat u, GLfloat v);
+ void (APIENTRY * EvalCoord2dv)(const GLdouble *u);
+ void (APIENTRY * EvalCoord2d)(GLdouble u, GLdouble v);
+ void (APIENTRY * EvalCoord1fv)(const GLfloat *u);
+ void (APIENTRY * EvalCoord1f)(GLfloat u);
+ void (APIENTRY * EvalCoord1dv)(const GLdouble *u);
+ void (APIENTRY * EvalCoord1d)(GLdouble u);
+ void (APIENTRY * MapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
+ void (APIENTRY * MapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
+ void (APIENTRY * MapGrid1f)(GLint un, GLfloat u1, GLfloat u2);
+ void (APIENTRY * MapGrid1d)(GLint un, GLdouble u1, GLdouble u2);
+ void (APIENTRY * Map2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+ void (APIENTRY * Map2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+ void (APIENTRY * Map1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+ void (APIENTRY * Map1d)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+ void (APIENTRY * PushAttrib)(GLbitfield mask);
+ void (APIENTRY * PopAttrib)();
+ void (APIENTRY * Accum)(GLenum op, GLfloat value);
+ void (APIENTRY * IndexMask)(GLuint mask);
+ void (APIENTRY * ClearIndex)(GLfloat c);
+ void (APIENTRY * ClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void (APIENTRY * PushName)(GLuint name);
+ void (APIENTRY * PopName)();
+ void (APIENTRY * PassThrough)(GLfloat token);
+ void (APIENTRY * LoadName)(GLuint name);
+ void (APIENTRY * InitNames)();
+ GLint (APIENTRY * RenderMode)(GLenum mode);
+ void (APIENTRY * SelectBuffer)(GLsizei size, GLuint *buffer);
+ void (APIENTRY * FeedbackBuffer)(GLsizei size, GLenum type, GLfloat *buffer);
+ void (APIENTRY * TexGeniv)(GLenum coord, GLenum pname, const GLint *params);
+ void (APIENTRY * TexGeni)(GLenum coord, GLenum pname, GLint param);
+ void (APIENTRY * TexGenfv)(GLenum coord, GLenum pname, const GLfloat *params);
+ void (APIENTRY * TexGenf)(GLenum coord, GLenum pname, GLfloat param);
+ void (APIENTRY * TexGendv)(GLenum coord, GLenum pname, const GLdouble *params);
+ void (APIENTRY * TexGend)(GLenum coord, GLenum pname, GLdouble param);
+ void (APIENTRY * TexEnviv)(GLenum target, GLenum pname, const GLint *params);
+ void (APIENTRY * TexEnvi)(GLenum target, GLenum pname, GLint param);
+ void (APIENTRY * TexEnvfv)(GLenum target, GLenum pname, const GLfloat *params);
+ void (APIENTRY * TexEnvf)(GLenum target, GLenum pname, GLfloat param);
+ void (APIENTRY * ShadeModel)(GLenum mode);
+ void (APIENTRY * PolygonStipple)(const GLubyte *mask);
+ void (APIENTRY * Materialiv)(GLenum face, GLenum pname, const GLint *params);
+ void (APIENTRY * Materiali)(GLenum face, GLenum pname, GLint param);
+ void (APIENTRY * Materialfv)(GLenum face, GLenum pname, const GLfloat *params);
+ void (APIENTRY * Materialf)(GLenum face, GLenum pname, GLfloat param);
+ void (APIENTRY * LineStipple)(GLint factor, GLushort pattern);
+ void (APIENTRY * LightModeliv)(GLenum pname, const GLint *params);
+ void (APIENTRY * LightModeli)(GLenum pname, GLint param);
+ void (APIENTRY * LightModelfv)(GLenum pname, const GLfloat *params);
+ void (APIENTRY * LightModelf)(GLenum pname, GLfloat param);
+ void (APIENTRY * Lightiv)(GLenum light, GLenum pname, const GLint *params);
+ void (APIENTRY * Lighti)(GLenum light, GLenum pname, GLint param);
+ void (APIENTRY * Lightfv)(GLenum light, GLenum pname, const GLfloat *params);
+ void (APIENTRY * Lightf)(GLenum light, GLenum pname, GLfloat param);
+ void (APIENTRY * Fogiv)(GLenum pname, const GLint *params);
+ void (APIENTRY * Fogi)(GLenum pname, GLint param);
+ void (APIENTRY * Fogfv)(GLenum pname, const GLfloat *params);
+ void (APIENTRY * Fogf)(GLenum pname, GLfloat param);
+ void (APIENTRY * ColorMaterial)(GLenum face, GLenum mode);
+ void (APIENTRY * ClipPlane)(GLenum plane, const GLdouble *equation);
+ void (APIENTRY * Vertex4sv)(const GLshort *v);
+ void (APIENTRY * Vertex4s)(GLshort x, GLshort y, GLshort z, GLshort w);
+ void (APIENTRY * Vertex4iv)(const GLint *v);
+ void (APIENTRY * Vertex4i)(GLint x, GLint y, GLint z, GLint w);
+ void (APIENTRY * Vertex4fv)(const GLfloat *v);
+ void (APIENTRY * Vertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * Vertex4dv)(const GLdouble *v);
+ void (APIENTRY * Vertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+ void (APIENTRY * Vertex3sv)(const GLshort *v);
+ void (APIENTRY * Vertex3s)(GLshort x, GLshort y, GLshort z);
+ void (APIENTRY * Vertex3iv)(const GLint *v);
+ void (APIENTRY * Vertex3i)(GLint x, GLint y, GLint z);
+ void (APIENTRY * Vertex3fv)(const GLfloat *v);
+ void (APIENTRY * Vertex3f)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Vertex3dv)(const GLdouble *v);
+ void (APIENTRY * Vertex3d)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * Vertex2sv)(const GLshort *v);
+ void (APIENTRY * Vertex2s)(GLshort x, GLshort y);
+ void (APIENTRY * Vertex2iv)(const GLint *v);
+ void (APIENTRY * Vertex2i)(GLint x, GLint y);
+ void (APIENTRY * Vertex2fv)(const GLfloat *v);
+ void (APIENTRY * Vertex2f)(GLfloat x, GLfloat y);
+ void (APIENTRY * Vertex2dv)(const GLdouble *v);
+ void (APIENTRY * Vertex2d)(GLdouble x, GLdouble y);
+ void (APIENTRY * TexCoord4sv)(const GLshort *v);
+ void (APIENTRY * TexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q);
+ void (APIENTRY * TexCoord4iv)(const GLint *v);
+ void (APIENTRY * TexCoord4i)(GLint s, GLint t, GLint r, GLint q);
+ void (APIENTRY * TexCoord4fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+ void (APIENTRY * TexCoord4dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+ void (APIENTRY * TexCoord3sv)(const GLshort *v);
+ void (APIENTRY * TexCoord3s)(GLshort s, GLshort t, GLshort r);
+ void (APIENTRY * TexCoord3iv)(const GLint *v);
+ void (APIENTRY * TexCoord3i)(GLint s, GLint t, GLint r);
+ void (APIENTRY * TexCoord3fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord3f)(GLfloat s, GLfloat t, GLfloat r);
+ void (APIENTRY * TexCoord3dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord3d)(GLdouble s, GLdouble t, GLdouble r);
+ void (APIENTRY * TexCoord2sv)(const GLshort *v);
+ void (APIENTRY * TexCoord2s)(GLshort s, GLshort t);
+ void (APIENTRY * TexCoord2iv)(const GLint *v);
+ void (APIENTRY * TexCoord2i)(GLint s, GLint t);
+ void (APIENTRY * TexCoord2fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord2f)(GLfloat s, GLfloat t);
+ void (APIENTRY * TexCoord2dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord2d)(GLdouble s, GLdouble t);
+ void (APIENTRY * TexCoord1sv)(const GLshort *v);
+ void (APIENTRY * TexCoord1s)(GLshort s);
+ void (APIENTRY * TexCoord1iv)(const GLint *v);
+ void (APIENTRY * TexCoord1i)(GLint s);
+ void (APIENTRY * TexCoord1fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord1f)(GLfloat s);
+ void (APIENTRY * TexCoord1dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord1d)(GLdouble s);
+ void (APIENTRY * Rectsv)(const GLshort *v1, const GLshort *v2);
+ void (APIENTRY * Rects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
+ void (APIENTRY * Rectiv)(const GLint *v1, const GLint *v2);
+ void (APIENTRY * Recti)(GLint x1, GLint y1, GLint x2, GLint y2);
+ void (APIENTRY * Rectfv)(const GLfloat *v1, const GLfloat *v2);
+ void (APIENTRY * Rectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+ void (APIENTRY * Rectdv)(const GLdouble *v1, const GLdouble *v2);
+ void (APIENTRY * Rectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
+ void (APIENTRY * RasterPos4sv)(const GLshort *v);
+ void (APIENTRY * RasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w);
+ void (APIENTRY * RasterPos4iv)(const GLint *v);
+ void (APIENTRY * RasterPos4i)(GLint x, GLint y, GLint z, GLint w);
+ void (APIENTRY * RasterPos4fv)(const GLfloat *v);
+ void (APIENTRY * RasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * RasterPos4dv)(const GLdouble *v);
+ void (APIENTRY * RasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+ void (APIENTRY * RasterPos3sv)(const GLshort *v);
+ void (APIENTRY * RasterPos3s)(GLshort x, GLshort y, GLshort z);
+ void (APIENTRY * RasterPos3iv)(const GLint *v);
+ void (APIENTRY * RasterPos3i)(GLint x, GLint y, GLint z);
+ void (APIENTRY * RasterPos3fv)(const GLfloat *v);
+ void (APIENTRY * RasterPos3f)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * RasterPos3dv)(const GLdouble *v);
+ void (APIENTRY * RasterPos3d)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * RasterPos2sv)(const GLshort *v);
+ void (APIENTRY * RasterPos2s)(GLshort x, GLshort y);
+ void (APIENTRY * RasterPos2iv)(const GLint *v);
+ void (APIENTRY * RasterPos2i)(GLint x, GLint y);
+ void (APIENTRY * RasterPos2fv)(const GLfloat *v);
+ void (APIENTRY * RasterPos2f)(GLfloat x, GLfloat y);
+ void (APIENTRY * RasterPos2dv)(const GLdouble *v);
+ void (APIENTRY * RasterPos2d)(GLdouble x, GLdouble y);
+ void (APIENTRY * Normal3sv)(const GLshort *v);
+ void (APIENTRY * Normal3s)(GLshort nx, GLshort ny, GLshort nz);
+ void (APIENTRY * Normal3iv)(const GLint *v);
+ void (APIENTRY * Normal3i)(GLint nx, GLint ny, GLint nz);
+ void (APIENTRY * Normal3fv)(const GLfloat *v);
+ void (APIENTRY * Normal3f)(GLfloat nx, GLfloat ny, GLfloat nz);
+ void (APIENTRY * Normal3dv)(const GLdouble *v);
+ void (APIENTRY * Normal3d)(GLdouble nx, GLdouble ny, GLdouble nz);
+ void (APIENTRY * Normal3bv)(const GLbyte *v);
+ void (APIENTRY * Normal3b)(GLbyte nx, GLbyte ny, GLbyte nz);
+ void (APIENTRY * Indexsv)(const GLshort *c);
+ void (APIENTRY * Indexs)(GLshort c);
+ void (APIENTRY * Indexiv)(const GLint *c);
+ void (APIENTRY * Indexi)(GLint c);
+ void (APIENTRY * Indexfv)(const GLfloat *c);
+ void (APIENTRY * Indexf)(GLfloat c);
+ void (APIENTRY * Indexdv)(const GLdouble *c);
+ void (APIENTRY * Indexd)(GLdouble c);
+ void (APIENTRY * End)();
+ void (APIENTRY * EdgeFlagv)(const GLboolean *flag);
+ void (APIENTRY * EdgeFlag)(GLboolean flag);
+ void (APIENTRY * Color4usv)(const GLushort *v);
+ void (APIENTRY * Color4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha);
+ void (APIENTRY * Color4uiv)(const GLuint *v);
+ void (APIENTRY * Color4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha);
+ void (APIENTRY * Color4ubv)(const GLubyte *v);
+ void (APIENTRY * Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+ void (APIENTRY * Color4sv)(const GLshort *v);
+ void (APIENTRY * Color4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha);
+ void (APIENTRY * Color4iv)(const GLint *v);
+ void (APIENTRY * Color4i)(GLint red, GLint green, GLint blue, GLint alpha);
+ void (APIENTRY * Color4fv)(const GLfloat *v);
+ void (APIENTRY * Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void (APIENTRY * Color4dv)(const GLdouble *v);
+ void (APIENTRY * Color4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+ void (APIENTRY * Color4bv)(const GLbyte *v);
+ void (APIENTRY * Color4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
+ void (APIENTRY * Color3usv)(const GLushort *v);
+ void (APIENTRY * Color3us)(GLushort red, GLushort green, GLushort blue);
+ void (APIENTRY * Color3uiv)(const GLuint *v);
+ void (APIENTRY * Color3ui)(GLuint red, GLuint green, GLuint blue);
+ void (APIENTRY * Color3ubv)(const GLubyte *v);
+ void (APIENTRY * Color3ub)(GLubyte red, GLubyte green, GLubyte blue);
+ void (APIENTRY * Color3sv)(const GLshort *v);
+ void (APIENTRY * Color3s)(GLshort red, GLshort green, GLshort blue);
+ void (APIENTRY * Color3iv)(const GLint *v);
+ void (APIENTRY * Color3i)(GLint red, GLint green, GLint blue);
+ void (APIENTRY * Color3fv)(const GLfloat *v);
+ void (APIENTRY * Color3f)(GLfloat red, GLfloat green, GLfloat blue);
+ void (APIENTRY * Color3dv)(const GLdouble *v);
+ void (APIENTRY * Color3d)(GLdouble red, GLdouble green, GLdouble blue);
+ void (APIENTRY * Color3bv)(const GLbyte *v);
+ void (APIENTRY * Color3b)(GLbyte red, GLbyte green, GLbyte blue);
+ void (APIENTRY * Bitmap)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
+ void (APIENTRY * Begin)(GLenum mode);
+ void (APIENTRY * ListBase)(GLuint base);
+ GLuint (APIENTRY * GenLists)(GLsizei range);
+ void (APIENTRY * DeleteLists)(GLuint list, GLsizei range);
+ void (APIENTRY * CallLists)(GLsizei n, GLenum type, const GLvoid *lists);
+ void (APIENTRY * CallList)(GLuint list);
+ void (APIENTRY * EndList)();
+ void (APIENTRY * NewList)(GLuint list, GLenum mode);
+
+ // OpenGL 1.1
+ void (APIENTRY * Indexubv)(const GLubyte *c);
+ void (APIENTRY * Indexub)(GLubyte c);
+ GLboolean (APIENTRY * IsTexture)(GLuint texture);
+ void (APIENTRY * GenTextures)(GLsizei n, GLuint *textures);
+ void (APIENTRY * DeleteTextures)(GLsizei n, const GLuint *textures);
+ void (APIENTRY * BindTexture)(GLenum target, GLuint texture);
+ void (APIENTRY * TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * CopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+ void (APIENTRY * CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void (APIENTRY * CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+ void (APIENTRY * PolygonOffset)(GLfloat factor, GLfloat units);
+ void (APIENTRY * GetPointerv)(GLenum pname, GLvoid* *params);
+ void (APIENTRY * DrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+ void (APIENTRY * DrawArrays)(GLenum mode, GLint first, GLsizei count);
+
+ void (APIENTRY * PushClientAttrib)(GLbitfield mask);
+ void (APIENTRY * PopClientAttrib)();
+ void (APIENTRY * PrioritizeTextures)(GLsizei n, const GLuint *textures, const GLfloat *priorities);
+ GLboolean (APIENTRY * AreTexturesResident)(GLsizei n, const GLuint *textures, GLboolean *residences);
+ void (APIENTRY * VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * NormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * InterleavedArrays)(GLenum format, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * IndexPointer)(GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * EnableClientState)(GLenum array);
+ void (APIENTRY * EdgeFlagPointer)(GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * DisableClientState)(GLenum array);
+ void (APIENTRY * ColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * ArrayElement)(GLint i);
+
+ // OpenGL ES 2.0
+ void (APIENTRY * ActiveTexture)(GLenum texture);
+ void (APIENTRY * AttachShader)(GLuint program, GLuint shader);
+ void (APIENTRY * BindAttribLocation)(GLuint program, GLuint index, const GLchar* name);
+ void (APIENTRY * BindBuffer)(GLenum target, GLuint buffer);
+ void (APIENTRY * BindFramebuffer)(GLenum target, GLuint framebuffer);
+ void (APIENTRY * BindRenderbuffer)(GLenum target, GLuint renderbuffer);
+ void (APIENTRY * BlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (APIENTRY * BlendEquation)(GLenum mode);
+ void (APIENTRY * BlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
+ void (APIENTRY * BlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void (APIENTRY * BufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+ void (APIENTRY * BufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+ GLenum (APIENTRY * CheckFramebufferStatus)(GLenum target);
+ void (APIENTRY * ClearDepthf)(GLclampf depth);
+ void (APIENTRY * CompileShader)(GLuint shader);
+ void (APIENTRY * CompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+ void (APIENTRY * CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+ GLuint (APIENTRY * CreateProgram)(void);
+ GLuint (APIENTRY * CreateShader)(GLenum type);
+ void (APIENTRY * DeleteBuffers)(GLsizei n, const GLuint* buffers);
+ void (APIENTRY * DeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
+ void (APIENTRY * DeleteProgram)(GLuint program);
+ void (APIENTRY * DeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
+ void (APIENTRY * DeleteShader)(GLuint shader);
+ void (APIENTRY * DepthRangef)(GLclampf zNear, GLclampf zFar);
+ void (APIENTRY * DetachShader)(GLuint program, GLuint shader);
+ void (APIENTRY * DisableVertexAttribArray)(GLuint index);
+ void (APIENTRY * EnableVertexAttribArray)(GLuint index);
+ void (APIENTRY * FramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ void (APIENTRY * FramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ void (APIENTRY * GenBuffers)(GLsizei n, GLuint* buffers);
+ void (APIENTRY * GenerateMipmap)(GLenum target);
+ void (APIENTRY * GenFramebuffers)(GLsizei n, GLuint* framebuffers);
+ void (APIENTRY * GenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
+ void (APIENTRY * GetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ void (APIENTRY * GetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ void (APIENTRY * GetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ int (APIENTRY * GetAttribLocation)(GLuint program, const GLchar* name);
+ void (APIENTRY * GetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * GetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void (APIENTRY * GetProgramiv)(GLuint program, GLenum pname, GLint* params);
+ void (APIENTRY * GetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+ void (APIENTRY * GetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * GetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+ void (APIENTRY * GetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+ void (APIENTRY * GetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void (APIENTRY * GetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+ void (APIENTRY * GetUniformfv)(GLuint program, GLint location, GLfloat* params);
+ void (APIENTRY * GetUniformiv)(GLuint program, GLint location, GLint* params);
+ int (APIENTRY * GetUniformLocation)(GLuint program, const GLchar* name);
+ void (APIENTRY * GetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
+ void (APIENTRY * GetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
+ void (APIENTRY * GetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer);
+ GLboolean (APIENTRY * IsBuffer)(GLuint buffer);
+ GLboolean (APIENTRY * IsFramebuffer)(GLuint framebuffer);
+ GLboolean (APIENTRY * IsProgram)(GLuint program);
+ GLboolean (APIENTRY * IsRenderbuffer)(GLuint renderbuffer);
+ GLboolean (APIENTRY * IsShader)(GLuint shader);
+ void (APIENTRY * LinkProgram)(GLuint program);
+ void (APIENTRY * ReleaseShaderCompiler)(void);
+ void (APIENTRY * RenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void (APIENTRY * SampleCoverage)(GLclampf value, GLboolean invert);
+ void (APIENTRY * ShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+ void (APIENTRY * ShaderSource)(GLuint shader, GLsizei count, const GLchar* *string, const GLint* length);
+ void (APIENTRY * StencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void (APIENTRY * StencilMaskSeparate)(GLenum face, GLuint mask);
+ void (APIENTRY * StencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void (APIENTRY * Uniform1f)(GLint location, GLfloat x);
+ void (APIENTRY * Uniform1fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform1i)(GLint location, GLint x);
+ void (APIENTRY * Uniform1iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * Uniform2f)(GLint location, GLfloat x, GLfloat y);
+ void (APIENTRY * Uniform2fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform2i)(GLint location, GLint x, GLint y);
+ void (APIENTRY * Uniform2iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * Uniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Uniform3fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform3i)(GLint location, GLint x, GLint y, GLint z);
+ void (APIENTRY * Uniform3iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * Uniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * Uniform4fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void (APIENTRY * Uniform4iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * UniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * UniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * UseProgram)(GLuint program);
+ void (APIENTRY * ValidateProgram)(GLuint program);
+ void (APIENTRY * VertexAttrib1f)(GLuint indx, GLfloat x);
+ void (APIENTRY * VertexAttrib1fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
+ void (APIENTRY * VertexAttrib2fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * VertexAttrib3fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * VertexAttrib4fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+
+protected:
+ HMODULE m_lib;
+ LibType m_libraryType;
+ bool m_loaded;
+};
+
+class QWindowsOpenGL : public QAbstractWindowsOpenGL
+{
+public:
+ QWindowsOpenGL();
+ ~QWindowsOpenGL();
+
+private:
+ bool load(const char *glName, const char *eglName);
+ void unload();
+
+ void resolve();
+
+ void resolveWGL();
+ void resolveEGL();
+ void resolveGLCommon();
+ void resolveGL11();
+ void resolveGLES2();
+
+ FARPROC resolveFunc(const char *name);
+ FARPROC resolveEglFunc(const char *name);
+
+ bool testDesktopGL();
+
+ HMODULE m_eglLib;
+};
+
+static QString qgl_windowsErrorMessage(unsigned long errorCode)
+{
+ QString rc = QString::fromLatin1("#%1: ").arg(errorCode);
+ ushort *lpMsgBuf;
+
+ const int len = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorCode, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
+ if (len) {
+ rc += QString::fromUtf16(lpMsgBuf, len);
+ LocalFree(lpMsgBuf);
+ } else {
+ rc += QString::fromLatin1("<unknown error>");
+ }
+ return rc;
+}
+
+static HMODULE qgl_loadLib(const char *name, bool warnOnFail = true)
+{
+ HMODULE lib = LoadLibraryA(name);
+
+ if (lib)
+ return lib;
+
+ if (warnOnFail) {
+ QString msg = qgl_windowsErrorMessage(GetLastError());
+ qCWarning(qglLc, "Failed to load %s: %s", name, qPrintable(msg));
+ }
+
+ return 0;
+}
+
+QWindowsOpenGL::QWindowsOpenGL()
+ : m_eglLib(0)
+{
+ if (qEnvironmentVariableIsSet("QT_OPENGLPROXY_DEBUG"))
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.gui.openglproxy=true"));
+
+ enum RequestedLib {
+ Unknown,
+ Desktop,
+ GLES
+ } req = Unknown;
+
+ // Check if the application has requested a certain implementation.
+ if (QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL))
+ req = Desktop;
+ else if (QCoreApplication::testAttribute(Qt::AA_UseOpenGLES))
+ req = GLES;
+
+ // Check if an implementation is forced through the environment variable.
+ QByteArray requested = qgetenv("QT_OPENGL");
+ if (requested == QByteArrayLiteral("desktop"))
+ req = Desktop;
+ else if (requested == QByteArrayLiteral("angle"))
+ req = GLES;
+
+ bool desktopTested = false;
+ if (req == Unknown) {
+ // No explicit request. Start testing. opengl32.dll is preferred. Angle is the fallback.
+ desktopTested = true;
+ if (testDesktopGL())
+ req = Desktop;
+ else
+ req = GLES;
+ }
+
+ Q_ASSERT(req != Unknown);
+
+ if (req == GLES) {
+ qCDebug(qglLc, "Using Angle");
+#ifdef QT_DEBUG
+ m_loaded = load("libglesv2d.dll", "libegld.dll");
+#else
+ m_loaded = load("libglesv2.dll", "libegl.dll");
+#endif
+ if (m_loaded) {
+ m_libraryType = QWindowsOpenGL::GLES2;
+ } else {
+ // Could not load Angle. Try opengl32.dll.
+ if (!desktopTested && testDesktopGL())
+ req = Desktop;
+ }
+ }
+
+ if (req == Desktop) {
+ qCDebug(qglLc, "Using desktop OpenGL");
+ m_loaded = load("opengl32.dll", 0);
+ if (m_loaded)
+ m_libraryType = QWindowsOpenGL::DesktopGL;
+ }
+
+ if (m_loaded)
+ resolve();
+
+ // When no library is loaded, keep on running. All EGL/WGL/GL functions will
+ // return 0 in this case without further errors. It is up to the clients
+ // (application code, Qt Quick, etc.) to act when eglInitialize() and
+ // friends fail, i.e. when QOpenGLContext::create() returns false due to the
+ // platform plugin's failure to create a platform context.
+}
+
+QWindowsOpenGL::~QWindowsOpenGL()
+{
+ unload();
+}
+
+bool QWindowsOpenGL::load(const char *glName, const char *eglName)
+{
+ qCDebug(qglLc, "Loading %s %s", glName, eglName ? eglName : "");
+
+ bool result = true;
+
+ if (glName) {
+ m_lib = qgl_loadLib(glName);
+ result &= m_lib != 0;
+ }
+
+ if (eglName) {
+ m_eglLib = qgl_loadLib(eglName);
+ result &= m_eglLib != 0;
+ }
+
+ if (!result)
+ unload();
+
+ return result;
+}
+
+void QWindowsOpenGL::unload()
+{
+ if (m_lib) {
+ FreeLibrary(m_lib);
+ m_lib = 0;
+ }
+ if (m_eglLib) {
+ FreeLibrary(m_eglLib);
+ m_eglLib = 0;
+ }
+ m_loaded = false;
+}
+
+FARPROC QWindowsOpenGL::resolveFunc(const char *name)
+{
+ FARPROC proc = m_lib ? ::GetProcAddress(m_lib, name) : 0;
+ if (!proc)
+ qCDebug(qglLc, "Failed to resolve GL function %s", name);
+ return proc;
+}
+
+FARPROC QWindowsOpenGL::resolveEglFunc(const char *name)
+{
+ FARPROC proc = m_eglLib ? ::GetProcAddress(m_eglLib, name) : 0;
+ if (!proc)
+ qCDebug(qglLc, "Failed to resolve EGL function %s", name);
+ return proc;
+}
+
+void QWindowsOpenGL::resolveWGL()
+{
+ CopyContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC, UINT)>(resolveFunc("wglCopyContext"));
+ CreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolveFunc("wglCreateContext"));
+ CreateLayerContext = reinterpret_cast<HGLRC (WINAPI *)(HDC, int)>(resolveFunc("wglCreateLayerContext"));
+ DeleteContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC)>(resolveFunc("wglDeleteContext"));
+ GetCurrentContext = reinterpret_cast<HGLRC (WINAPI *)()>(resolveFunc("wglGetCurrentContext"));
+ GetCurrentDC = reinterpret_cast<HDC (WINAPI *)()>(resolveFunc("wglGetCurrentDC"));
+ GetProcAddress = reinterpret_cast<PROC (WINAPI *)(LPCSTR)>(resolveFunc("wglGetProcAddress"));
+ MakeCurrent = reinterpret_cast<BOOL (WINAPI *)(HDC, HGLRC)>(resolveFunc("wglMakeCurrent"));
+ ShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolveFunc("wglShareLists"));
+ UseFontBitmapsW = reinterpret_cast<BOOL (WINAPI *)(HDC, DWORD, DWORD, DWORD)>(resolveFunc("wglUseFontBitmapsW"));
+ UseFontOutlinesW = reinterpret_cast<BOOL (WINAPI *)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)>(resolveFunc("wglUseFontOutlinesW"));
+ DescribeLayerPlane = reinterpret_cast<BOOL (WINAPI *)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)>(resolveFunc("wglDescribeLayerPlane"));
+ SetLayerPaletteEntries = reinterpret_cast<int (WINAPI *)(HDC, int, int, int, CONST COLORREF *)>(resolveFunc("wglSetLayerPaletteEntries"));
+ GetLayerPaletteEntries = reinterpret_cast<int (WINAPI *)(HDC, int, int, int, COLORREF *)>(resolveFunc("wglGetLayerPaletteEntries"));
+ RealizeLayerPalette = reinterpret_cast<BOOL (WINAPI *)(HDC, int, BOOL)>(resolveFunc("wglRealizeLayerPalette"));
+ SwapLayerBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC, UINT)>(resolveFunc("wglSwapLayerBuffers"));
+ SwapMultipleBuffers = reinterpret_cast<DWORD (WINAPI *)(UINT, CONST WGLSWAP *)>(resolveFunc("wglSwapMultipleBuffers"));
+}
+
+void QWindowsOpenGL::resolveEGL()
+{
+ EGL_GetError = reinterpret_cast<EGLint (EGLAPIENTRY *)(void)>(resolveEglFunc("eglGetError"));
+ EGL_GetDisplay = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(EGLNativeDisplayType)>(resolveEglFunc("eglGetDisplay"));
+ EGL_Initialize = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLint *, EGLint *)>(resolveEglFunc("eglInitialize"));
+ EGL_Terminate = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay)>(resolveEglFunc("eglTerminate"));
+ EGL_QueryString = reinterpret_cast<const char * (EGLAPIENTRY *)(EGLDisplay, EGLint)>(resolveEglFunc("eglQueryString"));
+ EGL_GetConfigs = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLDisplay, EGLConfig *, EGLint, EGLint *)>(resolveEglFunc("eglGetConfigs"));
+ EGL_ChooseConfig = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)>(resolveEglFunc("eglChooseConfig"));
+ EGL_GetConfigAttrib = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLint, EGLint *)>(resolveEglFunc("eglGetConfigAttrib"));
+ EGL_CreateWindowSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint *)>(resolveEglFunc("eglCreateWindowSurface"));
+ EGL_CreatePbufferSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLDisplay , EGLConfig, const EGLint *)>(resolveEglFunc("eglCreatePbufferSurface"));
+ EGL_CreatePixmapSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY * )(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType , const EGLint *)>(resolveEglFunc("eglCreatePixmapSurface"));
+ EGL_DestroySurface = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface )>(resolveEglFunc("eglDestroySurface"));
+ EGL_QuerySurface = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLDisplay , EGLSurface , EGLint , EGLint *)>(resolveEglFunc("eglQuerySurface"));
+ EGL_BindAPI = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLenum )>(resolveEglFunc("eglBindAPI"));
+ EGL_QueryAPI = reinterpret_cast<EGLenum (EGLAPIENTRY *)(void)>(resolveEglFunc("eglQueryAPI"));
+ EGL_WaitClient = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(void)>(resolveEglFunc("eglWaitClient"));
+ EGL_ReleaseThread = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(void)>(resolveEglFunc("eglReleaseThread"));
+ EGL_CreatePbufferFromClientBuffer = reinterpret_cast<EGLSurface (EGLAPIENTRY * )(EGLDisplay , EGLenum , EGLClientBuffer , EGLConfig , const EGLint *)>(resolveEglFunc("eglCreatePbufferFromClientBuffer"));
+ EGL_SurfaceAttrib = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLint , EGLint )>(resolveEglFunc("eglSurfaceAttrib"));
+ EGL_BindTexImage = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLDisplay, EGLSurface , EGLint )>(resolveEglFunc("eglBindTexImage"));
+ EGL_ReleaseTexImage = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLSurface , EGLint)>(resolveEglFunc("eglReleaseTexImage"));
+ EGL_SwapInterval = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLint )>(resolveEglFunc("eglSwapInterval"));
+ EGL_CreateContext = reinterpret_cast<EGLContext (EGLAPIENTRY *)(EGLDisplay , EGLConfig , EGLContext , const EGLint *)>(resolveEglFunc("eglCreateContext"));
+ EGL_DestroyContext = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLContext)>(resolveEglFunc("eglDestroyContext"));
+ EGL_MakeCurrent = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLSurface , EGLContext )>(resolveEglFunc("eglMakeCurrent"));
+ EGL_GetCurrentContext = reinterpret_cast<EGLContext (EGLAPIENTRY *)(void)>(resolveEglFunc("eglGetCurrentContext"));
+ EGL_GetCurrentSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLint )>(resolveEglFunc("eglGetCurrentSurface"));
+ EGL_GetCurrentDisplay = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(void)>(resolveEglFunc("eglGetCurrentDisplay"));
+ EGL_QueryContext = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLContext , EGLint , EGLint *)>(resolveEglFunc("eglQueryContext"));
+ EGL_WaitGL = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(void)>(resolveEglFunc("eglWaitGL"));
+ EGL_WaitNative = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLint )>(resolveEglFunc("eglWaitNative"));
+ EGL_SwapBuffers = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)>(resolveEglFunc("eglSwapBuffers"));
+ EGL_CopyBuffers = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLNativePixmapType )>(resolveEglFunc("eglCopyBuffers"));
+ EGL_GetProcAddress = reinterpret_cast<__eglMustCastToProperFunctionPointerType (EGLAPIENTRY * )(const char *)>(resolveEglFunc("eglGetProcAddress"));
+}
+
+void QWindowsOpenGL::resolveGLCommon()
+{
+ Viewport = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolveFunc("glViewport"));
+ IsEnabled = reinterpret_cast<GLboolean (APIENTRY *)(GLenum )>(resolveFunc("glIsEnabled"));
+ GetTexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetTexParameteriv"));
+ GetTexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetTexParameterfv"));
+ GetString = reinterpret_cast<const GLubyte * (APIENTRY *)(GLenum )>(resolveFunc("glGetString"));
+ GetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolveFunc("glGetIntegerv"));
+ GetFloatv = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat *)>(resolveFunc("glGetFloatv"));
+ GetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolveFunc("glGetError"));
+ GetBooleanv = reinterpret_cast<void (APIENTRY *)(GLenum , GLboolean *)>(resolveFunc("glGetBooleanv"));
+ ReadPixels = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , GLvoid *)>(resolveFunc("glReadPixels"));
+ PixelStorei = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glPixelStorei"));
+ DepthFunc = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDepthFunc"));
+ StencilOp = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum )>(resolveFunc("glStencilOp"));
+ StencilFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLuint )>(resolveFunc("glStencilFunc"));
+ BlendFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glBlendFunc"));
+ Flush = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glFlush"));
+ Finish = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glFinish"));
+ Enable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glEnable"));
+ Disable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDisable"));
+ DepthMask = reinterpret_cast<void (APIENTRY *)(GLboolean )>(resolveFunc("glDepthMask"));
+ ColorMask = reinterpret_cast<void (APIENTRY *)(GLboolean , GLboolean , GLboolean , GLboolean )>(resolveFunc("glColorMask"));
+ StencilMask = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glStencilMask"));
+ ClearStencil = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glClearStencil"));
+ ClearColor = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glClearColor"));
+ Clear = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolveFunc("glClear"));
+ TexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexImage2D"));
+ TexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glTexParameteriv"));
+ TexParameteri = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glTexParameteri"));
+ TexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glTexParameterfv"));
+ TexParameterf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glTexParameterf"));
+ Scissor = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolveFunc("glScissor"));
+ LineWidth = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glLineWidth"));
+ Hint = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glHint"));
+ FrontFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glFrontFace"));
+ CullFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glCullFace"));
+
+ IsTexture = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsTexture"));
+ GenTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint *)>(resolveFunc("glGenTextures"));
+ DeleteTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint *)>(resolveFunc("glDeleteTextures"));
+ BindTexture = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindTexture"));
+ TexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexSubImage2D"));
+ CopyTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint , GLint , GLsizei , GLsizei )>(resolveFunc("glCopyTexSubImage2D"));
+ CopyTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLsizei , GLint )>(resolveFunc("glCopyTexImage2D"));
+ PolygonOffset = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glPolygonOffset"));
+ DrawElements = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , GLenum , const GLvoid *)>(resolveFunc("glDrawElements"));
+ DrawArrays = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLsizei )>(resolveFunc("glDrawArrays"));
+}
+
+void QWindowsOpenGL::resolveGL11()
+{
+ DepthRange = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glDepthRange"));
+ GetTexImage = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLenum , GLvoid *)>(resolveFunc("glGetTexImage"));
+ LogicOp = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glLogicOp"));
+ ClearDepth = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glClearDepth"));
+ PolygonMode = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glPolygonMode"));
+ PointSize = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glPointSize"));
+ GetTexLevelParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint *)>(resolveFunc("glGetTexLevelParameteriv"));
+ GetTexLevelParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLfloat *)>(resolveFunc("glGetTexLevelParameterfv"));
+ GetDoublev = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble *)>(resolveFunc("glGetDoublev"));
+ PixelStoref = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glPixelStoref"));
+ ReadBuffer = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glReadBuffer"));
+ DrawBuffer = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDrawBuffer"));
+ TexImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexImage1D"));
+
+ Translatef = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glTranslatef"));
+ Translated = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glTranslated"));
+ Scalef = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glScalef"));
+ Scaled = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glScaled"));
+ Rotatef = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glRotatef"));
+ Rotated = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glRotated"));
+ PushMatrix = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPushMatrix"));
+ PopMatrix = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopMatrix"));
+ Ortho = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glOrtho"));
+ MultMatrixd = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glMultMatrixd"));
+ MultMatrixf = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glMultMatrixf"));
+ MatrixMode = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glMatrixMode"));
+ LoadMatrixd = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glLoadMatrixd"));
+ LoadMatrixf = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glLoadMatrixf"));
+ LoadIdentity = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glLoadIdentity"));
+ Frustum = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glFrustum"));
+ IsList = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsList"));
+ GetTexGeniv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetTexGeniv"));
+ GetTexGenfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetTexGenfv"));
+ GetTexGendv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLdouble *)>(resolveFunc("glGetTexGendv"));
+ GetTexEnviv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetTexEnviv"));
+ GetTexEnvfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetTexEnvfv"));
+ GetPolygonStipple = reinterpret_cast<void (APIENTRY *)(GLubyte *)>(resolveFunc("glGetPolygonStipple"));
+ GetPixelMapusv = reinterpret_cast<void (APIENTRY *)(GLenum , GLushort *)>(resolveFunc("glGetPixelMapusv"));
+ GetPixelMapuiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint *)>(resolveFunc("glGetPixelMapuiv"));
+ GetPixelMapfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat *)>(resolveFunc("glGetPixelMapfv"));
+ GetMaterialiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetMaterialiv"));
+ GetMaterialfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetMaterialfv"));
+ GetMapiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetMapiv"));
+ GetMapfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetMapfv"));
+ GetMapdv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLdouble *)>(resolveFunc("glGetMapdv"));
+ GetLightiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetLightiv"));
+ GetLightfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetLightfv"));
+ GetClipPlane = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble *)>(resolveFunc("glGetClipPlane"));
+ DrawPixels = reinterpret_cast<void (APIENTRY *)(GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(resolveFunc("glDrawPixels"));
+ CopyPixels = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei , GLenum )>(resolveFunc("glCopyPixels"));
+ PixelMapusv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , const GLushort *)>(resolveFunc("glPixelMapusv"));
+ PixelMapuiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , const GLuint *)>(resolveFunc("glPixelMapuiv"));
+ PixelMapfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , const GLfloat *)>(resolveFunc("glPixelMapfv"));
+ PixelTransferi = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glPixelTransferi"));
+ PixelTransferf = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glPixelTransferf"));
+ PixelZoom = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glPixelZoom"));
+ AlphaFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glAlphaFunc"));
+ EvalPoint2 = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glEvalPoint2"));
+ EvalMesh2 = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint )>(resolveFunc("glEvalMesh2"));
+ EvalPoint1 = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glEvalPoint1"));
+ EvalMesh1 = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint )>(resolveFunc("glEvalMesh1"));
+ EvalCoord2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glEvalCoord2fv"));
+ EvalCoord2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glEvalCoord2f"));
+ EvalCoord2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glEvalCoord2dv"));
+ EvalCoord2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glEvalCoord2d"));
+ EvalCoord1fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glEvalCoord1fv"));
+ EvalCoord1f = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glEvalCoord1f"));
+ EvalCoord1dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glEvalCoord1dv"));
+ EvalCoord1d = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glEvalCoord1d"));
+ MapGrid2f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLint , GLfloat , GLfloat )>(resolveFunc("glMapGrid2f"));
+ MapGrid2d = reinterpret_cast<void (APIENTRY *)(GLint , GLdouble , GLdouble , GLint , GLdouble , GLdouble )>(resolveFunc("glMapGrid2d"));
+ MapGrid1f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat )>(resolveFunc("glMapGrid1f"));
+ MapGrid1d = reinterpret_cast<void (APIENTRY *)(GLint , GLdouble , GLdouble )>(resolveFunc("glMapGrid1d"));
+ Map2f = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat , GLfloat , GLint , GLint , GLfloat , GLfloat , GLint , GLint , const GLfloat *)>(resolveFunc("glMap2f"));
+ Map2d = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble , GLdouble , GLint , GLint , GLdouble , GLdouble , GLint , GLint , const GLdouble *)>(resolveFunc("glMap2d"));
+ Map1f = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat , GLfloat , GLint , GLint , const GLfloat *)>(resolveFunc("glMap1f"));
+ Map1d = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble , GLdouble , GLint , GLint , const GLdouble *)>(resolveFunc("glMap1d"));
+ PushAttrib = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolveFunc("glPushAttrib"));
+ PopAttrib = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopAttrib"));
+ Accum = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glAccum"));
+ IndexMask = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glIndexMask"));
+ ClearIndex = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glClearIndex"));
+ ClearAccum = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glClearAccum"));
+ PushName = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glPushName"));
+ PopName = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopName"));
+ PassThrough = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glPassThrough"));
+ LoadName = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glLoadName"));
+ InitNames = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glInitNames"));
+ RenderMode = reinterpret_cast<GLint (APIENTRY *)(GLenum )>(resolveFunc("glRenderMode"));
+ SelectBuffer = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint *)>(resolveFunc("glSelectBuffer"));
+ FeedbackBuffer = reinterpret_cast<void (APIENTRY *)(GLsizei , GLenum , GLfloat *)>(resolveFunc("glFeedbackBuffer"));
+ TexGeniv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glTexGeniv"));
+ TexGeni = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glTexGeni"));
+ TexGenfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glTexGenfv"));
+ TexGenf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glTexGenf"));
+ TexGendv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLdouble *)>(resolveFunc("glTexGendv"));
+ TexGend = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLdouble )>(resolveFunc("glTexGend"));
+ TexEnviv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glTexEnviv"));
+ TexEnvi = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glTexEnvi"));
+ TexEnvfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glTexEnvfv"));
+ TexEnvf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glTexEnvf"));
+ ShadeModel = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glShadeModel"));
+ PolygonStipple = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glPolygonStipple"));
+ Materialiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glMaterialiv"));
+ Materiali = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glMateriali"));
+ Materialfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glMaterialfv"));
+ Materialf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glMaterialf"));
+ LineStipple = reinterpret_cast<void (APIENTRY *)(GLint , GLushort )>(resolveFunc("glLineStipple"));
+ LightModeliv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLint *)>(resolveFunc("glLightModeliv"));
+ LightModeli = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glLightModeli"));
+ LightModelfv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLfloat *)>(resolveFunc("glLightModelfv"));
+ LightModelf = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glLightModelf"));
+ Lightiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glLightiv"));
+ Lighti = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glLighti"));
+ Lightfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glLightfv"));
+ Lightf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glLightf"));
+ Fogiv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLint *)>(resolveFunc("glFogiv"));
+ Fogi = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glFogi"));
+ Fogfv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLfloat *)>(resolveFunc("glFogfv"));
+ Fogf = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glFogf"));
+ ColorMaterial = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glColorMaterial"));
+ ClipPlane = reinterpret_cast<void (APIENTRY *)(GLenum , const GLdouble *)>(resolveFunc("glClipPlane"));
+ Vertex4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glVertex4sv"));
+ Vertex4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glVertex4s"));
+ Vertex4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glVertex4iv"));
+ Vertex4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glVertex4i"));
+ Vertex4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glVertex4fv"));
+ Vertex4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertex4f"));
+ Vertex4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glVertex4dv"));
+ Vertex4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glVertex4d"));
+ Vertex3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glVertex3sv"));
+ Vertex3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glVertex3s"));
+ Vertex3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glVertex3iv"));
+ Vertex3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glVertex3i"));
+ Vertex3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glVertex3fv"));
+ Vertex3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertex3f"));
+ Vertex3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glVertex3dv"));
+ Vertex3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glVertex3d"));
+ Vertex2sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glVertex2sv"));
+ Vertex2s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort )>(resolveFunc("glVertex2s"));
+ Vertex2iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glVertex2iv"));
+ Vertex2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glVertex2i"));
+ Vertex2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glVertex2fv"));
+ Vertex2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glVertex2f"));
+ Vertex2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glVertex2dv"));
+ Vertex2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glVertex2d"));
+ TexCoord4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord4sv"));
+ TexCoord4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glTexCoord4s"));
+ TexCoord4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord4iv"));
+ TexCoord4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glTexCoord4i"));
+ TexCoord4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord4fv"));
+ TexCoord4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glTexCoord4f"));
+ TexCoord4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord4dv"));
+ TexCoord4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glTexCoord4d"));
+ TexCoord3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord3sv"));
+ TexCoord3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glTexCoord3s"));
+ TexCoord3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord3iv"));
+ TexCoord3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glTexCoord3i"));
+ TexCoord3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord3fv"));
+ TexCoord3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glTexCoord3f"));
+ TexCoord3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord3dv"));
+ TexCoord3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glTexCoord3d"));
+ TexCoord2sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord2sv"));
+ TexCoord2s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort )>(resolveFunc("glTexCoord2s"));
+ TexCoord2iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord2iv"));
+ TexCoord2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glTexCoord2i"));
+ TexCoord2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord2fv"));
+ TexCoord2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glTexCoord2f"));
+ TexCoord2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord2dv"));
+ TexCoord2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glTexCoord2d"));
+ TexCoord1sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord1sv"));
+ TexCoord1s = reinterpret_cast<void (APIENTRY *)(GLshort )>(resolveFunc("glTexCoord1s"));
+ TexCoord1iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord1iv"));
+ TexCoord1i = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glTexCoord1i"));
+ TexCoord1fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord1fv"));
+ TexCoord1f = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glTexCoord1f"));
+ TexCoord1dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord1dv"));
+ TexCoord1d = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glTexCoord1d"));
+ Rectsv = reinterpret_cast<void (APIENTRY *)(const GLshort *, const GLshort *)>(resolveFunc("glRectsv"));
+ Rects = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glRects"));
+ Rectiv = reinterpret_cast<void (APIENTRY *)(const GLint *, const GLint *)>(resolveFunc("glRectiv"));
+ Recti = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glRecti"));
+ Rectfv = reinterpret_cast<void (APIENTRY *)(const GLfloat *, const GLfloat *)>(resolveFunc("glRectfv"));
+ Rectf = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glRectf"));
+ Rectdv = reinterpret_cast<void (APIENTRY *)(const GLdouble *, const GLdouble *)>(resolveFunc("glRectdv"));
+ Rectd = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glRectd"));
+ RasterPos4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glRasterPos4sv"));
+ RasterPos4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glRasterPos4s"));
+ RasterPos4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glRasterPos4iv"));
+ RasterPos4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glRasterPos4i"));
+ RasterPos4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glRasterPos4fv"));
+ RasterPos4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glRasterPos4f"));
+ RasterPos4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glRasterPos4dv"));
+ RasterPos4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glRasterPos4d"));
+ RasterPos3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glRasterPos3sv"));
+ RasterPos3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glRasterPos3s"));
+ RasterPos3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glRasterPos3iv"));
+ RasterPos3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glRasterPos3i"));
+ RasterPos3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glRasterPos3fv"));
+ RasterPos3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glRasterPos3f"));
+ RasterPos3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glRasterPos3dv"));
+ RasterPos3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glRasterPos3d"));
+ RasterPos2sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glRasterPos2sv"));
+ RasterPos2s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort )>(resolveFunc("glRasterPos2s"));
+ RasterPos2iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glRasterPos2iv"));
+ RasterPos2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glRasterPos2i"));
+ RasterPos2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glRasterPos2fv"));
+ RasterPos2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glRasterPos2f"));
+ RasterPos2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glRasterPos2dv"));
+ RasterPos2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glRasterPos2d"));
+ Normal3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glNormal3sv"));
+ Normal3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glNormal3s"));
+ Normal3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glNormal3iv"));
+ Normal3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glNormal3i"));
+ Normal3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glNormal3fv"));
+ Normal3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glNormal3f"));
+ Normal3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glNormal3dv"));
+ Normal3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glNormal3d"));
+ Normal3bv = reinterpret_cast<void (APIENTRY *)(const GLbyte *)>(resolveFunc("glNormal3bv"));
+ Normal3b = reinterpret_cast<void (APIENTRY *)(GLbyte , GLbyte , GLbyte )>(resolveFunc("glNormal3b"));
+ Indexsv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glIndexsv"));
+ Indexs = reinterpret_cast<void (APIENTRY *)(GLshort )>(resolveFunc("glIndexs"));
+ Indexiv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glIndexiv"));
+ Indexi = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glIndexi"));
+ Indexfv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glIndexfv"));
+ Indexf = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glIndexf"));
+ Indexdv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glIndexdv"));
+ Indexd = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glIndexd"));
+ End = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glEnd"));
+ EdgeFlagv = reinterpret_cast<void (APIENTRY *)(const GLboolean *)>(resolveFunc("glEdgeFlagv"));
+ EdgeFlag = reinterpret_cast<void (APIENTRY *)(GLboolean )>(resolveFunc("glEdgeFlag"));
+ Color4usv = reinterpret_cast<void (APIENTRY *)(const GLushort *)>(resolveFunc("glColor4usv"));
+ Color4us = reinterpret_cast<void (APIENTRY *)(GLushort , GLushort , GLushort , GLushort )>(resolveFunc("glColor4us"));
+ Color4uiv = reinterpret_cast<void (APIENTRY *)(const GLuint *)>(resolveFunc("glColor4uiv"));
+ Color4ui = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLuint , GLuint )>(resolveFunc("glColor4ui"));
+ Color4ubv = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glColor4ubv"));
+ Color4ub = reinterpret_cast<void (APIENTRY *)(GLubyte , GLubyte , GLubyte , GLubyte )>(resolveFunc("glColor4ub"));
+ Color4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glColor4sv"));
+ Color4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glColor4s"));
+ Color4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glColor4iv"));
+ Color4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glColor4i"));
+ Color4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glColor4fv"));
+ Color4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glColor4f"));
+ Color4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glColor4dv"));
+ Color4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glColor4d"));
+ Color4bv = reinterpret_cast<void (APIENTRY *)(const GLbyte *)>(resolveFunc("glColor4bv"));
+ Color4b = reinterpret_cast<void (APIENTRY *)(GLbyte , GLbyte , GLbyte , GLbyte )>(resolveFunc("glColor4b"));
+ Color3usv = reinterpret_cast<void (APIENTRY *)(const GLushort *)>(resolveFunc("glColor3usv"));
+ Color3us = reinterpret_cast<void (APIENTRY *)(GLushort , GLushort , GLushort )>(resolveFunc("glColor3us"));
+ Color3uiv = reinterpret_cast<void (APIENTRY *)(const GLuint *)>(resolveFunc("glColor3uiv"));
+ Color3ui = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLuint )>(resolveFunc("glColor3ui"));
+ Color3ubv = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glColor3ubv"));
+ Color3ub = reinterpret_cast<void (APIENTRY *)(GLubyte , GLubyte , GLubyte )>(resolveFunc("glColor3ub"));
+ Color3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glColor3sv"));
+ Color3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glColor3s"));
+ Color3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glColor3iv"));
+ Color3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glColor3i"));
+ Color3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glColor3fv"));
+ Color3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glColor3f"));
+ Color3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glColor3dv"));
+ Color3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glColor3d"));
+ Color3bv = reinterpret_cast<void (APIENTRY *)(const GLbyte *)>(resolveFunc("glColor3bv"));
+ Color3b = reinterpret_cast<void (APIENTRY *)(GLbyte , GLbyte , GLbyte )>(resolveFunc("glColor3b"));
+ Bitmap = reinterpret_cast<void (APIENTRY *)(GLsizei , GLsizei , GLfloat , GLfloat , GLfloat , GLfloat , const GLubyte *)>(resolveFunc("glBitmap"));
+ Begin = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glBegin"));
+ ListBase = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glListBase"));
+ GenLists = reinterpret_cast<GLuint (APIENTRY *)(GLsizei )>(resolveFunc("glGenLists"));
+ DeleteLists = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei )>(resolveFunc("glDeleteLists"));
+ CallLists = reinterpret_cast<void (APIENTRY *)(GLsizei , GLenum , const GLvoid *)>(resolveFunc("glCallLists"));
+ CallList = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glCallList"));
+ EndList = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glEndList"));
+ NewList = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum )>(resolveFunc("glNewList"));
+
+ Indexubv = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glIndexubv"));
+ Indexub = reinterpret_cast<void (APIENTRY *)(GLubyte )>(resolveFunc("glIndexub"));
+ TexSubImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexSubImage1D"));
+ CopyTexSubImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint , GLsizei )>(resolveFunc("glCopyTexSubImage1D"));
+ CopyTexImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLint )>(resolveFunc("glCopyTexImage1D"));
+ GetPointerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLvoid* *)>(resolveFunc("glGetPointerv"));
+
+ PushClientAttrib = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolveFunc("glPushClientAttrib"));
+ PopClientAttrib = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopClientAttrib"));
+ PrioritizeTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint *, const GLfloat *)>(resolveFunc("glPrioritizeTextures"));
+ AreTexturesResident = reinterpret_cast<GLboolean (APIENTRY *)(GLsizei , const GLuint *, GLboolean *)>(resolveFunc("glAreTexturesResident"));
+ VertexPointer = reinterpret_cast<void (APIENTRY *)(GLint , GLenum , GLsizei , const GLvoid *)>(resolveFunc("glVertexPointer"));
+ TexCoordPointer = reinterpret_cast<void (APIENTRY *)(GLint , GLenum , GLsizei , const GLvoid *)>(resolveFunc("glTexCoordPointer"));
+ NormalPointer = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , const GLvoid *)>(resolveFunc("glNormalPointer"));
+ InterleavedArrays = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , const GLvoid *)>(resolveFunc("glInterleavedArrays"));
+ IndexPointer = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , const GLvoid *)>(resolveFunc("glIndexPointer"));
+ EnableClientState = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glEnableClientState"));
+ EdgeFlagPointer = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLvoid *)>(resolveFunc("glEdgeFlagPointer"));
+ DisableClientState = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDisableClientState"));
+ ColorPointer = reinterpret_cast<void (APIENTRY *)(GLint , GLenum , GLsizei , const GLvoid *)>(resolveFunc("glColorPointer"));
+ ArrayElement = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glArrayElement"));
+}
+
+void QWindowsOpenGL::resolveGLES2()
+{
+ ActiveTexture = reinterpret_cast<void (APIENTRY *)(GLenum)>(resolveFunc("glActiveTexture"));
+ AttachShader = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint )>(resolveFunc("glAttachShader"));
+ BindAttribLocation = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , const GLchar* )>(resolveFunc("glBindAttribLocation"));
+ BindBuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindBuffer"));
+ BindFramebuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindFramebuffer"));
+ BindRenderbuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindRenderbuffer"));
+ BlendColor = reinterpret_cast<void (APIENTRY *)(GLclampf , GLclampf , GLclampf , GLclampf )>(resolveFunc("glBlendColor"));
+ BlendEquation = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glBlendEquation"));
+ BlendEquationSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glBlendEquationSeparate"));
+ BlendFuncSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLenum )>(resolveFunc("glBlendFuncSeparate"));
+ BufferData = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizeiptr , const GLvoid* , GLenum )>(resolveFunc("glBufferData"));
+ BufferSubData = reinterpret_cast<void (APIENTRY *)(GLenum , GLintptr , GLsizeiptr , const GLvoid* )>(resolveFunc("glBufferSubData"));
+ CheckFramebufferStatus = reinterpret_cast<GLenum (APIENTRY *)(GLenum )>(resolveFunc("glCheckFramebufferStatus"));
+ ClearDepthf = reinterpret_cast<void (APIENTRY *)(GLclampf )>(resolveFunc("glClearDepthf"));
+ CompileShader = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glCompileShader"));
+ CompressedTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLsizei , GLsizei, GLint, GLsizei, const GLvoid* )>(resolveFunc("glCompressedTexImage2D"));
+ CompressedTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid* )>(resolveFunc("glCompressedTexSubImage2D"));
+ CreateProgram = reinterpret_cast<GLuint (APIENTRY *)(void)>(resolveFunc("glCreateProgram"));
+ CreateShader = reinterpret_cast<GLuint (APIENTRY *)(GLenum )>(resolveFunc("glCreateShader"));
+ DeleteBuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint*)>(resolveFunc("glDeleteBuffers"));
+ DeleteFramebuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint* )>(resolveFunc("glDeleteFramebuffers"));
+ DeleteProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glDeleteProgram"));
+ DeleteRenderbuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint* )>(resolveFunc("glDeleteRenderbuffers"));
+ DeleteShader = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glDeleteShader"));
+ DepthRangef = reinterpret_cast<void (APIENTRY *)(GLclampf , GLclampf )>(resolveFunc("glDepthRangef"));
+ DetachShader = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint )>(resolveFunc("glDetachShader"));
+ DisableVertexAttribArray = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glDisableVertexAttribArray"));
+ EnableVertexAttribArray = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glEnableVertexAttribArray"));
+ FramebufferRenderbuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLuint )>(resolveFunc("glFramebufferRenderbuffer"));
+ FramebufferTexture2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLuint , GLint )>(resolveFunc("glFramebufferTexture2D"));
+ GenBuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolveFunc("glGenBuffers"));
+ GenerateMipmap = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glGenerateMipmap"));
+ GenFramebuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolveFunc("glGenFramebuffers"));
+ GenRenderbuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolveFunc("glGenRenderbuffers"));
+ GetActiveAttrib = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLsizei , GLsizei* , GLint* , GLenum* , GLchar* )>(resolveFunc("glGetActiveAttrib"));
+ GetActiveUniform = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLsizei , GLsizei* , GLint* , GLenum* , GLchar* )>(resolveFunc("glGetActiveUniform"));
+ GetAttachedShaders = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei*, GLuint* )>(resolveFunc("glGetAttachedShaders"));
+ GetAttribLocation = reinterpret_cast<int (APIENTRY *)(GLuint , const GLchar* )>(resolveFunc("glGetAttribLocation"));
+ GetBufferParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* )>(resolveFunc("glGetBufferParameteriv"));
+ GetFramebufferAttachmentParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum, GLenum , GLint* )>(resolveFunc("glGetFramebufferAttachmentParameteriv"));
+ GetProgramiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolveFunc("glGetProgramiv"));
+ GetProgramInfoLog = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei* , GLchar* )>(resolveFunc("glGetProgramInfoLog"));
+ GetRenderbufferParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* )>(resolveFunc("glGetRenderbufferParameteriv"));
+ GetShaderiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolveFunc("glGetShaderiv"));
+ GetShaderInfoLog = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei*, GLchar*)>(resolveFunc("glGetShaderInfoLog"));
+ GetShaderPrecisionFormat = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* , GLint* )>(resolveFunc("glGetShaderPrecisionFormat"));
+ GetShaderSource = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei* , GLchar* )>(resolveFunc("glGetShaderSource"));
+ GetUniformfv = reinterpret_cast<void (APIENTRY *)(GLuint , GLint , GLfloat*)>(resolveFunc("glGetUniformfv"));
+ GetUniformiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLint , GLint*)>(resolveFunc("glGetUniformiv"));
+ GetUniformLocation = reinterpret_cast<int (APIENTRY *)(GLuint , const GLchar* )>(resolveFunc("glGetUniformLocation"));
+ GetVertexAttribfv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLfloat* )>(resolveFunc("glGetVertexAttribfv"));
+ GetVertexAttribiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolveFunc("glGetVertexAttribiv"));
+ GetVertexAttribPointerv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLvoid** pointer)>(resolveFunc("glGetVertexAttribPointerv"));
+ IsBuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsBuffer"));
+ IsFramebuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsFramebuffer"));
+ IsProgram = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsProgram"));
+ IsRenderbuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsRenderbuffer"));
+ IsShader = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsShader"));
+ LinkProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glLinkProgram"));
+ ReleaseShaderCompiler = reinterpret_cast<void (APIENTRY *)(void)>(resolveFunc("glReleaseShaderCompiler"));
+ RenderbufferStorage = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLsizei , GLsizei )>(resolveFunc("glRenderbufferStorage"));
+ SampleCoverage = reinterpret_cast<void (APIENTRY *)(GLclampf , GLboolean )>(resolveFunc("glSampleCoverage"));
+ ShaderBinary = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint*, GLenum , const GLvoid* , GLsizei )>(resolveFunc("glShaderBinary"));
+ ShaderSource = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , const GLchar* *, const GLint* )>(resolveFunc("glShaderSource"));
+ StencilFuncSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint , GLuint )>(resolveFunc("glStencilFuncSeparate"));
+ StencilMaskSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glStencilMaskSeparate"));
+ StencilOpSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLenum )>(resolveFunc("glStencilOpSeparate"));
+ Uniform1f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat )>(resolveFunc("glUniform1f"));
+ Uniform1fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform1fv"));
+ Uniform1i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glUniform1i"));
+ Uniform1iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform1iv"));
+ Uniform2f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat )>(resolveFunc("glUniform2f"));
+ Uniform2fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform2fv"));
+ Uniform2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glUniform2i"));
+ Uniform2iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform2iv"));
+ Uniform3f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLfloat )>(resolveFunc("glUniform3f"));
+ Uniform3fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform3fv"));
+ Uniform3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glUniform3i"));
+ Uniform3iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform3iv"));
+ Uniform4f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glUniform4f"));
+ Uniform4fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform4fv"));
+ Uniform4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint , GLint )>(resolveFunc("glUniform4i"));
+ Uniform4iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform4iv"));
+ UniformMatrix2fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolveFunc("glUniformMatrix2fv"));
+ UniformMatrix3fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolveFunc("glUniformMatrix3fv"));
+ UniformMatrix4fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolveFunc("glUniformMatrix4fv"));
+ UseProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glUseProgram"));
+ ValidateProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glValidateProgram"));
+ VertexAttrib1f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat )>(resolveFunc("glVertexAttrib1f"));
+ VertexAttrib1fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib1fv"));
+ VertexAttrib2f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat )>(resolveFunc("glVertexAttrib2f"));
+ VertexAttrib2fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib2fv"));
+ VertexAttrib3f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertexAttrib3f"));
+ VertexAttrib3fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib3fv"));
+ VertexAttrib4f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertexAttrib4f"));
+ VertexAttrib4fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib4fv"));
+ VertexAttribPointer = reinterpret_cast<void (APIENTRY *)(GLuint , GLint, GLenum, GLboolean, GLsizei, const GLvoid* )>(resolveFunc("glVertexAttribPointer"));
+}
+
+void QWindowsOpenGL::resolve()
+{
+ switch (libraryType()) {
+ case DesktopGL:
+ resolveWGL();
+ resolveGLCommon();
+ resolveGL11();
+ break;
+
+ case GLES2:
+ resolveEGL();
+ resolveGLCommon();
+ resolveGLES2();
+ break;
+
+ default:
+ Q_ASSERT_X(0, "QWindowsOpenGL", "Nothing to resolve");
+ break;
+ }
+}
+
+bool QWindowsOpenGL::testDesktopGL()
+{
+ HMODULE lib = 0;
+ HWND wnd = 0;
+ HDC dc = 0;
+ HGLRC context = 0;
+ LPCTSTR className = L"qtopenglproxytest";
+
+ HGLRC (WINAPI * CreateContext)(HDC dc) = 0;
+ BOOL (WINAPI * DeleteContext)(HGLRC context) = 0;
+ BOOL (WINAPI * MakeCurrent)(HDC dc, HGLRC context) = 0;
+ PROC (WINAPI * WGL_GetProcAddress)(LPCSTR name) = 0;
+
+ bool result = false;
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+ lib = qgl_loadLib("opengl32.dll", false);
+ if (lib) {
+ CreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(::GetProcAddress(lib, "wglCreateContext"));
+ if (!CreateContext)
+ goto cleanup;
+ DeleteContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC)>(::GetProcAddress(lib, "wglDeleteContext"));
+ if (!DeleteContext)
+ goto cleanup;
+ MakeCurrent = reinterpret_cast<BOOL (WINAPI *)(HDC, HGLRC)>(::GetProcAddress(lib, "wglMakeCurrent"));
+ if (!MakeCurrent)
+ goto cleanup;
+ WGL_GetProcAddress = reinterpret_cast<PROC (WINAPI *)(LPCSTR)>(::GetProcAddress(lib, "wglGetProcAddress"));
+ if (!WGL_GetProcAddress)
+ goto cleanup;
+
+ WNDCLASS wclass;
+ wclass.cbClsExtra = 0;
+ wclass.cbWndExtra = 0;
+ wclass.hInstance = (HINSTANCE) GetModuleHandle(0);
+ wclass.hIcon = 0;
+ wclass.hCursor = 0;
+ wclass.hbrBackground = (HBRUSH) (COLOR_BACKGROUND);
+ wclass.lpszMenuName = 0;
+ wclass.lpfnWndProc = DefWindowProc;
+ wclass.lpszClassName = className;
+ wclass.style = CS_OWNDC;
+ if (!RegisterClass(&wclass))
+ goto cleanup;
+ wnd = CreateWindow(className, L"qtopenglproxytest", WS_OVERLAPPED,
+ 0, 0, 640, 480, 0, 0, wclass.hInstance, 0);
+ if (!wnd)
+ goto cleanup;
+ dc = GetDC(wnd);
+ if (!dc)
+ goto cleanup;
+
+ PIXELFORMATDESCRIPTOR pfd;
+ memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ // Use the GDI functions. Under the hood this will call the wgl variants in opengl32.dll.
+ int pixelFormat = ChoosePixelFormat(dc, &pfd);
+ if (!pixelFormat)
+ goto cleanup;
+ if (!SetPixelFormat(dc, pixelFormat, &pfd))
+ goto cleanup;
+ context = CreateContext(dc);
+ if (!context)
+ goto cleanup;
+ if (!MakeCurrent(dc, context))
+ goto cleanup;
+
+ // Now that there is finally a context current, try doing something useful.
+ if (WGL_GetProcAddress("glCreateShader")) {
+ result = true;
+ qCDebug(qglLc, "OpenGL 2 entry points available");
+ } else {
+ qCDebug(qglLc, "OpenGL 2 entry points not found");
+ }
+ } else {
+ qCDebug(qglLc, "Failed to load opengl32.dll");
+ }
+
+cleanup:
+ if (MakeCurrent)
+ MakeCurrent(0, 0);
+ if (context)
+ DeleteContext(context);
+ if (dc && wnd)
+ ReleaseDC(wnd, dc);
+ if (wnd)
+ DestroyWindow(wnd);
+ UnregisterClass(className, GetModuleHandle(0));
+ if (lib)
+ FreeLibrary(lib);
+
+ return result;
+}
+
+class QWindowsOpenGLList
+{
+public:
+ QWindowsOpenGLList();
+ ~QWindowsOpenGLList();
+ QVector<QAbstractWindowsOpenGL *> list;
+};
+
+QWindowsOpenGLList::QWindowsOpenGLList()
+{
+ // For now there is always one OpenGL ( + winsys interface) loaded.
+ // This may change in the future.
+ list.append(new QWindowsOpenGL);
+}
+
+QWindowsOpenGLList::~QWindowsOpenGLList()
+{
+ qDeleteAll(list);
+}
+
+// Use Q_GLOBAL_STATIC and perform initialization in the constructor to be
+// thread safe.
+Q_GLOBAL_STATIC(QWindowsOpenGLList, gl)
+
+static inline QAbstractWindowsOpenGL *qgl_choose()
+{
+ return gl()->list[0];
+}
+
+// functionsReady() -> the DLL is there but some functions were not resolved. This is fatal.
+// !functionsReady() -> could not load a GL implementation. No error message in this case.
+#define GLWARN(g, func, prefix) \
+ { \
+ if (g->functionsReady()) \
+ qFatal("Qt OpenGL: Attempted to call unresolved function %s%s. " \
+ "This is likely caused by making OpenGL-only calls with an OpenGL ES implementation (Angle).", \
+ prefix, #func); \
+ }
+
+#define GLCALLV(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->func) \
+ g->func(__VA_ARGS__); \
+ else \
+ GLWARN(g, func, "gl") \
+ }
+
+#define GLCALL(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->func) \
+ return g->func(__VA_ARGS__); \
+ GLWARN(g, func, "gl") \
+ return 0; \
+ }
+
+#define WGLCALL(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->func) \
+ return g->func(__VA_ARGS__); \
+ GLWARN(g, func, "wgl") \
+ return 0; \
+ }
+
+#define EGLCALL(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->EGL_##func) \
+ return g->EGL_##func(__VA_ARGS__); \
+ GLWARN(g, func, "egl") \
+ return 0; \
+ }
+
+
+extern "C" {
+
+// WGL
+
+Q_DECL_EXPORT BOOL WINAPI wglCopyContext(HGLRC src, HGLRC dst, UINT mask)
+{
+ WGLCALL(CopyContext, src, dst, mask);
+}
+
+Q_DECL_EXPORT HGLRC WINAPI wglCreateContext(HDC dc)
+{
+ WGLCALL(CreateContext, dc);
+}
+
+Q_DECL_EXPORT HGLRC WINAPI wglCreateLayerContext(HDC dc, int plane)
+{
+ WGLCALL(CreateLayerContext, dc, plane);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglDeleteContext(HGLRC context)
+{
+ WGLCALL(DeleteContext, context);
+}
+
+Q_DECL_EXPORT HGLRC WINAPI wglGetCurrentContext(VOID)
+{
+ WGLCALL(GetCurrentContext);
+}
+
+Q_DECL_EXPORT HDC WINAPI wglGetCurrentDC(VOID)
+{
+ WGLCALL(GetCurrentDC);
+}
+
+Q_DECL_EXPORT PROC WINAPI wglGetProcAddress(LPCSTR name)
+{
+ WGLCALL(GetProcAddress, name);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglMakeCurrent(HDC dc, HGLRC context)
+{
+ WGLCALL(MakeCurrent, dc, context);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglShareLists(HGLRC context1, HGLRC context2)
+{
+ WGLCALL(ShareLists, context1, context2);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglUseFontBitmapsW(HDC dc, DWORD first, DWORD count, DWORD base)
+{
+ WGLCALL(UseFontBitmapsW, dc, first, count, base);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglUseFontOutlinesW(HDC dc, DWORD first, DWORD count, DWORD base, FLOAT deviation,
+ FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT gmf)
+{
+ WGLCALL(UseFontOutlinesW, dc, first, count, base, deviation, extrusion, format, gmf);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglDescribeLayerPlane(HDC dc, int pixelFormat, int plane, UINT n,
+ LPLAYERPLANEDESCRIPTOR planeDescriptor)
+{
+ WGLCALL(DescribeLayerPlane, dc, pixelFormat, plane, n, planeDescriptor);
+}
+
+Q_DECL_EXPORT int WINAPI wglSetLayerPaletteEntries(HDC dc, int plane, int start, int entries,
+ CONST COLORREF *colors)
+{
+ WGLCALL(SetLayerPaletteEntries, dc, plane, start, entries, colors);
+}
+
+Q_DECL_EXPORT int WINAPI wglGetLayerPaletteEntries(HDC dc, int plane, int start, int entries,
+ COLORREF *color)
+{
+ WGLCALL(GetLayerPaletteEntries, dc, plane, start, entries, color);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglRealizeLayerPalette(HDC dc, int plane, BOOL realize)
+{
+ WGLCALL(RealizeLayerPalette, dc, plane, realize);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglSwapLayerBuffers(HDC dc, UINT planes)
+{
+ WGLCALL(SwapLayerBuffers, dc, planes);
+}
+
+Q_DECL_EXPORT DWORD WINAPI wglSwapMultipleBuffers(UINT n, CONST WGLSWAP *buffers)
+{
+ WGLCALL(SwapMultipleBuffers, n, buffers);
+}
+
+// EGL
+
+Q_DECL_EXPORT EGLint EGLAPIENTRY eglGetError(void)
+{
+ EGLCALL(GetError);
+}
+
+Q_DECL_EXPORT EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
+{
+ EGLCALL(GetDisplay, display_id);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ EGLCALL(Initialize, dpy, major, minor);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
+{
+ EGLCALL(Terminate, dpy);
+}
+
+Q_DECL_EXPORT const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
+{
+ EGLCALL(QueryString, dpy, name);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
+{
+ EGLCALL(GetConfigs, dpy, configs, config_size, num_config);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config)
+{
+ EGLCALL(ChooseConfig, dpy, attrib_list, configs, config_size, num_config);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value)
+{
+ EGLCALL(GetConfigAttrib, dpy, config, attribute, value);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreateWindowSurface, dpy, config, win, attrib_list);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreatePbufferSurface, dpy, config, attrib_list);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreatePixmapSurface, dpy, config, pixmap, attrib_list);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ EGLCALL(DestroySurface, dpy, surface);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint *value)
+{
+ EGLCALL(QuerySurface, dpy, surface, attribute, value);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
+{
+ EGLCALL(BindAPI, api);
+}
+
+Q_DECL_EXPORT EGLenum EGLAPIENTRY eglQueryAPI(void)
+{
+ EGLCALL(QueryAPI);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglWaitClient(void)
+{
+ EGLCALL(WaitClient);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglReleaseThread(void)
+{
+ EGLCALL(ReleaseThread);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
+ EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+ EGLConfig config, const EGLint *attrib_list)
+{
+ EGLCALL(CreatePbufferFromClientBuffer, dpy, buftype, buffer, config, attrib_list);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint value)
+{
+ EGLCALL(SurfaceAttrib, dpy, surface, attribute, value);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EGLCALL(BindTexImage, dpy, surface, buffer);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EGLCALL(ReleaseTexImage, dpy, surface, buffer);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ EGLCALL(SwapInterval, dpy, interval);
+}
+
+Q_DECL_EXPORT EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreateContext, dpy, config, share_context, attrib_list);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ EGLCALL(DestroyContext, dpy, ctx);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx)
+{
+ EGLCALL(MakeCurrent, dpy, draw, read, ctx);
+}
+
+Q_DECL_EXPORT EGLContext EGLAPIENTRY eglGetCurrentContext(void)
+{
+ EGLCALL(GetCurrentContext);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
+{
+ EGLCALL(GetCurrentSurface, readdraw);
+}
+
+Q_DECL_EXPORT EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
+{
+ EGLCALL(GetCurrentDisplay);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value)
+{
+ EGLCALL(QueryContext, dpy, ctx, attribute, value);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglWaitGL(void)
+{
+ EGLCALL(WaitGL);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
+{
+ EGLCALL(WaitNative, engine);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ EGLCALL(SwapBuffers, dpy, surface);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
+ EGLNativePixmapType target)
+{
+ EGLCALL(CopyBuffers, dpy, surface, target);
+}
+
+// OpenGL
+
+Q_DECL_EXPORT void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLCALLV(Viewport, x, y, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthRange(GLdouble nearVal, GLdouble farVal)
+{
+ if (qgl_choose()->libraryType() == QAbstractWindowsOpenGL::DesktopGL) {
+ GLCALLV(DepthRange, nearVal, farVal);
+ } else {
+ GLCALLV(DepthRangef, nearVal, farVal);
+ }
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsEnabled(GLenum cap)
+{
+ GLCALL(IsEnabled, cap);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexLevelParameteriv, target, level, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexLevelParameterfv, target, level, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexParameteriv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexParameterfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
+{
+ GLCALLV(GetTexImage, target, level, format, type, pixels);
+}
+
+Q_DECL_EXPORT const GLubyte * APIENTRY glGetString(GLenum name)
+{
+ GLCALL(GetString, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetIntegerv(GLenum pname, GLint *params)
+{
+ GLCALLV(GetIntegerv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetFloatv(GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetFloatv, pname, params);
+}
+
+Q_DECL_EXPORT GLenum APIENTRY glGetError()
+{
+ GLCALL(GetError);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
+{
+ GLCALLV(GetDoublev, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetBooleanv(GLenum pname, GLboolean *params)
+{
+ GLCALLV(GetBooleanv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+{
+ GLCALLV(ReadPixels, x, y, width, height, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glReadBuffer(GLenum mode)
+{
+ GLCALLV(ReadBuffer, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+ GLCALLV(PixelStorei, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
+{
+ GLCALLV(PixelStoref, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthFunc(GLenum func)
+{
+ GLCALLV(DepthFunc, func);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GLCALLV(StencilOp, fail, zfail, zpass);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ GLCALLV(StencilFunc, func, ref, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glLogicOp(GLenum opcode)
+{
+ GLCALLV(LogicOp, opcode);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ GLCALLV(BlendFunc, sfactor, dfactor);
+}
+
+Q_DECL_EXPORT void APIENTRY glFlush()
+{
+ GLCALLV(Flush);
+}
+
+Q_DECL_EXPORT void APIENTRY glFinish()
+{
+ GLCALLV(Finish);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnable(GLenum cap)
+{
+ GLCALLV(Enable, cap);
+}
+
+Q_DECL_EXPORT void APIENTRY glDisable(GLenum cap)
+{
+ GLCALLV(Disable, cap);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthMask(GLboolean flag)
+{
+ GLCALLV(DepthMask, flag);
+}
+
+Q_DECL_EXPORT void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ GLCALLV(ColorMask, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilMask(GLuint mask)
+{
+ GLCALLV(StencilMask, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearDepth(GLdouble depth)
+{
+ if (qgl_choose()->libraryType() == QAbstractWindowsOpenGL::DesktopGL) {
+ GLCALLV(ClearDepth, depth);
+ } else {
+ GLCALLV(ClearDepthf, depth);
+ }
+}
+
+Q_DECL_EXPORT void APIENTRY glClearStencil(GLint s)
+{
+ GLCALLV(ClearStencil, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GLCALLV(ClearColor, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glClear(GLbitfield mask)
+{
+ GLCALLV(Clear, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawBuffer(GLenum mode)
+{
+ GLCALLV(DrawBuffer, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexImage1D, target, level, internalformat, width, border, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GLCALLV(TexParameteriv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GLCALLV(TexParameteri, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(TexParameterfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ GLCALLV(TexParameterf, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLCALLV(Scissor, x, y, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glPolygonMode(GLenum face, GLenum mode)
+{
+ GLCALLV(PolygonMode, face, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glPointSize(GLfloat size)
+{
+ GLCALLV(PointSize, size);
+}
+
+Q_DECL_EXPORT void APIENTRY glLineWidth(GLfloat width)
+{
+ GLCALLV(LineWidth, width);
+}
+
+Q_DECL_EXPORT void APIENTRY glHint(GLenum target, GLenum mode)
+{
+ GLCALLV(Hint, target, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glFrontFace(GLenum mode)
+{
+ GLCALLV(FrontFace, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glCullFace(GLenum mode)
+{
+ GLCALLV(CullFace, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Translatef, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Translated, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Scalef, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Scaled, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Rotatef, angle, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Rotated, angle, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushMatrix()
+{
+ GLCALLV(PushMatrix);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopMatrix()
+{
+ GLCALLV(PopMatrix);
+}
+
+Q_DECL_EXPORT void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ GLCALLV(Ortho, left, right, bottom, top, zNear, zFar);
+}
+
+Q_DECL_EXPORT void APIENTRY glMultMatrixd(const GLdouble *m)
+{
+ GLCALLV(MultMatrixd, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glMultMatrixf(const GLfloat *m)
+{
+ GLCALLV(MultMatrixf, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glMatrixMode(GLenum mode)
+{
+ GLCALLV(MatrixMode, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadMatrixd(const GLdouble *m)
+{
+ GLCALLV(LoadMatrixd, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadMatrixf(const GLfloat *m)
+{
+ GLCALLV(LoadMatrixf, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadIdentity()
+{
+ GLCALLV(LoadIdentity);
+}
+
+Q_DECL_EXPORT void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ GLCALLV(Frustum, left, right, bottom, top, zNear, zFar);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsList(GLuint list)
+{
+ GLCALL(IsList, list);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexGeniv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexGenfv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
+{
+ GLCALLV(GetTexGendv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexEnviv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexEnvfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPolygonStipple(GLubyte *mask)
+{
+ GLCALLV(GetPolygonStipple, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
+{
+ GLCALLV(GetPixelMapusv, map, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
+{
+ GLCALLV(GetPixelMapuiv, map, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
+{
+ GLCALLV(GetPixelMapfv, map, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
+{
+ GLCALLV(GetMaterialiv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetMaterialfv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
+{
+ GLCALLV(GetMapiv, target, query, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
+{
+ GLCALLV(GetMapfv, target, query, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
+{
+ GLCALLV(GetMapdv, target, query, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
+{
+ GLCALLV(GetLightiv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetLightfv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
+{
+ GLCALLV(GetClipPlane, plane, equation);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(DrawPixels, width, height, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
+{
+ GLCALLV(CopyPixels, x, y, width, height, type);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelMapusv(GLenum map, GLint mapsize, const GLushort *values)
+{
+ GLCALLV(PixelMapusv, map, mapsize, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelMapuiv(GLenum map, GLint mapsize, const GLuint *values)
+{
+ GLCALLV(PixelMapuiv, map, mapsize, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
+{
+ GLCALLV(PixelMapfv, map, mapsize, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelTransferi(GLenum pname, GLint param)
+{
+ GLCALLV(PixelTransferi, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
+{
+ GLCALLV(PixelTransferf, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
+{
+ GLCALLV(PixelZoom, xfactor, yfactor);
+}
+
+Q_DECL_EXPORT void APIENTRY glAlphaFunc(GLenum func, GLfloat ref)
+{
+ GLCALLV(AlphaFunc, func, ref);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalPoint2(GLint i, GLint j)
+{
+ GLCALLV(EvalPoint2, i, j);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
+{
+ GLCALLV(EvalMesh2, mode, i1, i2, j1, j2);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalPoint1(GLint i)
+{
+ GLCALLV(EvalPoint1, i);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
+{
+ GLCALLV(EvalMesh1, mode, i1, i2);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2fv(const GLfloat *u)
+{
+ GLCALLV(EvalCoord2fv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
+{
+ GLCALLV(EvalCoord2f, u, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2dv(const GLdouble *u)
+{
+ GLCALLV(EvalCoord2dv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
+{
+ GLCALLV(EvalCoord2d, u, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1fv(const GLfloat *u)
+{
+ GLCALLV(EvalCoord1fv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1f(GLfloat u)
+{
+ GLCALLV(EvalCoord1f, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1dv(const GLdouble *u)
+{
+ GLCALLV(EvalCoord1dv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1d(GLdouble u)
+{
+ GLCALLV(EvalCoord1d, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
+{
+ GLCALLV(MapGrid2f, un, u1, u2, vn, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
+{
+ GLCALLV(MapGrid2d, un, u1, u2, vn, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
+{
+ GLCALLV(MapGrid1f, un, u1, u2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
+{
+ GLCALLV(MapGrid1d, un, u1, u2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
+{
+ GLCALLV(Map2f, target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
+{
+ GLCALLV(Map2d, target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
+{
+ GLCALLV(Map1f, target, u1, u2, stride, order, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
+{
+ GLCALLV(Map1d, target, u1, u2, stride, order, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushAttrib(GLbitfield mask)
+{
+ GLCALLV(PushAttrib, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopAttrib()
+{
+ GLCALLV(PopAttrib);
+}
+
+Q_DECL_EXPORT void APIENTRY glAccum(GLenum op, GLfloat value)
+{
+ GLCALLV(Accum, op, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexMask(GLuint mask)
+{
+ GLCALLV(IndexMask, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearIndex(GLfloat c)
+{
+ GLCALLV(ClearIndex, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GLCALLV(ClearAccum, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushName(GLuint name)
+{
+ GLCALLV(PushName, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopName()
+{
+ GLCALLV(PopName);
+}
+
+Q_DECL_EXPORT void APIENTRY glPassThrough(GLfloat token)
+{
+ GLCALLV(PassThrough, token);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadName(GLuint name)
+{
+ GLCALLV(LoadName, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glInitNames()
+{
+ GLCALLV(InitNames);
+}
+
+Q_DECL_EXPORT GLint APIENTRY glRenderMode(GLenum mode)
+{
+ GLCALL(RenderMode, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
+{
+ GLCALLV(SelectBuffer, size, buffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
+{
+ GLCALLV(FeedbackBuffer, size, type, buffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+ GLCALLV(TexGeniv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
+{
+ GLCALLV(TexGeni, coord, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(TexGenfv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+ GLCALLV(TexGenf, coord, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
+{
+ GLCALLV(TexGendv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
+{
+ GLCALLV(TexGend, coord, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+ GLCALLV(TexEnviv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ GLCALLV(TexEnvi, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(TexEnvfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ GLCALLV(TexEnvf, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glShadeModel(GLenum mode)
+{
+ GLCALLV(ShadeModel, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glPolygonStipple(const GLubyte *mask)
+{
+ GLCALLV(PolygonStipple, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
+{
+ GLCALLV(Materialiv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
+{
+ GLCALLV(Materiali, face, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(Materialfv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+ GLCALLV(Materialf, face, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLineStipple(GLint factor, GLushort pattern)
+{
+ GLCALLV(LineStipple, factor, pattern);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
+{
+ GLCALLV(LightModeliv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModeli(GLenum pname, GLint param)
+{
+ GLCALLV(LightModeli, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
+{
+ GLCALLV(LightModelfv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModelf(GLenum pname, GLfloat param)
+{
+ GLCALLV(LightModelf, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
+{
+ GLCALLV(Lightiv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
+{
+ GLCALLV(Lighti, light, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(Lightfv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+ GLCALLV(Lightf, light, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogiv(GLenum pname, const GLint *params)
+{
+ GLCALLV(Fogiv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogi(GLenum pname, GLint param)
+{
+ GLCALLV(Fogi, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
+{
+ GLCALLV(Fogfv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogf(GLenum pname, GLfloat param)
+{
+ GLCALLV(Fogf, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glColorMaterial(GLenum face, GLenum mode)
+{
+ GLCALLV(ColorMaterial, face, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
+{
+ GLCALLV(ClipPlane, plane, equation);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4sv(const GLshort *v)
+{
+ GLCALLV(Vertex4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ GLCALLV(Vertex4s, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4iv(const GLint *v)
+{
+ GLCALLV(Vertex4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
+{
+ GLCALLV(Vertex4i, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4fv(const GLfloat *v)
+{
+ GLCALLV(Vertex4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(Vertex4f, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4dv(const GLdouble *v)
+{
+ GLCALLV(Vertex4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ GLCALLV(Vertex4d, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3sv(const GLshort *v)
+{
+ GLCALLV(Vertex3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
+{
+ GLCALLV(Vertex3s, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3iv(const GLint *v)
+{
+ GLCALLV(Vertex3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
+{
+ GLCALLV(Vertex3i, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3fv(const GLfloat *v)
+{
+ GLCALLV(Vertex3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Vertex3f, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3dv(const GLdouble *v)
+{
+ GLCALLV(Vertex3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Vertex3d, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2sv(const GLshort *v)
+{
+ GLCALLV(Vertex2sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2s(GLshort x, GLshort y)
+{
+ GLCALLV(Vertex2s, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2iv(const GLint *v)
+{
+ GLCALLV(Vertex2iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2i(GLint x, GLint y)
+{
+ GLCALLV(Vertex2i, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2fv(const GLfloat *v)
+{
+ GLCALLV(Vertex2fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2f(GLfloat x, GLfloat y)
+{
+ GLCALLV(Vertex2f, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2dv(const GLdouble *v)
+{
+ GLCALLV(Vertex2dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2d(GLdouble x, GLdouble y)
+{
+ GLCALLV(Vertex2d, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4sv(const GLshort *v)
+{
+ GLCALLV(TexCoord4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ GLCALLV(TexCoord4s, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4iv(const GLint *v)
+{
+ GLCALLV(TexCoord4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
+{
+ GLCALLV(TexCoord4i, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ GLCALLV(TexCoord4f, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ GLCALLV(TexCoord4d, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3sv(const GLshort *v)
+{
+ GLCALLV(TexCoord3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
+{
+ GLCALLV(TexCoord3s, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3iv(const GLint *v)
+{
+ GLCALLV(TexCoord3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
+{
+ GLCALLV(TexCoord3i, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
+{
+ GLCALLV(TexCoord3f, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
+{
+ GLCALLV(TexCoord3d, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2sv(const GLshort *v)
+{
+ GLCALLV(TexCoord2sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2s(GLshort s, GLshort t)
+{
+ GLCALLV(TexCoord2s, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2iv(const GLint *v)
+{
+ GLCALLV(TexCoord2iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2i(GLint s, GLint t)
+{
+ GLCALLV(TexCoord2i, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord2fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
+{
+ GLCALLV(TexCoord2f, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord2dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
+{
+ GLCALLV(TexCoord2d, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1sv(const GLshort *v)
+{
+ GLCALLV(TexCoord1sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1s(GLshort s)
+{
+ GLCALLV(TexCoord1s, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1iv(const GLint *v)
+{
+ GLCALLV(TexCoord1iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1i(GLint s)
+{
+ GLCALLV(TexCoord1i, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord1fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1f(GLfloat s)
+{
+ GLCALLV(TexCoord1f, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord1dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1d(GLdouble s)
+{
+ GLCALLV(TexCoord1d, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
+{
+ GLCALLV(Rectsv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
+{
+ GLCALLV(Rects, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
+{
+ GLCALLV(Rectiv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
+{
+ GLCALLV(Recti, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
+{
+ GLCALLV(Rectfv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ GLCALLV(Rectf, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
+{
+ GLCALLV(Rectdv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
+{
+ GLCALLV(Rectd, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4sv(const GLshort *v)
+{
+ GLCALLV(RasterPos4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ GLCALLV(RasterPos4s, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4iv(const GLint *v)
+{
+ GLCALLV(RasterPos4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+ GLCALLV(RasterPos4i, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4fv(const GLfloat *v)
+{
+ GLCALLV(RasterPos4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(RasterPos4f, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4dv(const GLdouble *v)
+{
+ GLCALLV(RasterPos4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ GLCALLV(RasterPos4d, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3sv(const GLshort *v)
+{
+ GLCALLV(RasterPos3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+ GLCALLV(RasterPos3s, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3iv(const GLint *v)
+{
+ GLCALLV(RasterPos3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
+{
+ GLCALLV(RasterPos3i, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3fv(const GLfloat *v)
+{
+ GLCALLV(RasterPos3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(RasterPos3f, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3dv(const GLdouble *v)
+{
+ GLCALLV(RasterPos3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(RasterPos3d, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2sv(const GLshort *v)
+{
+ GLCALLV(RasterPos2sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2s(GLshort x, GLshort y)
+{
+ GLCALLV(RasterPos2s, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2iv(const GLint *v)
+{
+ GLCALLV(RasterPos2iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2i(GLint x, GLint y)
+{
+ GLCALLV(RasterPos2i, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2fv(const GLfloat *v)
+{
+ GLCALLV(RasterPos2fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
+{
+ GLCALLV(RasterPos2f, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2dv(const GLdouble *v)
+{
+ GLCALLV(RasterPos2dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
+{
+ GLCALLV(RasterPos2d, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3sv(const GLshort *v)
+{
+ GLCALLV(Normal3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
+{
+ GLCALLV(Normal3s, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3iv(const GLint *v)
+{
+ GLCALLV(Normal3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
+{
+ GLCALLV(Normal3i, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3fv(const GLfloat *v)
+{
+ GLCALLV(Normal3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+ GLCALLV(Normal3f, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3dv(const GLdouble *v)
+{
+ GLCALLV(Normal3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
+{
+ GLCALLV(Normal3d, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3bv(const GLbyte *v)
+{
+ GLCALLV(Normal3bv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
+{
+ GLCALLV(Normal3b, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexsv(const GLshort *c)
+{
+ GLCALLV(Indexsv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexs(GLshort c)
+{
+ GLCALLV(Indexs, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexiv(const GLint *c)
+{
+ GLCALLV(Indexiv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexi(GLint c)
+{
+ GLCALLV(Indexi, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexfv(const GLfloat *c)
+{
+ GLCALLV(Indexfv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexf(GLfloat c)
+{
+ GLCALLV(Indexf, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexdv(const GLdouble *c)
+{
+ GLCALLV(Indexdv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexd(GLdouble c)
+{
+ GLCALLV(Indexd, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnd()
+{
+ GLCALLV(End);
+}
+
+Q_DECL_EXPORT void APIENTRY glEdgeFlagv(const GLboolean *flag)
+{
+ GLCALLV(EdgeFlagv, flag);
+}
+
+Q_DECL_EXPORT void APIENTRY glEdgeFlag(GLboolean flag)
+{
+ GLCALLV(EdgeFlag, flag);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4usv(const GLushort *v)
+{
+ GLCALLV(Color4usv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
+{
+ GLCALLV(Color4us, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4uiv(const GLuint *v)
+{
+ GLCALLV(Color4uiv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+{
+ GLCALLV(Color4ui, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4ubv(const GLubyte *v)
+{
+ GLCALLV(Color4ubv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+ GLCALLV(Color4ub, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4sv(const GLshort *v)
+{
+ GLCALLV(Color4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
+{
+ GLCALLV(Color4s, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4iv(const GLint *v)
+{
+ GLCALLV(Color4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
+{
+ GLCALLV(Color4i, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4fv(const GLfloat *v)
+{
+ GLCALLV(Color4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GLCALLV(Color4f, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4dv(const GLdouble *v)
+{
+ GLCALLV(Color4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
+{
+ GLCALLV(Color4d, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4bv(const GLbyte *v)
+{
+ GLCALLV(Color4bv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
+{
+ GLCALLV(Color4b, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3usv(const GLushort *v)
+{
+ GLCALLV(Color3usv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
+{
+ GLCALLV(Color3us, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3uiv(const GLuint *v)
+{
+ GLCALLV(Color3uiv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
+{
+ GLCALLV(Color3ui, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3ubv(const GLubyte *v)
+{
+ GLCALLV(Color3ubv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+ GLCALLV(Color3ub, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3sv(const GLshort *v)
+{
+ GLCALLV(Color3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
+{
+ GLCALLV(Color3s, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3iv(const GLint *v)
+{
+ GLCALLV(Color3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
+{
+ GLCALLV(Color3i, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3fv(const GLfloat *v)
+{
+ GLCALLV(Color3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+ GLCALLV(Color3f, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3dv(const GLdouble *v)
+{
+ GLCALLV(Color3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+ GLCALLV(Color3d, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3bv(const GLbyte *v)
+{
+ GLCALLV(Color3bv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+ GLCALLV(Color3b, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
+{
+ GLCALLV(Bitmap, width, height, xorig, yorig, xmove, ymove, bitmap);
+}
+
+Q_DECL_EXPORT void APIENTRY glBegin(GLenum mode)
+{
+ GLCALLV(Begin, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glListBase(GLuint base)
+{
+ GLCALLV(ListBase, base);
+}
+
+Q_DECL_EXPORT GLuint APIENTRY glGenLists(GLsizei range)
+{
+ GLCALL(GenLists, range);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteLists(GLuint list, GLsizei range)
+{
+ GLCALLV(DeleteLists, list, range);
+}
+
+Q_DECL_EXPORT void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
+{
+ GLCALLV(CallLists, n, type, lists);
+}
+
+Q_DECL_EXPORT void APIENTRY glCallList(GLuint list)
+{
+ GLCALLV(CallList, list);
+}
+
+Q_DECL_EXPORT void APIENTRY glEndList()
+{
+ GLCALLV(EndList);
+}
+
+Q_DECL_EXPORT void APIENTRY glNewList(GLuint list, GLenum mode)
+{
+ GLCALLV(NewList, list, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexubv(const GLubyte *c)
+{
+ GLCALLV(Indexubv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexub(GLubyte c)
+{
+ GLCALLV(Indexub, c);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsTexture(GLuint texture)
+{
+ GLCALL(IsTexture, texture);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenTextures(GLsizei n, GLuint *textures)
+{
+ GLCALLV(GenTextures, n, textures);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+ GLCALLV(DeleteTextures, n, textures);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+ GLCALLV(BindTexture, target, texture);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexSubImage1D, target, level, xoffset, width, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLCALLV(CopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+ GLCALLV(CopyTexSubImage1D, target, level, xoffset, x, y, width);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ GLCALLV(CopyTexImage2D, target, level, internalformat, x, y, width, height, border);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)
+{
+ GLCALLV(CopyTexImage1D, target, level, internalformat, x, y, width, border);
+}
+
+Q_DECL_EXPORT void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+ GLCALLV(PolygonOffset, factor, units);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
+{
+ GLCALLV(GetPointerv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+ GLCALLV(DrawElements, mode, count, type, indices);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ GLCALLV(DrawArrays, mode, first, count);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushClientAttrib(GLbitfield mask)
+{
+ GLCALLV(PushClientAttrib, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopClientAttrib()
+{
+ GLCALLV(PopClientAttrib);
+}
+
+Q_DECL_EXPORT void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities)
+{
+ GLCALLV(PrioritizeTextures, n, textures, priorities);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
+{
+ GLCALL(AreTexturesResident, n, textures, residences);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(VertexPointer, size, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(TexCoordPointer, size, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(NormalPointer, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(InterleavedArrays, format, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(IndexPointer, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnableClientState(GLenum array)
+{
+ GLCALLV(EnableClientState, array);
+}
+
+Q_DECL_EXPORT void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(EdgeFlagPointer, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glDisableClientState(GLenum array)
+{
+ GLCALLV(DisableClientState, array);
+}
+
+Q_DECL_EXPORT void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(ColorPointer, size, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glArrayElement(GLint i)
+{
+ GLCALLV(ArrayElement, i);
+}
+
+// OpenGL ES 2.0
+
+Q_DECL_EXPORT void APIENTRY glActiveTexture(GLenum texture)
+{
+ GLCALLV(ActiveTexture,texture);
+}
+
+Q_DECL_EXPORT void APIENTRY glAttachShader(GLuint program, GLuint shader)
+{
+ GLCALLV(AttachShader,program, shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+ GLCALLV(BindAttribLocation,program, index, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+ GLCALLV(BindBuffer,target, buffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ GLCALLV(BindFramebuffer,target, framebuffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ GLCALLV(BindRenderbuffer,target, renderbuffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ GLCALLV(BlendColor,red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendEquation(GLenum mode)
+{
+ GLCALLV(BlendEquation,mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ GLCALLV(BlendEquationSeparate,modeRGB, modeAlpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ GLCALLV(BlendFuncSeparate,srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ GLCALLV(BufferData,target, size, data, usage);
+}
+
+Q_DECL_EXPORT void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+ GLCALLV(BufferSubData,target, offset, size, data);
+}
+
+Q_DECL_EXPORT GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
+{
+ GLCALL(CheckFramebufferStatus,target);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearDepthf(GLclampf depth)
+{
+ glClearDepth(depth);
+}
+
+Q_DECL_EXPORT void APIENTRY glCompileShader(GLuint shader)
+{
+ GLCALLV(CompileShader,shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+ GLCALLV(CompressedTexImage2D,target, level, internalformat, width, height, border, imageSize, data);
+}
+
+Q_DECL_EXPORT void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+ GLCALLV(CompressedTexSubImage2D,target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+Q_DECL_EXPORT GLuint APIENTRY glCreateProgram(void)
+{
+ GLCALL(CreateProgram);
+}
+
+Q_DECL_EXPORT GLuint glCreateShader(GLenum type)
+{
+ GLCALL(CreateShader,type);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ GLCALLV(DeleteBuffers,n, buffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+ GLCALLV(DeleteFramebuffers,n, framebuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteProgram(GLuint program)
+{
+ GLCALLV(DeleteProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+ GLCALLV(DeleteRenderbuffers,n, renderbuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteShader(GLuint shader)
+{
+ GLCALLV(DeleteShader,shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+ glDepthRange(zNear, zFar);
+}
+
+Q_DECL_EXPORT void APIENTRY glDetachShader(GLuint program, GLuint shader)
+{
+ GLCALLV(DetachShader,program, shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glDisableVertexAttribArray(GLuint index)
+{
+ GLCALLV(DisableVertexAttribArray,index);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnableVertexAttribArray(GLuint index)
+{
+ GLCALLV(EnableVertexAttribArray,index);
+}
+
+Q_DECL_EXPORT void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ GLCALLV(FramebufferRenderbuffer,target, attachment, renderbuffertarget, renderbuffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ GLCALLV(FramebufferTexture2D,target, attachment, textarget, texture, level);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
+{
+ GLCALLV(GenBuffers,n, buffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenerateMipmap(GLenum target)
+{
+ GLCALLV(GenerateMipmap,target);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+ GLCALLV(GenFramebuffers,n, framebuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+ GLCALLV(GenRenderbuffers,n, renderbuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ GLCALLV(GetActiveAttrib,program, index, bufsize, length, size, type, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ GLCALLV(GetActiveUniform,program, index, bufsize, length, size, type, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ GLCALLV(GetAttachedShaders,program, maxcount, count, shaders);
+}
+
+Q_DECL_EXPORT int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
+{
+ GLCALL(GetAttribLocation,program, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ GLCALLV(GetBufferParameteriv,target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ GLCALLV(GetFramebufferAttachmentParameteriv,target, attachment, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ GLCALLV(GetProgramiv,program, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ GLCALLV(GetProgramInfoLog,program, bufsize, length, infolog);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ GLCALLV(GetRenderbufferParameteriv,target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ GLCALLV(GetShaderiv,shader, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ GLCALLV(GetShaderInfoLog,shader, bufsize, length, infolog);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ GLCALLV(GetShaderPrecisionFormat,shadertype, precisiontype, range, precision);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+ GLCALLV(GetShaderSource,shader, bufsize, length, source);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+ GLCALLV(GetUniformfv, program, location, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+ GLCALLV(GetUniformiv, program, location, params);
+}
+
+Q_DECL_EXPORT int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
+{
+ GLCALL(GetUniformLocation,program, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+ GLCALLV(GetVertexAttribfv,index, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+ GLCALLV(GetVertexAttribiv,index, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+ GLCALLV(GetVertexAttribPointerv,index, pname, pointer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsBuffer(GLuint buffer)
+{
+ GLCALL(IsBuffer,buffer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
+{
+ GLCALL(IsFramebuffer,framebuffer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsProgram(GLuint program)
+{
+ GLCALL(IsProgram,program);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
+{
+ GLCALL(IsRenderbuffer,renderbuffer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsShader(GLuint shader)
+{
+ GLCALL(IsShader,shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glLinkProgram(GLuint program)
+{
+ GLCALLV(LinkProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glReleaseShaderCompiler(void)
+{
+ GLCALLV(ReleaseShaderCompiler,);
+}
+
+Q_DECL_EXPORT void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ GLCALLV(RenderbufferStorage,target, internalformat, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+{
+ GLCALLV(SampleCoverage,value, invert);
+}
+
+Q_DECL_EXPORT void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+ GLCALLV(ShaderBinary,n, shaders, binaryformat, binary, length);
+}
+
+Q_DECL_EXPORT void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* *string, const GLint* length)
+{
+ GLCALLV(ShaderSource,shader, count, string, length);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ GLCALLV(StencilFuncSeparate,face, func, ref, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+ GLCALLV(StencilMaskSeparate,face, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GLCALLV(StencilOpSeparate,face, fail, zfail, zpass);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1f(GLint location, GLfloat x)
+{
+ GLCALLV(Uniform1f,location, x);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform1fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1i(GLint location, GLint x)
+{
+ GLCALLV(Uniform1i,location, x);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform1iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ GLCALLV(Uniform2f,location, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform2fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
+{
+ GLCALLV(Uniform2i,location, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform2iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Uniform3f,location, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform3fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ GLCALLV(Uniform3i,location, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform3iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(Uniform4f,location, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform4fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ GLCALLV(Uniform4i,location, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform4iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ GLCALLV(UniformMatrix2fv,location, count, transpose, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ GLCALLV(UniformMatrix3fv,location, count, transpose, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ GLCALLV(UniformMatrix4fv,location, count, transpose, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glUseProgram(GLuint program)
+{
+ GLCALLV(UseProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glValidateProgram(GLuint program)
+{
+ GLCALLV(ValidateProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+ GLCALLV(VertexAttrib1f,indx, x);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib1fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+ GLCALLV(VertexAttrib2f,indx, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib2fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(VertexAttrib3f,indx, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib3fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(VertexAttrib4f,indx, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib4fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+ GLCALLV(VertexAttribPointer,indx, size, type, normalized, stride, ptr);
+}
+
+// EGL
+
+Q_DECL_EXPORT __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
+{
+ // This is a bit more complicated since the GLES2 functions (that are not in OpenGL 1)
+ // must be made queriable in order to allow classes like QOpenGLFunctions to operate
+ // on the same code path for desktop GL and proxied ES.
+ typedef __eglMustCastToProperFunctionPointerType FuncType;
+ FuncType f = 0;
+ f = qgl_choose()->EGL_GetProcAddress(procname);
+ if (!f) {
+ static struct Tab {
+ const char *name;
+ FuncType func;
+ } tab[] = {
+ { "glActiveTexture", (FuncType) glActiveTexture },
+ { "glAttachShader", (FuncType) glAttachShader },
+ { "glBindAttribLocation", (FuncType) glBindAttribLocation },
+ { "glBindBuffer", (FuncType) glBindBuffer },
+ { "glBindFramebuffer", (FuncType) glBindFramebuffer },
+ { "glBindRenderbuffer", (FuncType) glBindRenderbuffer },
+ { "glBlendColor", (FuncType) glBlendColor },
+ { "glBlendEquation", (FuncType) glBlendEquation },
+ { "glBlendEquationSeparate", (FuncType) glBlendEquationSeparate },
+ { "glBlendFuncSeparate", (FuncType) glBlendFuncSeparate },
+ { "glBufferData", (FuncType) glBufferData },
+ { "glBufferSubData", (FuncType) glBufferSubData },
+ { "glCheckFramebufferStatus", (FuncType) glCheckFramebufferStatus },
+ { "glCompileShader", (FuncType) glCompileShader },
+ { "glCompressedTexImage2D", (FuncType) glCompressedTexImage2D },
+ { "glCompressedTexSubImage2D", (FuncType) glCompressedTexSubImage2D },
+ { "glCreateProgram", (FuncType) glCreateProgram },
+ { "glCreateShader", (FuncType) glCreateShader },
+ { "glDeleteBuffers", (FuncType) glDeleteBuffers },
+ { "glDeleteFramebuffers", (FuncType) glDeleteFramebuffers },
+ { "glDeleteProgram", (FuncType) glDeleteProgram },
+ { "glDeleteRenderbuffers", (FuncType) glDeleteRenderbuffers },
+ { "glDeleteShader", (FuncType) glDeleteShader },
+ { "glDetachShader", (FuncType) glDetachShader },
+ { "glDisableVertexAttribArray", (FuncType) glDisableVertexAttribArray },
+ { "glEnableVertexAttribArray", (FuncType) glEnableVertexAttribArray },
+ { "glFramebufferRenderbuffer", (FuncType) glFramebufferRenderbuffer },
+ { "glFramebufferTexture2D", (FuncType) glFramebufferTexture2D },
+ { "glGenBuffers", (FuncType) glGenBuffers },
+ { "glGenerateMipmap", (FuncType) glGenerateMipmap },
+ { "glGenFramebuffers", (FuncType) glGenFramebuffers },
+ { "glGenRenderbuffers", (FuncType) glGenRenderbuffers },
+ { "glGetActiveAttrib", (FuncType) glGetActiveAttrib },
+ { "glGetActiveUniform", (FuncType) glGetActiveUniform },
+ { "glGetAttachedShaders", (FuncType) glGetAttachedShaders },
+ { "glGetAttribLocation", (FuncType) glGetAttribLocation },
+ { "glGetBufferParameteriv", (FuncType) glGetBufferParameteriv },
+ { "glGetFramebufferAttachmentParameteriv", (FuncType) glGetFramebufferAttachmentParameteriv },
+ { "glGetProgramiv", (FuncType) glGetProgramiv },
+ { "glGetProgramInfoLog", (FuncType) glGetProgramInfoLog },
+ { "glGetRenderbufferParameteriv", (FuncType) glGetRenderbufferParameteriv },
+ { "glGetShaderiv", (FuncType) glGetShaderiv },
+ { "glGetShaderInfoLog", (FuncType) glGetShaderInfoLog },
+ { "glGetShaderPrecisionFormat", (FuncType) glGetShaderPrecisionFormat },
+ { "glGetShaderSource", (FuncType) glGetShaderSource },
+ { "glGetUniformfv", (FuncType) glGetUniformfv },
+ { "glGetUniformiv", (FuncType) glGetUniformiv },
+ { "glGetUniformLocation", (FuncType) glGetUniformLocation },
+ { "glGetVertexAttribfv", (FuncType) glGetVertexAttribfv },
+ { "glGetVertexAttribiv", (FuncType) glGetVertexAttribiv },
+ { "glGetVertexAttribPointerv", (FuncType) glGetVertexAttribPointerv },
+ { "glIsBuffer", (FuncType) glIsBuffer },
+ { "glIsFramebuffer", (FuncType) glIsFramebuffer },
+ { "glIsProgram", (FuncType) glIsProgram },
+ { "glIsRenderbuffer", (FuncType) glIsRenderbuffer },
+ { "glIsShader", (FuncType) glIsShader },
+ { "glLinkProgram", (FuncType) glLinkProgram },
+ { "glReleaseShaderCompiler", (FuncType) glReleaseShaderCompiler },
+ { "glRenderbufferStorage", (FuncType) glRenderbufferStorage },
+ { "glSampleCoverage", (FuncType) glSampleCoverage },
+ { "glShaderBinary", (FuncType) glShaderBinary },
+ { "glShaderSource", (FuncType) glShaderSource },
+ { "glStencilFuncSeparate", (FuncType) glStencilFuncSeparate },
+ { "glStencilMaskSeparate", (FuncType) glStencilMaskSeparate },
+ { "glStencilOpSeparate", (FuncType) glStencilOpSeparate },
+ { "glUniform1f", (FuncType) glUniform1f },
+ { "glUniform1fv", (FuncType) glUniform1fv },
+ { "glUniform1i", (FuncType) glUniform1i },
+ { "glUniform1iv", (FuncType) glUniform1iv },
+ { "glUniform2f", (FuncType) glUniform2f },
+ { "glUniform2fv", (FuncType) glUniform2fv },
+ { "glUniform2i", (FuncType) glUniform2i },
+ { "glUniform2iv", (FuncType) glUniform2iv },
+ { "glUniform3f", (FuncType) glUniform3f },
+ { "glUniform3fv", (FuncType) glUniform3fv },
+ { "glUniform3i", (FuncType) glUniform3i },
+ { "glUniform3iv", (FuncType) glUniform3iv },
+ { "glUniform4f", (FuncType) glUniform4f },
+ { "glUniform4fv", (FuncType) glUniform4fv },
+ { "glUniform4i", (FuncType) glUniform4i },
+ { "glUniform4iv", (FuncType) glUniform4iv },
+ { "glUniformMatrix2fv", (FuncType) glUniformMatrix2fv },
+ { "glUniformMatrix3fv", (FuncType) glUniformMatrix3fv },
+ { "glUniformMatrix4fv", (FuncType) glUniformMatrix4fv },
+ { "glUseProgram", (FuncType) glUseProgram },
+ { "glValidateProgram", (FuncType) glValidateProgram },
+ { "glVertexAttrib1f", (FuncType) glVertexAttrib1f },
+ { "glVertexAttrib1fv", (FuncType) glVertexAttrib1fv },
+ { "glVertexAttrib2f", (FuncType) glVertexAttrib2f },
+ { "glVertexAttrib2fv", (FuncType) glVertexAttrib2fv },
+ { "glVertexAttrib3f", (FuncType) glVertexAttrib3f },
+ { "glVertexAttrib3fv", (FuncType) glVertexAttrib3fv },
+ { "glVertexAttrib4f", (FuncType) glVertexAttrib4f },
+ { "glVertexAttrib4fv", (FuncType) glVertexAttrib4fv },
+ { "glVertexAttribPointer", (FuncType) glVertexAttribPointer }
+ };
+ for (size_t i = 0; i < sizeof(tab) / sizeof(Tab); ++i) {
+ uint len = qstrlen(tab[i].name);
+ if (!qstrncmp(tab[i].name, procname, len)
+ && procname[len] == '\0') {
+ f = tab[i].func;
+ break;
+ }
+ }
+ if (!f)
+ qCDebug(qglLc, "eglGetProcAddress failed for %s", procname);
+ }
+
+ return f;
+}
+
+} // extern "C"
+
+// For QOpenGLFunctions
+int qgl_proxyLibraryType(void)
+{
+ return qgl_choose()->libraryType();
+}
+
+HMODULE qgl_glHandle(void)
+{
+ return qgl_choose()->libraryHandle();
+}
+
+QAbstractWindowsOpenGL::QAbstractWindowsOpenGL()
+ :
+ CopyContext(0),
+ CreateContext(0),
+ CreateLayerContext(0),
+ DeleteContext(0),
+ GetCurrentContext(0),
+ GetCurrentDC(0),
+ GetProcAddress(0),
+ MakeCurrent(0),
+ ShareLists(0),
+ UseFontBitmapsW(0),
+ UseFontOutlinesW(0),
+ DescribeLayerPlane(0),
+ SetLayerPaletteEntries(0),
+ GetLayerPaletteEntries(0),
+ RealizeLayerPalette(0),
+ SwapLayerBuffers(0),
+ SwapMultipleBuffers(0),
+
+ EGL_GetError(0),
+ EGL_GetDisplay(0),
+ EGL_Initialize(0),
+ EGL_Terminate(0),
+ EGL_QueryString(0),
+ EGL_GetConfigs(0),
+ EGL_ChooseConfig(0),
+ EGL_GetConfigAttrib(0),
+ EGL_CreateWindowSurface(0),
+ EGL_CreatePbufferSurface(0),
+ EGL_CreatePixmapSurface(0),
+ EGL_DestroySurface(0),
+ EGL_QuerySurface(0),
+ EGL_BindAPI(0),
+ EGL_QueryAPI(0),
+ EGL_WaitClient(0),
+ EGL_ReleaseThread(0),
+ EGL_CreatePbufferFromClientBuffer(0),
+ EGL_SurfaceAttrib(0),
+ EGL_BindTexImage(0),
+ EGL_ReleaseTexImage(0),
+ EGL_SwapInterval(0),
+ EGL_CreateContext(0),
+ EGL_DestroyContext(0),
+ EGL_MakeCurrent (0),
+ EGL_GetCurrentContext(0),
+ EGL_GetCurrentSurface(0),
+ EGL_GetCurrentDisplay(0),
+ EGL_QueryContext(0),
+ EGL_WaitGL(0),
+ EGL_WaitNative(0),
+ EGL_SwapBuffers(0),
+ EGL_CopyBuffers(0),
+ EGL_GetProcAddress(0),
+
+ Viewport(0),
+ DepthRange(0),
+ IsEnabled(0),
+ GetTexLevelParameteriv(0),
+ GetTexLevelParameterfv(0),
+ GetTexParameteriv(0),
+ GetTexParameterfv(0),
+ GetTexImage(0),
+ GetString(0),
+ GetIntegerv(0),
+ GetFloatv(0),
+ GetError(0),
+ GetDoublev(0),
+ GetBooleanv(0),
+ ReadPixels(0),
+ ReadBuffer(0),
+ PixelStorei(0),
+ PixelStoref(0),
+ DepthFunc(0),
+ StencilOp(0),
+ StencilFunc(0),
+ LogicOp(0),
+ BlendFunc(0),
+ Flush(0),
+ Finish(0),
+ Enable(0),
+ Disable(0),
+ DepthMask(0),
+ ColorMask(0),
+ StencilMask(0),
+ ClearDepth(0),
+ ClearStencil(0),
+ ClearColor(0),
+ Clear(0),
+ DrawBuffer(0),
+ TexImage2D(0),
+ TexImage1D(0),
+ TexParameteriv(0),
+ TexParameteri(0),
+ TexParameterfv(0),
+ TexParameterf(0),
+ Scissor(0),
+ PolygonMode(0),
+ PointSize(0),
+ LineWidth(0),
+ Hint(0),
+ FrontFace(0),
+ CullFace(0),
+
+ Translatef(0),
+ Translated(0),
+ Scalef(0),
+ Scaled(0),
+ Rotatef(0),
+ Rotated(0),
+ PushMatrix(0),
+ PopMatrix(0),
+ Ortho(0),
+ MultMatrixd(0),
+ MultMatrixf(0),
+ MatrixMode(0),
+ LoadMatrixd(0),
+ LoadMatrixf(0),
+ LoadIdentity(0),
+ Frustum(0),
+ IsList(0),
+ GetTexGeniv(0),
+ GetTexGenfv(0),
+ GetTexGendv(0),
+ GetTexEnviv(0),
+ GetTexEnvfv(0),
+ GetPolygonStipple(0),
+ GetPixelMapusv(0),
+ GetPixelMapuiv(0),
+ GetPixelMapfv(0),
+ GetMaterialiv(0),
+ GetMaterialfv(0),
+ GetMapiv(0),
+ GetMapfv(0),
+ GetMapdv(0),
+ GetLightiv(0),
+ GetLightfv(0),
+ GetClipPlane(0),
+ DrawPixels(0),
+ CopyPixels(0),
+ PixelMapusv(0),
+ PixelMapuiv(0),
+ PixelMapfv(0),
+ PixelTransferi(0),
+ PixelTransferf(0),
+ PixelZoom(0),
+ AlphaFunc(0),
+ EvalPoint2(0),
+ EvalMesh2(0),
+ EvalPoint1(0),
+ EvalMesh1(0),
+ EvalCoord2fv(0),
+ EvalCoord2f(0),
+ EvalCoord2dv(0),
+ EvalCoord2d(0),
+ EvalCoord1fv(0),
+ EvalCoord1f(0),
+ EvalCoord1dv(0),
+ EvalCoord1d(0),
+ MapGrid2f(0),
+ MapGrid2d(0),
+ MapGrid1f(0),
+ MapGrid1d(0),
+ Map2f(0),
+ Map2d(0),
+ Map1f(0),
+ Map1d(0),
+ PushAttrib(0),
+ PopAttrib(0),
+ Accum(0),
+ IndexMask(0),
+ ClearIndex(0),
+ ClearAccum(0),
+ PushName(0),
+ PopName(0),
+ PassThrough(0),
+ LoadName(0),
+ InitNames(0),
+ RenderMode(0),
+ SelectBuffer(0),
+ FeedbackBuffer(0),
+ TexGeniv(0),
+ TexGeni(0),
+ TexGenfv(0),
+ TexGenf(0),
+ TexGendv(0),
+ TexGend(0),
+ TexEnviv(0),
+ TexEnvi(0),
+ TexEnvfv(0),
+ TexEnvf(0),
+ ShadeModel(0),
+ PolygonStipple(0),
+ Materialiv(0),
+ Materiali(0),
+ Materialfv(0),
+ Materialf(0),
+ LineStipple(0),
+ LightModeliv(0),
+ LightModeli(0),
+ LightModelfv(0),
+ LightModelf(0),
+ Lightiv(0),
+ Lighti(0),
+ Lightfv(0),
+ Lightf(0),
+ Fogiv(0),
+ Fogi(0),
+ Fogfv(0),
+ Fogf(0),
+ ColorMaterial(0),
+ ClipPlane(0),
+ Vertex4sv(0),
+ Vertex4s(0),
+ Vertex4iv(0),
+ Vertex4i(0),
+ Vertex4fv(0),
+ Vertex4f(0),
+ Vertex4dv(0),
+ Vertex4d(0),
+ Vertex3sv(0),
+ Vertex3s(0),
+ Vertex3iv(0),
+ Vertex3i(0),
+ Vertex3fv(0),
+ Vertex3f(0),
+ Vertex3dv(0),
+ Vertex3d(0),
+ Vertex2sv(0),
+ Vertex2s(0),
+ Vertex2iv(0),
+ Vertex2i(0),
+ Vertex2fv(0),
+ Vertex2f(0),
+ Vertex2dv(0),
+ Vertex2d(0),
+ TexCoord4sv(0),
+ TexCoord4s(0),
+ TexCoord4iv(0),
+ TexCoord4i(0),
+ TexCoord4fv(0),
+ TexCoord4f(0),
+ TexCoord4dv(0),
+ TexCoord4d(0),
+ TexCoord3sv(0),
+ TexCoord3s(0),
+ TexCoord3iv(0),
+ TexCoord3i(0),
+ TexCoord3fv(0),
+ TexCoord3f(0),
+ TexCoord3dv(0),
+ TexCoord3d(0),
+ TexCoord2sv(0),
+ TexCoord2s(0),
+ TexCoord2iv(0),
+ TexCoord2i(0),
+ TexCoord2fv(0),
+ TexCoord2f(0),
+ TexCoord2dv(0),
+ TexCoord2d(0),
+ TexCoord1sv(0),
+ TexCoord1s(0),
+ TexCoord1iv(0),
+ TexCoord1i(0),
+ TexCoord1fv(0),
+ TexCoord1f(0),
+ TexCoord1dv(0),
+ TexCoord1d(0),
+ Rectsv(0),
+ Rects(0),
+ Rectiv(0),
+ Recti(0),
+ Rectfv(0),
+ Rectf(0),
+ Rectdv(0),
+ Rectd(0),
+ RasterPos4sv(0),
+ RasterPos4s(0),
+ RasterPos4iv(0),
+ RasterPos4i(0),
+ RasterPos4fv(0),
+ RasterPos4f(0),
+ RasterPos4dv(0),
+ RasterPos4d(0),
+ RasterPos3sv(0),
+ RasterPos3s(0),
+ RasterPos3iv(0),
+ RasterPos3i(0),
+ RasterPos3fv(0),
+ RasterPos3f(0),
+ RasterPos3dv(0),
+ RasterPos3d(0),
+ RasterPos2sv(0),
+ RasterPos2s(0),
+ RasterPos2iv(0),
+ RasterPos2i(0),
+ RasterPos2fv(0),
+ RasterPos2f(0),
+ RasterPos2dv(0),
+ RasterPos2d(0),
+ Normal3sv(0),
+ Normal3s(0),
+ Normal3iv(0),
+ Normal3i(0),
+ Normal3fv(0),
+ Normal3f(0),
+ Normal3dv(0),
+ Normal3d(0),
+ Normal3bv(0),
+ Normal3b(0),
+ Indexsv(0),
+ Indexs(0),
+ Indexiv(0),
+ Indexi(0),
+ Indexfv(0),
+ Indexf(0),
+ Indexdv(0),
+ Indexd(0),
+ End(0),
+ EdgeFlagv(0),
+ EdgeFlag(0),
+ Color4usv(0),
+ Color4us(0),
+ Color4uiv(0),
+ Color4ui(0),
+ Color4ubv(0),
+ Color4ub(0),
+ Color4sv(0),
+ Color4s(0),
+ Color4iv(0),
+ Color4i(0),
+ Color4fv(0),
+ Color4f(0),
+ Color4dv(0),
+ Color4d(0),
+ Color4bv(0),
+ Color4b(0),
+ Color3usv(0),
+ Color3us(0),
+ Color3uiv(0),
+ Color3ui(0),
+ Color3ubv(0),
+ Color3ub(0),
+ Color3sv(0),
+ Color3s(0),
+ Color3iv(0),
+ Color3i(0),
+ Color3fv(0),
+ Color3f(0),
+ Color3dv(0),
+ Color3d(0),
+ Color3bv(0),
+ Color3b(0),
+ Bitmap(0),
+ Begin(0),
+ ListBase(0),
+ GenLists(0),
+ DeleteLists(0),
+ CallLists(0),
+ CallList(0),
+ EndList(0),
+ NewList(0),
+
+ Indexubv(0),
+ Indexub(0),
+ IsTexture(0),
+ GenTextures(0),
+ DeleteTextures(0),
+ BindTexture(0),
+ TexSubImage2D(0),
+ TexSubImage1D(0),
+ CopyTexSubImage2D(0),
+ CopyTexSubImage1D(0),
+ CopyTexImage2D(0),
+ CopyTexImage1D(0),
+ PolygonOffset(0),
+ GetPointerv(0),
+ DrawElements(0),
+ DrawArrays(0),
+
+ PushClientAttrib(0),
+ PopClientAttrib(0),
+ PrioritizeTextures(0),
+ AreTexturesResident(0),
+ VertexPointer(0),
+ TexCoordPointer(0),
+ NormalPointer(0),
+ InterleavedArrays(0),
+ IndexPointer(0),
+ EnableClientState(0),
+ EdgeFlagPointer(0),
+ DisableClientState(0),
+ ColorPointer(0),
+ ArrayElement(0),
+
+ ActiveTexture(0),
+ AttachShader(0),
+ BindAttribLocation(0),
+ BindBuffer(0),
+ BindFramebuffer(0),
+ BindRenderbuffer(0),
+ BlendColor(0),
+ BlendEquation(0),
+ BlendEquationSeparate(0),
+ BlendFuncSeparate(0),
+ BufferData(0),
+ BufferSubData(0),
+ CheckFramebufferStatus(0),
+ ClearDepthf(0),
+ CompileShader(0),
+ CompressedTexImage2D(0),
+ CompressedTexSubImage2D(0),
+ CreateProgram(0),
+ CreateShader(0),
+ DeleteBuffers(0),
+ DeleteFramebuffers(0),
+ DeleteProgram(0),
+ DeleteRenderbuffers(0),
+ DeleteShader(0),
+ DepthRangef(0),
+ DetachShader(0),
+ DisableVertexAttribArray(0),
+ EnableVertexAttribArray(0),
+ FramebufferRenderbuffer(0),
+ FramebufferTexture2D(0),
+ GenBuffers(0),
+ GenerateMipmap(0),
+ GenFramebuffers(0),
+ GenRenderbuffers(0),
+ GetActiveAttrib(0),
+ GetActiveUniform(0),
+ GetAttachedShaders(0),
+ GetAttribLocation(0),
+ GetBufferParameteriv(0),
+ GetFramebufferAttachmentParameteriv(0),
+ GetProgramiv(0),
+ GetProgramInfoLog(0),
+ GetRenderbufferParameteriv(0),
+ GetShaderiv(0),
+ GetShaderInfoLog(0),
+ GetShaderPrecisionFormat(0),
+ GetShaderSource(0),
+ GetUniformfv(0),
+ GetUniformiv(0),
+ GetUniformLocation(0),
+ GetVertexAttribfv(0),
+ GetVertexAttribiv(0),
+ GetVertexAttribPointerv(0),
+ IsBuffer(0),
+ IsFramebuffer(0),
+ IsProgram(0),
+ IsRenderbuffer(0),
+ IsShader(0),
+ LinkProgram(0),
+ ReleaseShaderCompiler(0),
+ RenderbufferStorage(0),
+ SampleCoverage(0),
+ ShaderBinary(0),
+ ShaderSource(0),
+ StencilFuncSeparate(0),
+ StencilMaskSeparate(0),
+ StencilOpSeparate(0),
+ Uniform1f(0),
+ Uniform1fv(0),
+ Uniform1i(0),
+ Uniform1iv(0),
+ Uniform2f(0),
+ Uniform2fv(0),
+ Uniform2i(0),
+ Uniform2iv(0),
+ Uniform3f(0),
+ Uniform3fv(0),
+ Uniform3i(0),
+ Uniform3iv(0),
+ Uniform4f(0),
+ Uniform4fv(0),
+ Uniform4i(0),
+ Uniform4iv(0),
+ UniformMatrix2fv(0),
+ UniformMatrix3fv(0),
+ UniformMatrix4fv(0),
+ UseProgram(0),
+ ValidateProgram(0),
+ VertexAttrib1f(0),
+ VertexAttrib1fv(0),
+ VertexAttrib2f(0),
+ VertexAttrib2fv(0),
+ VertexAttrib3f(0),
+ VertexAttrib3fv(0),
+ VertexAttrib4f(0),
+ VertexAttrib4fv(0),
+ VertexAttribPointer(0),
+
+ m_lib(0),
+ m_libraryType(DesktopGL),
+ m_loaded(false)
+{
+}
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index ecc38b902c..06f40eafd0 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -175,13 +175,15 @@ public:
#endif
{
#ifndef QT_OPENGL_ES_2
- QSurfaceFormat f = ctx->format();
-
- // Geometry shaders require OpenGL >= 3.2
- if (shaderType & QOpenGLShader::Geometry)
- supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
- else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
- supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
+ if (!QOpenGLFunctions::isES()) {
+ QSurfaceFormat f = ctx->format();
+
+ // Geometry shaders require OpenGL >= 3.2
+ if (shaderType & QOpenGLShader::Geometry)
+ supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
+ else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
+ supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
+ }
#endif
}
~QOpenGLShaderPrivate();
@@ -441,7 +443,8 @@ bool QOpenGLShader::compileSourceCode(const char *source)
}
#ifdef QOpenGL_REDEFINE_HIGHP
- if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers) {
+ if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers
+ && QOpenGLFunctions::isES()) {
src.append(redefineHighp);
srclen.append(GLint(sizeof(redefineHighp) - 1));
}
@@ -650,7 +653,8 @@ bool QOpenGLShaderProgram::init()
#ifndef QT_OPENGL_ES_2
// Resolve OpenGL 4 functions for tessellation shader support
QSurfaceFormat format = context->format();
- if (format.version() >= qMakePair<int, int>(4, 0)) {
+ if (!QOpenGLFunctions::isES()
+ && format.version() >= qMakePair<int, int>(4, 0)) {
d->tessellationFuncs = context->versionFunctions<QOpenGLFunctions_4_0_Core>();
d->tessellationFuncs->initializeOpenGLFunctions();
}
@@ -3248,14 +3252,16 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
#ifndef QT_OPENGL_ES_2
// Geometry shaders require OpenGL 3.2 or newer
QSurfaceFormat format = context->format();
- return (format.version() >= qMakePair<int, int>(3, 2));
+ return (!QOpenGLFunctions::isES())
+ && (format.version() >= qMakePair<int, int>(3, 2));
#else
// No geometry shader support in OpenGL ES2
return false;
#endif
} else if (type == TessellationControl || type == TessellationEvaluation) {
#if !defined(QT_OPENGL_ES_2)
- return (format.version() >= qMakePair<int, int>(4, 0));
+ return (!QOpenGLFunctions::isES())
+ && (format.version() >= qMakePair<int, int>(4, 0));
#else
// No tessellation shader support in OpenGL ES2
return false;
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index d9b2e82d0b..8bdbdba6f7 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -319,42 +319,70 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
return;
case QOpenGLTexture::Target1D:
- for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage1D(textureId, target, level, format,
- mipLevelSize(level, dimensions[0]),
- 0,
- QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
+ if (features.testFlag(QOpenGLTexture::Texture1D)) {
+ for (int level = 0; level < mipLevels; ++level)
+ texFuncs->glTextureImage1D(textureId, target, bindingTarget, level, format,
+ mipLevelSize(level, dimensions[0]),
+ 0,
+ QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
+ } else {
+ qWarning("1D textures are not supported");
+ return;
+ }
break;
case QOpenGLTexture::Target1DArray:
- if (features.testFlag(QOpenGLTexture::TextureArrays)) {
+ if (features.testFlag(QOpenGLTexture::Texture1D)
+ && features.testFlag(QOpenGLTexture::TextureArrays)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage2D(textureId, target, level, format,
+ texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
layers,
0,
QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
} else {
- qWarning("Array textures are not supported");
+ qWarning("1D array textures are not supported");
return;
}
break;
case QOpenGLTexture::Target2D:
- case QOpenGLTexture::TargetCubeMap:
case QOpenGLTexture::TargetRectangle:
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage2D(textureId, target, level, format,
+ texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
0,
QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
break;
+ case QOpenGLTexture::TargetCubeMap: {
+ // Cubemaps are the odd one out. We have to allocate storage for each
+ // face and miplevel using the special cubemap face targets rather than
+ // GL_TARGET_CUBEMAP.
+ const QOpenGLTexture::CubeMapFace faceTargets[] = {
+ QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapNegativeX,
+ QOpenGLTexture::CubeMapPositiveY, QOpenGLTexture::CubeMapNegativeY,
+ QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeZ
+ };
+
+ for (int faceTarget = 0; faceTarget < 6; ++faceTarget) {
+ for (int level = 0; level < mipLevels; ++level) {
+ texFuncs->glTextureImage2D(textureId, faceTargets[faceTarget], bindingTarget,
+ level, format,
+ mipLevelSize(level, dimensions[0]),
+ mipLevelSize(level, dimensions[1]),
+ 0,
+ QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
+ }
+ }
+ break;
+ }
+
case QOpenGLTexture::Target2DArray:
if (features.testFlag(QOpenGLTexture::TextureArrays)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage3D(textureId, target, level, format,
+ texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
layers,
@@ -370,7 +398,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
// Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage3D(textureId, target, level, format,
+ texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
6 * layers,
@@ -385,7 +413,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
case QOpenGLTexture::Target3D:
if (features.testFlag(QOpenGLTexture::Texture3D)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage3D(textureId, target, level, format,
+ texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
mipLevelSize(level, dimensions[2]),
@@ -399,7 +427,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
case QOpenGLTexture::Target2DMultisample:
if (features.testFlag(QOpenGLTexture::TextureMultisample)) {
- texFuncs->glTextureImage2DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureImage2DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1],
fixedSamplePositions);
} else {
@@ -411,7 +439,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
case QOpenGLTexture::Target2DMultisampleArray:
if (features.testFlag(QOpenGLTexture::TextureMultisample)
&& features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureImage3DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureImage3DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1], layers,
fixedSamplePositions);
} else {
@@ -433,16 +461,22 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
return;
case QOpenGLTexture::Target1D:
- texFuncs->glTextureStorage1D(textureId, target, mipLevels, format,
- dimensions[0]);
+ if (features.testFlag(QOpenGLTexture::Texture1D)) {
+ texFuncs->glTextureStorage1D(textureId, target, bindingTarget, mipLevels, format,
+ dimensions[0]);
+ } else {
+ qWarning("1D textures are not supported");
+ return;
+ }
break;
case QOpenGLTexture::Target1DArray:
- if (features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureStorage2D(textureId, target, mipLevels, format,
+ if (features.testFlag(QOpenGLTexture::Texture1D)
+ && features.testFlag(QOpenGLTexture::TextureArrays)) {
+ texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], layers);
} else {
- qWarning("Array textures are not supported");
+ qWarning("1D array textures are not supported");
return;
}
break;
@@ -450,13 +484,13 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target2D:
case QOpenGLTexture::TargetCubeMap:
case QOpenGLTexture::TargetRectangle:
- texFuncs->glTextureStorage2D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1]);
break;
case QOpenGLTexture::Target2DArray:
if (features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureStorage3D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1], layers);
} else {
qWarning("Array textures are not supported");
@@ -467,7 +501,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::TargetCubeMapArray:
// Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) {
- texFuncs->glTextureStorage3D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1], 6 * layers);
} else {
qWarning("Cubemap Array textures are not supported");
@@ -477,7 +511,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target3D:
if (features.testFlag(QOpenGLTexture::Texture3D)) {
- texFuncs->glTextureStorage3D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1], dimensions[2]);
} else {
qWarning("3D textures are not supported");
@@ -487,7 +521,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target2DMultisample:
if (features.testFlag(QOpenGLTexture::TextureMultisample)) {
- texFuncs->glTextureStorage2DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureStorage2DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1],
fixedSamplePositions);
} else {
@@ -499,7 +533,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target2DMultisampleArray:
if (features.testFlag(QOpenGLTexture::TextureMultisample)
&& features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureStorage3DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureStorage3DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1], layers,
fixedSamplePositions);
} else {
@@ -514,20 +548,20 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options)
+ const void *data, const QOpenGLPixelTransferOptions * const options)
{
switch (target) {
case QOpenGLTexture::Target1D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage1D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
0, mipLevelSize( mipLevel, dimensions[0] ),
sourceFormat, sourceType, data, options);
break;
case QOpenGLTexture::Target1DArray:
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, layer,
mipLevelSize(mipLevel, dimensions[0]),
1,
@@ -536,7 +570,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::Target2D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -545,7 +579,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::Target2DArray:
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -555,7 +589,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::Target3D:
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -565,7 +599,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::TargetCubeMap:
Q_UNUSED(layer);
- texFuncs->glTextureSubImage2D(textureId, cubeFace, mipLevel,
+ texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -575,7 +609,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::TargetCubeMapArray: {
int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
int layerFace = 6 * layer + faceIndex;
- texFuncs->glTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layerFace,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -588,7 +622,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
Q_UNUSED(mipLevel);
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage2D(textureId, target, 0,
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0,
0, 0,
dimensions[0],
dimensions[1],
@@ -611,21 +645,21 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
}
void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options)
{
switch (target) {
case QOpenGLTexture::Target1D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage1D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
0, mipLevelSize( mipLevel, dimensions[0] ),
format, dataSize, data, options);
break;
case QOpenGLTexture::Target1DArray:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, layer,
mipLevelSize(mipLevel, dimensions[0]),
1,
@@ -634,7 +668,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::Target2D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -643,7 +677,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::Target2DArray:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -653,7 +687,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::Target3D:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -663,7 +697,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::TargetCubeMap:
Q_UNUSED(layer);
- texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, mipLevel,
+ texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -673,7 +707,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::TargetCubeMapArray: {
int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
int layerFace = 6 * layer + faceIndex;
- texFuncs->glCompressedTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layerFace,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -686,7 +720,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
Q_UNUSED(mipLevel);
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, 0,
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, 0,
0, 0,
dimensions[0],
dimensions[1],
@@ -715,7 +749,7 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::WrapMode mode)
case QOpenGLTexture::Target1DArray:
case QOpenGLTexture::TargetBuffer:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
break;
case QOpenGLTexture::Target2D:
@@ -726,15 +760,15 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::WrapMode mode)
case QOpenGLTexture::Target2DMultisampleArray:
case QOpenGLTexture::TargetRectangle:
wrapModes[0] = wrapModes[1] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_T, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
break;
case QOpenGLTexture::Target3D:
wrapModes[0] = wrapModes[1] = wrapModes[2] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_T, mode);
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_R, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_R, mode);
break;
}
}
@@ -748,7 +782,7 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection dire
switch (direction) {
case QOpenGLTexture::DirectionS:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
break;
case QOpenGLTexture::DirectionT:
@@ -768,12 +802,12 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection dire
switch (direction) {
case QOpenGLTexture::DirectionS:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
break;
case QOpenGLTexture::DirectionT:
wrapModes[1] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_T, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
break;
case QOpenGLTexture::DirectionR:
@@ -786,17 +820,17 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection dire
switch (direction) {
case QOpenGLTexture::DirectionS:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, direction, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
break;
case QOpenGLTexture::DirectionT:
wrapModes[1] = mode;
- texFuncs->glTextureParameteri(textureId, target, direction, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
break;
case QOpenGLTexture::DirectionR:
wrapModes[2] = mode;
- texFuncs->glTextureParameteri(textureId, target, direction, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
break;
}
break;
@@ -1367,6 +1401,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
\value NPOTTextures Basic support for non-power-of-two textures
\value NPOTTextureRepeat Full support for non-power-of-two textures including texture
repeat modes
+ \value Texture1D Support for the 1 dimensional texture target
*/
/*!
@@ -2135,6 +2170,65 @@ bool QOpenGLTexture::isTextureView() const
If using a compressed format() then you should use setCompressedData() instead of this
function.
+ \since 5.3
+ \sa setCompressedData()
+*/
+void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ if (!isStorageAllocated()) {
+ qWarning("Cannot set data on a texture that does not have storage allocated.\n"
+ "To do so call allocate() before this function");
+ return;
+ }
+ d->setData(mipLevel, layer, cubeFace, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \since 5.3
+ \overload
+*/
+void QOpenGLTexture::setData(int mipLevel, int layer,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(mipLevel, layer, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \since 5.3
+ \overload
+*/
+void QOpenGLTexture::setData(int mipLevel,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(mipLevel, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \since 5.3
+ \overload
+*/
+void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \obsolete
+ \overload
+
\sa setCompressedData()
*/
void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
@@ -2152,6 +2246,7 @@ void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setData(int mipLevel, int layer,
@@ -2164,6 +2259,7 @@ void QOpenGLTexture::setData(int mipLevel, int layer,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setData(int mipLevel,
@@ -2176,6 +2272,7 @@ void QOpenGLTexture::setData(int mipLevel,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
@@ -2202,7 +2299,7 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps)
QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
QOpenGLPixelTransferOptions uploadOptions;
uploadOptions.setAlignment(1);
- setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.bits(), &uploadOptions);
+ setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.constBits(), &uploadOptions);
}
/*!
@@ -2212,6 +2309,59 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps)
If not using a compressed format() then you should use setData() instead of this
function.
+
+ \since 5.3
+*/
+void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
+ int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ if (!isStorageAllocated()) {
+ qWarning("Cannot set data on a texture that does not have storage allocated.\n"
+ "To do so call allocate() before this function");
+ return;
+ }
+ d->setCompressedData(mipLevel, layer, cubeFace, dataSize, data, options);
+}
+
+/*!
+ \overload
+*/
+void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setCompressedData(mipLevel, layer, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
+}
+
+/*!
+ \overload
+*/
+void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setCompressedData(mipLevel, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
+}
+
+/*!
+ \overload
+*/
+void QOpenGLTexture::setCompressedData(int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setCompressedData(0, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
+}
+
+/*!
+ \obsolete
+ \overload
*/
void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
int dataSize, void *data,
@@ -2228,6 +2378,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cube
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, void *data,
@@ -2239,6 +2390,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, vo
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, void *data,
@@ -2250,6 +2402,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, void *data,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setCompressedData(int dataSize, void *data,
@@ -2275,74 +2428,87 @@ bool QOpenGLTexture::hasFeature(Feature feature)
QSurfaceFormat f = ctx->format();
bool supported = false;
- switch (feature) {
+
#if !defined(QT_OPENGL_ES_2)
- case ImmutableMultisampleStorage:
- case TextureBuffer:
- case StencilTexturing:
- supported = f.version() >= qMakePair(4, 3);
- break;
+ if (!QOpenGLFunctions::isES()) {
+ switch (feature) {
+ case ImmutableMultisampleStorage:
+ case TextureBuffer:
+ case StencilTexturing:
+ supported = f.version() >= qMakePair(4, 3);
+ break;
- case ImmutableStorage:
- supported = f.version() >= qMakePair(4, 2);
- break;
+ case ImmutableStorage:
+ supported = f.version() >= qMakePair(4, 2);
+ break;
- case TextureCubeMapArrays:
- supported = f.version() >= qMakePair(4, 0);
- break;
+ case TextureCubeMapArrays:
+ supported = f.version() >= qMakePair(4, 0);
+ break;
- case Swizzle:
- supported = f.version() >= qMakePair(3, 3);
- break;
+ case Swizzle:
+ supported = f.version() >= qMakePair(3, 3);
+ break;
- case TextureMultisample:
- supported = f.version() >= qMakePair(3, 2);
- break;
+ case TextureMultisample:
+ supported = f.version() >= qMakePair(3, 2);
+ break;
- case TextureArrays:
- supported = f.version() >= qMakePair(3, 0);
- break;
+ case TextureArrays:
+ supported = f.version() >= qMakePair(3, 0);
+ break;
- case TextureRectangle:
- supported = f.version() >= qMakePair(2, 1);
- break;
+ case TextureRectangle:
+ supported = f.version() >= qMakePair(2, 1);
+ break;
- case Texture3D:
- supported = f.version() >= qMakePair(1, 3);
- break;
+ case Texture3D:
+ supported = f.version() >= qMakePair(1, 3);
+ break;
- case AnisotropicFiltering:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
- break;
+ case AnisotropicFiltering:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
+ break;
- case NPOTTextures:
- case NPOTTextureRepeat:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
- break;
+ case NPOTTextures:
+ case NPOTTextureRepeat:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
+ break;
- case MaxFeatureFlag:
- break;
- }
+ case Texture1D:
+ supported = f.version() >= qMakePair(1, 1);
+ break;
-#else
- case Texture3D:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
- break;
- case AnisotropicFiltering:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
- break;
- case NPOTTextures:
- case NPOTTextureRepeat:
- supported = f.version() >= qMakePair(3,0);
- if (!supported) {
- supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
- if (!supported)
- supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
+ case MaxFeatureFlag:
+ break;
+
+ default:
+ break;
}
- default:
- break;
}
+
+ if (QOpenGLFunctions::isES())
#endif
+ {
+ switch (feature) {
+ case Texture3D:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
+ break;
+ case AnisotropicFiltering:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
+ break;
+ case NPOTTextures:
+ case NPOTTextureRepeat:
+ supported = f.version() >= qMakePair(3,0);
+ if (!supported) {
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
+ if (!supported)
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
+ }
+ default:
+ break;
+ }
+ }
return supported;
}
@@ -2356,17 +2522,20 @@ bool QOpenGLTexture::hasFeature(Feature feature)
void QOpenGLTexture::setMipBaseLevel(int baseLevel)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->textureId);
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(baseLevel <= d->maxLevel);
- d->baseLevel = baseLevel;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(baseLevel <= d->maxLevel);
+ d->baseLevel = baseLevel;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ return;
+ }
#else
Q_UNUSED(baseLevel);
- qWarning("QOpenGLTexture: Mipmap base level is not supported");
#endif
+ qWarning("QOpenGLTexture: Mipmap base level is not supported");
}
/*!
@@ -2390,17 +2559,20 @@ int QOpenGLTexture::mipBaseLevel() const
void QOpenGLTexture::setMipMaxLevel(int maxLevel)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->textureId);
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->baseLevel <= maxLevel);
- d->maxLevel = maxLevel;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->baseLevel <= maxLevel);
+ d->maxLevel = maxLevel;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ return;
+ }
#else
Q_UNUSED(maxLevel);
- qWarning("QOpenGLTexture: Mipmap max level is not supported");
#endif
+ qWarning("QOpenGLTexture: Mipmap max level is not supported");
}
/*!
@@ -2424,18 +2596,21 @@ int QOpenGLTexture::mipMaxLevel() const
void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->textureId);
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(baseLevel <= maxLevel);
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_BASE_LEVEL, baseLevel);
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(baseLevel <= maxLevel);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ return;
+ }
#else
Q_UNUSED(baseLevel);
Q_UNUSED(maxLevel);
- qWarning("QOpenGLTexture: Mipmap level range is not supported");
#endif
+ qWarning("QOpenGLTexture: Mipmap level range is not supported");
}
/*!
@@ -2487,7 +2662,7 @@ void QOpenGLTexture::generateMipMaps()
Q_D(QOpenGLTexture);
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
- d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target);
+ d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
}
/*!
@@ -2511,7 +2686,7 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
if (resetBaseLevel)
oldBaseLevel = mipBaseLevel();
setMipBaseLevel(baseLevel);
- d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target);
+ d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
if (resetBaseLevel)
setMipBaseLevel(oldBaseLevel);
}
@@ -2531,21 +2706,24 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- if (!d->features.testFlag(Swizzle)) {
- qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ if (!d->features.testFlag(Swizzle)) {
+ qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ return;
+ }
+ d->swizzleMask[component - SwizzleRed] = value;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
return;
}
- d->swizzleMask[component - SwizzleRed] = value;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, component, value);
#else
Q_UNUSED(component);
Q_UNUSED(value);
- qWarning("QOpenGLTexture: Texture swizzling is not supported");
#endif
+ qWarning("QOpenGLTexture: Texture swizzling is not supported");
}
/*!
@@ -2555,27 +2733,30 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
SwizzleValue b, SwizzleValue a)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- if (!d->features.testFlag(Swizzle)) {
- qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ if (!d->features.testFlag(Swizzle)) {
+ qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ return;
+ }
+ GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
+ d->swizzleMask[0] = r;
+ d->swizzleMask[1] = g;
+ d->swizzleMask[2] = b;
+ d->swizzleMask[3] = a;
+ d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
return;
}
- GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
- d->swizzleMask[0] = r;
- d->swizzleMask[1] = g;
- d->swizzleMask[2] = b;
- d->swizzleMask[3] = a;
- d->texFuncs->glTextureParameteriv(d->textureId, d->target, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Texture swizzling is not supported");
#endif
+ qWarning("QOpenGLTexture: Texture swizzling is not supported");
}
/*!
@@ -2591,9 +2772,9 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon
If using a texture that has a combined depth/stencil format this function sets
which component of the texture is accessed to \a mode.
- When the parameter is set to ?DepthMode, then accessing it from the
+ When the parameter is set to DepthMode, then accessing it from the
shader will access the depth component as a single float, as normal. But when
- the parameter is set to StencilMode?, the shader will access the stencil component.
+ the parameter is set to StencilMode, the shader will access the stencil component.
\note This function has no effect on Mac and Qt built for OpenGL ES 2.
\sa depthStencilMode()
@@ -2601,20 +2782,23 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon
void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- if (!d->features.testFlag(StencilTexturing)) {
- qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ if (!d->features.testFlag(StencilTexturing)) {
+ qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
+ return;
+ }
+ d->depthStencilMode = mode;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
return;
}
- d->depthStencilMode = mode;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
#else
Q_UNUSED(mode);
- qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
#endif
+ qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
}
/*!
@@ -2640,7 +2824,7 @@ void QOpenGLTexture::setMinificationFilter(QOpenGLTexture::Filter filter)
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
d->minFilter = filter;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MIN_FILTER, filter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, filter);
}
/*!
@@ -2666,7 +2850,7 @@ void QOpenGLTexture::setMagnificationFilter(QOpenGLTexture::Filter filter)
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
d->magFilter = filter;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAG_FILTER, filter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, filter);
}
/*!
@@ -2695,8 +2879,8 @@ void QOpenGLTexture::setMinMagFilters(QOpenGLTexture::Filter minificationFilter,
Q_ASSERT(d->textureId);
d->minFilter = minificationFilter;
d->magFilter = magnificationFilter;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MIN_FILTER, minificationFilter);
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAG_FILTER, magnificationFilter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, minificationFilter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, magnificationFilter);
}
/*!
@@ -2727,7 +2911,7 @@ void QOpenGLTexture::setMaximumAnisotropy(float anisotropy)
return;
}
d->maxAnisotropy = anisotropy;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
}
/*!
@@ -2788,23 +2972,26 @@ QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDire
void QOpenGLTexture::setBorderColor(QColor color)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- float values[4];
- values[0] = color.redF();
- values[1] = color.greenF();
- values[2] = color.blueF();
- values[3] = color.alphaF();
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameterfv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ float values[4];
+ values[0] = color.redF();
+ values[1] = color.greenF();
+ values[2] = color.blueF();
+ values[3] = color.alphaF();
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(color);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
}
/*!
@@ -2813,26 +3000,29 @@ void QOpenGLTexture::setBorderColor(QColor color)
void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- float values[4];
- values[0] = r;
- values[1] = g;
- values[2] = b;
- values[3] = a;
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameterfv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ float values[4];
+ values[0] = r;
+ values[1] = g;
+ values[2] = b;
+ values[3] = a;
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
}
/*!
@@ -2841,26 +3031,29 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- int values[4];
- values[0] = r;
- values[1] = g;
- values[2] = b;
- values[3] = a;
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameteriv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ int values[4];
+ values[0] = r;
+ values[1] = g;
+ values[2] = b;
+ values[3] = a;
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
// TODO Handle case of using glTextureParameterIiv() based on format
}
@@ -2871,26 +3064,29 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- int values[4];
- values[0] = int(r);
- values[1] = int(g);
- values[2] = int(b);
- values[3] = int(a);
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameteriv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ int values[4];
+ values[0] = int(r);
+ values[1] = int(g);
+ values[2] = int(b);
+ values[3] = int(a);
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
// TODO Handle case of using glTextureParameterIuiv() based on format
}
@@ -2974,17 +3170,20 @@ void QOpenGLTexture::borderColor(unsigned int *border) const
void QOpenGLTexture::setMinimumLevelOfDetail(float value)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- Q_ASSERT(value < d->maxLevelOfDetail);
- d->minLevelOfDetail = value;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MIN_LOD, value);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(value < d->maxLevelOfDetail);
+ d->minLevelOfDetail = value;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
+ return;
+ }
#else
Q_UNUSED(value);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@@ -3008,17 +3207,20 @@ float QOpenGLTexture::minimumLevelOfDetail() const
void QOpenGLTexture::setMaximumLevelOfDetail(float value)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- Q_ASSERT(value > d->minLevelOfDetail);
- d->maxLevelOfDetail = value;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MAX_LOD, value);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(value > d->minLevelOfDetail);
+ d->maxLevelOfDetail = value;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
+ return;
+ }
#else
Q_UNUSED(value);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@@ -3041,20 +3243,23 @@ float QOpenGLTexture::maximumLevelOfDetail() const
void QOpenGLTexture::setLevelOfDetailRange(float min, float max)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- Q_ASSERT(min < max);
- d->minLevelOfDetail = min;
- d->maxLevelOfDetail = max;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MIN_LOD, min);
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MAX_LOD, max);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(min < max);
+ d->minLevelOfDetail = min;
+ d->maxLevelOfDetail = max;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
+ return;
+ }
#else
Q_UNUSED(min);
Q_UNUSED(max);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@@ -3077,16 +3282,19 @@ QPair<float, float> QOpenGLTexture::levelOfDetailRange() const
void QOpenGLTexture::setLevelofDetailBias(float bias)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- d->levelOfDetailBias = bias;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_LOD_BIAS, bias);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ d->levelOfDetailBias = bias;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
+ return;
+ }
#else
Q_UNUSED(bias);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h
index 5c0f8101a6..0c272456f6 100644
--- a/src/gui/opengl/qopengltexture.h
+++ b/src/gui/opengl/qopengltexture.h
@@ -337,28 +337,53 @@ public:
};
// Pixel transfer
+ // ### Qt 6: remove the non-const void * overloads
+ QT_DEPRECATED void setData(int mipLevel, int layer, CubeMapFace cubeFace,
+ PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setData(int mipLevel, int layer,
+ PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setData(int mipLevel,
+ PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setData(PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+
void setData(int mipLevel, int layer, CubeMapFace cubeFace,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
void setData(int mipLevel, int layer,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
void setData(int mipLevel,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
void setData(PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
// Compressed data upload
+ // ### Qt 6: remove the non-const void * overloads
+ QT_DEPRECATED void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
+ int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setCompressedData(int mipLevel, int layer,
+ int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setCompressedData(int mipLevel, int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setCompressedData(int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+
void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
void setCompressedData(int mipLevel, int layer,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
- void setCompressedData(int mipLevel, int dataSize, void *data,
+ void setCompressedData(int mipLevel, int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
- void setCompressedData(int dataSize, void *data,
+ void setCompressedData(int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
// Helpful overloads for setData
@@ -379,8 +404,9 @@ public:
AnisotropicFiltering = 0x00000400,
NPOTTextures = 0x00000800,
NPOTTextureRepeat = 0x00001000,
+ Texture1D = 0x00002000,
#ifndef Q_QDOC
- MaxFeatureFlag = 0x00002000
+ MaxFeatureFlag = 0x00004000
#endif
};
Q_DECLARE_FLAGS(Features, Feature)
diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h
index 009561533b..a732805f55 100644
--- a/src/gui/opengl/qopengltexture_p.h
+++ b/src/gui/opengl/qopengltexture_p.h
@@ -89,9 +89,9 @@ public:
void allocateImmutableStorage();
void setData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options);
+ const void *data, const QOpenGLPixelTransferOptions * const options);
void setCompressedData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options);
void setWrapMode(QOpenGLTexture::WrapMode mode);
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
new file mode 100644
index 0000000000..b776444347
--- /dev/null
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltextureblitter_p.h"
+
+#include <QtGui/QOpenGLBuffer>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLVertexArrayObject>
+#include <QtGui/QOpenGLContext>
+
+QT_BEGIN_NAMESPACE
+
+static const char vertex_shader150[] =
+ "#version 150 core\n"
+ "in vec3 vertexCoord;"
+ "in vec2 textureCoord;"
+ "out vec2 uv;"
+ "uniform mat4 vertexTransform;"
+ "uniform mat3 textureTransform;"
+ "void main() {"
+ " uv = (textureTransform * vec3(textureCoord,1.0)).xy;"
+ " gl_Position = vertexTransform * vec4(vertexCoord,1.0);"
+ "}";
+
+static const char fragment_shader150[] =
+ "#version 150 core\n"
+ "in vec2 uv;"
+ "out vec4 fragcolor;"
+ "uniform sampler2D textureSampler;"
+ "uniform bool swizzle;"
+ "void main() {"
+ " if (swizzle) {"
+ " fragcolor = texture(textureSampler, uv).bgra;"
+ " } else {"
+ " fragcolor = texture(textureSampler,uv);"
+ " }"
+ "}";
+
+static const char vertex_shader[] =
+ "attribute highp vec3 vertexCoord;"
+ "attribute highp vec2 textureCoord;"
+ "varying highp vec2 uv;"
+ "uniform highp mat4 vertexTransform;"
+ "uniform highp mat3 textureTransform;"
+ "void main() {"
+ " uv = (textureTransform * vec3(textureCoord,1.0)).xy;"
+ " gl_Position = vertexTransform * vec4(vertexCoord,1.0);"
+ "}";
+
+static const char fragment_shader[] =
+ "varying highp vec2 uv;"
+ "uniform sampler2D textureSampler;"
+ "uniform bool swizzle;"
+ "void main() {"
+ " if (swizzle) {"
+ " gl_FragColor = texture2D(textureSampler, uv).bgra;"
+ " } else {"
+ " gl_FragColor = texture2D(textureSampler,uv);"
+ " }"
+ "}";
+
+static const GLfloat vertex_buffer_data[] = {
+ -1,-1, 0,
+ -1, 1, 0,
+ 1,-1, 0,
+ -1, 1, 0,
+ 1,-1, 0,
+ 1, 1, 0
+};
+
+static const GLfloat texture_buffer_data[] = {
+ 0, 0,
+ 0, 1,
+ 1, 0,
+ 0, 1,
+ 1, 0,
+ 1, 1
+};
+
+class TextureBinder
+{
+public:
+ TextureBinder(GLuint textureId)
+ {
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ }
+ ~TextureBinder()
+ {
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+};
+
+class QOpenGLTextureBlitterPrivate
+{
+public:
+ enum TextureMatrixUniform {
+ User,
+ Identity,
+ IdentityFlipped
+ };
+
+ QOpenGLTextureBlitterPrivate()
+ : program(0)
+ , vertexCoordAttribPos(0)
+ , vertexTransformUniformPos(0)
+ , textureCoordAttribPos(0)
+ , textureTransformUniformPos(0)
+ , swizzle(false)
+ , swizzleOld(false)
+ , textureMatrixUniformState(User)
+ , vao(new QOpenGLVertexArrayObject())
+ { }
+
+ void blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform);
+ void blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin);
+
+ void prepareProgram(const QMatrix4x4 &vertexTransform)
+ {
+ vertexBuffer.bind();
+ program->setAttributeBuffer(vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ program->enableAttributeArray(vertexCoordAttribPos);
+ vertexBuffer.release();
+
+ program->setUniformValue(vertexTransformUniformPos, vertexTransform);
+
+ textureBuffer.bind();
+ program->setAttributeBuffer(textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ program->enableAttributeArray(textureCoordAttribPos);
+ textureBuffer.release();
+
+ if (swizzle != swizzleOld) {
+ program->setUniformValue(swizzleUniformPos, swizzle);
+ swizzleOld = swizzle;
+ }
+ }
+
+ QOpenGLBuffer vertexBuffer;
+ QOpenGLBuffer textureBuffer;
+ QScopedPointer<QOpenGLShaderProgram> program;
+ GLuint vertexCoordAttribPos;
+ GLuint vertexTransformUniformPos;
+ GLuint textureCoordAttribPos;
+ GLuint textureTransformUniformPos;
+ GLuint swizzleUniformPos;
+ bool swizzle;
+ bool swizzleOld;
+ TextureMatrixUniform textureMatrixUniformState;
+ QScopedPointer<QOpenGLVertexArrayObject> vao;
+};
+
+void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
+ const QMatrix4x4 &vertexTransform,
+ const QMatrix3x3 &textureTransform)
+{
+ TextureBinder binder(texture);
+ prepareProgram(vertexTransform);
+
+ program->setUniformValue(textureTransformUniformPos, textureTransform);
+ textureMatrixUniformState = User;
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
+ const QMatrix4x4 &vertexTransform,
+ QOpenGLTextureBlitter::Origin origin)
+{
+ TextureBinder binder(texture);
+ prepareProgram(vertexTransform);
+
+ if (origin == QOpenGLTextureBlitter::OriginTopLeft) {
+ if (textureMatrixUniformState != IdentityFlipped) {
+ QMatrix3x3 flipped;
+ flipped(1,1) = -1;
+ flipped(1,2) = 1;
+ program->setUniformValue(textureTransformUniformPos, flipped);
+ textureMatrixUniformState = IdentityFlipped;
+ }
+ } else if (textureMatrixUniformState != Identity) {
+ program->setUniformValue(textureTransformUniformPos, QMatrix3x3());
+ textureMatrixUniformState = Identity;
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+QOpenGLTextureBlitter::QOpenGLTextureBlitter()
+ : d_ptr(new QOpenGLTextureBlitterPrivate)
+{
+}
+
+QOpenGLTextureBlitter::~QOpenGLTextureBlitter()
+{
+}
+
+bool QOpenGLTextureBlitter::create()
+{
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext();
+ if (!currentContext)
+ return false;
+
+ Q_D(QOpenGLTextureBlitter);
+
+ d->vao->create();
+ d->vao->bind();
+
+ if (d->program)
+ return true;
+
+ d->program.reset(new QOpenGLShaderProgram());
+
+ QSurfaceFormat format = currentContext->format();
+
+ if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) {
+ d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader150);
+ d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader150);
+ } else {
+ d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader);
+ d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader);
+ }
+ d->program->link();
+ if (!d->program->isLinked()) {
+ qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << d->program->log();
+ return false;
+ }
+
+ d->program->bind();
+
+ d->vertexBuffer.create();
+ d->vertexBuffer.bind();
+ d->vertexBuffer.allocate(vertex_buffer_data, sizeof(vertex_buffer_data) * sizeof(vertex_buffer_data[0]));
+ d->vertexBuffer.release();
+
+ d->textureBuffer.create();
+ d->textureBuffer.bind();
+ d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data) * sizeof(texture_buffer_data[0]));
+ d->textureBuffer.release();
+
+ d->vertexCoordAttribPos = d->program->attributeLocation("vertexCoord");
+ d->vertexTransformUniformPos = d->program->uniformLocation("vertexTransform");
+ d->textureCoordAttribPos = d->program->attributeLocation("textureCoord");
+ d->textureTransformUniformPos = d->program->uniformLocation("textureTransform");
+ d->swizzleUniformPos = d->program->uniformLocation("swizzle");
+
+ d->program->setUniformValue(d->swizzleUniformPos,false);
+
+ d->vao->release();
+
+ return true;
+}
+
+void QOpenGLTextureBlitter::destroy()
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->program.reset();
+ d->vertexBuffer.destroy();
+ d->textureBuffer.destroy();
+ d->vao.reset();
+}
+
+void QOpenGLTextureBlitter::bind()
+{
+ Q_D(QOpenGLTextureBlitter);
+
+ d->vao->bind();
+
+ d->program->bind();
+
+ d->vertexBuffer.bind();
+ d->program->setAttributeBuffer(d->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ d->program->enableAttributeArray(d->vertexCoordAttribPos);
+ d->vertexBuffer.release();
+
+ d->textureBuffer.bind();
+ d->program->setAttributeBuffer(d->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ d->program->enableAttributeArray(d->textureCoordAttribPos);
+ d->textureBuffer.release();
+}
+
+void QOpenGLTextureBlitter::release()
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->program->release();
+ d->vao->release();
+}
+
+void QOpenGLTextureBlitter::setSwizzleRB(bool swizzle)
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->swizzle = swizzle;
+}
+
+void QOpenGLTextureBlitter::blit(GLuint texture,
+ const QMatrix4x4 &targetTransform,
+ Origin sourceOrigin)
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->blit(texture,targetTransform, sourceOrigin);
+}
+
+void QOpenGLTextureBlitter::blit(GLuint texture,
+ const QMatrix4x4 &targetTransform,
+ const QMatrix3x3 &sourceTransform)
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->blit(texture, targetTransform, sourceTransform);
+}
+
+QMatrix4x4 QOpenGLTextureBlitter::targetTransform(const QRectF &target,
+ const QRect &viewport)
+{
+ qreal x_scale = target.width() / viewport.width();
+ qreal y_scale = target.height() / viewport.height();
+
+ const QPointF relative_to_viewport = target.topLeft() - viewport.topLeft();
+ qreal x_translate = x_scale - 1 + ((relative_to_viewport.x() / viewport.width()) * 2);
+ qreal y_translate = -y_scale + 1 - ((relative_to_viewport.y() / viewport.height()) * 2);
+
+ QMatrix4x4 matrix;
+ matrix(0,3) = x_translate;
+ matrix(1,3) = y_translate;
+
+ matrix(0,0) = x_scale;
+ matrix(1,1) = y_scale;
+
+ return matrix;
+}
+
+QMatrix3x3 QOpenGLTextureBlitter::sourceTransform(const QRectF &subTexture,
+ const QSize &textureSize,
+ Origin origin)
+{
+ qreal x_scale = subTexture.width() / textureSize.width();
+ qreal y_scale = subTexture.height() / textureSize.height();
+
+ const QPointF topLeft = subTexture.topLeft();
+ qreal x_translate = topLeft.x() / textureSize.width();
+ qreal y_translate = topLeft.y() / textureSize.height();
+
+ if (origin == OriginTopLeft) {
+ y_scale = -y_scale;
+ y_translate = 1 - y_translate;
+ }
+
+ QMatrix3x3 matrix;
+ matrix(0,2) = x_translate;
+ matrix(1,2) = y_translate;
+
+ matrix(0,0) = x_scale;
+ matrix(1,1) = y_scale;
+
+ return matrix;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h
new file mode 100644
index 0000000000..b2ccc13391
--- /dev/null
+++ b/src/gui/opengl/qopengltextureblitter_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLTEXTUREBLITTER_P_H
+#define QOPENGLTEXTUREBLITTER_P_H
+
+#include <QtGui/qopengl.h>
+#include <QtGui/QMatrix3x3>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLTextureBlitterPrivate;
+
+
+class Q_GUI_EXPORT QOpenGLTextureBlitter
+{
+public:
+ QOpenGLTextureBlitter();
+ ~QOpenGLTextureBlitter();
+
+ enum Origin {
+ OriginBottomLeft,
+ OriginTopLeft
+ };
+
+ bool create();
+ void destroy();
+
+ void bind();
+ void release();
+
+ void setSwizzleRB(bool swizzle);
+
+ void blit(GLuint texture, const QMatrix4x4 &targetTransform, Origin sourceOrigin);
+ void blit(GLuint texture, const QMatrix4x4 &targetTransform, const QMatrix3x3 &sourceTransform);
+
+ static QMatrix4x4 targetTransform(const QRectF &target, const QRect &viewport);
+ static QMatrix3x3 sourceTransform(const QRectF &subTexture, const QSize &textureSize, Origin origin);
+
+private:
+ Q_DISABLE_COPY(QOpenGLTextureBlitter);
+ Q_DECLARE_PRIVATE(QOpenGLTextureBlitter);
+ QScopedPointer<QOpenGLTextureBlitterPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif //QOPENGLTEXTUREBLITTER_P_H
diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp
index 3b62d1d63a..0d9a2359bd 100644
--- a/src/gui/opengl/qopengltextureglyphcache.cpp
+++ b/src/gui/opengl/qopengltextureglyphcache.cpp
@@ -328,8 +328,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
if (mask.format() == QImage::Format_RGB32
// We need to make the alpha component equal to the average of the RGB values.
// This is needed when drawing sub-pixel antialiased text on translucent targets.
-#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|| mask.format() == QImage::Format_ARGB32_Premultiplied
+#else
+ || (mask.format() == QImage::Format_ARGB32_Premultiplied
+ && QOpenGLFunctions::isES())
#endif
) {
for (int y = 0; y < maskHeight; ++y) {
@@ -345,10 +348,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
avg = qAlpha(src[x]);
src[x] = qRgba(r, g, b, avg);
-#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
// swizzle the bits to accommodate for the GL_RGBA upload.
- src[x] = ARGB2RGBA(src[x]);
+#if Q_BYTE_ORDER != Q_BIG_ENDIAN
+ if (QOpenGLFunctions::isES())
#endif
+ src[x] = ARGB2RGBA(src[x]);
}
}
}
@@ -356,11 +360,16 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
if (mask.depth() == 32) {
-#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits());
+#ifdef QT_OPENGL_ES_2
+ GLenum fmt = GL_RGBA;
#else
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
+ GLenum fmt = QOpenGLFunctions::isES() ? GL_RGBA : GL_BGRA;
+#endif // QT_OPENGL_ES_2
+
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ fmt = GL_RGBA;
#endif
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, fmt, GL_UNSIGNED_BYTE, mask.bits());
} else {
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp
index 676c0802de..1f44a81276 100644
--- a/src/gui/opengl/qopengltexturehelper.cpp
+++ b/src/gui/opengl/qopengltexturehelper.cpp
@@ -42,14 +42,15 @@
#include "qopengltexturehelper_p.h"
#include <QOpenGLContext>
+#include <QOpenGLFunctions>
QT_BEGIN_NAMESPACE
QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
{
// Resolve EXT_direct_state_access entry points if present
-#if !defined(QT_OPENGL_ES_2)
- if (context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
+ if (!QOpenGLFunctions::isES()
+ && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT")));
TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT")));
TextureParameterfEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLfloat )>(context->getProcAddress(QByteArrayLiteral("glTextureParameterfEXT")));
@@ -97,7 +98,6 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
CompressedTextureImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureImage2D;
CompressedTextureImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureImage3D;
} else {
-#endif
// Use our own DSA emulation
TextureParameteri = &QOpenGLTextureHelper::qt_TextureParameteri;
TextureParameteriv = &QOpenGLTextureHelper::qt_TextureParameteriv;
@@ -119,37 +119,28 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
CompressedTextureImage1D = &QOpenGLTextureHelper::qt_CompressedTextureImage1D;
CompressedTextureImage2D = &QOpenGLTextureHelper::qt_CompressedTextureImage2D;
CompressedTextureImage3D = &QOpenGLTextureHelper::qt_CompressedTextureImage3D;
-#if defined(QT_OPENGL_ES_2)
- if (context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
- TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES")));
- TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES")));
- CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES")));
- CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES")));
- }
-#endif
-
-#if !defined(QT_OPENGL_ES_2)
}
-#endif
// Some DSA functions are part of NV_texture_multisample instead
-#if !defined(QT_OPENGL_ES_2)
- if (context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
+ if (!QOpenGLFunctions::isES()
+ && context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
TextureImage3DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage3DMultisampleNV")));
TextureImage2DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage2DMultisampleNV")));
TextureImage3DMultisample = &QOpenGLTextureHelper::dsa_TextureImage3DMultisample;
TextureImage2DMultisample = &QOpenGLTextureHelper::dsa_TextureImage2DMultisample;
} else {
-#endif
TextureImage3DMultisample = &QOpenGLTextureHelper::qt_TextureImage3DMultisample;
TextureImage2DMultisample = &QOpenGLTextureHelper::qt_TextureImage2DMultisample;
-#if !defined(QT_OPENGL_ES_2)
}
-#endif
+
+ // wglGetProcAddress should not be used to (and indeed will not) load OpenGL <= 1.1 functions.
+ // Hence, we resolve them "the hard way"
#if defined(Q_OS_WIN) && !defined(QT_OPENGL_ES_2)
- HMODULE handle = GetModuleHandleA("opengl32.dll");
+ HMODULE handle = static_cast<HMODULE>(QOpenGLFunctions::platformGLHandle());
+ if (!handle)
+ handle = GetModuleHandleA("opengl32.dll");
// OpenGL 1.0
GetIntegerv = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint *)>(GetProcAddress(handle, QByteArrayLiteral("glGetIntegerv")));
@@ -200,18 +191,27 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
TexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage1D")));
#endif
- // OpenGL 1.2
- TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D")));
- TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D")));
+ if (QOpenGLFunctions::isES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
+ TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES")));
+ TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES")));
+ CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES")));
+ CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES")));
+ } else {
+ // OpenGL 1.2
+ TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D")));
+ TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D")));
+
+ // OpenGL 1.3
+ CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D")));
+ CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D")));
+ }
// OpenGL 1.3
GetCompressedTexImage = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glGetCompressedTexImage")));
CompressedTexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage1D")));
CompressedTexSubImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage2D")));
- CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D")));
CompressedTexImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage1D")));
CompressedTexImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage2D")));
- CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D")));
ActiveTexture = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum )>(context->getProcAddress(QByteArrayLiteral("glActiveTexture")));
// OpenGL 3.0
@@ -233,4 +233,404 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
TextureView = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLuint , GLenum , GLuint , GLuint , GLuint , GLuint )>(context->getProcAddress(QByteArrayLiteral("glTextureView")));
}
+void QOpenGLTextureHelper::dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameteriEXT(texture, target, pname, param);
+}
+
+void QOpenGLTextureHelper::dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameterivEXT(texture, target, pname, params);
+}
+
+void QOpenGLTextureHelper::dsa_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameterfEXT(texture, target, pname, param);
+}
+
+void QOpenGLTextureHelper::dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameterfvEXT(texture, target, pname, params);
+}
+
+void QOpenGLTextureHelper::dsa_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
+{
+ Q_UNUSED(bindingTarget);
+ GenerateTextureMipmapEXT(texture, target);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage3DEXT(texture, target, levels, internalFormat, width, height, depth);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage2DEXT(texture, target, levels, internalFormat, width, height);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage1DEXT(texture, target, levels, internalFormat, width);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage3DMultisampleEXT(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage2DMultisampleEXT(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage2DEXT(texture, target, level, internalFormat, width, height, border, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage1DEXT(texture, target, level, internalFormat, width, border, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage3DMultisampleNV(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage2DMultisampleNV(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureImage1DEXT(texture, target, level, internalFormat, width, border, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureImage2DEXT(texture, target, level, internalFormat, width, height, border, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameteri(target, pname, param);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameteriv(target, pname, params);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameterf(target, pname, param);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameterfv(target, pname, params);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glGenerateMipmap(target);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage3D(target, levels, internalFormat, width, height, depth);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage2D(target, levels, internalFormat, width, height);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage1D(target, levels, internalFormat, width);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ // For cubemaps we can't use the standard DSA emulation as it is illegal to
+ // try to bind a texture to one of the cubemap face targets. So we force the
+ // target and binding target to the cubemap values in this case.
+ GLint oldTexture;
+
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
+ glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
+ break;
+
+ default:
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
+ glBindTexture(target, oldTexture);
+ break;
+ }
+}
+
+void QOpenGLTextureHelper::qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage1D(target, level, internalFormat, width, border, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ // For cubemaps we can't use the standard DSA emulation as it is illegal to
+ // try to bind a texture to one of the cubemap face targets. So we force the
+ // target and binding target to the cubemap values in this case.
+ GLint oldTexture;
+
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
+ break;
+
+ default:
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ glBindTexture(target, oldTexture);
+ break;
+ }
+}
+
+void QOpenGLTextureHelper::qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h
index fa4bd8120a..782486b90d 100644
--- a/src/gui/opengl/qopengltexturehelper_p.h
+++ b/src/gui/opengl/qopengltexturehelper_p.h
@@ -59,135 +59,135 @@ class QOpenGLTextureHelper
public:
QOpenGLTextureHelper(QOpenGLContext *context);
- // DSA API
- inline void glTextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param)
+ // DSA-like API. Will either use real DSA or our emulation
+ inline void glTextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
{
- (this->*TextureParameteri)(texture, target, pname, param);
+ (this->*TextureParameteri)(texture, target, bindingTarget, pname, param);
}
- inline void glTextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *params)
+ inline void glTextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
{
- (this->*TextureParameteriv)(texture, target, pname, params);
+ (this->*TextureParameteriv)(texture, target, bindingTarget, pname, params);
}
- inline void glTextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param)
+ inline void glTextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
{
- (this->*TextureParameterf)(texture, target, pname, param);
+ (this->*TextureParameterf)(texture, target, bindingTarget, pname, param);
}
- inline void glTextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
+ inline void glTextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
{
- (this->*TextureParameterfv)(texture, target, pname, params);
+ (this->*TextureParameterfv)(texture, target, bindingTarget, pname, params);
}
- inline void glGenerateTextureMipmap(GLuint texture, GLenum target)
+ inline void glGenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
{
- (this->*GenerateTextureMipmap)(texture, target);
+ (this->*GenerateTextureMipmap)(texture, target, bindingTarget);
}
- inline void glTextureStorage3D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
+ inline void glTextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth)
{
- (this->*TextureStorage3D)(texture, target, levels, internalFormat, width, height, depth);
+ (this->*TextureStorage3D)(texture, target, bindingTarget, levels, internalFormat, width, height, depth);
}
- inline void glTextureStorage2D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
+ inline void glTextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height)
{
- (this->*TextureStorage2D)(texture, target, levels, internalFormat, width, height);
+ (this->*TextureStorage2D)(texture, target, bindingTarget, levels, internalFormat, width, height);
}
- inline void glTextureStorage1D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
+ inline void glTextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
GLsizei width)
{
- (this->*TextureStorage1D)(texture, target, levels, internalFormat, width);
+ (this->*TextureStorage1D)(texture, target, bindingTarget, levels, internalFormat, width);
}
- inline void glTextureStorage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
+ inline void glTextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
{
- (this->*TextureStorage3DMultisample)(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ (this->*TextureStorage3DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, depth, fixedSampleLocations);
}
- inline void glTextureStorage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
+ inline void glTextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
{
- (this->*TextureStorage2DMultisample)(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+ (this->*TextureStorage2DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, fixedSampleLocations);
}
- inline void glTextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
+ inline void glTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- (this->*TextureImage3D)(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels);
+ (this->*TextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, format, type, pixels);
}
- inline void glTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
+ inline void glTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- (this->*TextureImage2D)(texture, target, level, internalFormat, width, height, border, format, type, pixels);
+ (this->*TextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, format, type, pixels);
}
- inline void glTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
+ inline void glTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- (this->*TextureImage1D)(texture, target, level, internalFormat, width, border, format, type, pixels);
+ (this->*TextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, format, type, pixels);
}
- inline void glTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ inline void glTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
const GLvoid *pixels, const QOpenGLPixelTransferOptions * const options = 0)
{
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*TextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ (this->*TextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
setPixelUploadOptions(oldOptions);
} else {
- (this->*TextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ (this->*TextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
}
- inline void glTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ inline void glTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLenum type,
const GLvoid *pixels, const QOpenGLPixelTransferOptions * const options = 0)
{
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*TextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
+ (this->*TextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, type, pixels);
setPixelUploadOptions(oldOptions);
} else {
- (this->*TextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
+ (this->*TextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, type, pixels);
}
}
- inline void glTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset,
+ inline void glTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset,
GLsizei width, GLenum format, GLenum type,
const GLvoid *pixels, const QOpenGLPixelTransferOptions * const options = 0)
{
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*TextureSubImage1D)(texture, target, level, xoffset, width, format, type, pixels);
+ (this->*TextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, type, pixels);
setPixelUploadOptions(oldOptions);
} else {
- (this->*TextureSubImage1D)(texture, target, level, xoffset, width, format, type, pixels);
+ (this->*TextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, type, pixels);
}
}
- inline void glTextureImage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
+ inline void glTextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
{
- (this->*TextureImage3DMultisample)(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ (this->*TextureImage3DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, depth, fixedSampleLocations);
}
- inline void glTextureImage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
+ inline void glTextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
{
- (this->*TextureImage2DMultisample)(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+ (this->*TextureImage2DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, fixedSampleLocations);
}
- inline void glCompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLint xoffset, GLsizei width,
GLenum format, GLsizei imageSize, const GLvoid *bits,
const QOpenGLPixelTransferOptions * const options = 0)
@@ -195,14 +195,14 @@ public:
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*CompressedTextureSubImage1D)(texture, target, level, xoffset, width, format, imageSize, bits);
+ (this->*CompressedTextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, imageSize, bits);
setPixelUploadOptions(oldOptions);
} else {
- (this->*CompressedTextureSubImage1D)(texture, target, level, xoffset, width, format, imageSize, bits);
+ (this->*CompressedTextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, imageSize, bits);
}
}
- inline void glCompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize, const GLvoid *bits,
@@ -211,14 +211,14 @@ public:
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*CompressedTextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+ (this->*CompressedTextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, imageSize, bits);
setPixelUploadOptions(oldOptions);
} else {
- (this->*CompressedTextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+ (this->*CompressedTextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, imageSize, bits);
}
}
- inline void glCompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLsizei imageSize, const GLvoid *bits,
@@ -227,443 +227,200 @@ public:
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*CompressedTextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+ (this->*CompressedTextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
setPixelUploadOptions(oldOptions);
} else {
- (this->*CompressedTextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+ (this->*CompressedTextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
}
}
- inline void glCompressedTextureImage1D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width,
GLint border, GLsizei imageSize, const GLvoid *bits)
{
- (this->*CompressedTextureImage1D)(texture, target, level, internalFormat, width, border, imageSize, bits);
+ (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits);
}
- inline void glCompressedTextureImage2D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid *bits)
{
- (this->*CompressedTextureImage2D)(texture, target, level, internalFormat, width, height, border, imageSize, bits);
+ (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits);
}
- inline void glCompressedTextureImage3D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLsizei imageSize, const GLvoid *bits)
{
- (this->*CompressedTextureImage3D)(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
+ (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits);
}
private:
-#if !defined(QT_OPENGL_ES_2)
// DSA wrapper (so we can use pointer to member function as switch)
- inline void dsa_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param)
- {
- TextureParameteriEXT(texture, target, pname, param);
- }
+ void dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
- inline void dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *params)
- {
- TextureParameterivEXT(texture, target, pname, params);
- }
+ void dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params);
- inline void dsa_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param)
- {
- TextureParameterfEXT(texture, target, pname, param);
- }
+ void dsa_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param);
- inline void dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
- {
- TextureParameterfvEXT(texture, target, pname, params);
- }
+ void dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params);
- inline void dsa_GenerateTextureMipmap(GLuint texture, GLenum target)
- {
- GenerateTextureMipmapEXT(texture, target);
- }
+ void dsa_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget);
- inline void dsa_TextureStorage3D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth)
- {
- TextureStorage3DEXT(texture, target, levels, internalFormat, width, height, depth);
- }
+ void dsa_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth);
- inline void dsa_TextureStorage2D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
- GLsizei width, GLsizei height)
- {
- TextureStorage2DEXT(texture, target, levels, internalFormat, width, height);
- }
+ void dsa_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
+ GLsizei width, GLsizei height);
- inline void dsa_TextureStorage1D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
- GLsizei width)
- {
- TextureStorage1DEXT(texture, target, levels, internalFormat, width);
- }
+ void dsa_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
+ GLsizei width);
- inline void dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
- {
- TextureStorage3DMultisampleEXT(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- }
+ void dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- inline void dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
- GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
- {
- TextureStorage2DMultisampleEXT(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
- }
+ void dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- inline void dsa_TextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels);
- }
+ void dsa_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureImage2DEXT(texture, target, level, internalFormat, width, height, border, format, type, pixels);
- }
+ void dsa_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureImage1DEXT(texture, target, level, internalFormat, width, border, format, type, pixels);
- }
+ void dsa_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
- }
+ void dsa_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
- }
+ void dsa_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels);
- }
+ void dsa_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset,
+ GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
- {
- TextureImage3DMultisampleNV(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- }
+ void dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- inline void dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
- GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
- {
- TextureImage2DMultisampleNV(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
- }
+ void dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
+ GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- inline void dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLsizei width,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits);
- }
+ void dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
- }
+ void dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
- }
+ void dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLint level,
- GLenum internalFormat, GLsizei width,
- GLint border, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureImage1DEXT(texture, target, level, internalFormat, width, border, imageSize, bits);
- }
+ void dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLint border, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLint border, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureImage2DEXT(texture, target, level, internalFormat, width, height, border, imageSize, bits);
- }
+ void dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLint border, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLint level,
- GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
- }
-#endif
+ void dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLsizei imageSize, const GLvoid *bits);
+ // DSA emulation API
+ void qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
- // DSA-like API
- inline void qt_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameteri(target, pname, param);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params);
- inline void qt_TextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *params)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameteriv(target, pname, params);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param);
- inline void qt_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameterf(target, pname, param);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params);
- inline void qt_TextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameterfv(target, pname, params);
- glBindTexture(target, oldTexture);
- }
+ void qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget);
- inline void qt_GenerateTextureMipmap(GLuint texture, GLenum target)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glGenerateMipmap(target);
- glBindTexture(target, oldTexture);
- }
-
- inline void qt_TextureStorage3D(GLuint texture, GLenum target, GLsizei levels,
- GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage3D(target, levels, internalFormat, width, height, depth);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
- inline void qt_TextureStorage2D(GLuint texture, GLenum target, GLsizei levels,
- GLenum internalFormat, GLsizei width, GLsizei height)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage2D(target, levels, internalFormat, width, height);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height);
- inline void qt_TextureStorage1D(GLuint texture, GLenum target, GLsizei levels,
- GLenum internalFormat, GLsizei width)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage1D(target, levels, internalFormat, width);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels,
+ GLenum internalFormat, GLsizei width);
- inline void qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLsizei depth, GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedSampleLocations);
- inline void qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLboolean fixedSampleLocations);
- inline void qt_TextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type,
- const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels);
- inline void qt_TextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type,
- const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels);
- inline void qt_TextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLint border, GLenum format, GLenum type,
- const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage1D(target, level, internalFormat, width, border, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels);
- inline void qt_TextureSubImage3D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels);
- inline void qt_TextureSubImage2D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid *pixels);
- inline void qt_TextureSubImage1D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLsizei width,
- GLenum format, GLenum type, const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type, const GLvoid *pixels);
- inline void qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth,
- GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLboolean fixedSampleLocations);
- inline void qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLint internalFormat, GLsizei width, GLsizei height,
- GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLint internalFormat, GLsizei width, GLsizei height,
+ GLboolean fixedSampleLocations);
- inline void qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLint border,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLint border,
+ GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLint border,
+ GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *bits);
public:
// Raw OpenGL functions, resolved and used by our DSA-like static functions if no EXT_direct_state_access is available
@@ -936,31 +693,33 @@ public:
}
private:
- // Typedefs and pointers to member functions used to switch between EXT_direct_state_access and our own emulated DSA
- typedef void (QOpenGLTextureHelper::*TextureParameteriMemberFunc)(GLuint texture, GLenum target, GLenum pname, GLint param);
- typedef void (QOpenGLTextureHelper::*TextureParameterivMemberFunc)(GLuint texture, GLenum target, GLenum pname, const GLint *params);
- typedef void (QOpenGLTextureHelper::*TextureParameterfMemberFunc)(GLuint texture, GLenum target, GLenum pname, GLfloat param);
- typedef void (QOpenGLTextureHelper::*TextureParameterfvMemberFunc)(GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
- typedef void (QOpenGLTextureHelper::*GenerateTextureMipmapMemberFunc)(GLuint texture, GLenum target);
- typedef void (QOpenGLTextureHelper::*TextureStorage3DMemberFunc)(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
- typedef void (QOpenGLTextureHelper::*TextureStorage2DMemberFunc)(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height);
- typedef void (QOpenGLTextureHelper::*TextureStorage1DMemberFunc)(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width);
- typedef void (QOpenGLTextureHelper::*TextureStorage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*TextureStorage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*TextureImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureImage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*TextureImage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+ // Typedefs and pointers to member functions used to switch between EXT_direct_state_access and our own emulated DSA.
+ // The argument match the corresponding GL function, but there's an extra "GLenum bindingTarget" which gets used with
+ // the DSA emulation -- it contains the right GL_BINDING_TEXTURE_X to use.
+ typedef void (QOpenGLTextureHelper::*TextureParameteriMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
+ typedef void (QOpenGLTextureHelper::*TextureParameterivMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params);
+ typedef void (QOpenGLTextureHelper::*TextureParameterfMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param);
+ typedef void (QOpenGLTextureHelper::*TextureParameterfvMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params);
+ typedef void (QOpenGLTextureHelper::*GenerateTextureMipmapMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget);
+ typedef void (QOpenGLTextureHelper::*TextureStorage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
+ typedef void (QOpenGLTextureHelper::*TextureStorage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height);
+ typedef void (QOpenGLTextureHelper::*TextureStorage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width);
+ typedef void (QOpenGLTextureHelper::*TextureStorage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*TextureStorage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*TextureImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureImage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*TextureImage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
TextureParameteriMemberFunc TextureParameteri;
@@ -988,7 +747,6 @@ private:
CompressedTextureImage2DMemberFunc CompressedTextureImage2D;
CompressedTextureImage3DMemberFunc CompressedTextureImage3D;
-#if !defined(QT_OPENGL_ES_2)
// Raw function pointers for core and DSA functions
// EXT_direct_state_access used when DSA is available
@@ -1019,7 +777,6 @@ private:
// Plus some missing ones that are in the NV_texture_multisample extension instead
void (QOPENGLF_APIENTRYP TextureImage3DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
void (QOPENGLF_APIENTRYP TextureImage2DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
-#endif
// OpenGL 1.0
void (QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params);
diff --git a/src/gui/opengl/qopengltimerquery.cpp b/src/gui/opengl/qopengltimerquery.cpp
index c5c3d42e5d..deb88b7778 100644
--- a/src/gui/opengl/qopengltimerquery.cpp
+++ b/src/gui/opengl/qopengltimerquery.cpp
@@ -44,6 +44,7 @@
#include "qopenglqueryhelper_p.h"
#include <QtCore/private/qobject_p.h>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE
@@ -123,6 +124,11 @@ public:
bool QOpenGLTimerQueryPrivate::create()
{
+ if (QOpenGLFunctions::isES()) {
+ qWarning("QOpenGLTimerQuery: Not supported on dynamic GL ES");
+ return false;
+ }
+
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (timer && context == ctx)
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index ee8abde77b..e26c6ec25a 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -43,6 +43,7 @@
#include <QtCore/private/qobject_p.h>
#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglfunctions.h>
#if !defined(QT_OPENGL_ES_2)
#include <QtGui/qopenglfunctions_3_0.h>
@@ -156,6 +157,13 @@ bool QOpenGLVertexArrayObjectPrivate::create()
return false;
}
+#if !defined(QT_OPENGL_ES_2)
+ if (QOpenGLFunctions::isES()) {
+ qWarning("QOpenGLVertexArrayObject: Not supported on dynamic GL ES");
+ return false;
+ }
+#endif
+
Q_Q(QOpenGLVertexArrayObject);
if (context)
QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index aadcc0f686..6bf80eddbd 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -87,14 +87,15 @@ SOURCES += \
painting/qpaintbuffer.cpp \
painting/qpathsimplifier.cpp
-SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
-SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
+contains(QT_CPU_FEATURES.$$QT_ARCH, sse2) {
+ SOURCES += painting/qdrawhelper_sse2.cpp
+ SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
+}
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
-AVX_SOURCES += painting/qdrawhelper_avx.cpp
-!ios {
- NEON_SOURCES += painting/qdrawhelper_neon.cpp
- NEON_HEADERS += painting/qdrawhelper_neon_p.h
+!ios:contains(QT_CPU_FEATURES.$$QT_ARCH, neon) {
+ SOURCES += painting/qdrawhelper_neon.cpp
+ HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
}
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 8bbe6b6f42..b35fa38ce0 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -56,44 +56,49 @@ QT_BEGIN_NAMESPACE
const uchar *qt_patternForBrush(int brushStyle, bool invert)
{
Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
- if(invert) {
- static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
- static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
- static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
- static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
- static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
- static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
- static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
- static const uchar hor_pat[] = { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 };
- static const uchar ver_pat[] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 };
- static const uchar cross_pat[] = { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 };
- static const uchar bdiag_pat[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
- static const uchar fdiag_pat[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
- static const uchar dcross_pat[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };
- static const uchar *const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
- return pat_tbl[brushStyle - Qt::Dense1Pattern];
- }
- static const uchar dense1_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
- static const uchar dense2_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
- static const uchar dense3_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
- static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
- static const uchar dense5_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
- static const uchar dense6_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
- static const uchar dense7_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
- static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff };
- static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef };
- static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef };
- static const uchar bdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
- static const uchar fdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
- static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e };
- static const uchar *const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
- return pat_tbl[brushStyle - Qt::Dense1Pattern];
+ static const uchar pat_tbl[][2][8] = {
+ {
+ /* dense1 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
+ /*~dense1 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
+ }, {
+ /* dense2 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ /*~dense2 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
+ }, {
+ /* dense3 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
+ /*~dense3 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
+ }, {
+ /* dense4 */ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
+ /*~dense4 */ { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
+ }, {
+ /* dense5 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
+ /*~dense5 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
+ }, {
+ /* dense6 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
+ /*~dense6 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ }, {
+ /* dense7 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
+ /*~dense7 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
+ }, {
+ /* hor */ { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff },
+ /*~hor */ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 },
+ }, {
+ /* ver */ { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef },
+ /*~ver */ { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
+ }, {
+ /* cross */ { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef },
+ /*~cross */ { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 },
+ }, {
+ /* bdiag */ { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe },
+ /*~bdiag */ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
+ }, {
+ /* fdiag */ { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f },
+ /*~fdiag */ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
+ }, {
+ /* dcross */ { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e },
+ /*~dcross */ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 },
+ },
+ };
+ return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
}
QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 706273c151..b9d3ca888e 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -2499,6 +2499,41 @@ QDataStream &operator>>(QDataStream &stream, QColor &color)
}
#endif // QT_NO_DATASTREAM
+// A table of precalculated results of 0x00ff00ff/alpha use by qUnpremultiply:
+const uint qt_inv_premul_factor[256] = {
+ 0, 16711935, 8355967, 5570645, 4177983, 3342387, 2785322, 2387419,
+ 2088991, 1856881, 1671193, 1519266, 1392661, 1285533, 1193709, 1114129,
+ 1044495, 983055, 928440, 879575, 835596, 795806, 759633, 726605,
+ 696330, 668477, 642766, 618960, 596854, 576273, 557064, 539094,
+ 522247, 506422, 491527, 477483, 464220, 451673, 439787, 428511,
+ 417798, 407608, 397903, 388649, 379816, 371376, 363302, 355573,
+ 348165, 341059, 334238, 327685, 321383, 315319, 309480, 303853,
+ 298427, 293191, 288136, 283253, 278532, 273966, 269547, 265268,
+ 261123, 257106, 253211, 249431, 245763, 242201, 238741, 235379,
+ 232110, 228930, 225836, 222825, 219893, 217038, 214255, 211543,
+ 208899, 206320, 203804, 201348, 198951, 196611, 194324, 192091,
+ 189908, 187774, 185688, 183647, 181651, 179698, 177786, 175915,
+ 174082, 172287, 170529, 168807, 167119, 165464, 163842, 162251,
+ 160691, 159161, 157659, 156186, 154740, 153320, 151926, 150557,
+ 149213, 147893, 146595, 145321, 144068, 142837, 141626, 140436,
+ 139266, 138115, 136983, 135869, 134773, 133695, 132634, 131590,
+ 130561, 129549, 128553, 127572, 126605, 125653, 124715, 123792,
+ 122881, 121984, 121100, 120229, 119370, 118524, 117689, 116866,
+ 116055, 115254, 114465, 113686, 112918, 112160, 111412, 110675,
+ 109946, 109228, 108519, 107818, 107127, 106445, 105771, 105106,
+ 104449, 103800, 103160, 102527, 101902, 101284, 100674, 100071,
+ 99475, 98887, 98305, 97730, 97162, 96600, 96045, 95496,
+ 94954, 94417, 93887, 93362, 92844, 92331, 91823, 91322,
+ 90825, 90334, 89849, 89368, 88893, 88422, 87957, 87497,
+ 87041, 86590, 86143, 85702, 85264, 84832, 84403, 83979,
+ 83559, 83143, 82732, 82324, 81921, 81521, 81125, 80733,
+ 80345, 79961, 79580, 79203, 78829, 78459, 78093, 77729,
+ 77370, 77013, 76660, 76310, 75963, 75619, 75278, 74941,
+ 74606, 74275, 73946, 73620, 73297, 72977, 72660, 72346,
+ 72034, 71725, 71418, 71114, 70813, 70514, 70218, 69924,
+ 69633, 69344, 69057, 68773, 68491, 68211, 67934, 67659,
+ 67386, 67116, 66847, 66581, 66317, 66055, 65795, 65537
+};
/*****************************************************************************
QColor global functions (documentation only)
@@ -2581,6 +2616,26 @@ QDataStream &operator>>(QDataStream &stream, QColor &color)
*/
/*!
+ \fn QRgb qPremultiply(QRgb rgb)
+ \since 5.3
+ \relates QColor
+
+ Converts an unpremultiplied ARGB quadruplet \a rgb into a premultiplied ARGB quadruplet.
+
+ \sa qUnpremultiply()
+*/
+
+/*!
+ \fn QRgb qUnpremultiply(QRgb rgb)
+ \since 5.3
+ \relates QColor
+
+ Converts a premultiplied ARGB quadruplet \a rgb into an unpremultiplied ARGB quadruplet.
+
+ \sa qPremultiply()
+*/
+
+/*!
\fn QColor QColor::convertTo(Spec colorSpec) const
Creates a copy of \e this color in the format specified by \a colorSpec.
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c71d75cf94..66481d4287 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -53,6 +53,13 @@
# endif
#endif
+#include <qglobal.h>
+#ifdef Q_OS_IOS
+// We don't build the NEON drawhelpers as they are implemented partly
+// in GAS syntax assembly, which is not supported by the iOS toolchain.
+#undef __ARM_NEON__
+#endif
+
#include <qstylehints.h>
#include <qguiapplication.h>
#include <qatomic.h>
@@ -84,74 +91,254 @@ enum {
// must be multiple of 4 for easier SIMD implementations
static const int buffer_size = 2048;
+#ifdef Q_COMPILER_CONSTEXPR
+
+template<QImage::Format> Q_DECL_CONSTEXPR uint redWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint redShift();
+template<QImage::Format> Q_DECL_CONSTEXPR uint greenWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint greenShift();
+template<QImage::Format> Q_DECL_CONSTEXPR uint blueWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint blueShift();
+template<QImage::Format> Q_DECL_CONSTEXPR uint alphaWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint alphaShift();
+
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB16>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB16>() { return 11; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB444>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB555>() { return 10; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB666>() { return 12; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB888>() { return 16; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB4444_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8555_Premultiplied>() { return 18; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8565_Premultiplied>() { return 19; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB6666_Premultiplied>() { return 12; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB16>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8565_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB16>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8555_Premultiplied>() { return 13; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8565_Premultiplied>() { return 13; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB16>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB16>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB444>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB555>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB666>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB4444_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB6666_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB4444_Premultiplied>() { return 12; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8555_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8565_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB6666_Premultiplied>() { return 18; }
+
+template<QImage::Format> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel();
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB16>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB444>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB555>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB666>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB888>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB4444_Premultiplied>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8555_Premultiplied>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8565_Premultiplied>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB6666_Premultiplied>() { return QPixelLayout::BPP24; }
+
+
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+ Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+ Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
+ Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
+ Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint red = (src[i] >> redShift<Format>()) & redMask;
+ uint green = (src[i] >> greenShift<Format>()) & greenMask;
+ uint blue = (src[i] >> blueShift<Format>()) & blueMask;
+
+ red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
+ green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ buffer[i] = 0xff000000 | red | green | blue;
+ }
-// To convert in place, let 'dest' and 'src' be the same.
-static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *clut)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = PREMUL(clut[src[i]]);
return buffer;
}
-static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
- const QPixelLayout *, const QRgb *)
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
{
- return src;
+ Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar alphaLeftShift = 8 - alphaWidth<Format>();
+ Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+
+ Q_CONSTEXPR uchar alphaRightShift = 2 * alphaWidth<Format>() - 8;
+ Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
+ Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
+ Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask;
+ uint red = (src[i] >> redShift<Format>()) & redMask;
+ uint green = (src[i] >> greenShift<Format>()) & greenMask;
+ uint blue = (src[i] >> blueShift<Format>()) & blueMask;
+
+ alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
+ red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift));
+ green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift));
+ blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift));
+ buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue;
+ }
+
+ return buffer;
}
-static const uint *QT_FASTCALL convertRGB16ToARGB32PM(uint *buffer, const uint *src, int count,
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qConvertRgb16To32(src[i]);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar redRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueRightShift = 8 - blueWidth<Format>();
+
+ for (int i = 0; i < count; ++i) {
+ const uint color = qUnpremultiply(src[i]);
+ const uint red = ((color >> redRightShift) & redMask) << redShift<Format>();
+ const uint green = ((color >> greenRightShift) & greenMask) << greenShift<Format>();
+ const uint blue = ((color >> blueRightShift) & blueMask) << blueShift<Format>();
+ buffer[i] = red | green | blue;
+ }
return buffer;
}
-static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertRGBFromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = PREMUL(src[i]);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar redRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueRightShift = 8 - blueWidth<Format>();
+
+ for (int i = 0; i < count; ++i) {
+ const uint red = ((src[i] >> redRightShift) & redMask) << redShift<Format>();
+ const uint green = ((src[i] >> greenRightShift) & greenMask) << greenShift<Format>();
+ const uint blue = ((src[i] >> blueRightShift) & blueMask) << blueShift<Format>();
+ buffer[i] = red | green | blue;
+ }
return buffer;
}
-static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
- const QPixelLayout *layout, const QRgb *)
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
{
- Q_ASSERT(layout->redWidth >= 4);
- Q_ASSERT(layout->greenWidth >= 4);
- Q_ASSERT(layout->blueWidth >= 4);
- Q_ASSERT(layout->alphaWidth == 0);
-
- const uint redMask = ((1 << layout->redWidth) - 1);
- const uint greenMask = ((1 << layout->greenWidth) - 1);
- const uint blueMask = ((1 << layout->blueWidth) - 1);
-
- const uchar redLeftShift = 8 - layout->redWidth;
- const uchar greenLeftShift = 8 - layout->greenWidth;
- const uchar blueLeftShift = 8 - layout->blueWidth;
+ Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
- const uchar redRightShift = 2 * layout->redWidth - 8;
- const uchar greenRightShift = 2 * layout->greenWidth - 8;
- const uchar blueRightShift = 2 * layout->blueWidth - 8;
+ Q_CONSTEXPR uchar alphaRightShift = 32 - alphaWidth<Format>();
+ Q_CONSTEXPR uchar redRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueRightShift = 8 - blueWidth<Format>();
for (int i = 0; i < count; ++i) {
- uint red = (src[i] >> layout->redShift) & redMask;
- uint green = (src[i] >> layout->greenShift) & greenMask;
- uint blue = (src[i] >> layout->blueShift) & blueMask;
-
- red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
- green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
- blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- buffer[i] = 0xff000000 | red | green | blue;
+ const uint alpha = ((src[i] >> alphaRightShift) & alphaMask) << alphaShift<Format>();
+ const uint red = ((src[i] >> redRightShift) & redMask) << redShift<Format>();
+ const uint green = ((src[i] >> greenRightShift) & greenMask) << greenShift<Format>();
+ const uint blue = ((src[i] >> blueRightShift) & blueMask) << blueShift<Format>();
+ buffer[i] = alpha | red | green | blue;
}
-
return buffer;
}
+template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB()
+{
+ return QPixelLayout{
+ redWidth<Format>(), redShift<Format>(),
+ greenWidth<Format>(), greenShift<Format>(),
+ blueWidth<Format>(), blueShift<Format>(),
+ 0, 0,
+ false, bitsPerPixel<Format>(),
+ convertToRGB32<Format>,
+ convertRGBFromARGB32PM<Format>,
+ convertRGBFromRGB32<Format>
+ };
+}
+
+template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutARGBPM()
+{
+ return QPixelLayout{
+ redWidth<Format>(), redShift<Format>(),
+ greenWidth<Format>(), greenShift<Format>(),
+ blueWidth<Format>(), blueShift<Format>(),
+ alphaWidth<Format>(), alphaShift<Format>(),
+ true, bitsPerPixel<Format>(),
+ convertARGBPMToARGB32PM<Format>,
+ convertARGBPMFromARGB32PM<Format>,
+ 0
+ };
+}
+
+#else // CONSTEXPR
+
static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *layout, const QRgb *)
{
@@ -200,25 +387,42 @@ static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src,
red = (red << redLeftShift) | (red >> redRightShift);
green = (green << greenLeftShift) | (green >> greenRightShift);
blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- buffer[i] = PREMUL((alpha << 24) | (red << 16) | (green << 8) | blue);
+ buffer[i] = qPremultiply((alpha << 24) | (red << 16) | (green << 8) | blue);
}
}
return buffer;
}
-static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
+static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qConvertRgb32To16(INV_PREMUL(src[i]));
- return buffer;
-}
+ Q_ASSERT(layout->redWidth >= 4);
+ Q_ASSERT(layout->greenWidth >= 4);
+ Q_ASSERT(layout->blueWidth >= 4);
+ Q_ASSERT(layout->alphaWidth == 0);
-static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = INV_PREMUL(src[i]);
+ const uint redMask = ((1 << layout->redWidth) - 1);
+ const uint greenMask = ((1 << layout->greenWidth) - 1);
+ const uint blueMask = ((1 << layout->blueWidth) - 1);
+
+ const uchar redLeftShift = 8 - layout->redWidth;
+ const uchar greenLeftShift = 8 - layout->greenWidth;
+ const uchar blueLeftShift = 8 - layout->blueWidth;
+
+ const uchar redRightShift = 2 * layout->redWidth - 8;
+ const uchar greenRightShift = 2 * layout->greenWidth - 8;
+ const uchar blueRightShift = 2 * layout->blueWidth - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint red = (src[i] >> layout->redShift) & redMask;
+ uint green = (src[i] >> layout->greenShift) & greenMask;
+ uint blue = (src[i] >> layout->blueShift) & blueMask;
+
+ red = (red << redLeftShift) | (red >> redRightShift);
+ green = (green << greenLeftShift) | (green >> greenRightShift);
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ buffer[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
+ }
return buffer;
}
@@ -242,7 +446,7 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src
if (!layout->premultiplied) {
for (int i = 0; i < count; ++i)
- buffer[i] = qAlpha(src[i]) == 255 ? src[i] : INV_PREMUL(src[i]);
+ buffer[i] = qUnpremultiply(src[i]);
src = buffer;
}
for (int i = 0; i < count; ++i) {
@@ -255,13 +459,14 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src
return buffer;
}
-static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *layout, const QRgb *)
+static const uint *QT_FASTCALL convertFromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
{
Q_ASSERT(layout->redWidth <= 8);
Q_ASSERT(layout->greenWidth <= 8);
Q_ASSERT(layout->blueWidth <= 8);
Q_ASSERT(layout->alphaWidth == 0);
+ Q_ASSERT(!layout->premultiplied);
const uint redMask = (1 << layout->redWidth) - 1;
const uint greenMask = (1 << layout->greenWidth) - 1;
@@ -272,16 +477,118 @@ static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *
const uchar blueRightShift = 8 - layout->blueWidth;
for (int i = 0; i < count; ++i) {
- uint color = INV_PREMUL(src[i]);
- uint red = ((color >> redRightShift) & redMask) << layout->redShift;
- uint green = ((color >> greenRightShift) & greenMask) << layout->greenShift;
- uint blue = ((color >> blueRightShift) & blueMask) << layout->blueShift;
- uint alpha = 0xff << layout->alphaShift;
- buffer[i] = red | green | blue | alpha;
+ uint red = ((src[i] >> redRightShift) & redMask) << layout->redShift;
+ uint green = ((src[i] >> greenRightShift) & greenMask) << layout->greenShift;
+ uint blue = ((src[i] >> blueRightShift) & blueMask) << layout->blueShift;
+ buffer[i] = red | green | blue;
}
return buffer;
}
+static const uint *QT_FASTCALL convertRGB16ToRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb16To32(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGB16FromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb32To16(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb32To16(qUnpremultiply(src[i]));
+ return buffer;
+}
+#endif
+
+// To convert in place, let 'dest' and 'src' be the same.
+static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *clut)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(clut[src[i]]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
+ const QPixelLayout *, const QRgb *)
+{
+ return src;
+}
+
+static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = RGBA2ARGB(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(RGBA2ARGB(src[i]));
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qUnpremultiply(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(qUnpremultiply(src[i]));
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(0xff000000 | src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply(src[i]));
+ return buffer;
+}
+
template <QPixelLayout::BPP bpp> static
uint QT_FASTCALL fetchPixel(const uchar *src, int index);
@@ -392,30 +699,44 @@ inline void QT_FASTCALL storePixels<QPixelLayout::BPP32>(uchar *dest, const uint
// convertFromArgb32() assumes that no color channel is more than 8 bits.
// QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits.
QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0 }, // Format_Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0 }, // Format_Mono
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0 }, // Format_MonoLSB
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0 }, // Format_Indexed8
- { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_RGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM }, // Format_ARGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_ARGB32_Premultiplied
- { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToARGB32PM, convertRGB16FromARGB32PM }, // Format_RGB16
- { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8565_Premultiplied
- { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB666
- { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB6666_Premultiplied
- { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB555
- { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied
- { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888
- { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444
- { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB4444_Premultiplied
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0, 0 }, // Format_Invalid
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0 }, // Format_Mono
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0 }, // Format_MonoLSB
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0 }, // Format_Indexed8
+ // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong,
+ // but everywhere this generic conversion would be wrong is currently overloaed.
+ { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough }, // Format_RGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, 0 }, // Format_ARGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, 0 }, // Format_ARGB32_Premultiplied
+#ifdef Q_COMPILER_CONSTEXPR
+ pixelLayoutRGB<QImage::Format_RGB16>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB8565_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB666>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB6666_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB555>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB8555_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB888>(),
+ pixelLayoutRGB<QImage::Format_RGB444>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB4444_Premultiplied>(),
+#else
+ { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToRGB32, convertRGB16FromARGB32PM, convertRGB16FromRGB32 }, // Format_RGB16
+ { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8565_Premultiplied
+ { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB666
+ { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB6666_Premultiplied
+ { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB555
+ { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8555_Premultiplied
+ { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB888
+ { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB444
+ { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB4444_Premultiplied
+#endif
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
- { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888
- { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888_Premultiplied
+ { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 }, // Format_RGBA8888_Premultiplied
#else
- { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
- { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 (ABGR32)
- { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM } // Format_RGBA8888_Premultiplied
+ { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888
+ { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888 (ABGR32)
+ { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 } // Format_RGBA8888_Premultiplied
#endif
};
@@ -532,9 +853,9 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
*/
static inline QRgb findNearestColor(QRgb color, QRasterBuffer *rbuf)
{
- QRgb color_0 = PREMUL(rbuf->destColor0);
- QRgb color_1 = PREMUL(rbuf->destColor1);
- color = PREMUL(color);
+ QRgb color_0 = qPremultiply(rbuf->destColor0);
+ QRgb color_1 = qPremultiply(rbuf->destColor1);
+ color = qPremultiply(color);
int r = qRed(color);
int g = qGreen(color);
@@ -630,7 +951,12 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con
uchar *dest = rasterBuffer->scanLine(y);
while (length) {
int l = qMin(length, buffer_size);
- const uint *ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0);
+ const uint *ptr = 0;
+ if (layout->convertFromRGB32) {
+ Q_ASSERT(!layout->premultiplied && !layout->alphaWidth);
+ ptr = layout->convertFromRGB32(buf, buffer, l, layout, 0);
+ } else
+ ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0);
store(dest, ptr, x, l);
length -= l;
buffer += l;
@@ -891,7 +1217,7 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i
{
uint distxy = distx * disty;
//idistx * disty = (16-distx) * disty = 16*disty - distxy
- //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*dity + distxy
+ //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*disty + distxy
uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy);
uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy);
uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy));
@@ -973,6 +1299,44 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i
}
#endif
+#if defined(__SSE2__)
+static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
+{
+ // First interpolate right and left pixels in parallel.
+ __m128i vl = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(bl));
+ __m128i vr = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tr), _mm_cvtsi32_si128(br));
+ vl = _mm_unpacklo_epi8(vl, _mm_setzero_si128());
+ vr = _mm_unpacklo_epi8(vr, _mm_setzero_si128());
+ vl = _mm_mullo_epi16(vl, _mm_set1_epi16(256 - distx));
+ vr = _mm_mullo_epi16(vr, _mm_set1_epi16(distx));
+ __m128i vtb = _mm_add_epi16(vl, vr);
+ vtb = _mm_srli_epi16(vtb, 8);
+ // vtb now contains the result of the first two interpolate calls vtb = unpacked((xbot << 64) | xtop)
+
+ // Now the last interpolate between top and bottom interpolations.
+ const __m128i vidisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - disty), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vdisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(disty), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vmuly = _mm_unpacklo_epi16(vidisty, vdisty);
+ vtb = _mm_unpacklo_epi16(vtb, _mm_srli_si128(vtb, 8));
+ // vtb now contains the colors of top and bottom interleaved { ta, ba, tr, br, tg, bg, tb, bb }
+ vtb = _mm_madd_epi16(vtb, vmuly); // Multiply and horizontal add.
+ vtb = _mm_srli_epi32(vtb, 8);
+ vtb = _mm_packs_epi32(vtb, _mm_setzero_si128());
+ vtb = _mm_packus_epi16(vtb, _mm_setzero_si128());
+ return _mm_cvtsi128_si32(vtb);
+}
+#else
+static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
+{
+ uint idistx = 256 - distx;
+ uint idisty = 256 - disty;
+ uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
+ uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
+ return INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+}
+#endif
+
+
template<TextureBlendType blendType>
void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2);
@@ -1177,7 +1541,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
const uint *s1 = (const uint *)data->texture.scanLine(y1);
const uint *s2 = (const uint *)data->texture.scanLine(y2);
int disty = (fy & 0x0000ffff) >> 8;
- int idisty = 256 - disty;
while (b < end) {
int x1 = (fx >> 16);
int x2;
@@ -1186,13 +1549,8 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
uint tr = s1[x2];
uint bl = s2[x1];
uint br = s2[x2];
-
int distx = (fx & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
-
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fx += fdx;
++b;
@@ -1356,12 +1714,8 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int idisty = 256 - disty;
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fx += fdx;
fy += fdy;
@@ -1418,8 +1772,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
int distx = int((px - x1) * 256);
int disty = int((py - y1) * 256);
- int idistx = 256 - distx;
- int idisty = 256 - disty;
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
@@ -1432,9 +1784,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
uint bl = s2[x1];
uint br = s2[x2];
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fx += fdx;
fy += fdy;
@@ -1606,17 +1956,13 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x
int disty = (fy & 0x0000ffff) >> 8;
- int idisty = 256 - disty;
for (int i = 0; i < len; ++i) {
uint tl = buf1[i * 2 + 0];
uint tr = buf1[i * 2 + 1];
uint bl = buf2[i * 2 + 0];
uint br = buf2[i * 2 + 1];
int distx = (fracX & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fracX += fdx;
}
} else { //scale down
@@ -1677,12 +2023,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
int distx = (fracX & 0x0000ffff) >> 8;
int disty = (fracY & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int idisty = 256 - disty;
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fracX += fdx;
fracY += fdy;
}
@@ -1764,17 +2106,13 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
for (int i = 0; i < len; ++i) {
int distx = distxs[i];
int disty = distys[i];
- int idistx = 256 - distx;
- int idisty = 256 - disty;
uint tl = buf1[i * 2 + 0];
uint tr = buf1[i * 2 + 1];
uint bl = buf2[i * 2 + 0];
uint br = buf2[i * 2 + 1];
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
}
length -= len;
b += len;
@@ -5071,13 +5409,15 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us
int l = qMin(length, buffer_size);
const uint *end = buffer + l;
uint *b = buffer;
+ int px16 = x % (image_width << 16);
+ int py16 = y % (image_height << 16);
+ int px_delta = fdx % (image_width << 16);
+ int py_delta = fdy % (image_height << 16);
while (b < end) {
- int px = x >> 16;
- int py = y >> 16;
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
+ if (px16 < 0) px16 += image_width << 16;
+ if (py16 < 0) py16 += image_height << 16;
+ int px = px16 >> 16;
+ int py = py16 >> 16;
int y_offset = py * scanline_offset;
Q_ASSERT(px >= 0 && px < image_width);
@@ -5086,6 +5426,12 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us
*b = image_bits[y_offset + px];
x += fdx;
y += fdy;
+ px16 += px_delta;
+ if (px16 >= image_width << 16)
+ px16 -= image_width << 16;
+ py16 += py_delta;
+ if (py16 >= image_height << 16)
+ py16 -= image_height << 16;
++b;
}
func(target, buffer, l, coverage);
@@ -5916,7 +6262,7 @@ static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer,
quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine());
+ qUnpremultiply(color), x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_rgba(QRasterBuffer *rasterBuffer,
@@ -5932,7 +6278,7 @@ static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer,
quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- ARGB2RGBA(INV_PREMUL(color)), x, y, width, height, rasterBuffer->bytesPerLine());
+ ARGB2RGBA(qUnpremultiply(color)), x, y, width, height, rasterBuffer->bytesPerLine());
}
@@ -6140,110 +6486,73 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count)
}
#endif
-static void qt_memfill_quint16(quint16 *dest, quint16 color, int count)
+#if !defined(__SSE2__)
+void qt_memfill16(quint16 *dest, quint16 color, int count)
{
qt_memfill_template<quint16>(dest, color, count);
}
-
-typedef void (*qt_memfill32_func)(quint32 *dest, quint32 value, int count);
-typedef void (*qt_memfill16_func)(quint16 *dest, quint16 value, int count);
-static void qt_memfill32_setup(quint32 *dest, quint32 value, int count);
-static void qt_memfill16_setup(quint16 *dest, quint16 value, int count);
-
-qt_memfill32_func qt_memfill32 = qt_memfill32_setup;
-qt_memfill16_func qt_memfill16 = qt_memfill16_setup;
+#endif
+#if !defined(__SSE2__) && !defined(__ARM_NEON__)
+void qt_memfill32(quint32 *dest, quint32 color, int count)
+{
+# ifdef QT_COMPILER_SUPPORTS_MIPS_DSP
+ extern "C" qt_memfill32_asm_mips_dsp(quint32 *, quint32, int);
+ qt_memfill32_asm_mips_dsp(dest, color, count);
+# else
+ qt_memfill_template<quint32>(dest, color, count);
+# endif
+}
+#endif
void qInitDrawhelperAsm()
{
-
- qt_memfill32 = qt_memfill_template<quint32>;
- qt_memfill16 = qt_memfill_quint16; //qt_memfill_template<quint16>;
-
CompositionFunction *functionForModeAsm = 0;
CompositionFunctionSolid *functionForModeSolidAsm = 0;
const uint features = qCpuFeatures();
- if (false) {
- Q_UNUSED(features);
-#ifdef QT_COMPILER_SUPPORTS_AVX
- } else if (features & AVX) {
- qt_memfill32 = qt_memfill32_avx;
- qt_memfill16 = qt_memfill16_avx;
- qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_avx;
- qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
-
- extern void qt_scale_image_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
- const QRectF &sourceRect,
- const QRect &clip,
- int const_alpha);
- qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
- qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
- qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
-#endif
-#endif
-#ifdef QT_COMPILER_SUPPORTS_SSE2
- } else if (features & SSE2) {
- qt_memfill32 = qt_memfill32_sse2;
- qt_memfill16 = qt_memfill16_sse2;
- qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
- qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
-
- extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
- const QRectF &sourceRect,
- const QRect &clip,
- int const_alpha);
- qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
- qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
- qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
-#endif
-#endif
- }
-
-#ifdef QT_COMPILER_SUPPORTS_SSE2
- if (features & SSE2) {
- extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
- extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
-#endif
-
- extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length);
-
- qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
- }
+ Q_UNUSED(features);
+#ifdef __SSE2__
+ qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
+ qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
+
+ extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ int const_alpha);
+ qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+
+ extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+ extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+
+ extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length);
+
+ qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
#ifdef QT_COMPILER_SUPPORTS_SSSE3
if (features & SSSE3) {
@@ -6254,65 +6563,13 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
-#endif
}
#endif // SSSE3
-#ifdef QT_COMPILER_SUPPORTS_AVX
- if (features & AVX) {
- extern void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
- extern void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
-#endif
-
- extern const uint * QT_FASTCALL qt_fetch_radial_gradient_avx(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length);
-
- qt_fetch_radial_gradient = qt_fetch_radial_gradient_avx;
- }
-#endif // AVX
-
-#endif // SSE2
-
-#ifdef QT_COMPILER_SUPPORTS_SSE2
- if (features & SSE2) {
- functionForModeAsm = qt_functionForMode_SSE2;
- functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
- }
-#endif
-#ifdef QT_COMPILER_SUPPORTS_AVX
- if (features & AVX) {
- extern void QT_FASTCALL comp_func_SourceOver_avx(uint *destPixels,
- const uint *srcPixels,
- int length,
- uint const_alpha);
- extern void QT_FASTCALL comp_func_solid_SourceOver_avx(uint *destPixels, int length, uint color, uint const_alpha);
- extern void QT_FASTCALL comp_func_Plus_avx(uint *dst, const uint *src, int length, uint const_alpha);
- extern void QT_FASTCALL comp_func_Source_avx(uint *dst, const uint *src, int length, uint const_alpha);
-
- functionForModeAsm[0] = comp_func_SourceOver_avx;
- functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_avx;
- functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_avx;
- functionForModeSolidAsm[0] = comp_func_solid_SourceOver_avx;
- }
+ functionForModeAsm = qt_functionForMode_SSE2;
+ functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
#endif // SSE2
#ifdef QT_COMPILER_SUPPORTS_IWMMXT
@@ -6323,45 +6580,42 @@ void qInitDrawhelperAsm()
}
#endif // IWMMXT
-#if defined(QT_COMPILER_SUPPORTS_NEON) && !defined(Q_OS_IOS)
- if (features & NEON) {
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
+#if defined(__ARM_NEON__) && !defined(Q_OS_IOS)
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
#endif
- qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
- qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
+ qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
+ qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
- qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
- qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
+ qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
+ qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
- qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
+ qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
- functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
- functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
- functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
- destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
- destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
+ functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
+ functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
+ functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
+ destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
+ destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
- qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
- qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
- qt_memfill32 = qt_memfill32_neon;
+ qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
+ qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
- extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length);
+ extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length);
- qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
- }
+ qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
#endif
#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP)
@@ -6385,8 +6639,6 @@ void qInitDrawhelperAsm()
functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
- qt_memfill32 = qt_memfill32_asm_mips_dsp;
-
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
@@ -6427,16 +6679,4 @@ void qInitDrawhelperAsm()
functionForMode = functionForModeAsm;
}
-static void qt_memfill32_setup(quint32 *dest, quint32 value, int count)
-{
- qInitDrawhelperAsm();
- qt_memfill32(dest, value, count);
-}
-
-static void qt_memfill16_setup(quint16 *dest, quint16 value, int count)
-{
- qInitDrawhelperAsm();
- qt_memfill16(dest, value, count);
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 541b3ef619..a40166d5be 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -43,7 +43,7 @@
#include <private/qblendfunctions_p.h>
#include <private/qmath_p.h>
-#ifdef QT_COMPILER_SUPPORTS_NEON
+#ifdef __ARM_NEON__
#include <private/qdrawhelper_neon_p.h>
#include <private/qpaintengine_raster_p.h>
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
-void qt_memfill32_neon(quint32 *dest, quint32 value, int count)
+void qt_memfill32(quint32 *dest, quint32 value, int count)
{
const int epilogueSize = count % 16;
if (count >= 16) {
@@ -998,5 +998,5 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Opera
QT_END_NAMESPACE
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
index 475df639f8..cad6fe22e9 100644
--- a/src/gui/painting/qdrawhelper_neon_p.h
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_COMPILER_SUPPORTS_NEON
+#ifdef __ARM_NEON__
void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -139,7 +139,7 @@ void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer,
void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha);
void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha);
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 418294c56d..bbeb73f0af 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -171,6 +171,8 @@ extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3];
extern DrawHelper qDrawHelper[QImage::NImageFormats];
void qBlendTexture(int count, const QSpan *spans, void *userData);
+extern void qt_memfill32(quint32 *dest, quint32 value, int count);
+extern void qt_memfill16(quint16 *dest, quint16 value, int count);
typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha);
typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha);
@@ -386,8 +388,6 @@ static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c)
return (b * b) - (4 * a * c);
}
-extern void (*qt_memfill32)(quint32 *dest, quint32 value, int count);
-
template <class RadialFetchFunc> Q_STATIC_TEMPLATE_FUNCTION
const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length)
@@ -599,14 +599,6 @@ static Q_ALWAYS_INLINE uint BYTE_MUL(uint x, uint a) {
return (uint(t)) | (uint(t >> 24));
}
-static Q_ALWAYS_INLINE uint PREMUL(uint x) {
- uint a = x >> 24;
- quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
- t &= 0x000000ff00ff00ff;
- return (uint(t)) | (uint(t >> 24)) | (a << 24);
-}
-
#else // 32-bit versions
static Q_ALWAYS_INLINE uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
@@ -639,20 +631,9 @@ static Q_ALWAYS_INLINE uint BYTE_MUL(uint x, uint a) {
# pragma pop
#endif
-static Q_ALWAYS_INLINE uint PREMUL(uint x) {
- uint a = x >> 24;
- uint t = (x & 0xff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff) * a;
- x = (x + ((x >> 8) & 0xff) + 0x80);
- x &= 0xff00;
- x |= t | (a << 24);
- return x;
-}
#endif
+
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
quint32 rgb = x >> 8;
@@ -691,12 +672,9 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) {
return t;
}
-#define INV_PREMUL(p) \
- (qAlpha(p) == 0 ? 0 : \
- ((qAlpha(p) << 24) \
- | (((255*qRed(p))/ qAlpha(p)) << 16) \
- | (((255*qGreen(p)) / qAlpha(p)) << 8) \
- | ((255*qBlue(p)) / qAlpha(p))))
+// FIXME: Remove when all Qt modules have stopped using PREMUL and INV_PREMUL
+#define PREMUL(x) qPremultiply(x)
+#define INV_PREMUL(p) qUnpremultiply(p)
struct quint24 {
quint24(uint value);
@@ -726,7 +704,6 @@ template<> inline void qt_memfill(quint32 *dest, quint32 color, int count)
template<> inline void qt_memfill(quint16 *dest, quint16 color, int count)
{
- extern void (*qt_memfill16)(quint16 *dest, quint16 value, int count);
qt_memfill16(dest, color, count);
}
@@ -1031,6 +1008,7 @@ struct QPixelLayout
BPP bpp;
ConvertFunc convertToARGB32PM;
ConvertFunc convertFromARGB32PM;
+ ConvertFunc convertFromRGB32;
};
typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index a9dc5a7fb7..f5523f7113 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -238,7 +238,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u
}
}
-void qt_memfill32_sse2(quint32 *dest, quint32 value, int count)
+void qt_memfill32(quint32 *dest, quint32 value, int count)
{
if (count < 7) {
switch (count) {
@@ -259,33 +259,39 @@ void qt_memfill32_sse2(quint32 *dest, quint32 value, int count)
case 12: *dest++ = value; --count;
}
+ const int rest = count & 0x3;
+ if (rest) {
+ switch (rest) {
+ case 3: dest[count - 3] = value;
+ case 2: dest[count - 2] = value;
+ case 1: dest[count - 1] = value;
+ }
+ }
+
int count128 = count / 4;
__m128i *dst128 = reinterpret_cast<__m128i*>(dest);
+ __m128i *end128 = dst128 + count128;
const __m128i value128 = _mm_set_epi32(value, value, value, value);
- int n = (count128 + 3) / 4;
+ while (dst128 + 3 < end128) {
+ _mm_stream_si128(dst128 + 0, value128);
+ _mm_stream_si128(dst128 + 1, value128);
+ _mm_stream_si128(dst128 + 2, value128);
+ _mm_stream_si128(dst128 + 3, value128);
+ dst128 += 4;
+ }
+
switch (count128 & 0x3) {
- case 0: do { _mm_stream_si128(dst128++, value128);
case 3: _mm_stream_si128(dst128++, value128);
case 2: _mm_stream_si128(dst128++, value128);
case 1: _mm_stream_si128(dst128++, value128);
- } while (--n > 0);
- }
-
- const int rest = count & 0x3;
- if (rest) {
- switch (rest) {
- case 3: dest[count - 3] = value;
- case 2: dest[count - 2] = value;
- case 1: dest[count - 1] = value;
- }
}
}
void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha)
{
if ((const_alpha & qAlpha(color)) == 255) {
- qt_memfill32_sse2(destPixels, color, length);
+ qt_memfill32(destPixels, color, length);
} else {
if (const_alpha != 255)
color = BYTE_MUL(color, const_alpha);
@@ -397,7 +403,7 @@ CompositionFunction qt_functionForMode_SSE2[numCompositionFunctions] = {
};
#endif
-void qt_memfill16_sse2(quint16 *dest, quint16 value, int count)
+void qt_memfill16(quint16 *dest, quint16 value, int count)
{
if (count < 3) {
switch (count) {
@@ -413,7 +419,7 @@ void qt_memfill16_sse2(quint16 *dest, quint16 value, int count)
}
const quint32 value32 = (value << 16) | value;
- qt_memfill32_sse2(reinterpret_cast<quint32*>(dest), value32, count / 2);
+ qt_memfill32(reinterpret_cast<quint32*>(dest), value32, count / 2);
if (count & 0x1)
dest[count - 1] = value;
diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h
index d64b9cec39..699c586cb0 100644
--- a/src/gui/painting/qdrawhelper_x86_p.h
+++ b/src/gui/painting/qdrawhelper_x86_p.h
@@ -57,9 +57,9 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_COMPILER_SUPPORTS_SSE2
-void qt_memfill32_sse2(quint32 *dest, quint32 value, int count);
-void qt_memfill16_sse2(quint16 *dest, quint16 value, int count);
+#ifdef __SSE2__
+void qt_memfill32(quint32 *dest, quint32 value, int count);
+void qt_memfill16(quint16 *dest, quint16 value, int count);
void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride);
@@ -77,26 +77,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
extern CompositionFunction qt_functionForMode_SSE2[];
extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[];
-#endif // QT_COMPILER_SUPPORTS_SSE2
-
-#ifdef QT_COMPILER_SUPPORTS_AVX
-void qt_memfill32_avx(quint32 *dest, quint32 value, int count);
-void qt_memfill16_avx(quint16 *dest, quint16 value, int count);
-void qt_bitmapblit32_avx(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
- const uchar *src, int width, int height, int stride);
-void qt_bitmapblit16_avx(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
- const uchar *src, int width, int height, int stride);
-void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-#endif // QT_COMPILER_SUPPORTS_AVX
+#endif // __SSE2__
#ifdef QT_COMPILER_SUPPORTS_IWMMXT
void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData);
diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h
index 0e0c06f56c..cdf68b932d 100644
--- a/src/gui/painting/qdrawingprimitive_sse2_p.h
+++ b/src/gui/painting/qdrawingprimitive_sse2_p.h
@@ -44,7 +44,7 @@
#include <private/qsimd_p.h>
-#ifdef QT_COMPILER_SUPPORTS_SSE2
+#ifdef __SSE2__
//
// W A R N I N G
@@ -242,6 +242,6 @@ QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
-#endif // QT_COMPILER_SUPPORTS_SSE2
+#endif // __SSE2__
#endif // QDRAWINGPRIMITIVE_SSE2_P_H
diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp
index bb87b4fd6e..0fb907b6c5 100644
--- a/src/gui/painting/qemulationpaintengine.cpp
+++ b/src/gui/painting/qemulationpaintengine.cpp
@@ -169,7 +169,7 @@ void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &text
{
if (state()->bgMode == Qt::OpaqueMode) {
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
- QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
+ QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent).toReal());
fillBGRect(rect);
}
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index f855e9e32d..421d706230 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -70,13 +70,11 @@ QTextItemIntCopy::QTextItemIntCopy(const QTextItem &item)
m_item.chars = chars;
m_item.logClusters = logClusters;
- const int size = QGlyphLayout::spaceNeededForGlyphLayout(m_item.glyphs.numGlyphs);
- char *glyphLayoutData = new char[size];
+ char *glyphLayoutData = new char[m_item.glyphs.numGlyphs * QGlyphLayout::SpaceNeeded];
QGlyphLayout glyphs(glyphLayoutData, m_item.glyphs.numGlyphs);
memcpy(glyphs.offsets, m_item.glyphs.offsets, m_item.glyphs.numGlyphs * sizeof(QFixedPoint));
memcpy(glyphs.glyphs, m_item.glyphs.glyphs, m_item.glyphs.numGlyphs * sizeof(glyph_t));
- memcpy(glyphs.advances_x, m_item.glyphs.advances_x, m_item.glyphs.numGlyphs * sizeof(QFixed));
- memcpy(glyphs.advances_y, m_item.glyphs.advances_y, m_item.glyphs.numGlyphs * sizeof(QFixed));
+ memcpy(glyphs.advances, m_item.glyphs.advances, m_item.glyphs.numGlyphs * sizeof(QFixed));
memcpy(glyphs.justifications, m_item.glyphs.justifications, m_item.glyphs.numGlyphs * sizeof(QGlyphJustification));
memcpy(glyphs.attributes, m_item.glyphs.attributes, m_item.glyphs.numGlyphs * sizeof(QGlyphAttributes));
m_item.glyphs = glyphs;
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index f1eaea0f6b..acab08e794 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -387,6 +387,7 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw
\value OpenGL2
\value PaintBuffer
\value Blitter
+ \value Direct2D Windows only, Direct2D based engine
*/
/*!
diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
index 18b6d84146..7b928ba5f6 100644
--- a/src/gui/painting/qpaintengine.h
+++ b/src/gui/painting/qpaintengine.h
@@ -207,6 +207,7 @@ public:
OpenGL2,
PaintBuffer,
Blitter,
+ Direct2D,
User = 50, // first user type id
MaxUser = 100 // last user type id
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index bdd0d9cd4c..9a2e49618c 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1823,7 +1823,7 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
- d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color.rgba(), s->intOpacity));
+ d->solid_color_filler.solid.color = qPremultiply(ARGB_COMBINE_ALPHA(color.rgba(), s->intOpacity));
if ((d->solid_color_filler.solid.color & 0xff000000) == 0
&& s->composition_mode == QPainter::CompositionMode_SourceOver) {
return;
@@ -2272,7 +2272,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
| ((((color & 0xff00ff00) >> 8) * s->intOpacity) & 0xff00ff00);
break;
default:
- d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color, s->intOpacity));
+ d->solid_color_filler.solid.color = qPremultiply(ARGB_COMBINE_ALPHA(color, s->intOpacity));
break;
}
@@ -3662,7 +3662,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);
QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied);
- QRgb fg = PREMUL(color.rgba());
+ QRgb fg = qPremultiply(color.rgba());
QRgb bg = 0;
int height = sourceImage.height();
@@ -3702,8 +3702,8 @@ QImage::Format QRasterBuffer::prepare(QImage *image)
drawHelper = qDrawHelper + format;
if (image->depth() == 1 && image->colorTable().size() == 2) {
monoDestinationWithClut = true;
- destColor0 = PREMUL(image->colorTable()[0]);
- destColor1 = PREMUL(image->colorTable()[1]);
+ destColor0 = qPremultiply(image->colorTable()[0]);
+ destColor1 = qPremultiply(image->colorTable()[1]);
}
return format;
@@ -4260,8 +4260,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
}
if (colorInterpolation) {
- first_color = PREMUL(first_color);
- second_color = PREMUL(second_color);
+ first_color = qPremultiply(first_color);
+ second_color = qPremultiply(second_color);
}
int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1));
@@ -4282,7 +4282,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[i] = first_color;
else
- colorTable[i] = PREMUL(first_color);
+ colorTable[i] = qPremultiply(first_color);
}
if (i < second_index) {
@@ -4311,7 +4311,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[i] = color;
else
- colorTable[i] = PREMUL(color);
+ colorTable[i] = qPremultiply(color);
}
}
@@ -4319,7 +4319,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[i] = second_color;
else
- colorTable[i] = PREMUL(second_color);
+ colorTable[i] = qPremultiply(second_color);
}
return;
@@ -4327,7 +4327,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
if (stopCount == 1) {
- current_color = PREMUL(current_color);
+ current_color = qPremultiply(current_color);
for (int i = 0; i < size; ++i)
colorTable[i] = current_color;
return;
@@ -4344,7 +4344,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
qreal dpos = 1.5 * incr; // current position in gradient stop list (0 to 1)
// Up to first point
- colorTable[pos++] = PREMUL(current_color);
+ colorTable[pos++] = qPremultiply(current_color);
while (dpos <= begin_pos) {
colorTable[pos] = colorTable[pos - 1];
++pos;
@@ -4366,8 +4366,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
if (colorInterpolation) {
- current_color = PREMUL(current_color);
- next_color = PREMUL(next_color);
+ current_color = qPremultiply(current_color);
+ next_color = qPremultiply(next_color);
}
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
@@ -4384,7 +4384,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
else
- colorTable[pos] = PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+ colorTable[pos] = qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
++pos;
dpos += incr;
@@ -4408,8 +4408,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation) {
if (skip != 1)
- current_color = PREMUL(current_color);
- next_color = PREMUL(next_color);
+ current_color = qPremultiply(current_color);
+ next_color = qPremultiply(next_color);
}
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
@@ -4421,7 +4421,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
}
// After last point
- current_color = PREMUL(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
+ current_color = qPremultiply(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
while (pos < size - 1) {
colorTable[pos] = current_color;
++pos;
@@ -4455,7 +4455,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = Solid;
QColor c = qbrush_color(brush);
QRgb rgba = c.rgba();
- solid.color = PREMUL(ARGB_COMBINE_ALPHA(rgba, alpha));
+ solid.color = qPremultiply(ARGB_COMBINE_ALPHA(rgba, alpha));
if ((solid.color & 0xff000000) == 0
&& compositionMode == QPainter::CompositionMode_SourceOver) {
type = None;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 41a2e39fc9..1fc044aa44 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5617,8 +5617,7 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positio
textItem.glyphs.numGlyphs = glyphCount;
textItem.glyphs.glyphs = const_cast<glyph_t *>(glyphArray);
textItem.glyphs.offsets = positions;
- textItem.glyphs.advances_x = advances.data();
- textItem.glyphs.advances_y = advances.data();
+ textItem.glyphs.advances = advances.data();
textItem.glyphs.justifications = glyphJustifications.data();
textItem.glyphs.attributes = glyphAttributes.data();
@@ -5846,11 +5845,8 @@ void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justif
int numGlyphs = len;
QVarLengthGlyphLayoutArray glyphs(len);
QFontEngine *fontEngine = d->state->font.d->engineForScript(QChar::Script_Common);
- if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) {
- glyphs.resize(numGlyphs);
- if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- }
+ if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
+ Q_UNREACHABLE();
QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine);
drawTextItem(p, gf);
@@ -6354,7 +6350,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText
QTextItemInt &ti = const_cast<QTextItemInt &>(static_cast<const QTextItemInt &>(_ti));
if (!extended && state->bgMode == Qt::OpaqueMode) {
- QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
+ QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent).toReal());
q->fillRect(rect, state->bgBrush);
}
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 156e411154..aa2b9bea54 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1738,8 +1738,8 @@ QList<QPolygonF> QPainterPath::toFillPolygons(const QMatrix &matrix) const
//same as qt_polygon_isect_line in qpolygon.cpp
static void qt_painterpath_isect_line(const QPointF &p1,
- const QPointF &p2,
- const QPointF &pos,
+ const QPointF &p2,
+ const QPointF &pos,
int *winding)
{
qreal x1 = p1.x();
@@ -2551,6 +2551,26 @@ QPainterPathStroker::QPainterPathStroker()
}
/*!
+ Creates a new stroker based on \a pen.
+
+ \since 5.3
+ */
+QPainterPathStroker::QPainterPathStroker(const QPen &pen)
+ : d_ptr(new QPainterPathStrokerPrivate)
+{
+ setWidth(pen.widthF());
+ setCapStyle(pen.capStyle());
+ setJoinStyle(pen.joinStyle());
+ setMiterLimit(pen.miterLimit());
+ setDashOffset(pen.dashOffset());
+
+ if (pen.style() == Qt::CustomDashLine)
+ setDashPattern(pen.dashPattern());
+ else
+ setDashPattern(pen.style());
+}
+
+/*!
Destroys the stroker.
*/
QPainterPathStroker::~QPainterPathStroker()
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index e22c1729f3..c922867eb9 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -57,6 +57,7 @@ class QPainterPathPrivate;
struct QPainterPathPrivateDeleter;
class QPainterPathData;
class QPainterPathStrokerPrivate;
+class QPen;
class QPolygonF;
class QRegion;
class QVectorPath;
@@ -243,6 +244,7 @@ class Q_GUI_EXPORT QPainterPathStroker
Q_DECLARE_PRIVATE(QPainterPathStroker)
public:
QPainterPathStroker();
+ QPainterPathStroker(const QPen &pen);
~QPainterPathStroker();
void setWidth(qreal width);
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 6a3eacd67a..c0b3769c2d 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -455,15 +455,19 @@ QVector<qreal> QPen::dashPattern() const
switch (d->style) {
case Qt::DashLine:
+ dd->dashPattern.reserve(2);
dd->dashPattern << dash << space;
break;
case Qt::DotLine:
+ dd->dashPattern.reserve(2);
dd->dashPattern << dot << space;
break;
case Qt::DashDotLine:
+ dd->dashPattern.reserve(4);
dd->dashPattern << dash << space << dot << space;
break;
case Qt::DashDotDotLine:
+ dd->dashPattern.reserve(6);
dd->dashPattern << dash << space << dot << space << dot << space;
break;
default:
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index feec0c7f3d..15459dd748 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -44,6 +44,16 @@
#include <qpixmap.h>
#include <private/qwindow_p.h>
+#include <qopengl.h>
+#include <qopenglcontext.h>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
+#ifndef QT_NO_OPENGL
+#include <QtGui/private/qopengltextureblitter_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QPlatformBackingStorePrivate
@@ -51,13 +61,109 @@ class QPlatformBackingStorePrivate
public:
QPlatformBackingStorePrivate(QWindow *w)
: window(w)
+#ifndef QT_NO_OPENGL
+ , blitter(0)
+#endif
{
}
+ ~QPlatformBackingStorePrivate()
+ {
+#ifndef QT_NO_OPENGL
+ if (blitter)
+ blitter->destroy();
+ delete blitter;
+#endif
+ }
QWindow *window;
QSize size;
+#ifndef QT_NO_OPENGL
+ mutable GLuint textureId;
+ mutable QSize textureSize;
+ QOpenGLTextureBlitter *blitter;
+#endif
};
+#ifndef QT_NO_OPENGL
+
+struct QBackingstoreTextureInfo
+{
+ GLuint textureId;
+ QRect rect;
+};
+
+Q_DECLARE_TYPEINFO(QBackingstoreTextureInfo, Q_MOVABLE_TYPE);
+
+class QPlatformTextureListPrivate : public QObjectPrivate
+{
+public:
+ QPlatformTextureListPrivate()
+ : locked(false)
+ {
+ }
+
+ QList<QBackingstoreTextureInfo> textures;
+ bool locked;
+};
+
+QPlatformTextureList::QPlatformTextureList(QObject *parent)
+: QObject(*new QPlatformTextureListPrivate, parent)
+{
+}
+
+QPlatformTextureList::~QPlatformTextureList()
+{
+}
+
+int QPlatformTextureList::count() const
+{
+ Q_D(const QPlatformTextureList);
+ return d->textures.count();
+}
+
+GLuint QPlatformTextureList::textureId(int index) const
+{
+ Q_D(const QPlatformTextureList);
+ return d->textures.at(index).textureId;
+}
+
+QRect QPlatformTextureList::geometry(int index) const
+{
+ Q_D(const QPlatformTextureList);
+ return d->textures.at(index).rect;
+}
+
+void QPlatformTextureList::lock(bool on)
+{
+ Q_D(QPlatformTextureList);
+ if (on != d->locked) {
+ d->locked = on;
+ emit locked(on);
+ }
+}
+
+bool QPlatformTextureList::isLocked() const
+{
+ Q_D(const QPlatformTextureList);
+ return d->locked;
+}
+
+void QPlatformTextureList::appendTexture(GLuint textureId, const QRect &geometry)
+{
+ Q_D(QPlatformTextureList);
+ QBackingstoreTextureInfo bi;
+ bi.textureId = textureId;
+ bi.rect = geometry;
+ d->textures.append(bi);
+}
+
+void QPlatformTextureList::clear()
+{
+ Q_D(QPlatformTextureList);
+ d->textures.clear();
+}
+#endif // QT_NO_OPENGL
+
/*!
\class QPlatformBackingStore
\since 5.0
@@ -79,6 +185,147 @@ public:
Note that the \a offset parameter is currently unused.
*/
+#ifndef QT_NO_OPENGL
+/*!
+ Flushes the given \a region from the specified \a window onto the
+ screen, and composes it with the specified \a textures.
+
+ The default implementation retrieves the contents using toTexture()
+ and composes using OpenGL. May be reimplemented in subclasses if there
+ is a more efficient native way to do it.
+
+ Note that the \a offset parameter is currently unused.
+ */
+
+void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region,
+ const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context)
+{
+ Q_UNUSED(offset);
+
+ context->makeCurrent(window);
+ glViewport(0, 0, window->width(), window->height());
+
+ if (!d_ptr->blitter) {
+ d_ptr->blitter = new QOpenGLTextureBlitter;
+ d_ptr->blitter->create();
+ }
+
+ d_ptr->blitter->bind();
+
+ QRect windowRect(QPoint(), window->size());
+ for (int i = 0; i < textures->count(); ++i) {
+ GLuint textureId = textures->textureId(i);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), windowRect);
+ d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ }
+
+ GLuint textureId = toTexture(region);
+ if (!textureId)
+ return;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
+ d_ptr->blitter->setSwizzleRB(true);
+ d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ d_ptr->blitter->setSwizzleRB(false);
+
+ glDisable(GL_BLEND);
+ d_ptr->blitter->release();
+ context->swapBuffers(window);
+}
+
+/*!
+ Implemented in subclasses to return the content of the backingstore as a QImage.
+
+ If QPlatformIntegration::RasterGLSurface is supported, either this function or
+ toTexture() must be implemented.
+
+ \sa toTexture()
+ */
+QImage QPlatformBackingStore::toImage() const
+{
+ return QImage();
+}
+
+/*!
+ May be reimplemented in subclasses to return the content of the
+ backingstore as an OpenGL texture. \a dirtyRegion is the part of the
+ backingstore which may have changed since the last call to this function. The
+ caller of this function must ensure that there is a current context.
+
+ The ownership of the texture is not transferred. The caller must not store
+ the return value between calls, but instead call this function before each use.
+
+ The default implementation returns a cached texture if \a dirtyRegion is
+ empty and the window has not been resized, otherwise it retrieves the
+ content using toImage() and performs a texture upload.
+ */
+
+GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const
+{
+ QImage image = toImage();
+ QSize imageSize = image.size();
+ if (imageSize.isEmpty())
+ return 0;
+
+ bool resized = d_ptr->textureSize != imageSize;
+ if (dirtyRegion.isEmpty() && !resized)
+ return d_ptr->textureId;
+
+ if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888)
+ image = image.convertToFormat(QImage::Format_RGBA8888);
+
+ if (resized) {
+ if (d_ptr->textureId)
+ glDeleteTextures(1, &d_ptr->textureId);
+ glGenTextures(1, &d_ptr->textureId);
+ glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
+#ifndef QT_OPENGL_ES_2
+ if (!QOpenGLFunctions::isES()) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ }
+#endif
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ const_cast<uchar*>(image.constBits()));
+ d_ptr->textureSize = imageSize;
+ } else {
+ glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
+ QRect imageRect = image.rect();
+ QRect rect = dirtyRegion.boundingRect() & imageRect;
+ // if the rect is wide enough it's cheaper to just
+ // extend it instead of doing an image copy
+ if (rect.width() >= imageRect.width() / 2) {
+ rect.setX(0);
+ rect.setWidth(imageRect.width());
+ }
+
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's no gap between scanlines
+
+ if (rect.width() == imageRect.width()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.copy(rect).constBits());
+ }
+ }
+
+ return d_ptr->textureId;
+}
+#endif // QT_NO_OPENGL
+
/*!
\fn QPaintDevice* QPlatformBackingStore::paintDevice()
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 1b19b2c379..76fd3d40b4 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -52,9 +52,11 @@
//
#include <QtCore/qrect.h>
+#include <QtCore/qobject.h>
#include <QtGui/qwindow.h>
#include <QtGui/qregion.h>
+#include <QtGui/qopengl.h>
QT_BEGIN_NAMESPACE
@@ -65,6 +67,33 @@ class QPoint;
class QImage;
class QPlatformBackingStorePrivate;
class QPlatformWindow;
+class QPlatformTextureList;
+class QPlatformTextureListPrivate;
+class QOpenGLContext;
+
+#ifndef QT_NO_OPENGL
+class Q_GUI_EXPORT QPlatformTextureList : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlatformTextureList)
+public:
+ explicit QPlatformTextureList(QObject *parent = 0);
+ ~QPlatformTextureList();
+
+ int count() const;
+ bool isEmpty() const { return count() == 0; }
+ GLuint textureId(int index) const;
+ QRect geometry(int index) const;
+ void lock(bool on);
+ bool isLocked() const;
+
+ void appendTexture(GLuint textureId, const QRect &geometry);
+ void clear();
+
+ Q_SIGNALS:
+ void locked(bool);
+};
+#endif
class Q_GUI_EXPORT QPlatformBackingStore
{
@@ -79,6 +108,11 @@ public:
// 'window' can be a child window, in which case 'region' is in child window coordinates and
// offset is the (child) window's offset in relation to the window surface.
virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset) = 0;
+#ifndef QT_NO_OPENGL
+ virtual void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset, QPlatformTextureList *textures, QOpenGLContext *context);
+ virtual QImage toImage() const;
+ virtual GLuint toTexture(const QRegion &dirtyRegion) const;
+#endif
virtual void resize(const QSize &size, const QRegion &staticContents) = 0;
diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h
index 3c2bc5b97a..d8e19302d1 100644
--- a/src/gui/painting/qrgb.h
+++ b/src/gui/painting/qrgb.h
@@ -43,6 +43,7 @@
#define QRGB_H
#include <QtCore/qglobal.h>
+#include <QtCore/qprocessordetection.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,48 @@ inline Q_DECL_CONSTEXPR int qGray(QRgb rgb) // convert RGB to gra
inline Q_DECL_CONSTEXPR bool qIsGray(QRgb rgb)
{ return qRed(rgb) == qGreen(rgb) && qRed(rgb) == qBlue(rgb); }
+
+#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit version
+inline QRgb qPremultiply(QRgb x)
+{
+ const uint a = qAlpha(x);
+ quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
+ t &= 0x000000ff00ff00ff;
+ return (uint(t)) | (uint(t >> 24)) | (a << 24);
+}
+#else // 32-bit version
+inline QRgb qPremultiply(QRgb x)
+{
+ const uint a = qAlpha(x);
+ uint t = (x & 0xff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff) * a;
+ x = (x + ((x >> 8) & 0xff) + 0x80);
+ x &= 0xff00;
+ x |= t | (a << 24);
+ return x;
+}
+#endif
+
+Q_GUI_EXPORT extern const uint qt_inv_premul_factor[];
+
+inline QRgb qUnpremultiply(QRgb p)
+{
+ const uint alpha = qAlpha(p);
+ // Alpha 255 and 0 are the two most common values, which makes them beneficial to short-cut.
+ if (alpha == 255)
+ return p;
+ if (alpha == 0)
+ return 0;
+ // (p*(0x00ff00ff/alpha)) >> 16 == (p*255)/alpha for all p and alpha <= 256.
+ const uint invAlpha = qt_inv_premul_factor[alpha];
+ // We add 0x8000 to get even rounding. The rounding also ensures that qPremultiply(qUnpremultiply(p)) == p for all p.
+ return qRgba((qRed(p)*invAlpha + 0x8000)>>16, (qGreen(p)*invAlpha + 0x8000)>>16, (qBlue(p)*invAlpha + 0x8000)>>16, alpha);
+}
+
QT_END_NAMESPACE
#endif // QRGB_H
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index e584b66a25..f2b88c4692 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -739,13 +739,19 @@ bool qt_fontHasNarrowOutlines(QFontEngine *fontEngine)
if (!fe)
return false;
- QGlyphLayout glyphs;
+ const QChar uc(QLatin1Char('O'));
+
glyph_t glyph;
- glyphs.glyphs = &glyph;
+
+ QGlyphLayout glyphs;
glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
int numGlyphs = 1;
- QChar uc = QLatin1Char('O');
- fe->stringToCMap(&uc, 1, &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly);
+
+ if (!fe->stringToCMap(&uc, 1, &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(numGlyphs == 1);
+
QImage im = fe->alphaMapForGlyph(glyph, QFixed(), QTransform());
Q_ASSERT(fe->ref.load() == 0);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 49b5a9ba46..83f2d7190b 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -2073,6 +2073,18 @@ QString QFont::toString() const
QString::number((int) rawMode());
}
+/*!
+ Returns the hash value for \a font. If specified, \a seed is used
+ to initialize the hash.
+
+ \relates QFont
+ \since 5.3
+*/
+uint qHash(const QFont &font, uint seed) Q_DECL_NOTHROW
+{
+ return qHash(QFontPrivate::get(font)->request, seed);
+}
+
/*!
Sets this font to match the description \a descrip. The description
@@ -2533,8 +2545,10 @@ bool QFontInfo::fixedPitch() const
QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') };
QGlyphLayoutArray<2> g;
int l = 2;
- engine->stringToCMap(ch, 2, &g, &l, 0);
- engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
+ if (!engine->stringToCMap(ch, 2, &g, &l, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(l == 2);
+ engine->fontDef.fixedPitch = g.advances[0] == g.advances[1];
engine->fontDef.fixedPitchComputed = true;
}
#endif
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 6d36f7839b..a207a1d60e 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -315,6 +315,8 @@ private:
Q_DECLARE_SHARED(QFont)
+Q_GUI_EXPORT uint qHash(const QFont &font, uint seed = 0) Q_DECL_NOTHROW;
+
inline bool QFont::bold() const
{ return weight() > Normal; }
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 5b7f918e21..6165554388 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -55,6 +55,7 @@
#include "QtGui/qfont.h"
#include "QtCore/qmap.h"
+#include "QtCore/qhash.h"
#include "QtCore/qobject.h"
#include "QtCore/qstringlist.h"
#include <QtGui/qfontdatabase.h>
@@ -133,6 +134,22 @@ struct QFontDef
}
};
+inline uint qHash(const QFontDef &fd, uint seed = 0) Q_DECL_NOTHROW
+{
+ return qHash(qRound64(fd.pixelSize*10000)) // use only 4 fractional digits
+ ^ qHash(fd.weight)
+ ^ qHash(fd.style)
+ ^ qHash(fd.stretch)
+ ^ qHash(fd.styleHint)
+ ^ qHash(fd.styleStrategy)
+ ^ qHash(fd.ignorePitch)
+ ^ qHash(fd.fixedPitch)
+ ^ qHash(fd.family, seed)
+ ^ qHash(fd.styleName)
+ ^ qHash(fd.hintingPreference)
+ ;
+}
+
class QFontEngineData
{
public:
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 708b8cbd58..9986ef6c60 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -167,8 +167,6 @@ private:
friend class QFontPrivate;
friend class QFontDialog;
friend class QFontDialogPrivate;
- friend class QFontEngineMultiXLFD;
- friend class QFontEngineMultiQWS;
friend class QFontEngineMultiQPA;
QFontDatabasePrivate *d;
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 6f4971e267..1972f5d58c 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -182,10 +182,17 @@ QFontEngine *loadSingleEngine(int script,
QFontCache::Key key(def,script);
QFontEngine *engine = QFontCache::instance()->findEngine(key);
if (!engine) {
- engine = pfdb->fontEngine(def, QChar::Script(script), size->handle);
+ engine = pfdb->fontEngine(def, size->handle);
if (engine) {
- QFontCache::Key key(def,script);
- QFontCache::instance()->instance()->insertEngine(key,engine);
+ // Also check for OpenType tables when using complex scripts
+ if (!engine->supportsScript(QChar::Script(script))) {
+ qWarning(" OpenType support missing for script %d", script);
+ if (engine->ref.load() == 0)
+ delete engine;
+ return 0;
+ }
+
+ QFontCache::instance()->insertEngine(key, engine);
}
}
return engine;
@@ -221,10 +228,10 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
pfMultiEngine->setFallbackFamiliesList(fallbacks);
engine = pfMultiEngine;
- // Cache Multi font engine as well in case we got the FT single
+ // Cache Multi font engine as well in case we got the single
// font engine when we are actually looking for a Multi one
QFontCache::Key key(request, script, 1);
- QFontCache::instance()->instance()->insertEngine(key, engine);
+ QFontCache::instance()->insertEngine(key, engine);
}
return engine;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 9eea2e786f..14ce5d2396 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -48,6 +48,7 @@
#include "qvarlengtharray.h"
#include <qmath.h>
#include <qendian.h>
+#include <private/qstringiterator_p.h>
#ifdef QT_ENABLE_HARFBUZZ_NG
# include "qharfbuzzng_p.h"
@@ -89,18 +90,48 @@ static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint
{
QFontEngine *fe = (QFontEngine *)font->userData;
+ const QChar *str = reinterpret_cast<const QChar *>(string);
+
QGlyphLayout qglyphs;
qglyphs.numGlyphs = *numGlyphs;
qglyphs.glyphs = glyphs;
-
- QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (rightToLeft)
- shaperFlags |= QFontEngine::RightToLeft;
-
int nGlyphs = *numGlyphs;
- bool result = fe->stringToCMap(reinterpret_cast<const QChar *>(string), length, &qglyphs, &nGlyphs, shaperFlags);
+ bool result = fe->stringToCMap(str, length, &qglyphs, &nGlyphs, QFontEngine::GlyphIndicesOnly);
*numGlyphs = nGlyphs;
+ if (rightToLeft && result && !fe->symbol) {
+ uint glyph_pos = 0;
+ for (uint i = 0; i < length; ++i, ++glyph_pos) {
+ uint ucs4 = str[i].unicode();
+ if (Q_UNLIKELY(QChar::isHighSurrogate(ucs4) && i + 1 < length)) {
+ uint low = str[i + 1].unicode();
+ if (Q_LIKELY(QChar::isLowSurrogate(low))) {
+ ucs4 = QChar::surrogateToUcs4(ucs4, low);
+ ++i;
+ }
+ }
+
+ uint mirrored = QChar::mirroredChar(ucs4);
+ if (Q_UNLIKELY(mirrored != ucs4)) {
+ QChar chars[2];
+ uint numChars = 0;
+ if (Q_UNLIKELY(QChar::requiresSurrogates(mirrored))) {
+ chars[numChars++] = QChar(QChar::highSurrogate(mirrored));
+ chars[numChars++] = QChar(QChar::lowSurrogate(mirrored));
+ } else {
+ chars[numChars++] = QChar(mirrored);
+ }
+
+ qglyphs.numGlyphs = numChars;
+ qglyphs.glyphs = glyphs + glyph_pos;
+ nGlyphs = numChars;
+ if (!fe->stringToCMap(chars, numChars, &qglyphs, &nGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nGlyphs == 1);
+ }
+ }
+ }
+
return result;
}
@@ -108,13 +139,10 @@ static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGl
{
QFontEngine *fe = (QFontEngine *)font->userData;
- QVarLengthArray<QFixed> advances_y(numGlyphs);
-
QGlyphLayout qglyphs;
qglyphs.numGlyphs = numGlyphs;
qglyphs.glyphs = const_cast<glyph_t *>(glyphs);
- qglyphs.advances_x = reinterpret_cast<QFixed *>(advances);
- qglyphs.advances_y = advances_y.data(); // not used
+ qglyphs.advances = reinterpret_cast<QFixed *>(advances);
fe->recalcAdvances(&qglyphs, (flags & HB_ShaperFlag_UseDesignMetrics) ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlags(0));
}
@@ -278,6 +306,10 @@ void *QFontEngine::harfbuzzFont() const
return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this));
#endif
if (!font_) {
+ HB_Face hbFace = (HB_Face)harfbuzzFace();
+ if (hbFace->font_for_init != 0)
+ q_check_ptr(qHBLoadFace(hbFace));
+
HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
Q_CHECK_PTR(hbFont);
hbFont->klass = &hb_fontClass;
@@ -308,8 +340,6 @@ void *QFontEngine::harfbuzzFace() const
if (!face_) {
HB_Face hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable);
Q_CHECK_PTR(hbFace);
- if (hbFace->font_for_init != 0)
- hbFace = qHBLoadFace(hbFace);
hbFace->isSymbolFont = symbol;
face_ = (void *)hbFace;
@@ -349,6 +379,8 @@ bool QFontEngine::supportsScript(QChar::Script script) const
}
#endif
HB_Face hbFace = (HB_Face)harfbuzzFace();
+ if (hbFace->font_for_init != 0)
+ q_check_ptr(qHBLoadFace(hbFace));
return hbFace->supported_scripts[script_to_hbscript(script)];
}
@@ -364,23 +396,39 @@ glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix
QFixed QFontEngine::xHeight() const
{
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
QChar x((ushort)'x');
- stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly);
- glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyph);
return bb.height;
}
QFixed QFontEngine::averageCharWidth() const
{
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
QChar x((ushort)'x');
- stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly);
- glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyph);
return bb.xoff;
}
@@ -411,8 +459,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
while(i--) {
if (glyphs.attributes[i].dontPrint)
continue;
- xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- ypos += glyphs.advances_y[i];
+ xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
totalKashidas += glyphs.justifications[i].nKashidas;
}
positions.resize(glyphs.numGlyphs+totalKashidas);
@@ -424,8 +471,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
++i;
continue;
}
- xpos -= glyphs.advances_x[i];
- ypos -= glyphs.advances_y[i];
+ xpos -= glyphs.advances[i];
QFixed gpos_x = xpos + glyphs.offsets[i].x;
QFixed gpos_y = ypos + glyphs.offsets[i].y;
@@ -441,12 +487,22 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
++current;
if (glyphs.justifications[i].nKashidas) {
QChar ch(0x640); // Kashida character
- QGlyphLayoutArray<8> g;
- int nglyphs = 7;
- stringToCMap(&ch, 1, &g, &nglyphs, 0);
+
+ glyph_t kashidaGlyph;
+ QFixed kashidaWidth;
+
+ QGlyphLayout g;
+ g.numGlyphs = 1;
+ g.glyphs = &kashidaGlyph;
+ g.advances = &kashidaWidth;
+
+ int nglyphs = 1;
+ if (!stringToCMap(&ch, 1, &g, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
for (uint k = 0; k < glyphs.justifications[i].nKashidas; ++k) {
- xpos -= g.advances_x[0];
- ypos -= g.advances_y[0];
+ xpos -= kashidaWidth;
QFixed gpos_x = xpos + glyphs.offsets[i].x;
QFixed gpos_y = ypos + glyphs.offsets[i].y;
@@ -458,7 +514,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
}
positions[current].x = gpos_x;
positions[current].y = gpos_y;
- glyphs_out[current] = g.glyphs[0];
+ glyphs_out[current] = kashidaGlyph;
++current;
}
} else {
@@ -476,8 +532,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
positions[current].x = xpos + glyphs.offsets[i].x;
positions[current].y = ypos + glyphs.offsets[i].y;
glyphs_out[current] = glyphs.glyphs[i];
- xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- ypos += glyphs.advances_y[i];
+ xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
++current;
}
++i;
@@ -492,8 +547,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
positions[current].x = QFixed::fromReal(gpos.x());
positions[current].y = QFixed::fromReal(gpos.y());
glyphs_out[current] = glyphs.glyphs[i];
- xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- ypos += glyphs.advances_y[i];
+ xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
++current;
}
++i;
@@ -656,8 +710,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
for (int i=0; i < glyphs.numGlyphs; ++i) {
glyph_metrics_t metrics = boundingBox(glyphs.glyphs[i]);
if (metrics.width.value() == 0 || metrics.height.value() == 0) {
- advanceX += glyphs.advances_x[i];
- advanceY += glyphs.advances_y[i];
+ advanceX += glyphs.advances[i];
continue;
}
const QImage alphaMask = alphaMapForGlyph(glyphs.glyphs[i]);
@@ -692,8 +745,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
advanceX += offset.x;
advanceY += offset.y;
qt_addBitmapToPath((advanceX + metrics.x).toReal(), (advanceY + metrics.y).toReal(), bitmap_data, bitmap.bytesPerLine(), w, h, path);
- advanceX += glyphs.advances_x[i];
- advanceY += glyphs.advances_y[i];
+ advanceX += glyphs.advances[i];
}
}
@@ -704,16 +756,12 @@ void QFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int n
qreal y = positions[0].y.toReal();
QVarLengthGlyphLayoutArray g(nGlyphs);
- for (int i = 0; i < nGlyphs; ++i) {
+ for (int i = 0; i < nGlyphs - 1; ++i) {
g.glyphs[i] = glyphs[i];
- if (i < nGlyphs - 1) {
- g.advances_x[i] = positions[i+1].x - positions[i].x;
- g.advances_y[i] = positions[i+1].y - positions[i].y;
- } else {
- g.advances_x[i] = QFixed::fromReal(maxCharWidth());
- g.advances_y[i] = 0;
- }
+ g.advances[i] = positions[i + 1].x - positions[i].x;
}
+ g.glyphs[nGlyphs - 1] = glyphs[nGlyphs - 1];
+ g.advances[nGlyphs - 1] = QFixed::fromReal(maxCharWidth());
addBitmapFontToPath(x, y, g, path, flags);
}
@@ -973,10 +1021,10 @@ void QFontEngine::doKerning(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags
if (flags & DesignMetrics) {
for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
- glyphs->advances_x[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
+ glyphs->advances[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
} else {
for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
- glyphs->advances_x[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
+ glyphs->advances[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
}
}
@@ -1320,17 +1368,22 @@ QFontEngineBox::~QFontEngineBox()
{
}
-bool QFontEngineBox::stringToCMap(const QChar *, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const
+bool QFontEngineBox::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const
{
if (*nglyphs < len) {
*nglyphs = len;
return false;
}
- memset(glyphs->glyphs, 0, len * sizeof(glyph_t));
+ int ucs4Length = 0;
+ QStringIterator it(str, str + len);
+ while (it.hasNext()) {
+ it.advance();
+ glyphs->glyphs[ucs4Length++] = 0;
+ }
- *nglyphs = len;
- glyphs->numGlyphs = len;
+ *nglyphs = ucs4Length;
+ glyphs->numGlyphs = ucs4Length;
if (!(flags & GlyphIndicesOnly))
recalcAdvances(glyphs, flags);
@@ -1340,10 +1393,8 @@ bool QFontEngineBox::stringToCMap(const QChar *, int len, QGlyphLayout *glyphs,
void QFontEngineBox::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
- for (int i = 0; i < glyphs->numGlyphs; i++) {
- glyphs->advances_x[i] = _size;
- glyphs->advances_y[i] = 0;
- }
+ for (int i = 0; i < glyphs->numGlyphs; i++)
+ glyphs->advances[i] = _size;
}
void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
@@ -1503,11 +1554,9 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate());
uint ucs4 = surrogate ? QChar::surrogateToUcs4(str[i], str[i+1]) : str[i].unicode();
if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) {
- QFixedPoint tmpAdvance;
- if (!(flags & GlyphIndicesOnly)) {
- tmpAdvance.x = glyphs->advances_x[glyph_pos];
- tmpAdvance.y = glyphs->advances_y[glyph_pos];
- }
+ QFixed tmpAdvance;
+ if (!(flags & GlyphIndicesOnly))
+ tmpAdvance = glyphs->advances[glyph_pos];
for (int x = 1, n = qMin(engines.size(), 256); x < n; ++x) {
if (engines.at(x) == 0 && !shouldLoadFontEngineForCharacter(x, ucs4))
continue;
@@ -1522,11 +1571,12 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
continue;
if (!(flags & GlyphIndicesOnly))
- glyphs->advances_x[glyph_pos] = glyphs->advances_y[glyph_pos] = 0;
+ glyphs->advances[glyph_pos] = QFixed();
int num = 2;
- QGlyphLayout offs = glyphs->mid(glyph_pos, num);
- engine->stringToCMap(str + i, surrogate ? 2 : 1, &offs, &num, flags);
- Q_ASSERT(num == 1); // surrogates only give 1 glyph
+ QGlyphLayout g = glyphs->mid(glyph_pos, num);
+ if (!engine->stringToCMap(str + i, surrogate ? 2 : 1, &g, &num, flags))
+ Q_UNREACHABLE();
+ Q_ASSERT(num == 1);
if (glyphs->glyphs[glyph_pos]) {
// set the high byte to indicate which engine the glyph came from
glyphs->glyphs[glyph_pos] |= (x << 24);
@@ -1535,10 +1585,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
}
// ensure we use metrics from the 1st font when we use the fallback image.
- if (!(flags & GlyphIndicesOnly) && glyphs->glyphs[glyph_pos] == 0) {
- glyphs->advances_x[glyph_pos] = tmpAdvance.x;
- glyphs->advances_y[glyph_pos] = tmpAdvance.y;
- }
+ if (!(flags & GlyphIndicesOnly) && glyphs->glyphs[glyph_pos] == 0)
+ glyphs->advances[glyph_pos] = tmpAdvance;
}
if (surrogate)
@@ -1639,10 +1687,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
int start = 0;
int end, i;
if (flags & QTextItem::RightToLeft) {
- for (int gl = 0; gl < glyphs.numGlyphs; gl++) {
- x += glyphs.advances_x[gl].toReal();
- y += glyphs.advances_y[gl].toReal();
- }
+ for (int gl = 0; gl < glyphs.numGlyphs; gl++)
+ x += glyphs.advances[gl].toReal();
}
for (end = 0; end < glyphs.numGlyphs; ++end) {
const int e = highByte(glyphs.glyphs[end]);
@@ -1650,10 +1696,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
continue;
if (flags & QTextItem::RightToLeft) {
- for (i = start; i < end; ++i) {
- x -= glyphs.advances_x[i].toReal();
- y -= glyphs.advances_y[i].toReal();
- }
+ for (i = start; i < end; ++i)
+ x -= glyphs.advances[i].toReal();
}
// set the high byte to zero
@@ -1666,10 +1710,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
glyphs.glyphs[i] = hi | glyphs.glyphs[i];
if (!(flags & QTextItem::RightToLeft)) {
- for (i = start; i < end; ++i) {
- x += glyphs.advances_x[i].toReal();
- y += glyphs.advances_y[i].toReal();
- }
+ for (i = start; i < end; ++i)
+ x += glyphs.advances[i].toReal();
}
// change engine
@@ -1678,10 +1720,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
}
if (flags & QTextItem::RightToLeft) {
- for (i = start; i < end; ++i) {
- x -= glyphs.advances_x[i].toReal();
- y -= glyphs.advances_y[i].toReal();
- }
+ for (i = start; i < end; ++i)
+ x -= glyphs.advances[i].toReal();
}
// set the high byte to zero
@@ -1847,16 +1887,11 @@ bool QFontEngineMulti::canRender(const QChar *string, int len)
QGlyphLayout g;
g.numGlyphs = nglyphs;
g.glyphs = glyphs.data();
- if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly)) {
- glyphs.resize(nglyphs);
- g.numGlyphs = nglyphs;
- g.glyphs = glyphs.data();
- if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly))
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- }
+ if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly))
+ Q_UNREACHABLE();
for (int i = 0; i < nglyphs; i++) {
- if (g.glyphs[i] == 0)
+ if (glyphs[i] == 0)
return false;
}
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 05bd014bd7..665932e4a5 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -723,7 +723,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
FT_Set_Transform(face, &matrix, 0);
freetype->matrix = matrix;
// fake bold
- if ((fontDef.weight == QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face))
+ if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face))
embolden = true;
// underline metrics
line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));
@@ -1196,7 +1196,7 @@ int QFontEngineFT::synthesized() const
int s = 0;
if ((fontDef.style != QFont::StyleNormal) && !(freetype->face->style_flags & FT_STYLE_FLAG_ITALIC))
s = SynthesizedItalic;
- if ((fontDef.weight == QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD))
+ if ((fontDef.weight >= QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD))
s |= SynthesizedBold;
if (fontDef.stretch != 100 && FT_IS_SCALABLE(freetype->face))
s |= SynthesizedStretch;
@@ -1283,13 +1283,22 @@ qreal QFontEngineFT::minRightBearing() const
{
if (rbearing == SHRT_MIN) {
lbearing = rbearing = 0;
- const QChar *ch = (const QChar *)(const void*)char_table;
- QGlyphLayoutArray<char_table_entries> glyphs;
+
+ const QChar *ch = reinterpret_cast<const QChar *>(char_table);
+
+ glyph_t glyphs[char_table_entries];
+
+ QGlyphLayout g;
+ g.glyphs = glyphs;
+ g.numGlyphs = char_table_entries;
int ng = char_table_entries;
- stringToCMap(ch, char_table_entries, &glyphs, &ng, GlyphIndicesOnly);
+ if (!stringToCMap(ch, char_table_entries, &g, &ng, GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(ng == char_table_entries);
+
while (--ng) {
- if (glyphs.glyphs[ng]) {
- glyph_metrics_t gi = const_cast<QFontEngineFT *>(this)->boundingBox(glyphs.glyphs[ng]);
+ if (glyphs[ng]) {
+ glyph_metrics_t gi = const_cast<QFontEngineFT *>(this)->boundingBox(glyphs[ng]);
lbearing = qMin(lbearing, gi.x);
rbearing = qMin(rbearing, (gi.xoff - gi.x - gi.width));
}
@@ -1525,7 +1534,6 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
return false;
}
- bool mirrored = flags & QFontEngine::RightToLeft;
int glyph_pos = 0;
if (freetype->symbol_map) {
FT_Face face = freetype->face;
@@ -1561,8 +1569,6 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
FT_Face face = freetype->face;
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
if (!glyphs->glyphs[glyph_pos]) {
{
@@ -1607,24 +1613,23 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag
// Since we are passing Format_None to loadGlyph, use same default format logic as loadGlyph
GlyphFormat acceptableFormat = (defaultFormat != Format_None) ? defaultFormat : Format_Mono;
if (g && g->format == acceptableFormat) {
- glyphs->advances_x[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
+ glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
} else {
if (!face)
face = lockFace();
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs->glyphs[i], 0, Format_None, true);
- glyphs->advances_x[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
- : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
+ glyphs->advances[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
+ : QFixed::fromFixed(face->glyph->metrics.horiAdvance);
if (!cacheEnabled)
delete g;
}
- glyphs->advances_y[i] = 0;
}
if (face)
unlockFace();
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyphs->numGlyphs; ++i)
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances[i] = glyphs->advances[i].round();
}
}
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index a04f4bd0ac..532ebaf8ff 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -121,7 +121,6 @@ public:
};
enum ShaperFlag {
- RightToLeft = 0x0001,
DesignMetrics = 0x0002,
GlyphIndicesOnly = 0x0004
};
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index 28b95bd509..cb40a5388a 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -353,13 +353,10 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
const uchar *cmap = externalCMap ? externalCMap : (fontData + cmapOffset);
- bool mirrored = flags & QFontEngine::RightToLeft;
int glyph_pos = 0;
if (symbol) {
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
@@ -368,8 +365,6 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
} else {
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
#if 0 && defined(DEBUG_FONTENGINE)
QChar c(uc);
@@ -399,8 +394,7 @@ void QFontEngineQPA::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFla
glyphs->glyphs[i] = 0;
continue;
}
- glyphs->advances_x[i] = g->advance;
- glyphs->advances_y[i] = 0;
+ glyphs->advances[i] = g->advance;
}
}
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 1a66657cbd..2f4709afe4 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -458,12 +458,19 @@ int QFontMetrics::leftBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal lb;
- engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+ engine->getGlyphBearings(glyph, &lb);
return qRound(lb);
}
@@ -493,12 +500,19 @@ int QFontMetrics::rightBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal rb;
- engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+ engine->getGlyphBearings(glyph, 0, &rb);
return qRound(rb);
}
@@ -538,15 +552,12 @@ int QFontMetrics::width(const QString &text, int len, int flags) const
int numGlyphs = len;
QVarLengthGlyphLayoutArray glyphs(numGlyphs);
QFontEngine *engine = d->engineForScript(QChar::Script_Common);
- if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) {
- glyphs.resize(numGlyphs);
- if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0))
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- }
+ if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0))
+ Q_UNREACHABLE();
QFixed width;
for (int i = 0; i < numGlyphs; ++i)
- width += glyphs.advances_x[i];
+ width += glyphs.advances[i];
return qRound(width);
}
@@ -594,10 +605,20 @@ int QFontMetrics::width(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- return qRound(glyphs.advances_x[0]);
+ QFixed advance;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyph_t glyph;
+ glyphs.glyphs = &glyph;
+ glyphs.advances = &advance;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ return qRound(advance);
}
/*! \obsolete
@@ -639,10 +660,20 @@ int QFontMetrics::charWidth(const QString &text, int pos) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- width = qRound(glyphs.advances_x[0]);
+ QFixed advance;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyph_t glyph;
+ glyphs.glyphs = &glyph;
+ glyphs.advances = &advance;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ width = qRound(advance);
}
return width;
}
@@ -708,10 +739,18 @@ QRect QFontMetrics::boundingRect(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t gm = engine->boundingBox(glyph);
return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
@@ -1326,12 +1365,19 @@ qreal QFontMetricsF::leftBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal lb;
- engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+ engine->getGlyphBearings(glyph, &lb);
return lb;
}
@@ -1361,12 +1407,19 @@ qreal QFontMetricsF::rightBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal rb;
- engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+ engine->getGlyphBearings(glyph, 0, &rb);
return rb;
}
@@ -1431,10 +1484,20 @@ qreal QFontMetricsF::width(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- return glyphs.advances_x[0].toReal();
+ QFixed advance;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyph_t glyph;
+ glyphs.glyphs = &glyph;
+ glyphs.advances = &advance;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ return advance.toReal();
}
/*!
@@ -1496,10 +1559,18 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t gm = engine->boundingBox(glyph);
return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
}
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index 152e15a54d..2109b16bb5 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -201,12 +201,22 @@ static void checkRanges(QPdf::ByteStream &ts, QByteArray &ranges, int &nranges)
QVector<int> QFontSubset::getReverseMap() const
{
QVector<int> reverseMap(0x10000, 0);
- QGlyphLayoutArray<10> glyphs;
+
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.glyphs = &glyph;
+ glyphs.numGlyphs = 1;
+
for (uint uc = 0; uc < 0x10000; ++uc) {
QChar ch(uc);
- int nglyphs = 10;
- fontEngine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- int idx = glyph_indices.indexOf(glyphs.glyphs[0]);
+
+ int nglyphs = 1;
+ if (!fontEngine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ int idx = glyph_indices.indexOf(glyph);
if (idx >= 0 && !reverseMap.at(idx))
reverseMap[idx] = uc;
}
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index d2e7df9c10..c09f27b665 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -397,13 +397,7 @@ _hb_qt_font_get_glyph(hb_font_t * /*font*/, void *font_data,
QFontEngine *fe = (QFontEngine *)font_data;
Q_ASSERT(fe);
- glyph_t glyphs[2] = { 0, 0 };
-
- QGlyphLayout g;
- g.numGlyphs = 2;
- g.glyphs = glyphs;
-
- QChar chars[4];
+ QChar chars[2];
int numChars = 0;
if (Q_UNLIKELY(QChar::requiresSurrogates(unicode))) {
chars[numChars++] = QChar(QChar::highSurrogate(unicode));
@@ -422,11 +416,14 @@ _hb_qt_font_get_glyph(hb_font_t * /*font*/, void *font_data,
}
#endif
- int numGlyphs = g.numGlyphs;
- bool ok = fe->stringToCMap(chars, numChars, &g, &numGlyphs, QFontEngine::GlyphIndicesOnly);
- Q_ASSERT(ok); Q_UNUSED(ok)
+ QGlyphLayout g;
+ g.numGlyphs = numChars;
+ g.glyphs = glyph;
- *glyph = g.glyphs[0];
+ int numGlyphs = numChars;
+ if (!fe->stringToCMap(chars, numChars, &g, &numGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(numGlyphs == 1);
return true;
}
@@ -439,18 +436,16 @@ _hb_qt_font_get_glyph_h_advance(hb_font_t *font, void *font_data,
QFontEngine *fe = (QFontEngine *)font_data;
Q_ASSERT(fe);
- QFixed advance_x;
- QFixed advance_y;
+ QFixed advance;
QGlyphLayout g;
g.numGlyphs = 1;
g.glyphs = &glyph;
- g.advances_x = &advance_x;
- g.advances_y = &advance_y;
+ g.advances = &advance;
fe->recalcAdvances(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));
- return g.advances_x[0].value();
+ return advance.value();
}
static hb_position_t
@@ -490,18 +485,16 @@ _hb_qt_font_get_glyph_h_kerning(hb_font_t *font, void *font_data,
Q_ASSERT(fe);
glyph_t glyphs[2] = { first_glyph, second_glyph };
- QFixed advance_x;
- QFixed advance_y;
+ QFixed advance;
QGlyphLayout g;
g.numGlyphs = 2;
g.glyphs = glyphs;
- g.advances_x = &advance_x;
- g.advances_y = &advance_y;
+ g.advances = &advance;
fe->doKerning(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));
- return g.advances_x[0].value();
+ return advance.value();
}
static hb_position_t
@@ -710,7 +703,11 @@ _hb_qt_font_create(QFontEngine *fe)
const int x_ppem = (fe->fontDef.pixelSize * fe->fontDef.stretch) / 100;
hb_font_set_funcs(font, hb_qt_get_font_funcs(), (void *)fe, NULL);
+#ifdef Q_OS_MAC
+ hb_font_set_scale(font, QFixed(x_ppem).value(), QFixed(y_ppem).value());
+#else
hb_font_set_scale(font, QFixed(x_ppem).value(), -QFixed(y_ppem).value());
+#endif
hb_font_set_ppem(font, x_ppem, y_ppem);
return font;
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 37610a9099..7936831e13 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -289,13 +289,11 @@ QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine
Returns the font engine that can be used to render the font described by
the font definition, \a fontDef, in the specified \a script.
*/
-QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle)
+QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{
- Q_UNUSED(script);
- Q_UNUSED(handle);
QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
QFontEngineQPA *engine = new QFontEngineQPA(fontDef,*fileDataPtr);
- //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family << script;
+ //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family;
return engine;
}
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 6053f11051..5f2c9a74ba 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -97,7 +97,7 @@ public:
virtual ~QPlatformFontDatabase();
virtual void populateFontDatabase();
virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
- virtual QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
virtual void releaseHandle(void *handle);
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index b1b910422c..449278df06 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -479,16 +479,8 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
QGlyphLayout glyphs;
glyphs.numGlyphs = numGlyphs;
glyphs.glyphs = glyphIndexes.data();
- if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly)) {
- glyphIndexes.resize(numGlyphs);
-
- glyphs.numGlyphs = numGlyphs;
- glyphs.glyphs = glyphIndexes.data();
- if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly)) {
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- return QVector<quint32>();
- }
- }
+ if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
glyphIndexes.resize(numGlyphs);
return glyphIndexes;
@@ -565,13 +557,12 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
if (!d->isValid() || numGlyphs <= 0)
return false;
+ QVarLengthArray<QFixed> tmpAdvances(numGlyphs);
+
QGlyphLayout glyphs;
glyphs.glyphs = const_cast<glyph_t *>(glyphIndexes);
glyphs.numGlyphs = numGlyphs;
- QVarLengthArray<QFixed> advances_x(numGlyphs);
- QVarLengthArray<QFixed> advances_y(numGlyphs);
- glyphs.advances_x = advances_x.data();
- glyphs.advances_y = advances_y.data();
+ glyphs.advances = tmpAdvances.data();
bool design = layoutFlags & UseDesignMetrics;
@@ -580,7 +571,7 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
d->fontEngine->doKerning(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
for (int i=0; i<numGlyphs; ++i)
- advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal());
+ advances[i] = QPointF(tmpAdvances[i].toReal(), 0.0);
return true;
}
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index d12f3cccd8..ac9762b183 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -174,7 +174,6 @@ void QTextCursorPrivate::remove()
} else {
priv->remove(pos1, pos2-pos1, op);
adjusted_anchor = anchor = position;
- priv->finishEdit();
}
}
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 4a34f0d3c3..fa54776b6d 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -551,6 +551,39 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option)
}
/*!
+ \property QTextDocument::baseUrl
+ \since 5.3
+ \brief the base URL used to resolve relative resource URLs within the document.
+
+ Resource URLs are resolved to be within the same directory as the target of the base
+ URL meaning any portion of the path after the last '/' will be ignored.
+
+ \table
+ \header \li Base URL \li Relative URL \li Resolved URL
+ \row \li file:///path/to/content \li images/logo.png \li file:///path/to/images/logo.png
+ \row \li file:///path/to/content/ \li images/logo.png \li file:///path/to/content/images/logo.png
+ \row \li file:///path/to/content/index.html \li images/logo.png \li file:///path/to/content/images/logo.png
+ \row \li file:///path/to/content/images/ \li ../images/logo.png \li file:///path/to/content/images/logo.png
+ \endtable
+*/
+QUrl QTextDocument::baseUrl() const
+{
+ Q_D(const QTextDocument);
+ return d->baseUrl;
+}
+
+void QTextDocument::setBaseUrl(const QUrl &url)
+{
+ Q_D(QTextDocument);
+ if (d->baseUrl != url) {
+ d->baseUrl = url;
+ if (d->lout)
+ d->lout->documentChanged(0, 0, d->length());
+ emit baseUrlChanged(url);
+ }
+}
+
+/*!
\since 4.8
The default cursor movement style is used by all QTextCursor objects
@@ -1849,11 +1882,12 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
QVariant QTextDocument::resource(int type, const QUrl &name) const
{
Q_D(const QTextDocument);
- QVariant r = d->resources.value(name);
+ const QUrl url = d->baseUrl.resolved(name);
+ QVariant r = d->resources.value(url);
if (!r.isValid()) {
- r = d->cachedResources.value(name);
+ r = d->cachedResources.value(url);
if (!r.isValid())
- r = const_cast<QTextDocument *>(this)->loadResource(type, name);
+ r = const_cast<QTextDocument *>(this)->loadResource(type, url);
}
return r;
}
@@ -1924,27 +1958,29 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
}
// if resource was not loaded try to load it here
- if (!qobject_cast<QTextDocument *>(p) && r.isNull() && name.isRelative()) {
- QUrl currentURL = d->url;
+ if (!qobject_cast<QTextDocument *>(p) && r.isNull()) {
QUrl resourceUrl = name;
- // For the second case QUrl can merge "#someanchor" with "foo.html"
- // correctly to "foo.html#someanchor"
- if (!(currentURL.isRelative()
- || (currentURL.scheme() == QLatin1String("file")
- && !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
- || (name.hasFragment() && name.path().isEmpty())) {
- resourceUrl = currentURL.resolved(name);
- } else {
- // this is our last resort when current url and new url are both relative
- // we try to resolve against the current working directory in the local
- // file system.
- QFileInfo fi(currentURL.toLocalFile());
- if (fi.exists()) {
- resourceUrl =
- QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(name);
- } else if (currentURL.isEmpty()) {
- resourceUrl.setScheme(QLatin1String("file"));
+ if (name.isRelative()) {
+ QUrl currentURL = d->url;
+ // For the second case QUrl can merge "#someanchor" with "foo.html"
+ // correctly to "foo.html#someanchor"
+ if (!(currentURL.isRelative()
+ || (currentURL.scheme() == QLatin1String("file")
+ && !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
+ || (name.hasFragment() && name.path().isEmpty())) {
+ resourceUrl = currentURL.resolved(name);
+ } else {
+ // this is our last resort when current url and new url are both relative
+ // we try to resolve against the current working directory in the local
+ // file system.
+ QFileInfo fi(currentURL.toLocalFile());
+ if (fi.exists()) {
+ resourceUrl =
+ QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(name);
+ } else if (currentURL.isEmpty()) {
+ resourceUrl.setScheme(QLatin1String("file"));
+ }
}
}
@@ -2124,13 +2160,21 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format)
html += QLatin1String("pt;");
attributesEmitted = true;
} else if (format.hasProperty(QTextFormat::FontSizeAdjustment)) {
- static const char * const sizeNames[] = {
- "small", "medium", "large", "x-large", "xx-large"
+ static const char sizeNameData[] =
+ "small" "\0"
+ "medium" "\0"
+ "xx-large" ;
+ static const quint8 sizeNameOffsets[] = {
+ 0, // "small"
+ sizeof("small"), // "medium"
+ sizeof("small") + sizeof("medium") + 3, // "large" )
+ sizeof("small") + sizeof("medium") + 1, // "x-large" )> compressed into "xx-large"
+ sizeof("small") + sizeof("medium"), // "xx-large" )
};
const char *name = 0;
const int idx = format.intProperty(QTextFormat::FontSizeAdjustment) + 1;
if (idx >= 0 && idx <= 4) {
- name = sizeNames[idx];
+ name = sizeNameData + sizeNameOffsets[idx];
}
if (name) {
html += QLatin1String(" font-size:");
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index d8f52e9f98..854cb29ed9 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -47,6 +47,7 @@
#include <QtCore/qrect.h>
#include <QtCore/qvariant.h>
#include <QtGui/qfont.h>
+#include <QtCore/qurl.h>
QT_BEGIN_NAMESPACE
@@ -63,7 +64,6 @@ class QTextFormat;
class QTextFrame;
class QTextBlock;
class QTextCodec;
-class QUrl;
class QVariant;
class QRectF;
class QTextOption;
@@ -116,6 +116,7 @@ class Q_GUI_EXPORT QTextDocument : public QObject
Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
Q_PROPERTY(qreal documentMargin READ documentMargin WRITE setDocumentMargin)
QDOC_PROPERTY(QTextOption defaultTextOption READ defaultTextOption WRITE setDefaultTextOption)
+ Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl NOTIFY baseUrlChanged)
public:
explicit QTextDocument(QObject *parent = 0);
@@ -258,6 +259,9 @@ public:
QTextOption defaultTextOption() const;
void setDefaultTextOption(const QTextOption &option);
+ QUrl baseUrl() const;
+ void setBaseUrl(const QUrl &url);
+
Qt::CursorMoveStyle defaultCursorMoveStyle() const;
void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style);
@@ -270,7 +274,7 @@ Q_SIGNALS:
void modificationChanged(bool m);
void cursorPositionChanged(const QTextCursor &cursor);
void blockCountChanged(int newBlockCount);
-
+ void baseUrlChanged(const QUrl &url);
void documentLayoutChanged();
public Q_SLOTS:
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index 8d4cab30ae..fa22131c9e 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -355,6 +355,7 @@ public:
QString url;
qreal indentWidth;
qreal documentMargin;
+ QUrl baseUrl;
void mergeCachedResources(const QTextDocumentPrivate *priv);
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index df67fb581a..3bd1e2a801 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -489,7 +489,7 @@ void QTextHtmlImporter::import()
&& currentNode->id != Html_unknown)
{
hasBlock = false;
- } else if (hasBlock) {
+ } else if (blockTagClosed && hasBlock) {
// when collapsing subsequent block tags we need to clear the block format
QTextBlockFormat blockFormat = currentNode->blockFormat;
blockFormat.setIndent(indent);
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index febdaaa86c..eb31c520ed 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -241,7 +241,8 @@ using namespace std;
static const char *directions[] = {
"DirL", "DirR", "DirEN", "DirES", "DirET", "DirAN", "DirCS", "DirB", "DirS", "DirWS", "DirON",
- "DirLRE", "DirLRO", "DirAL", "DirRLE", "DirRLO", "DirPDF", "DirNSM", "DirBN"
+ "DirLRE", "DirLRO", "DirAL", "DirRLE", "DirRLO", "DirPDF", "DirNSM", "DirBN",
+ "DirLRI", "DirRLI", "DirFSI", "DirPDI"
};
#endif
@@ -928,21 +929,8 @@ void QTextEngine::shapeText(int item) const
int nGlyphs = initialGlyphs.numGlyphs;
QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (si.analysis.bidiLevel % 2)
- shaperFlags |= QFontEngine::RightToLeft;
-
- if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags)) {
- nGlyphs = qMax(nGlyphs, itemLength); // ### needed for QFontEngine::stringToCMap() to not fail twice
- if (!ensureSpace(nGlyphs)) {
- Q_UNREACHABLE(); // ### report OOM error somehow
- return;
- }
- initialGlyphs = availableGlyphs(&si);
- if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags)) {
- Q_UNREACHABLE(); // ### if this happens there is a bug in the fontengine
- return;
- }
- }
+ if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags))
+ Q_UNREACHABLE();
uint lastEngine = ~0u;
for (int i = 0, glyph_pos = 0; i < itemLength; ++i, ++glyph_pos) {
@@ -1014,17 +1002,17 @@ void QTextEngine::shapeText(int item) const
for (int i = 1; i < si.num_glyphs; ++i) {
if (glyphs.attributes[i].clusterStart) {
if (letterSpacingIsAbsolute)
- glyphs.advances_x[i-1] += letterSpacing;
+ glyphs.advances[i - 1] += letterSpacing;
else {
- QFixed &advance = glyphs.advances_x[i-1];
+ QFixed &advance = glyphs.advances[i - 1];
advance += (letterSpacing - 100) * advance / 100;
}
}
}
if (letterSpacingIsAbsolute)
- glyphs.advances_x[si.num_glyphs-1] += letterSpacing;
+ glyphs.advances[si.num_glyphs - 1] += letterSpacing;
else {
- QFixed &advance = glyphs.advances_x[si.num_glyphs-1];
+ QFixed &advance = glyphs.advances[si.num_glyphs - 1];
advance += (letterSpacing - 100) * advance / 100;
}
}
@@ -1036,13 +1024,13 @@ void QTextEngine::shapeText(int item) const
if (i + 1 == si.num_glyphs
||(glyphs.attributes[i+1].justification != QGlyphAttributes::Space
&& glyphs.attributes[i+1].justification != QGlyphAttributes::Arabic_Space))
- glyphs.advances_x[i] += wordSpacing;
+ glyphs.advances[i] += wordSpacing;
}
}
}
for (int i = 0; i < si.num_glyphs; ++i)
- si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
+ si.width += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
}
#ifdef QT_ENABLE_HARFBUZZ_NG
@@ -1139,8 +1127,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
for (uint i = 0; i < num_glyphs; ++i) {
g.glyphs[i] = infos[i].codepoint;
- g.advances_x[i] = QFixed::fromFixed(positions[i].x_advance);
- g.advances_y[i] = QFixed::fromFixed(positions[i].y_advance);
+ g.advances[i] = QFixed::fromFixed(positions[i].x_advance);
g.offsets[i].x = QFixed::fromFixed(positions[i].x_offset);
g.offsets[i].y = QFixed::fromFixed(positions[i].y_offset);
@@ -1163,6 +1150,13 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
g.glyphs[i] |= (engineIdx << 24);
}
+#ifdef Q_OS_MAC
+ if (actualFontEngine->fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ for (uint i = 0; i < num_glyphs; ++i)
+ g.advances[i] = g.advances[i].round();
+ }
+#endif
+
glyphs_shaped += num_glyphs;
}
@@ -1238,7 +1232,8 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
if (fontEngine->type() == QFontEngine::Multi) {
actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
- shaper_item.glyphIndicesPresent = true;
+ if ((si.analysis.bidiLevel % 2) == 0)
+ shaper_item.glyphIndicesPresent = true;
}
shaper_item.font = (HB_Font)actualFontEngine->harfbuzzFont();
@@ -1256,7 +1251,7 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
shaper_item.glyphs = reinterpret_cast<HB_Glyph *>(g.glyphs);
shaper_item.attributes = reinterpret_cast<HB_GlyphAttributes *>(g.attributes);
- shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances_x);
+ shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances);
shaper_item.offsets = reinterpret_cast<HB_FixedPoint *>(g.offsets);
if (engineIdx != 0 && shaper_item.glyphIndicesPresent) {
@@ -1360,9 +1355,9 @@ void QTextEngine::shape(int item) const
if (layoutData->items[item].analysis.flags == QScriptAnalysis::Object) {
ensureSpace(1);
if (block.docHandle()) {
- QTextFormat format = formats()->format(formatIndex(&layoutData->items[item]));
docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)),
- layoutData->items[item].position + block.position(), format);
+ layoutData->items[item].position + block.position(),
+ format(&layoutData->items[item]));
}
} else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) {
// set up at least the ascent/descent/leading of the script item for the tab
@@ -1394,7 +1389,7 @@ void QTextEngine::invalidate()
minWidth = 0;
maxWidth = 0;
if (specialData)
- specialData->resolvedFormatIndices.clear();
+ specialData->resolvedFormats.clear();
resetFontEngineCache();
}
@@ -1468,8 +1463,18 @@ void QTextEngine::itemize() const
{
QVarLengthArray<uchar> scripts(length);
QUnicodeTools::initScripts(string, length, scripts.data());
- for (int i = 0; i < length; ++i)
- analysis[i].script = scripts.at(i);
+ for (int i = 0; i < length; ++i) {
+ ushort script = scripts.at(i);
+ switch (script) {
+ case QChar::Script_Hiragana:
+ case QChar::Script_Katakana:
+ script = QChar::Script_Han;
+ break;
+ default:
+ break;
+ }
+ analysis[i].script = script;
+ }
}
const ushort *uc = string;
@@ -1563,10 +1568,9 @@ void QTextEngine::itemize() const
#ifndef QT_NO_RAWFONT
if (useRawFont && specialData) {
int lastIndex = 0;
- const QTextFormatCollection *collection = formats();
for (int i = 0; i < specialData->addFormats.size(); ++i) {
const QTextLayout::FormatRange &range = specialData->addFormats.at(i);
- const QTextCharFormat format = collection->charFormat(specialData->addFormatIndices.at(i));
+ const QTextCharFormat &format = range.format;
if (format.hasProperty(QTextFormat::FontCapitalization)) {
itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase);
itemizer.generate(range.start, range.length, format.fontCapitalization());
@@ -1674,7 +1678,7 @@ QFixed QTextEngine::width(int from, int len) const
// qDebug("char: start=%d end=%d / glyph: start = %d, end = %d", charFrom, charEnd, glyphStart, glyphEnd);
for (int i = glyphStart; i < glyphEnd; i++)
- w += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
+ w += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
}
}
}
@@ -1963,11 +1967,22 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph,
if (type >= QGlyphAttributes::Arabic_Normal) {
QChar ch(0x640); // Kashida character
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- fe->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- if (glyphs.glyphs[0] && glyphs.advances_x[0] != 0) {
- point->kashidaWidth = glyphs.advances_x[0];
+
+ glyph_t kashidaGlyph;
+ QFixed kashidaWidth;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &kashidaGlyph;
+ glyphs.advances = &kashidaWidth;
+
+ int nglyphs = 1;
+ if (!fe->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ if (kashidaGlyph != 0 && kashidaWidth != 0) {
+ point->kashidaWidth = kashidaWidth;
} else {
point->type = QGlyphAttributes::NoJustification;
point->kashidaWidth = 0;
@@ -2209,7 +2224,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int
int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;
int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;
- available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::spaceNeededForGlyphLayout(1);
+ available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::SpaceNeeded;
if (available_glyphs < str.length()) {
// need to allocate on the heap
@@ -2251,7 +2266,7 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;
int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;
- int space_glyphs = QGlyphLayout::spaceNeededForGlyphLayout(totalGlyphs)/sizeof(void*) + 2;
+ int space_glyphs = (totalGlyphs * QGlyphLayout::SpaceNeeded) / sizeof(void *) + 2;
int newAllocated = space_charAttributes + space_glyphs + space_logClusters;
// These values can be negative if the length of string/glyphs causes overflow,
@@ -2298,8 +2313,7 @@ void QGlyphLayout::grow(char *address, int totalGlyphs)
// move the existing data
memmove(newLayout.attributes, oldLayout.attributes, numGlyphs * sizeof(QGlyphAttributes));
memmove(newLayout.justifications, oldLayout.justifications, numGlyphs * sizeof(QGlyphJustification));
- memmove(newLayout.advances_y, oldLayout.advances_y, numGlyphs * sizeof(QFixed));
- memmove(newLayout.advances_x, oldLayout.advances_x, numGlyphs * sizeof(QFixed));
+ memmove(newLayout.advances, oldLayout.advances, numGlyphs * sizeof(QFixed));
memmove(newLayout.glyphs, oldLayout.glyphs, numGlyphs * sizeof(glyph_t));
}
@@ -2328,8 +2342,12 @@ void QTextEngine::freeMemory()
int QTextEngine::formatIndex(const QScriptItem *si) const
{
- if (specialData && !specialData->resolvedFormatIndices.isEmpty())
- return specialData->resolvedFormatIndices.at(si - &layoutData->items[0]);
+ if (specialData && !specialData->resolvedFormats.isEmpty()) {
+ QTextFormatCollection *collection = formats();
+ Q_ASSERT(collection);
+ return collection->indexForFormat(specialData->resolvedFormats.at(si - &layoutData->items[0]));
+ }
+
QTextDocumentPrivate *p = block.docHandle();
if (!p)
return -1;
@@ -2442,23 +2460,6 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText)
clearLineData();
}
-QList<QTextLayout::FormatRange> QTextEngine::additionalFormats() const
-{
- QList<QTextLayout::FormatRange> formatList;
- if (!specialData)
- return formatList;
-
- formatList = specialData->addFormats;
- if (!specialData->addFormatIndices.isEmpty()) {
- const QTextFormatCollection *formats = this->formats();
- Q_ASSERT(formats);
- for (int i = 0; i < specialData->addFormatIndices.size(); ++i)
- formatList[i].format = formats->charFormat(specialData->addFormatIndices.at(i));
- }
-
- return formatList;
-}
-
void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList)
{
if (formatList.isEmpty()) {
@@ -2469,7 +2470,6 @@ void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &fo
specialData = 0;
} else {
specialData->addFormats.clear();
- specialData->addFormatIndices.clear();
}
} else {
if (!specialData) {
@@ -2484,19 +2484,17 @@ void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &fo
void QTextEngine::indexAdditionalFormats()
{
- specialData->addFormatIndices.resize(specialData->addFormats.count());
-
- QTextFormatCollection *formats = this->formats();
-
- if (!formats) {
+ QTextFormatCollection *collection = formats();
+ if (!collection) {
Q_ASSERT(!block.docHandle());
specialData->formats.reset(new QTextFormatCollection);
- formats = specialData->formats.data();
+ collection = specialData->formats.data();
}
+ // replace with shared copies
for (int i = 0; i < specialData->addFormats.count(); ++i) {
- specialData->addFormatIndices[i] = formats->indexForFormat(specialData->addFormats.at(i).format);
- specialData->addFormats[i].format = QTextCharFormat();
+ QTextCharFormat &format = specialData->addFormats[i].format;
+ format = collection->charFormat(collection->indexForFormat(format));
}
}
@@ -2510,7 +2508,8 @@ static inline bool nextCharJoins(const QString &string, int pos)
++pos;
if (pos == string.length())
return false;
- return string.at(pos).joining() != QChar::OtherJoining;
+ QChar::JoiningType joining = string.at(pos).joiningType();
+ return joining != QChar::Joining_None && joining != QChar::Joining_Transparent;
}
static inline bool prevCharJoins(const QString &string, int pos)
@@ -2519,19 +2518,15 @@ static inline bool prevCharJoins(const QString &string, int pos)
--pos;
if (pos == 0)
return false;
- QChar::Joining joining = string.at(pos - 1).joining();
- return (joining == QChar::Dual || joining == QChar::Center);
+ QChar::JoiningType joining = string.at(pos - 1).joiningType();
+ return joining == QChar::Joining_Dual || joining == QChar::Joining_Causing;
}
static inline bool isRetainableControlCode(QChar c)
{
- return (c.unicode() == 0x202a // LRE
- || c.unicode() == 0x202b // LRE
- || c.unicode() == 0x202c // PDF
- || c.unicode() == 0x202d // LRO
- || c.unicode() == 0x202e // RLO
- || c.unicode() == 0x200e // LRM
- || c.unicode() == 0x200f); // RLM
+ return (c.unicode() >= 0x202a && c.unicode() <= 0x202e) // LRE, RLE, PDF, LRO, RLO
+ || (c.unicode() >= 0x200e && c.unicode() <= 0x200f) // LRM, RLM
+ || (c.unicode() >= 0x2066 && c.unicode() <= 0x2069); // LRM, RLM
}
static QString stringMidRetainingBidiCC(const QString &string,
@@ -2619,14 +2614,14 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
if (feForEllipsis->type() == QFontEngine::Mac)
feForEllipsis = fe;
- if (feForEllipsis->canRender(&ellipsisChar, 1)) {
- int nGlyphs = 1;
- feForEllipsis->stringToCMap(&ellipsisChar, 1, &ellipsisGlyph, &nGlyphs, 0);
- }
+ int nGlyphs = 1;
+ if (!feForEllipsis->stringToCMap(&ellipsisChar, 1, &ellipsisGlyph, &nGlyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nGlyphs == 1);
}
if (ellipsisGlyph.glyphs[0]) {
- ellipsisWidth = ellipsisGlyph.advances_x[0];
+ ellipsisWidth = ellipsisGlyph.advances[0];
ellipsisText = ellipsisChar;
} else {
QString dotDotDot(QLatin1String("..."));
@@ -2634,10 +2629,11 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
QGlyphLayoutArray<3> glyphs;
int nGlyphs = 3;
if (!fe->stringToCMap(dotDotDot.constData(), 3, &glyphs, &nGlyphs, 0))
- // should never happen...
- return layoutData->string;
+ Q_UNREACHABLE();
+ Q_ASSERT(nGlyphs == 3);
+
for (int i = 0; i < nGlyphs; ++i)
- ellipsisWidth += glyphs.advances_x[i];
+ ellipsisWidth += glyphs.advances[i];
ellipsisText = dotDotDot;
}
}
@@ -2786,7 +2782,7 @@ void QTextEngine::splitItem(int item, int pos) const
QFixed w = 0;
const QGlyphLayout g = shapedGlyphs(&oldItem);
for(int j = 0; j < breakGlyph; ++j)
- w += g.advances_x[j] * !g.attributes[j].dontPrint;
+ w += g.advances[j] * !g.attributes[j].dontPrint;
newItem.width = oldItem.width - w;
oldItem.width = w;
@@ -2859,9 +2855,9 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
QGlyphLayout glyphs = this->shapedGlyphs(&item);
const int end = qMin(item.position + item.num_glyphs, tabSectionEnd) - item.position;
for (int i=0; i < end; i++)
- length += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
+ length += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
if (end + item.position == tabSectionEnd && tabSpec.type == QTextOption::DelimiterTab) // remove half of matching char
- length -= glyphs.advances_x[end] / 2 * !glyphs.attributes[end].dontPrint;
+ length -= glyphs.advances[end] / 2 * !glyphs.attributes[end].dontPrint;
}
switch (tabSpec.type) {
@@ -2915,14 +2911,13 @@ public:
void QTextEngine::resolveAdditionalFormats() const
{
if (!specialData || specialData->addFormats.isEmpty()
- || !specialData->resolvedFormatIndices.isEmpty())
+ || !specialData->resolvedFormats.isEmpty())
return;
QTextFormatCollection *collection = formats();
- specialData->resolvedFormatIndices.clear();
- QVector<int> indices(layoutData->items.count());
-
+ specialData->resolvedFormats.clear();
+ QVector<QTextCharFormat> resolvedFormats(layoutData->items.count());
QVarLengthArray<int, 64> addFormatSortedByStart;
addFormatSortedByStart.reserve(specialData->addFormats.count());
@@ -2958,21 +2953,24 @@ void QTextEngine::resolveAdditionalFormats() const
currentFormats.remove(currentFormatIterator - currentFormats.begin());
++endIt;
}
- QTextCharFormat format;
+
+ QTextCharFormat &format = resolvedFormats[i];
if (block.docHandle()) {
// when we have a docHandle, formatIndex might still return a valid index based
// on the preeditPosition. for all other cases, we cleared the resolved format indices
format = collection->charFormat(formatIndex(si));
}
-
- foreach (int cur, currentFormats) {
- Q_ASSERT(specialData->addFormats.at(cur).start <= si->position
- && specialData->addFormats.at(cur).start + specialData->addFormats.at(cur).length >= end);
- format.merge(collection->format(specialData->addFormatIndices.at(cur)));
+ if (!currentFormats.isEmpty()) {
+ foreach (int cur, currentFormats) {
+ const QTextLayout::FormatRange &range = specialData->addFormats.at(cur);
+ Q_ASSERT(range.start <= si->position && range.start + range.length >= end);
+ format.merge(range.format);
+ }
+ format = collection->charFormat(collection->indexForFormat(format)); // get shared copy
}
- indices[i] = collection->indexForFormat(format);
}
- specialData->resolvedFormatIndices = indices;
+
+ specialData->resolvedFormats = resolvedFormats;
}
QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line)
@@ -3026,7 +3024,7 @@ QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, in
break;
}
if (clusterLength)
- return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
+ return glyphs.advances[glyph_pos] * offsetInCluster / clusterLength;
}
return 0;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index fb71ab40b8..1616a78937 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -190,11 +190,15 @@ Q_DECLARE_TYPEINFO(QGlyphJustification, Q_PRIMITIVE_TYPE);
struct QGlyphLayout
{
+ enum {
+ SpaceNeeded = sizeof(glyph_t) + sizeof(QFixed) + sizeof(QFixedPoint)
+ + sizeof(QGlyphAttributes) + sizeof(QGlyphJustification)
+ };
+
// init to 0 not needed, done when shaping
QFixedPoint *offsets; // 8 bytes per element
glyph_t *glyphs; // 4 bytes per element
- QFixed *advances_x; // 4 bytes per element
- QFixed *advances_y; // 4 bytes per element
+ QFixed *advances; // 4 bytes per element
QGlyphJustification *justifications; // 4 bytes per element
QGlyphAttributes *attributes; // 2 bytes per element
@@ -208,9 +212,7 @@ struct QGlyphLayout
int offset = totalGlyphs * sizeof(QFixedPoint);
glyphs = reinterpret_cast<glyph_t *>(address + offset);
offset += totalGlyphs * sizeof(glyph_t);
- advances_x = reinterpret_cast<QFixed *>(address + offset);
- offset += totalGlyphs * sizeof(QFixed);
- advances_y = reinterpret_cast<QFixed *>(address + offset);
+ advances = reinterpret_cast<QFixed *>(address + offset);
offset += totalGlyphs * sizeof(QFixed);
justifications = reinterpret_cast<QGlyphJustification *>(address + offset);
offset += totalGlyphs * sizeof(QGlyphJustification);
@@ -221,8 +223,7 @@ struct QGlyphLayout
inline QGlyphLayout mid(int position, int n = -1) const {
QGlyphLayout copy = *this;
copy.glyphs += position;
- copy.advances_x += position;
- copy.advances_y += position;
+ copy.advances += position;
copy.offsets += position;
copy.justifications += position;
copy.attributes += position;
@@ -233,27 +234,20 @@ struct QGlyphLayout
return copy;
}
- static inline int spaceNeededForGlyphLayout(int totalGlyphs) {
- return totalGlyphs * (sizeof(glyph_t) + sizeof(QGlyphAttributes)
- + sizeof(QFixed) + sizeof(QFixed) + sizeof(QFixedPoint)
- + sizeof(QGlyphJustification));
- }
-
inline QFixed effectiveAdvance(int item) const
- { return (advances_x[item] + QFixed::fromFixed(justifications[item].space_18d6)) * !attributes[item].dontPrint; }
+ { return (advances[item] + QFixed::fromFixed(justifications[item].space_18d6)) * !attributes[item].dontPrint; }
inline void clear(int first = 0, int last = -1) {
if (last == -1)
last = numGlyphs;
if (first == 0 && last == numGlyphs
&& reinterpret_cast<char *>(offsets + numGlyphs) == reinterpret_cast<char *>(glyphs)) {
- memset(offsets, 0, spaceNeededForGlyphLayout(numGlyphs));
+ memset(offsets, 0, (numGlyphs * SpaceNeeded));
} else {
const int num = last - first;
memset(offsets + first, 0, num * sizeof(QFixedPoint));
memset(glyphs + first, 0, num * sizeof(glyph_t));
- memset(advances_x + first, 0, num * sizeof(QFixed));
- memset(advances_y + first, 0, num * sizeof(QFixed));
+ memset(advances + first, 0, num * sizeof(QFixed));
memset(justifications + first, 0, num * sizeof(QGlyphJustification));
memset(attributes + first, 0, num * sizeof(QGlyphAttributes));
}
@@ -272,7 +266,7 @@ private:
typedef QVarLengthArray<void *> Array;
public:
QVarLengthGlyphLayoutArray(int totalGlyphs)
- : Array(spaceNeededForGlyphLayout(totalGlyphs) / sizeof(void *) + 1)
+ : Array((totalGlyphs * SpaceNeeded) / sizeof(void *) + 1)
, QGlyphLayout(reinterpret_cast<char *>(Array::data()), totalGlyphs)
{
memset(Array::data(), 0, Array::size() * sizeof(void *));
@@ -280,7 +274,7 @@ public:
void resize(int totalGlyphs)
{
- Array::resize(spaceNeededForGlyphLayout(totalGlyphs) / sizeof(void *) + 1);
+ Array::resize((totalGlyphs * SpaceNeeded) / sizeof(void *) + 1);
*((QGlyphLayout *)this) = QGlyphLayout(reinterpret_cast<char *>(Array::data()), totalGlyphs);
memset(Array::data(), 0, Array::size() * sizeof(void *));
@@ -297,10 +291,7 @@ public:
}
private:
- void *buffer[(N * (sizeof(glyph_t) + sizeof(QGlyphAttributes)
- + sizeof(QFixed) + sizeof(QFixed) + sizeof(QFixedPoint)
- + sizeof(QGlyphJustification)))
- / sizeof(void *) + 1];
+ void *buffer[(N * SpaceNeeded) / sizeof(void *) + 1];
};
struct QScriptItem;
@@ -449,7 +440,6 @@ public:
typedef QList<ItemDecoration> ItemDecorationList;
- QTextEngine(LayoutData *data);
QTextEngine();
QTextEngine(const QString &str, const QFont &f);
~QTextEngine();
@@ -553,6 +543,7 @@ public:
mutable QScriptLineArray lines;
+private:
struct FontEngineCache {
FontEngineCache();
mutable QFontEngine *prevFontEngine;
@@ -570,6 +561,7 @@ public:
};
mutable FontEngineCache feCache;
+public:
QString text;
mutable QFont fnt;
#ifndef QT_NO_RAWFONT
@@ -611,7 +603,8 @@ public:
void setPreeditArea(int position, const QString &text);
inline bool hasFormats() const { return block.docHandle() || (specialData && !specialData->addFormats.isEmpty()); }
- QList<QTextLayout::FormatRange> additionalFormats() const;
+ inline QList<QTextLayout::FormatRange> additionalFormats() const
+ { return specialData ? specialData->addFormats : QList<QTextLayout::FormatRange>(); }
void setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList);
private:
@@ -621,8 +614,7 @@ private:
int preeditPosition;
QString preeditText;
QList<QTextLayout::FormatRange> addFormats;
- QVector<int> addFormatIndices;
- QVector<int> resolvedFormatIndices;
+ QVector<QTextCharFormat> resolvedFormats;
// only used when no docHandle is available
QScopedPointer<QTextFormatCollection> formats;
};
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 2389427da0..4854af0d01 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -524,7 +524,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value BlockFormat The object formats a text block
\value CharFormat The object formats a single character
\value ListFormat The object formats a list
- \value TableFormat The object formats a table
+ \omitvalue TableFormat Unused Value, a table's FormatType is FrameFormat.
\value FrameFormat The object formats a frame
\value UserFormat
@@ -706,6 +706,15 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
*/
/*!
+ \fn bool QTextFormat::isEmpty() const
+ \since 5.3
+
+ Returns true if the format does not store any properties; false otherwise.
+
+ \sa propertyCount(), properties()
+*/
+
+/*!
\fn bool QTextFormat::isCharFormat() const
Returns \c true if this text format is a \c CharFormat; otherwise
@@ -1870,36 +1879,93 @@ QStringList QTextCharFormat::anchorNames() const
*/
/*!
+ \enum QTextCharFormat::FontPropertiesInheritanceBehavior
+ \since 5.3
+
+ This enum specifies how the setFont() function should behave with
+ respect to unset font properties.
+
+ \value FontPropertiesSpecifiedOnly If a property is not explicitly set, do not
+ change the text format's property value.
+ \value FontPropertiesAll If a property is not explicitly set, override the
+ text format's property with a default value.
+
+ \sa setFont()
+*/
+
+/*!
+ \overload
+
Sets the text format's \a font.
+
+ \sa font()
*/
void QTextCharFormat::setFont(const QFont &font)
{
- setFontFamily(font.family());
+ setFont(font, FontPropertiesAll);
+}
- const qreal pointSize = font.pointSizeF();
- if (pointSize > 0) {
- setFontPointSize(pointSize);
- } else {
- const int pixelSize = font.pixelSize();
- if (pixelSize > 0)
- setProperty(QTextFormat::FontPixelSize, pixelSize);
+/*!
+ \since 5.3
+
+ Sets the text format's \a font.
+
+ If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that
+ has not been explicitly set is treated like as it were set with default value;
+ If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that
+ has not been explicitly set is ignored and the respective property value
+ remains unchanged.
+
+ \sa font()
+*/
+void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavior behavior)
+{
+ const uint mask = behavior == FontPropertiesAll ? uint(QFont::AllPropertiesResolved)
+ : font.resolve();
+
+ if (mask & QFont::FamilyResolved)
+ setFontFamily(font.family());
+ if (mask & QFont::SizeResolved) {
+ const qreal pointSize = font.pointSizeF();
+ if (pointSize > 0) {
+ setFontPointSize(pointSize);
+ } else {
+ const int pixelSize = font.pixelSize();
+ if (pixelSize > 0)
+ setProperty(QTextFormat::FontPixelSize, pixelSize);
+ }
}
- setFontWeight(font.weight());
- setFontItalic(font.italic());
- setUnderlineStyle(font.underline() ? SingleUnderline : NoUnderline);
- setFontOverline(font.overline());
- setFontStrikeOut(font.strikeOut());
- setFontFixedPitch(font.fixedPitch());
- setFontCapitalization(font.capitalization());
- setFontWordSpacing(font.wordSpacing());
- setFontLetterSpacingType(font.letterSpacingType());
- setFontLetterSpacing(font.letterSpacing());
- setFontStretch(font.stretch());
- setFontStyleHint(font.styleHint());
- setFontStyleStrategy(font.styleStrategy());
- setFontHintingPreference(font.hintingPreference());
- setFontKerning(font.kerning());
+ if (mask & QFont::WeightResolved)
+ setFontWeight(font.weight());
+ if (mask & QFont::StyleResolved)
+ setFontItalic(font.style() != QFont::StyleNormal);
+ if (mask & QFont::UnderlineResolved)
+ setUnderlineStyle(font.underline() ? SingleUnderline : NoUnderline);
+ if (mask & QFont::OverlineResolved)
+ setFontOverline(font.overline());
+ if (mask & QFont::StrikeOutResolved)
+ setFontStrikeOut(font.strikeOut());
+ if (mask & QFont::FixedPitchResolved)
+ setFontFixedPitch(font.fixedPitch());
+ if (mask & QFont::CapitalizationResolved)
+ setFontCapitalization(font.capitalization());
+ if (mask & QFont::LetterSpacingResolved)
+ setFontWordSpacing(font.wordSpacing());
+ if (mask & QFont::LetterSpacingResolved) {
+ setFontLetterSpacingType(font.letterSpacingType());
+ setFontLetterSpacing(font.letterSpacing());
+ }
+ if (mask & QFont::StretchResolved)
+ setFontStretch(font.stretch());
+ if (mask & QFont::StyleHintResolved)
+ setFontStyleHint(font.styleHint());
+ if (mask & QFont::StyleStrategyResolved)
+ setFontStyleStrategy(font.styleStrategy());
+ if (mask & QFont::HintingPreferenceResolved)
+ setFontHintingPreference(font.hintingPreference());
+ if (mask & QFont::KerningResolved)
+ setFontKerning(font.kerning());
}
/*!
@@ -3376,19 +3442,6 @@ bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const
return false;
}
-QTextFormat QTextFormatCollection::objectFormat(int objectIndex) const
-{
- if (objectIndex == -1)
- return QTextFormat();
- return format(objFormats.at(objectIndex));
-}
-
-void QTextFormatCollection::setObjectFormat(int objectIndex, const QTextFormat &f)
-{
- const int formatIndex = indexForFormat(f);
- objFormats[objectIndex] = formatIndex;
-}
-
int QTextFormatCollection::objectFormatIndex(int objectIndex) const
{
if (objectIndex == -1)
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index 2098369811..5369001a03 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -141,7 +141,9 @@ public:
BlockFormat = 1,
CharFormat = 2,
ListFormat = 3,
+#if QT_DEPRECATED_SINCE(5, 3)
TableFormat = 4,
+#endif
FrameFormat = 5,
UserFormat = 100
@@ -295,6 +297,7 @@ public:
void merge(const QTextFormat &other);
inline bool isValid() const { return type() != InvalidFormat; }
+ inline bool isEmpty() const { return propertyCount() == 0; }
int type() const;
@@ -407,7 +410,13 @@ public:
QTextCharFormat();
bool isValid() const { return isCharFormat(); }
- void setFont(const QFont &font);
+
+ enum FontPropertiesInheritanceBehavior {
+ FontPropertiesSpecifiedOnly,
+ FontPropertiesAll
+ };
+ void setFont(const QFont &font, FontPropertiesInheritanceBehavior behavior);
+ void setFont(const QFont &font); // ### Qt6: Merge with above
QFont font() const;
inline void setFontFamily(const QString &family)
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index 6b2958a4b6..e3998d4f3f 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -68,8 +68,10 @@ public:
QTextFormatCollection(const QTextFormatCollection &rhs);
QTextFormatCollection &operator=(const QTextFormatCollection &rhs);
- QTextFormat objectFormat(int objectIndex) const;
- void setObjectFormat(int objectIndex, const QTextFormat &format);
+ inline QTextFormat objectFormat(int objectIndex) const
+ { return format(objectFormatIndex(objectIndex)); }
+ inline void setObjectFormat(int objectIndex, const QTextFormat &format)
+ { setObjectFormatIndex(objectIndex, indexForFormat(format)); }
int objectFormatIndex(int objectIndex) const;
void setObjectFormatIndex(int objectIndex, int formatIndex);
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 3cb61b9eae..e8a02c44b2 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1361,33 +1361,7 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
QFont f;
int adjustment = -255;
extractor.extractFont(&f, &adjustment);
- if (f.resolve() & QFont::SizeResolved) {
- if (f.pointSize() > 0) {
- charFormat.setFontPointSize(f.pointSize());
- } else if (f.pixelSize() > 0) {
- charFormat.setProperty(QTextFormat::FontPixelSize, f.pixelSize());
- }
- }
- if (f.resolve() & QFont::StyleResolved)
- charFormat.setFontItalic(f.style() != QFont::StyleNormal);
-
- if (f.resolve() & QFont::WeightResolved)
- charFormat.setFontWeight(f.weight());
-
- if (f.resolve() & QFont::FamilyResolved)
- charFormat.setFontFamily(f.family());
-
- if (f.resolve() & QFont::UnderlineResolved)
- charFormat.setUnderlineStyle(f.underline() ? QTextCharFormat::SingleUnderline : QTextCharFormat::NoUnderline);
-
- if (f.resolve() & QFont::OverlineResolved)
- charFormat.setFontOverline(f.overline());
-
- if (f.resolve() & QFont::StrikeOutResolved)
- charFormat.setFontStrikeOut(f.strikeOut());
-
- if (f.resolve() & QFont::CapitalizationResolved)
- charFormat.setFontCapitalization(f.capitalization());
+ charFormat.setFont(f, QTextCharFormat::FontPropertiesSpecifiedOnly);
if (adjustment >= -1)
charFormat.setProperty(QTextFormat::FontSizeAdjustment, adjustment);
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 66341e186a..0c9866c6cf 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -239,9 +239,7 @@ int QTextInlineObject::formatIndex() const
*/
QTextFormat QTextInlineObject::format() const
{
- if (!eng->block.docHandle())
- return QTextFormat();
- return eng->formats()->format(eng->formatIndex(&eng->layoutData->items[itm]));
+ return eng->format(&eng->layoutData->items[itm]);
}
/*!
@@ -1693,7 +1691,7 @@ static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &gly
} while (pos < end && logClusters[pos] == glyphPosition);
do { // calculate the textWidth for the rest of the current cluster.
if (!glyphs.attributes[glyphPosition].dontPrint)
- line.textWidth += glyphs.advances_x[glyphPosition];
+ line.textWidth += glyphs.advances[glyphPosition];
++glyphPosition;
} while (glyphPosition < current.num_glyphs && !glyphs.attributes[glyphPosition].clusterStart);
@@ -1812,9 +1810,10 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.whiteSpaceOrObject = true;
lbh.tmpData.length++;
- QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item]));
- if (eng->block.docHandle())
- eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format);
+ if (eng->block.docHandle()) {
+ QTextInlineObject inlineObject(item, eng);
+ eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, inlineObject.format());
+ }
lbh.tmpData.textWidth += current.width;
@@ -1871,9 +1870,9 @@ void QTextLine::layout_helper(int maxGlyphs)
// and thus become invisible again.
//
if (line.length)
- lbh.softHyphenWidth = lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
+ lbh.softHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
else if (breakany)
- lbh.tmpData.textWidth += lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
+ lbh.tmpData.textWidth += lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
}
// The actual width of the text needs to take the right bearing into account. The
@@ -2249,14 +2248,12 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
if (relativeFrom != (iterator.itemStart - si.position) && !rtl) {
for (int i=itemGlyphsStart; i<glyphsStart; ++i) {
QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
- pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
- glyphLayout.advances_y[i].toReal());
+ pos.rx() += (glyphLayout.advances[i] + justification).toReal();
}
} else if (relativeTo != (iterator.itemEnd - si.position - 1) && rtl) {
for (int i=itemGlyphsEnd; i>glyphsEnd; --i) {
QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
- pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
- glyphLayout.advances_y[i].toReal());
+ pos.rx() += (glyphLayout.advances[i] + justification).toReal();
}
}
@@ -2295,10 +2292,8 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
glyphRuns.append(glyphRunWithInfo(multiFontEngine->engine(which),
subLayout, pos, subFlags, x, width));
- for (int i = 0; i < subLayout.numGlyphs; i++) {
- pos += QPointF(subLayout.advances_x[i].toReal(),
- subLayout.advances_y[i].toReal());
- }
+ for (int i = 0; i < subLayout.numGlyphs; ++i)
+ pos.rx() += subLayout.advances[i].toReal();
if (rtl)
end = start;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index d1a39c6ab6..bd1e970583 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -1233,6 +1233,56 @@ QString QTextBlock::text() const
return text;
}
+/*!
+ \since 5.3
+
+ Returns the block's text format options as a list of continuous ranges
+ of QTextCharFormat. The range's character format is used when inserting text
+ within the range boundaries.
+
+ \sa charFormat(), blockFormat()
+*/
+QList<QTextLayout::FormatRange> QTextBlock::textFormats() const
+{
+ QList<QTextLayout::FormatRange> formats;
+ if (!p || !n)
+ return formats;
+
+ const QTextFormatCollection *formatCollection = p->formatCollection();
+
+ int start = 0;
+ int cur = start;
+ int format = -1;
+
+ const int pos = position();
+ QTextDocumentPrivate::FragmentIterator it = p->find(pos);
+ QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
+ for (; it != end; ++it) {
+ const QTextFragmentData * const frag = it.value();
+ if (format != it.value()->format) {
+ if (cur - start > 0) {
+ QTextLayout::FormatRange range;
+ range.start = start;
+ range.length = cur - start;
+ range.format = formatCollection->charFormat(format);
+ formats.append(range);
+ }
+
+ format = frag->format;
+ start = cur;
+ }
+ cur += frag->size_array[0];
+ }
+ if (cur - start > 0) {
+ QTextLayout::FormatRange range;
+ range.start = start;
+ range.length = cur - start;
+ range.format = formatCollection->charFormat(format);
+ formats.append(range);
+ }
+
+ return formats;
+}
/*!
Returns the text document this text block belongs to, or 0 if the
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index 87f2cf6197..6a127f0315 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtGui/qtextformat.h>
+#include <QtGui/qtextlayout.h>
#include <QtGui/qglyphrun.h>
QT_BEGIN_NAMESPACE
@@ -55,7 +56,6 @@ class QTextDocumentPrivate;
class QTextCursor;
class QTextBlock;
class QTextFragment;
-class QTextLayout;
class QTextList;
class Q_GUI_EXPORT QTextObject : public QObject
@@ -223,6 +223,8 @@ public:
QString text() const;
+ QList<QTextLayout::FormatRange> textFormats() const;
+
const QTextDocument *document() const;
QTextList *textList() const;
diff --git a/src/gui/util/qabstractlayoutstyleinfo.cpp b/src/gui/util/qabstractlayoutstyleinfo.cpp
new file mode 100644
index 0000000000..4f7c635594
--- /dev/null
+++ b/src/gui/util/qabstractlayoutstyleinfo.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractlayoutstyleinfo_p.h"
+
+QT_BEGIN_NAMESPACE
+
+bool QAbstractLayoutStyleInfo::hasChanged() const
+{
+ if (m_changed == Unknown)
+ m_changed = hasChangedCore() ? Changed : Unchanged;
+ return m_changed == Changed;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qabstractlayoutstyleinfo_p.h b/src/gui/util/qabstractlayoutstyleinfo_p.h
new file mode 100644
index 0000000000..52f151c5d2
--- /dev/null
+++ b/src/gui/util/qabstractlayoutstyleinfo_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTLAYOUTSTYLEINFO_P_H
+#define QABSTRACTLAYOUTSTYLEINFO_P_H
+
+#include <QtCore/qnamespace.h>
+#include "qlayoutpolicy_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+class Q_GUI_EXPORT QAbstractLayoutStyleInfo {
+public:
+ typedef enum {
+ Unknown = 0,
+ Changed,
+ Unchanged
+ } ChangedState;
+
+ QAbstractLayoutStyleInfo() : m_isWindow(false), m_changed(Changed) {}
+ virtual ~QAbstractLayoutStyleInfo() {}
+ virtual qreal combinedLayoutSpacing(QLayoutPolicy::ControlTypes /*controls1*/,
+ QLayoutPolicy::ControlTypes /*controls2*/, Qt::Orientation /*orientation*/) const {
+ return -1;
+ }
+
+ virtual qreal perItemSpacing(QLayoutPolicy::ControlType /*control1*/,
+ QLayoutPolicy::ControlType /*control2*/,
+ Qt::Orientation /*orientation*/) const {
+ return -1;
+ }
+
+ virtual qreal spacing(Qt::Orientation orientation) const = 0;
+
+ virtual bool hasChangedCore() const = 0;
+
+ void updateChanged(ChangedState change) {
+ m_changed = change;
+ }
+
+ bool hasChanged() const;
+
+ virtual void invalidate() { updateChanged(Changed);}
+
+ virtual qreal windowMargin(Qt::Orientation orientation) const = 0;
+
+ bool isWindow() const {
+ return m_isWindow;
+ }
+
+protected:
+ unsigned m_isWindow : 1;
+ mutable unsigned m_changed : 2;
+};
+
+QT_END_NAMESPACE
+
+#endif // QABSTRACTLAYOUTSTYLEINFO_P_H
diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp
new file mode 100644
index 0000000000..10b4a2ee35
--- /dev/null
+++ b/src/gui/util/qgridlayoutengine.cpp
@@ -0,0 +1,1635 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include <math.h>
+
+#include "qgridlayoutengine_p.h"
+#include "qvarlengtharray.h"
+
+#include <QtDebug>
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+template <typename T>
+static void insertOrRemoveItems(QVector<T> &items, int index, int delta)
+{
+ int count = items.count();
+ if (index < count) {
+ if (delta > 0) {
+ items.insert(index, delta, T());
+ } else if (delta < 0) {
+ items.remove(index, qMin(-delta, count - index));
+ }
+ }
+}
+
+static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired)
+{
+ Q_ASSERT(sumDesired != 0.0);
+ return desired * qPow(sumAvailable / sumDesired, desired / sumDesired);
+}
+
+static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize)
+{
+ if (descent < 0.0)
+ return -1.0;
+
+ Q_ASSERT(descent >= 0.0);
+ Q_ASSERT(ascent >= 0.0);
+ Q_ASSERT(targetSize >= ascent + descent);
+
+ qreal extra = targetSize - (ascent + descent);
+ return descent + (extra / 2.0);
+}
+
+static qreal compare(const QGridLayoutBox &box1, const QGridLayoutBox &box2, int which)
+{
+ qreal size1 = box1.q_sizes(which);
+ qreal size2 = box2.q_sizes(which);
+
+ if (which == MaximumSize) {
+ return size2 - size1;
+ } else {
+ return size1 - size2;
+ }
+}
+
+void QGridLayoutBox::add(const QGridLayoutBox &other, int stretch, qreal spacing)
+{
+ Q_ASSERT(q_minimumDescent < 0.0);
+
+ q_minimumSize += other.q_minimumSize + spacing;
+ q_preferredSize += other.q_preferredSize + spacing;
+ q_maximumSize += ((stretch == 0) ? other.q_preferredSize : other.q_maximumSize) + spacing;
+}
+
+void QGridLayoutBox::combine(const QGridLayoutBox &other)
+{
+ q_minimumDescent = qMax(q_minimumDescent, other.q_minimumDescent);
+ q_minimumAscent = qMax(q_minimumAscent, other.q_minimumAscent);
+
+ q_minimumSize = qMax(q_minimumAscent + q_minimumDescent,
+ qMax(q_minimumSize, other.q_minimumSize));
+ qreal maxMax;
+ if (q_maximumSize == FLT_MAX && other.q_maximumSize != FLT_MAX)
+ maxMax = other.q_maximumSize;
+ else if (other.q_maximumSize == FLT_MAX && q_maximumSize != FLT_MAX)
+ maxMax = q_maximumSize;
+ else
+ maxMax = qMax(q_maximumSize, other.q_maximumSize);
+
+ q_maximumSize = qMax(q_minimumSize, maxMax);
+ q_preferredSize = qBound(q_minimumSize, qMax(q_preferredSize, other.q_preferredSize),
+ q_maximumSize);
+}
+
+void QGridLayoutBox::normalize()
+{
+ q_maximumSize = qMax(qreal(0.0), q_maximumSize);
+ q_minimumSize = qBound(qreal(0.0), q_minimumSize, q_maximumSize);
+ q_preferredSize = qBound(q_minimumSize, q_preferredSize, q_maximumSize);
+ q_minimumDescent = qMin(q_minimumDescent, q_minimumSize);
+
+ Q_ASSERT((q_minimumDescent < 0.0) == (q_minimumAscent < 0.0));
+}
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+void QGridLayoutBox::dump(int indent) const
+{
+ qDebug("%*sBox (%g <= %g <= %g [%g/%g])", indent, "", q_minimumSize, q_preferredSize,
+ q_maximumSize, q_minimumAscent, q_minimumDescent);
+}
+#endif
+
+bool operator==(const QGridLayoutBox &box1, const QGridLayoutBox &box2)
+{
+ for (int i = 0; i < NSizes; ++i) {
+ if (box1.q_sizes(i) != box2.q_sizes(i))
+ return false;
+ }
+ return box1.q_minimumDescent == box2.q_minimumDescent
+ && box1.q_minimumAscent == box2.q_minimumAscent;
+}
+
+void QGridLayoutRowData::reset(int count)
+{
+ ignore.fill(false, count);
+ boxes.fill(QGridLayoutBox(), count);
+ multiCellMap.clear();
+ stretches.fill(0, count);
+ spacings.fill(0.0, count);
+ hasIgnoreFlag = false;
+}
+
+void QGridLayoutRowData::distributeMultiCells(const QGridLayoutRowInfo &rowInfo)
+{
+ MultiCellMap::const_iterator i = multiCellMap.constBegin();
+ for (; i != multiCellMap.constEnd(); ++i) {
+ int start = i.key().first;
+ int span = i.key().second;
+ int end = start + span;
+ const QGridLayoutBox &box = i.value().q_box;
+ int stretch = i.value().q_stretch;
+
+ QGridLayoutBox totalBox = this->totalBox(start, end);
+ QVarLengthArray<QGridLayoutBox> extras(span);
+ QVarLengthArray<qreal> dummy(span);
+ QVarLengthArray<qreal> newSizes(span);
+
+ for (int j = 0; j < NSizes; ++j) {
+ qreal extra = compare(box, totalBox, j);
+ if (extra > 0.0) {
+ calculateGeometries(start, end, box.q_sizes(j), dummy.data(), newSizes.data(),
+ 0, totalBox, rowInfo);
+
+ for (int k = 0; k < span; ++k)
+ extras[k].q_sizes(j) = newSizes[k];
+ }
+ }
+
+ for (int k = 0; k < span; ++k) {
+ boxes[start + k].combine(extras[k]);
+ if (stretch != 0)
+ stretches[start + k] = qMax(stretches[start + k], stretch);
+ }
+ }
+ multiCellMap.clear();
+}
+
+void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSize, qreal *positions,
+ qreal *sizes, qreal *descents,
+ const QGridLayoutBox &totalBox,
+ const QGridLayoutRowInfo &rowInfo)
+{
+ Q_ASSERT(end > start);
+
+ targetSize = qMax(totalBox.q_minimumSize, targetSize);
+
+ int n = end - start;
+ QVarLengthArray<qreal> newSizes(n);
+ QVarLengthArray<qreal> factors(n);
+ qreal sumFactors = 0.0;
+ int sumStretches = 0;
+ qreal sumAvailable;
+
+ for (int i = 0; i < n; ++i) {
+ if (stretches[start + i] > 0)
+ sumStretches += stretches[start + i];
+ }
+
+ if (targetSize < totalBox.q_preferredSize) {
+ stealBox(start, end, MinimumSize, positions, sizes);
+
+ sumAvailable = targetSize - totalBox.q_minimumSize;
+ if (sumAvailable > 0.0) {
+ qreal sumDesired = totalBox.q_preferredSize - totalBox.q_minimumSize;
+
+ for (int i = 0; i < n; ++i) {
+ if (ignore.testBit(start + i)) {
+ factors[i] = 0.0;
+ continue;
+ }
+
+ const QGridLayoutBox &box = boxes.at(start + i);
+ qreal desired = box.q_preferredSize - box.q_minimumSize;
+ factors[i] = growthFactorBelowPreferredSize(desired, sumAvailable, sumDesired);
+ sumFactors += factors[i];
+ }
+
+ for (int i = 0; i < n; ++i) {
+ Q_ASSERT(sumFactors > 0.0);
+ qreal delta = sumAvailable * factors[i] / sumFactors;
+ newSizes[i] = sizes[i] + delta;
+ }
+ }
+ } else {
+ bool isLargerThanMaximum = (targetSize > totalBox.q_maximumSize);
+ if (isLargerThanMaximum) {
+ stealBox(start, end, MaximumSize, positions, sizes);
+ sumAvailable = targetSize - totalBox.q_maximumSize;
+ } else {
+ stealBox(start, end, PreferredSize, positions, sizes);
+ sumAvailable = targetSize - totalBox.q_preferredSize;
+ }
+
+ if (sumAvailable > 0.0) {
+ qreal sumCurrentAvailable = sumAvailable;
+ bool somethingHasAMaximumSize = false;
+
+ qreal sumSizes = 0.0;
+ for (int i = 0; i < n; ++i)
+ sumSizes += sizes[i];
+
+ for (int i = 0; i < n; ++i) {
+ if (ignore.testBit(start + i)) {
+ newSizes[i] = 0.0;
+ factors[i] = 0.0;
+ continue;
+ }
+
+ const QGridLayoutBox &box = boxes.at(start + i);
+ qreal boxSize;
+
+ qreal desired;
+ if (isLargerThanMaximum) {
+ boxSize = box.q_maximumSize;
+ desired = rowInfo.boxes.value(start + i).q_maximumSize - boxSize;
+ } else {
+ boxSize = box.q_preferredSize;
+ desired = box.q_maximumSize - boxSize;
+ }
+ if (desired == 0.0) {
+ newSizes[i] = sizes[i];
+ factors[i] = 0.0;
+ } else {
+ Q_ASSERT(desired > 0.0);
+
+ int stretch = stretches[start + i];
+ if (sumStretches == 0) {
+ if (hasIgnoreFlag || sizes[i] == 0.0) {
+ factors[i] = (stretch < 0) ? 1.0 : 0.0;
+ } else {
+ factors[i] = (stretch < 0) ? sizes[i] : 0.0;
+ }
+ } else if (stretch == sumStretches) {
+ factors[i] = 1.0;
+ } else if (stretch <= 0) {
+ factors[i] = 0.0;
+ } else {
+ qreal ultimateSize;
+ qreal ultimateSumSizes;
+ qreal x = ((stretch * sumSizes)
+ - (sumStretches * boxSize))
+ / (sumStretches - stretch);
+ if (x >= 0.0) {
+ ultimateSize = boxSize + x;
+ ultimateSumSizes = sumSizes + x;
+ } else {
+ ultimateSize = boxSize;
+ ultimateSumSizes = (sumStretches * boxSize)
+ / stretch;
+ }
+
+ /*
+ We multiply these by 1.5 to give some space for a smooth transition
+ (at the expense of the stretch factors, which are not fully respected
+ during the transition).
+ */
+ ultimateSize = ultimateSize * 3 / 2;
+ ultimateSumSizes = ultimateSumSizes * 3 / 2;
+
+ qreal beta = ultimateSumSizes - sumSizes;
+ if (!beta) {
+ factors[i] = 1;
+ } else {
+ qreal alpha = qMin(sumCurrentAvailable, beta);
+ qreal ultimateFactor = (stretch * ultimateSumSizes / sumStretches)
+ - (boxSize);
+ qreal transitionalFactor = sumCurrentAvailable * (ultimateSize - boxSize) / beta;
+
+ factors[i] = ((alpha * ultimateFactor)
+ + ((beta - alpha) * transitionalFactor)) / beta;
+ }
+
+ }
+ sumFactors += factors[i];
+ if (desired < sumCurrentAvailable)
+ somethingHasAMaximumSize = true;
+
+ newSizes[i] = -1.0;
+ }
+ }
+
+ bool keepGoing = somethingHasAMaximumSize;
+ while (keepGoing) {
+ keepGoing = false;
+
+ for (int i = 0; i < n; ++i) {
+ if (newSizes[i] >= 0.0)
+ continue;
+
+ qreal maxBoxSize;
+ if (isLargerThanMaximum)
+ maxBoxSize = rowInfo.boxes.value(start + i).q_maximumSize;
+ else
+ maxBoxSize = boxes.at(start + i).q_maximumSize;
+
+ qreal avail = sumCurrentAvailable * factors[i] / sumFactors;
+ if (sizes[i] + avail >= maxBoxSize) {
+ newSizes[i] = maxBoxSize;
+ sumCurrentAvailable -= maxBoxSize - sizes[i];
+ sumFactors -= factors[i];
+ keepGoing = (sumCurrentAvailable > 0.0);
+ if (!keepGoing)
+ break;
+ }
+ }
+ }
+
+ for (int i = 0; i < n; ++i) {
+ if (newSizes[i] < 0.0) {
+ qreal delta = (sumFactors == 0.0) ? 0.0
+ : sumCurrentAvailable * factors[i] / sumFactors;
+ newSizes[i] = sizes[i] + delta;
+ }
+ }
+ }
+ }
+
+ if (sumAvailable > 0) {
+ qreal offset = 0;
+ for (int i = 0; i < n; ++i) {
+ qreal delta = newSizes[i] - sizes[i];
+ positions[i] += offset;
+ sizes[i] += delta;
+ offset += delta;
+ }
+
+#if 0 // some "pixel allocation"
+ int surplus = targetSize - (positions[n - 1] + sizes[n - 1]);
+ Q_ASSERT(surplus >= 0 && surplus <= n);
+
+ int prevSurplus = -1;
+ while (surplus > 0 && surplus != prevSurplus) {
+ prevSurplus = surplus;
+
+ int offset = 0;
+ for (int i = 0; i < n; ++i) {
+ const QGridLayoutBox &box = boxes.at(start + i);
+ int delta = (!ignore.testBit(start + i) && surplus > 0
+ && factors[i] > 0 && sizes[i] < box.q_maximumSize)
+ ? 1 : 0;
+
+ positions[i] += offset;
+ sizes[i] += delta;
+ offset += delta;
+ surplus -= delta;
+ }
+ }
+ Q_ASSERT(surplus == 0);
+#endif
+ }
+
+ if (descents) {
+ for (int i = 0; i < n; ++i) {
+ if (ignore.testBit(start + i))
+ continue;
+ const QGridLayoutBox &box = boxes.at(start + i);
+ descents[i] = fixedDescent(box.q_minimumDescent, box.q_minimumAscent, sizes[i]);
+ }
+ }
+}
+
+QGridLayoutBox QGridLayoutRowData::totalBox(int start, int end) const
+{
+ QGridLayoutBox result;
+ if (start < end) {
+ result.q_maximumSize = 0.0;
+ qreal nextSpacing = 0.0;
+ for (int i = start; i < end; ++i) {
+ if (ignore.testBit(i))
+ continue;
+ result.add(boxes.at(i), stretches.at(i), nextSpacing);
+ nextSpacing = spacings.at(i);
+ }
+ }
+ return result;
+}
+
+void QGridLayoutRowData::stealBox(int start, int end, int which, qreal *positions, qreal *sizes)
+{
+ qreal offset = 0.0;
+ qreal nextSpacing = 0.0;
+
+ for (int i = start; i < end; ++i) {
+ qreal avail = 0.0;
+
+ if (!ignore.testBit(i)) {
+ const QGridLayoutBox &box = boxes.at(i);
+ avail = box.q_sizes(which);
+ offset += nextSpacing;
+ nextSpacing = spacings.at(i);
+ }
+
+ *positions++ = offset;
+ *sizes++ = avail;
+ offset += avail;
+ }
+}
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+void QGridLayoutRowData::dump(int indent) const
+{
+ qDebug("%*sData", indent, "");
+
+ for (int i = 0; i < ignore.count(); ++i) {
+ qDebug("%*s Row %d (stretch %d, spacing %g)", indent, "", i, stretches.at(i),
+ spacings.at(i));
+ if (ignore.testBit(i))
+ qDebug("%*s Ignored", indent, "");
+ boxes.at(i).dump(indent + 2);
+ }
+
+ MultiCellMap::const_iterator it = multiCellMap.constBegin();
+ while (it != multiCellMap.constEnd()) {
+ qDebug("%*s Multi-cell entry <%d, %d> (stretch %d)", indent, "", it.key().first,
+ it.key().second, it.value().q_stretch);
+ it.value().q_box.dump(indent + 2);
+ }
+}
+#endif
+
+QGridLayoutItem::QGridLayoutItem(int row, int column, int rowSpan, int columnSpan,
+ Qt::Alignment alignment)
+ : q_alignment(alignment)
+{
+ q_firstRows[Hor] = column;
+ q_firstRows[Ver] = row;
+ q_rowSpans[Hor] = columnSpan;
+ q_rowSpans[Ver] = rowSpan;
+ q_stretches[Hor] = -1;
+ q_stretches[Ver] = -1;
+}
+
+int QGridLayoutItem::firstRow(Qt::Orientation orientation) const
+{
+ return q_firstRows[orientation == Qt::Vertical];
+}
+
+int QGridLayoutItem::firstColumn(Qt::Orientation orientation) const
+{
+ return q_firstRows[orientation == Qt::Horizontal];
+}
+
+int QGridLayoutItem::lastRow(Qt::Orientation orientation) const
+{
+ return firstRow(orientation) + rowSpan(orientation) - 1;
+}
+
+int QGridLayoutItem::lastColumn(Qt::Orientation orientation) const
+{
+ return firstColumn(orientation) + columnSpan(orientation) - 1;
+}
+
+int QGridLayoutItem::rowSpan(Qt::Orientation orientation) const
+{
+ return q_rowSpans[orientation == Qt::Vertical];
+}
+
+int QGridLayoutItem::columnSpan(Qt::Orientation orientation) const
+{
+ return q_rowSpans[orientation == Qt::Horizontal];
+}
+
+void QGridLayoutItem::setFirstRow(int row, Qt::Orientation orientation)
+{
+ q_firstRows[orientation == Qt::Vertical] = row;
+}
+
+void QGridLayoutItem::setRowSpan(int rowSpan, Qt::Orientation orientation)
+{
+ q_rowSpans[orientation == Qt::Vertical] = rowSpan;
+}
+
+int QGridLayoutItem::stretchFactor(Qt::Orientation orientation) const
+{
+ int stretch = q_stretches[orientation == Qt::Vertical];
+ if (stretch >= 0)
+ return stretch;
+
+ QLayoutPolicy::Policy policy = sizePolicy(orientation);
+
+ if (policy & QLayoutPolicy::ExpandFlag) {
+ return 1;
+ } else if (policy & QLayoutPolicy::GrowFlag) {
+ return -1; // because we max it up
+ } else {
+ return 0;
+ }
+}
+
+void QGridLayoutItem::setStretchFactor(int stretch, Qt::Orientation orientation)
+{
+ Q_ASSERT(stretch >= 0); // ### deal with too big stretches
+ q_stretches[orientation == Qt::Vertical] = stretch;
+}
+
+QLayoutPolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /*side*/) const
+{
+ return QLayoutPolicy::DefaultType;
+}
+
+QGridLayoutBox QGridLayoutItem::box(Qt::Orientation orientation, qreal constraint) const
+{
+ QGridLayoutBox result;
+ QLayoutPolicy::Policy policy = sizePolicy(orientation);
+
+ if (orientation == Qt::Horizontal) {
+ QSizeF constraintSize(-1.0, constraint);
+
+ result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).width();
+
+ if (policy & QLayoutPolicy::ShrinkFlag) {
+ result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).width();
+ } else {
+ result.q_minimumSize = result.q_preferredSize;
+ }
+
+ if (policy & (QLayoutPolicy::GrowFlag | QLayoutPolicy::ExpandFlag)) {
+ result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).width();
+ } else {
+ result.q_maximumSize = result.q_preferredSize;
+ }
+ } else {
+ QSizeF constraintSize(constraint, -1.0);
+
+ result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).height();
+
+ if (policy & QLayoutPolicy::ShrinkFlag) {
+ result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).height();
+ } else {
+ result.q_minimumSize = result.q_preferredSize;
+ }
+
+ if (policy & (QLayoutPolicy::GrowFlag | QLayoutPolicy::ExpandFlag)) {
+ result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).height();
+ } else {
+ result.q_maximumSize = result.q_preferredSize;
+ }
+
+ if (alignment() & Qt::AlignBaseline) {
+ result.q_minimumDescent = sizeHint(Qt::MinimumDescent, constraintSize).height();
+ if (result.q_minimumDescent != -1.0) {
+ const qreal minSizeHint = sizeHint(Qt::MinimumSize, constraintSize).height();
+ result.q_minimumDescent -= (minSizeHint - result.q_minimumSize);
+ result.q_minimumAscent = result.q_minimumSize - result.q_minimumDescent;
+ }
+ }
+ }
+ if (policy & QLayoutPolicy::IgnoreFlag)
+ result.q_preferredSize = result.q_minimumSize;
+
+ return result;
+}
+
+QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal height,
+ qreal rowDescent, Qt::Alignment align) const
+{
+ const qreal cellWidth = width;
+ const qreal cellHeight = height;
+
+ QSizeF size = effectiveMaxSize(QSizeF(-1,-1));
+ if (hasDynamicConstraint()) {
+ if (dynamicConstraintOrientation() == Qt::Vertical) {
+ if (size.width() > cellWidth)
+ size = effectiveMaxSize(QSizeF(cellWidth, -1));
+ } else if (size.height() > cellHeight) {
+ size = effectiveMaxSize(QSizeF(-1, cellHeight));
+ }
+ }
+ size = size.boundedTo(QSizeF(cellWidth, cellHeight));
+ width = size.width();
+ height = size.height();
+
+ switch (align & Qt::AlignHorizontal_Mask) {
+ case Qt::AlignHCenter:
+ x += (cellWidth - width)/2;
+ break;
+ case Qt::AlignRight:
+ x += cellWidth - width;
+ break;
+ default:
+ break;
+ }
+
+ switch (align & Qt::AlignVertical_Mask) {
+ case Qt::AlignVCenter:
+ y += (cellHeight - height)/2;
+ break;
+ case Qt::AlignBottom:
+ y += cellHeight - height;
+ break;
+ case Qt::AlignBaseline: {
+ width = qMin(effectiveMaxSize(QSizeF(-1,-1)).width(), width);
+ QGridLayoutBox vBox = box(Qt::Vertical);
+ const qreal descent = vBox.q_minimumDescent;
+ const qreal ascent = vBox.q_minimumSize - descent;
+ y += (cellHeight - rowDescent - ascent);
+ height = ascent + descent;
+ break; }
+ default:
+ break;
+ }
+ return QRectF(x, y, width, height);
+}
+
+void QGridLayoutItem::transpose()
+{
+ qSwap(q_firstRows[Hor], q_firstRows[Ver]);
+ qSwap(q_rowSpans[Hor], q_rowSpans[Ver]);
+ qSwap(q_stretches[Hor], q_stretches[Ver]);
+}
+
+void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation orientation)
+{
+ int oldFirstRow = firstRow(orientation);
+ if (oldFirstRow >= row) {
+ setFirstRow(oldFirstRow + delta, orientation);
+ } else if (lastRow(orientation) >= row) {
+ setRowSpan(rowSpan(orientation) + delta, orientation);
+ }
+}
+/*!
+ \internal
+ returns the effective maximumSize, will take the sizepolicy into
+ consideration. (i.e. if sizepolicy does not have QLayoutPolicy::Grow, then
+ maxSizeHint will be the preferredSize)
+ Note that effectiveSizeHint does not take sizePolicy into consideration,
+ (since it only evaluates the hints, as the name implies)
+*/
+QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const
+{
+ QSizeF size = constraint;
+ bool vGrow = (sizePolicy(Qt::Vertical) & QLayoutPolicy::GrowFlag) == QLayoutPolicy::GrowFlag;
+ bool hGrow = (sizePolicy(Qt::Horizontal) & QLayoutPolicy::GrowFlag) == QLayoutPolicy::GrowFlag;
+ if (!vGrow || !hGrow) {
+ QSizeF pref = sizeHint(Qt::PreferredSize, constraint);
+ if (!vGrow)
+ size.setHeight(pref.height());
+ if (!hGrow)
+ size.setWidth(pref.width());
+ }
+
+ if (!size.isValid()) {
+ QSizeF maxSize = sizeHint(Qt::MaximumSize, size);
+ if (size.width() == -1)
+ size.setWidth(maxSize.width());
+ if (size.height() == -1)
+ size.setHeight(maxSize.height());
+ }
+ return size;
+}
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+void QGridLayoutItem::dump(int indent) const
+{
+ qDebug("%*s (%d, %d) %d x %d", indent, "", firstRow(), firstColumn(), //###
+ rowSpan(), columnSpan());
+
+ if (q_stretches[Hor] >= 0)
+ qDebug("%*s Horizontal stretch: %d", indent, "", q_stretches[Hor]);
+ if (q_stretches[Ver] >= 0)
+ qDebug("%*s Vertical stretch: %d", indent, "", q_stretches[Ver]);
+ if (q_alignment != 0)
+ qDebug("%*s Alignment: %x", indent, "", uint(q_alignment));
+ qDebug("%*s Horizontal size policy: %x Vertical size policy: %x",
+ indent, "", sizePolicy(Qt::Horizontal), sizePolicy(Qt::Vertical));
+}
+#endif
+
+void QGridLayoutRowInfo::insertOrRemoveRows(int row, int delta)
+{
+ count += delta;
+
+ insertOrRemoveItems(stretches, row, delta);
+ insertOrRemoveItems(spacings, row, delta);
+ insertOrRemoveItems(alignments, row, delta);
+ insertOrRemoveItems(boxes, row, delta);
+}
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+void QGridLayoutRowInfo::dump(int indent) const
+{
+ qDebug("%*sInfo (count: %d)", indent, "", count);
+ for (int i = 0; i < count; ++i) {
+ QString message;
+
+ if (stretches.value(i).value() >= 0)
+ message += QString::fromLatin1(" stretch %1").arg(stretches.value(i).value());
+ if (spacings.value(i).value() >= 0.0)
+ message += QString::fromLatin1(" spacing %1").arg(spacings.value(i).value());
+ if (alignments.value(i) != 0)
+ message += QString::fromLatin1(" alignment %1").arg(int(alignments.value(i)), 16);
+
+ if (!message.isEmpty() || boxes.value(i) != QGridLayoutBox()) {
+ qDebug("%*s Row %d:%s", indent, "", i, qPrintable(message));
+ if (boxes.value(i) != QGridLayoutBox())
+ boxes.value(i).dump(indent + 1);
+ }
+ }
+}
+#endif
+
+QGridLayoutEngine::QGridLayoutEngine(Qt::Alignment defaultAlignment)
+{
+ m_visualDirection = Qt::LeftToRight;
+ m_defaultAlignment = defaultAlignment;
+ invalidate();
+}
+
+int QGridLayoutEngine::rowCount(Qt::Orientation orientation) const
+{
+ return q_infos[orientation == Qt::Vertical].count;
+}
+
+int QGridLayoutEngine::columnCount(Qt::Orientation orientation) const
+{
+ return q_infos[orientation == Qt::Horizontal].count;
+}
+
+int QGridLayoutEngine::itemCount() const
+{
+ return q_items.count();
+}
+
+QGridLayoutItem *QGridLayoutEngine::itemAt(int index) const
+{
+ Q_ASSERT(index >= 0 && index < itemCount());
+ return q_items.at(index);
+}
+
+int QGridLayoutEngine::effectiveFirstRow(Qt::Orientation orientation) const
+{
+ ensureEffectiveFirstAndLastRows();
+ return q_cachedEffectiveFirstRows[orientation == Qt::Vertical];
+}
+
+int QGridLayoutEngine::effectiveLastRow(Qt::Orientation orientation) const
+{
+ ensureEffectiveFirstAndLastRows();
+ return q_cachedEffectiveLastRows[orientation == Qt::Vertical];
+}
+
+void QGridLayoutEngine::setSpacing(qreal spacing, Qt::Orientations orientations)
+{
+ if (orientations & Qt::Horizontal)
+ q_defaultSpacings[Hor].setUserValue(spacing);
+ if (orientations & Qt::Vertical)
+ q_defaultSpacings[Ver].setUserValue(spacing);
+
+ invalidate();
+}
+
+qreal QGridLayoutEngine::spacing(Qt::Orientation orientation, const QAbstractLayoutStyleInfo *styleInfo) const
+{
+ if (!q_defaultSpacings[orientation == Qt::Vertical].isUser()) {
+ qreal defaultSpacing = styleInfo->spacing(orientation);
+ q_defaultSpacings[orientation == Qt::Vertical].setCachedValue(defaultSpacing);
+ }
+ return q_defaultSpacings[orientation == Qt::Vertical].value();
+}
+
+void QGridLayoutEngine::setRowSpacing(int row, qreal spacing, Qt::Orientation orientation)
+{
+ Q_ASSERT(row >= 0);
+
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
+ if (row >= rowInfo.spacings.count())
+ rowInfo.spacings.resize(row + 1);
+ if (spacing >= 0)
+ rowInfo.spacings[row].setUserValue(spacing);
+ else
+ rowInfo.spacings[row] = QLayoutParameter<qreal>();
+ invalidate();
+}
+
+qreal QGridLayoutEngine::rowSpacing(int row, Qt::Orientation orientation) const
+{
+ QLayoutParameter<qreal> spacing = q_infos[orientation == Qt::Vertical].spacings.value(row);
+ if (!spacing.isDefault())
+ return spacing.value();
+ return q_defaultSpacings[orientation == Qt::Vertical].value();
+}
+
+void QGridLayoutEngine::setRowStretchFactor(int row, int stretch, Qt::Orientation orientation)
+{
+ Q_ASSERT(row >= 0);
+ Q_ASSERT(stretch >= 0);
+
+ maybeExpandGrid(row, -1, orientation);
+
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
+ if (row >= rowInfo.stretches.count())
+ rowInfo.stretches.resize(row + 1);
+ rowInfo.stretches[row].setUserValue(stretch);
+}
+
+int QGridLayoutEngine::rowStretchFactor(int row, Qt::Orientation orientation) const
+{
+ QStretchParameter stretch = q_infos[orientation == Qt::Vertical].stretches.value(row);
+ if (!stretch.isDefault())
+ return stretch.value();
+ return 0;
+}
+
+void QGridLayoutEngine::setRowSizeHint(Qt::SizeHint which, int row, qreal size,
+ Qt::Orientation orientation)
+{
+ Q_ASSERT(row >= 0);
+ Q_ASSERT(size >= 0.0);
+
+ maybeExpandGrid(row, -1, orientation);
+
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
+ if (row >= rowInfo.boxes.count())
+ rowInfo.boxes.resize(row + 1);
+ rowInfo.boxes[row].q_sizes(which) = size;
+}
+
+qreal QGridLayoutEngine::rowSizeHint(Qt::SizeHint which, int row, Qt::Orientation orientation) const
+{
+ return q_infos[orientation == Qt::Vertical].boxes.value(row).q_sizes(which);
+}
+
+void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment,
+ Qt::Orientation orientation)
+{
+ Q_ASSERT(row >= 0);
+
+ maybeExpandGrid(row, -1, orientation);
+
+ QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
+ if (row >= rowInfo.alignments.count())
+ rowInfo.alignments.resize(row + 1);
+ rowInfo.alignments[row] = alignment;
+}
+
+Qt::Alignment QGridLayoutEngine::rowAlignment(int row, Qt::Orientation orientation) const
+{
+ Q_ASSERT(row >= 0);
+ return q_infos[orientation == Qt::Vertical].alignments.value(row);
+}
+
+Qt::Alignment QGridLayoutEngine::effectiveAlignment(const QGridLayoutItem *layoutItem) const
+{
+ Qt::Alignment align = layoutItem->alignment();
+ if (!(align & Qt::AlignVertical_Mask)) {
+ // no vertical alignment, respect the row alignment
+ int y = layoutItem->firstRow();
+ align |= (rowAlignment(y, Qt::Vertical) & Qt::AlignVertical_Mask);
+ if (!(align & Qt::AlignVertical_Mask))
+ align |= (m_defaultAlignment & Qt::AlignVertical_Mask);
+ }
+ if (!(align & Qt::AlignHorizontal_Mask)) {
+ // no horizontal alignment, respect the column alignment
+ int x = layoutItem->firstColumn();
+ align |= (rowAlignment(x, Qt::Horizontal) & Qt::AlignHorizontal_Mask);
+ }
+
+ return align;
+}
+
+/*!
+ \internal
+ The \a index is only used by QGraphicsLinearLayout to ensure that itemAt() reflects the order
+ of visual arrangement. Strictly speaking it does not have to, but most people expect it to.
+ (And if it didn't we would have to add itemArrangedAt(int index) or something..)
+ */
+void QGridLayoutEngine::insertItem(QGridLayoutItem *item, int index)
+{
+ maybeExpandGrid(item->lastRow(), item->lastColumn());
+
+ if (index == -1)
+ q_items.append(item);
+ else
+ q_items.insert(index, item);
+
+ for (int i = item->firstRow(); i <= item->lastRow(); ++i) {
+ for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) {
+ if (itemAt(i, j))
+ qWarning("QGridLayoutEngine::addItem: Cell (%d, %d) already taken", i, j);
+ setItemAt(i, j, item);
+ }
+ }
+}
+
+void QGridLayoutEngine::addItem(QGridLayoutItem *item)
+{
+ insertItem(item, -1);
+}
+
+void QGridLayoutEngine::removeItem(QGridLayoutItem *item)
+{
+ Q_ASSERT(q_items.contains(item));
+
+ invalidate();
+
+ for (int i = item->firstRow(); i <= item->lastRow(); ++i) {
+ for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) {
+ if (itemAt(i, j) == item)
+ setItemAt(i, j, 0);
+ }
+ }
+
+ q_items.removeAll(item);
+}
+
+
+QGridLayoutItem *QGridLayoutEngine::itemAt(int row, int column, Qt::Orientation orientation) const
+{
+ if (orientation == Qt::Horizontal)
+ qSwap(row, column);
+ if (uint(row) >= uint(rowCount()) || uint(column) >= uint(columnCount()))
+ return 0;
+ return q_grid.at((row * internalGridColumnCount()) + column);
+}
+
+void QGridLayoutEngine::invalidate()
+{
+ q_cachedEffectiveFirstRows[Hor] = -1;
+ q_cachedEffectiveFirstRows[Ver] = -1;
+ q_cachedEffectiveLastRows[Hor] = -1;
+ q_cachedEffectiveLastRows[Ver] = -1;
+ q_totalBoxesValid = false;
+ q_sizeHintValid[Hor] = false;
+ q_sizeHintValid[Ver] = false;
+ q_cachedSize = QSizeF();
+ q_cachedConstraintOrientation = UnknownConstraint;
+}
+
+static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect)
+{
+ if (dir == Qt::RightToLeft)
+ geom->moveRight(contentsRect.right() - (geom->left() - contentsRect.left()));
+}
+
+void QGridLayoutEngine::setGeometries(const QRectF &contentsGeometry, const QAbstractLayoutStyleInfo *styleInfo)
+{
+ if (rowCount() < 1 || columnCount() < 1)
+ return;
+
+ ensureGeometries(contentsGeometry.size(), styleInfo);
+
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ QGridLayoutItem *item = q_items.at(i);
+
+ qreal x = q_xx[item->firstColumn()];
+ qreal y = q_yy[item->firstRow()];
+ qreal width = q_widths[item->lastColumn()];
+ qreal height = q_heights[item->lastRow()];
+
+ if (item->columnSpan() != 1)
+ width += q_xx[item->lastColumn()] - x;
+ if (item->rowSpan() != 1)
+ height += q_yy[item->lastRow()] - y;
+
+ QRectF geom = item->geometryWithin(contentsGeometry.x() + x, contentsGeometry.y() + y,
+ width, height, q_descents[item->lastRow()], effectiveAlignment(item));
+ visualRect(&geom, visualDirection(), contentsGeometry);
+ item->setGeometry(geom);
+ }
+}
+
+// ### candidate for deletion
+QRectF QGridLayoutEngine::cellRect(const QRectF &contentsGeometry, int row, int column, int rowSpan,
+ int columnSpan, const QAbstractLayoutStyleInfo *styleInfo) const
+{
+ if (uint(row) >= uint(rowCount()) || uint(column) >= uint(columnCount())
+ || rowSpan < 1 || columnSpan < 1)
+ return QRectF();
+
+ ensureGeometries(contentsGeometry.size(), styleInfo);
+
+ int lastColumn = qMax(column + columnSpan, columnCount()) - 1;
+ int lastRow = qMax(row + rowSpan, rowCount()) - 1;
+
+ qreal x = q_xx[column];
+ qreal y = q_yy[row];
+ qreal width = q_widths[lastColumn];
+ qreal height = q_heights[lastRow];
+
+ if (columnSpan != 1)
+ width += q_xx[lastColumn] - x;
+ if (rowSpan != 1)
+ height += q_yy[lastRow] - y;
+
+ return QRectF(contentsGeometry.x() + x, contentsGeometry.y() + y, width, height);
+}
+
+QSizeF QGridLayoutEngine::sizeHint(Qt::SizeHint which, const QSizeF &constraint,
+ const QAbstractLayoutStyleInfo *styleInfo) const
+{
+
+
+ if (hasDynamicConstraint() && rowCount() > 0 && columnCount() > 0) {
+ QGridLayoutBox sizehint_totalBoxes[NOrientations];
+ bool sizeHintCalculated = false;
+ if (constraintOrientation() == Qt::Vertical) {
+ //We have items whose height depends on their width
+ if (constraint.width() >= 0) {
+ ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], NULL, NULL, Qt::Horizontal, styleInfo);
+ QVector<qreal> sizehint_xx;
+ QVector<qreal> sizehint_widths;
+
+ sizehint_xx.resize(columnCount());
+ sizehint_widths.resize(columnCount());
+ qreal width = constraint.width();
+ //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
+ //constraints to find the row heights
+ q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(),
+ 0, sizehint_totalBoxes[Hor], q_infos[Hor]);
+ ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical, styleInfo);
+ sizeHintCalculated = true;
+ }
+ } else {
+ if (constraint.height() >= 0) {
+ //We have items whose width depends on their height
+ ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo);
+ QVector<qreal> sizehint_yy;
+ QVector<qreal> sizehint_heights;
+
+ sizehint_yy.resize(rowCount());
+ sizehint_heights.resize(rowCount());
+ qreal height = constraint.height();
+ //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
+ //constraints to find the column widths
+ q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(),
+ 0, sizehint_totalBoxes[Ver], q_infos[Ver]);
+ ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal, styleInfo);
+ sizeHintCalculated = true;
+ }
+ }
+ if (sizeHintCalculated)
+ return QSizeF(sizehint_totalBoxes[Hor].q_sizes(which), sizehint_totalBoxes[Ver].q_sizes(which));
+ }
+
+ //No items with height for width, so it doesn't matter which order we do these in
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], NULL, NULL, Qt::Horizontal, styleInfo);
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo);
+ return QSizeF(q_totalBoxes[Hor].q_sizes(which), q_totalBoxes[Ver].q_sizes(which));
+}
+
+QLayoutPolicy::ControlTypes QGridLayoutEngine::controlTypes(LayoutSide side) const
+{
+ Qt::Orientation orientation = (side == Top || side == Bottom) ? Qt::Vertical : Qt::Horizontal;
+ int row = (side == Top || side == Left) ? effectiveFirstRow(orientation)
+ : effectiveLastRow(orientation);
+ QLayoutPolicy::ControlTypes result = 0;
+
+ for (int column = columnCount(orientation) - 1; column >= 0; --column) {
+ if (QGridLayoutItem *item = itemAt(row, column, orientation))
+ result |= item->controlTypes(side);
+ }
+ return result;
+}
+
+void QGridLayoutEngine::transpose()
+{
+ invalidate();
+
+ for (int i = q_items.count() - 1; i >= 0; --i)
+ q_items.at(i)->transpose();
+
+ qSwap(q_defaultSpacings[Hor], q_defaultSpacings[Ver]);
+ qSwap(q_infos[Hor], q_infos[Ver]);
+
+ regenerateGrid();
+}
+
+void QGridLayoutEngine::setVisualDirection(Qt::LayoutDirection direction)
+{
+ m_visualDirection = direction;
+}
+
+Qt::LayoutDirection QGridLayoutEngine::visualDirection() const
+{
+ return m_visualDirection;
+}
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+void QGridLayoutEngine::dump(int indent) const
+{
+ qDebug("%*sEngine", indent, "");
+
+ qDebug("%*s Items (%d)", indent, "", q_items.count());
+ int i;
+ for (i = 0; i < q_items.count(); ++i)
+ q_items.at(i)->dump(indent + 2);
+
+ qDebug("%*s Grid (%d x %d)", indent, "", internalGridRowCount(),
+ internalGridColumnCount());
+ for (int row = 0; row < internalGridRowCount(); ++row) {
+ QString message = QLatin1String("[ ");
+ for (int column = 0; column < internalGridColumnCount(); ++column) {
+ message += QString::number(q_items.indexOf(itemAt(row, column))).rightJustified(3);
+ message += QLatin1Char(' ');
+ }
+ message += QLatin1Char(']');
+ qDebug("%*s %s", indent, "", qPrintable(message));
+ }
+
+ if (q_defaultSpacings[Hor].value() >= 0.0 || q_defaultSpacings[Ver].value() >= 0.0)
+ qDebug("%*s Default spacings: %g %g", indent, "", q_defaultSpacings[Hor].value(),
+ q_defaultSpacings[Ver].value());
+
+ qDebug("%*s Column and row info", indent, "");
+ q_infos[Hor].dump(indent + 2);
+ q_infos[Ver].dump(indent + 2);
+
+ qDebug("%*s Column and row data", indent, "");
+ q_columnData.dump(indent + 2);
+ q_rowData.dump(indent + 2);
+
+ qDebug("%*s Geometries output", indent, "");
+ QVector<qreal> *cellPos = &q_yy;
+ for (int pass = 0; pass < 2; ++pass) {
+ QString message;
+ for (i = 0; i < cellPos->count(); ++i) {
+ message += QLatin1String((message.isEmpty() ? "[" : ", "));
+ message += QString::number(cellPos->at(i));
+ }
+ message += QLatin1Char(']');
+ qDebug("%*s %s %s", indent, "", (pass == 0 ? "rows:" : "columns:"), qPrintable(message));
+ cellPos = &q_xx;
+ }
+}
+#endif
+
+void QGridLayoutEngine::maybeExpandGrid(int row, int column, Qt::Orientation orientation)
+{
+ invalidate(); // ### move out of here?
+
+ if (orientation == Qt::Horizontal)
+ qSwap(row, column);
+
+ if (row < rowCount() && column < columnCount())
+ return;
+
+ int oldGridRowCount = internalGridRowCount();
+ int oldGridColumnCount = internalGridColumnCount();
+
+ q_infos[Ver].count = qMax(row + 1, rowCount());
+ q_infos[Hor].count = qMax(column + 1, columnCount());
+
+ int newGridRowCount = internalGridRowCount();
+ int newGridColumnCount = internalGridColumnCount();
+
+ int newGridSize = newGridRowCount * newGridColumnCount;
+ if (newGridSize != q_grid.count()) {
+ q_grid.resize(newGridSize);
+
+ if (newGridColumnCount != oldGridColumnCount) {
+ for (int i = oldGridRowCount - 1; i >= 1; --i) {
+ for (int j = oldGridColumnCount - 1; j >= 0; --j) {
+ int oldIndex = (i * oldGridColumnCount) + j;
+ int newIndex = (i * newGridColumnCount) + j;
+
+ Q_ASSERT(newIndex > oldIndex);
+ q_grid[newIndex] = q_grid[oldIndex];
+ q_grid[oldIndex] = 0;
+ }
+ }
+ }
+ }
+}
+
+void QGridLayoutEngine::regenerateGrid()
+{
+ q_grid.fill(0);
+
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ QGridLayoutItem *item = q_items.at(i);
+
+ for (int j = item->firstRow(); j <= item->lastRow(); ++j) {
+ for (int k = item->firstColumn(); k <= item->lastColumn(); ++k) {
+ setItemAt(j, k, item);
+ }
+ }
+ }
+}
+
+void QGridLayoutEngine::setItemAt(int row, int column, QGridLayoutItem *item)
+{
+ Q_ASSERT(row >= 0 && row < rowCount());
+ Q_ASSERT(column >= 0 && column < columnCount());
+ q_grid[(row * internalGridColumnCount()) + column] = item;
+}
+
+void QGridLayoutEngine::insertOrRemoveRows(int row, int delta, Qt::Orientation orientation)
+{
+ int oldRowCount = rowCount(orientation);
+ Q_ASSERT(uint(row) <= uint(oldRowCount));
+
+ invalidate();
+
+ // appending rows (or columns) is easy
+ if (row == oldRowCount && delta > 0) {
+ maybeExpandGrid(oldRowCount + delta - 1, -1, orientation);
+ return;
+ }
+
+ q_infos[orientation == Qt::Vertical].insertOrRemoveRows(row, delta);
+
+ for (int i = q_items.count() - 1; i >= 0; --i)
+ q_items.at(i)->insertOrRemoveRows(row, delta, orientation);
+
+ q_grid.resize(internalGridRowCount() * internalGridColumnCount());
+ regenerateGrid();
+}
+
+void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData,
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const
+{
+ const int ButtonMask = QLayoutPolicy::ButtonBox | QLayoutPolicy::PushButton;
+ const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
+ const QGridLayoutRowInfo &columnInfo = q_infos[orientation == Qt::Horizontal];
+ LayoutSide top = (orientation == Qt::Vertical) ? Top : Left;
+ LayoutSide bottom = (orientation == Qt::Vertical) ? Bottom : Right;
+
+ const QLayoutParameter<qreal> &defaultSpacing = q_defaultSpacings[orientation == Qt::Vertical];
+ qreal innerSpacing = styleInfo->spacing(orientation);
+ if (innerSpacing >= 0.0)
+ defaultSpacing.setCachedValue(innerSpacing);
+
+ for (int row = 0; row < rowInfo.count; ++row) {
+ bool rowIsEmpty = true;
+ bool rowIsIdenticalToPrevious = (row > 0);
+
+ for (int column = 0; column < columnInfo.count; ++column) {
+ QGridLayoutItem *item = itemAt(row, column, orientation);
+
+ if (rowIsIdenticalToPrevious && item != itemAt(row - 1, column, orientation))
+ rowIsIdenticalToPrevious = false;
+
+ if (item)
+ rowIsEmpty = false;
+ }
+
+ if ((rowIsEmpty || rowIsIdenticalToPrevious)
+ && rowInfo.spacings.value(row).isDefault()
+ && rowInfo.stretches.value(row).isDefault()
+ && rowInfo.boxes.value(row) == QGridLayoutBox())
+ rowData->ignore.setBit(row, true);
+
+ if (rowInfo.spacings.value(row).isUser()) {
+ rowData->spacings[row] = rowInfo.spacings.at(row).value();
+ } else if (!defaultSpacing.isDefault()) {
+ rowData->spacings[row] = defaultSpacing.value();
+ }
+
+ rowData->stretches[row] = rowInfo.stretches.value(row).value();
+ }
+
+ struct RowAdHocData {
+ int q_row;
+ unsigned int q_hasButtons : 8;
+ unsigned int q_hasNonButtons : 8;
+
+ inline RowAdHocData() : q_row(-1), q_hasButtons(false), q_hasNonButtons(false) {}
+ inline void init(int row) {
+ this->q_row = row;
+ q_hasButtons = false;
+ q_hasNonButtons = false;
+ }
+ inline bool hasOnlyButtons() const { return q_hasButtons && !q_hasNonButtons; }
+ inline bool hasOnlyNonButtons() const { return q_hasNonButtons && !q_hasButtons; }
+ };
+ RowAdHocData lastRowAdHocData;
+ RowAdHocData nextToLastRowAdHocData;
+ RowAdHocData nextToNextToLastRowAdHocData;
+
+ rowData->hasIgnoreFlag = false;
+ for (int row = 0; row < rowInfo.count; ++row) {
+ if (rowData->ignore.testBit(row))
+ continue;
+
+ QGridLayoutBox &rowBox = rowData->boxes[row];
+ if (styleInfo->isWindow()) {
+ nextToNextToLastRowAdHocData = nextToLastRowAdHocData;
+ nextToLastRowAdHocData = lastRowAdHocData;
+ lastRowAdHocData.init(row);
+ }
+
+ bool userRowStretch = rowInfo.stretches.value(row).isUser();
+ int &rowStretch = rowData->stretches[row];
+
+ bool hasIgnoreFlag = true;
+ for (int column = 0; column < columnInfo.count; ++column) {
+ QGridLayoutItem *item = itemAt(row, column, orientation);
+ if (item) {
+ int itemRow = item->firstRow(orientation);
+ int itemColumn = item->firstColumn(orientation);
+
+ if (itemRow == row && itemColumn == column) {
+ int itemStretch = item->stretchFactor(orientation);
+ if (!(item->sizePolicy(orientation) & QLayoutPolicy::IgnoreFlag))
+ hasIgnoreFlag = false;
+ int itemRowSpan = item->rowSpan(orientation);
+
+ int effectiveRowSpan = 1;
+ for (int i = 1; i < itemRowSpan; ++i) {
+ if (!rowData->ignore.testBit(i + itemRow))
+ ++effectiveRowSpan;
+ }
+
+ QGridLayoutBox *box;
+ if (effectiveRowSpan == 1) {
+ box = &rowBox;
+ if (!userRowStretch && itemStretch != 0)
+ rowStretch = qMax(rowStretch, itemStretch);
+ } else {
+ QGridLayoutMultiCellData &multiCell =
+ rowData->multiCellMap[qMakePair(row, effectiveRowSpan)];
+ box = &multiCell.q_box;
+ multiCell.q_stretch = itemStretch;
+ }
+ // Items with constraints need to be passed the constraint
+ if (colSizes && colPositions && item->hasDynamicConstraint() && orientation == item->dynamicConstraintOrientation()) {
+ /* Get the width of the item by summing up the widths of the columns that it spans.
+ * We need to have already calculated the widths of the columns by calling
+ * q_columns->calculateGeometries() before hand and passing the value in the colSizes
+ * and colPositions parameters.
+ * The variable name is still colSizes even when it actually has the row sizes
+ */
+ qreal length = colSizes[item->lastColumn(orientation)];
+ if (item->columnSpan(orientation) != 1)
+ length += colPositions[item->lastColumn(orientation)] - colPositions[item->firstColumn(orientation)];
+ box->combine(item->box(orientation, length));
+ } else {
+ box->combine(item->box(orientation));
+ }
+
+ if (effectiveRowSpan == 1) {
+ QLayoutPolicy::ControlTypes controls = item->controlTypes(top);
+ if (controls & ButtonMask)
+ lastRowAdHocData.q_hasButtons = true;
+ if (controls & ~ButtonMask)
+ lastRowAdHocData.q_hasNonButtons = true;
+ }
+ }
+ }
+ }
+ if (row < rowInfo.boxes.count()) {
+ QGridLayoutBox rowBoxInfo = rowInfo.boxes.at(row);
+ rowBoxInfo.normalize();
+ rowBox.q_minimumSize = qMax(rowBox.q_minimumSize, rowBoxInfo.q_minimumSize);
+ rowBox.q_maximumSize = qMax(rowBox.q_minimumSize,
+ (rowBoxInfo.q_maximumSize != FLT_MAX ?
+ rowBoxInfo.q_maximumSize : rowBox.q_maximumSize));
+ rowBox.q_preferredSize = qBound(rowBox.q_minimumSize,
+ qMax(rowBox.q_preferredSize, rowBoxInfo.q_preferredSize),
+ rowBox.q_maximumSize);
+ }
+ if (hasIgnoreFlag)
+ rowData->hasIgnoreFlag = true;
+ }
+
+ /*
+ Heuristic: Detect button boxes that don't use QLayoutPolicy::ButtonBox.
+ This is somewhat ad hoc but it usually does the trick.
+ */
+ bool lastRowIsButtonBox = (lastRowAdHocData.hasOnlyButtons()
+ && nextToLastRowAdHocData.hasOnlyNonButtons());
+ bool lastTwoRowsIsButtonBox = (lastRowAdHocData.hasOnlyButtons()
+ && nextToLastRowAdHocData.hasOnlyButtons()
+ && nextToNextToLastRowAdHocData.hasOnlyNonButtons()
+ && orientation == Qt::Vertical);
+
+ if (defaultSpacing.isDefault()) {
+ int prevRow = -1;
+ for (int row = 0; row < rowInfo.count; ++row) {
+ if (rowData->ignore.testBit(row))
+ continue;
+
+ if (prevRow != -1 && !rowInfo.spacings.value(prevRow).isUser()) {
+ qreal &rowSpacing = rowData->spacings[prevRow];
+ for (int column = 0; column < columnInfo.count; ++column) {
+ QGridLayoutItem *item1 = itemAt(prevRow, column, orientation);
+ QGridLayoutItem *item2 = itemAt(row, column, orientation);
+
+ if (item1 && item2 && item1 != item2) {
+ QLayoutPolicy::ControlTypes controls1 = item1->controlTypes(bottom);
+ QLayoutPolicy::ControlTypes controls2 = item2->controlTypes(top);
+
+ if (controls2 & QLayoutPolicy::PushButton) {
+ if ((row == nextToLastRowAdHocData.q_row && lastTwoRowsIsButtonBox)
+ || (row == lastRowAdHocData.q_row && lastRowIsButtonBox)) {
+ controls2 &= ~QLayoutPolicy::PushButton;
+ controls2 |= QLayoutPolicy::ButtonBox;
+ }
+ }
+
+ qreal spacing = styleInfo->combinedLayoutSpacing(controls1, controls2,
+ orientation);
+ if (orientation == Qt::Horizontal) {
+ qreal width1 = rowData->boxes.at(prevRow).q_minimumSize;
+ qreal width2 = rowData->boxes.at(row).q_minimumSize;
+ QRectF rect1 = item1->geometryWithin(0.0, 0.0, width1, FLT_MAX, -1.0, effectiveAlignment(item1));
+ QRectF rect2 = item2->geometryWithin(0.0, 0.0, width2, FLT_MAX, -1.0, effectiveAlignment(item2));
+ spacing -= (width1 - (rect1.x() + rect1.width())) + rect2.x();
+ } else {
+ const QGridLayoutBox &box1 = rowData->boxes.at(prevRow);
+ const QGridLayoutBox &box2 = rowData->boxes.at(row);
+ qreal height1 = box1.q_minimumSize;
+ qreal height2 = box2.q_minimumSize;
+ qreal rowDescent1 = fixedDescent(box1.q_minimumDescent,
+ box1.q_minimumAscent, height1);
+ qreal rowDescent2 = fixedDescent(box2.q_minimumDescent,
+ box2.q_minimumAscent, height2);
+ QRectF rect1 = item1->geometryWithin(0.0, 0.0, FLT_MAX, height1,
+ rowDescent1, effectiveAlignment(item1));
+ QRectF rect2 = item2->geometryWithin(0.0, 0.0, FLT_MAX, height2,
+ rowDescent2, effectiveAlignment(item2));
+ spacing -= (height1 - (rect1.y() + rect1.height())) + rect2.y();
+ }
+ rowSpacing = qMax(spacing, rowSpacing);
+ }
+ }
+ }
+ prevRow = row;
+ }
+ } else if (lastRowIsButtonBox || lastTwoRowsIsButtonBox) {
+ /*
+ Even for styles that define a uniform spacing, we cheat a
+ bit and use the window margin as the spacing. This
+ significantly improves the look of dialogs.
+ */
+ int prevRow = lastRowIsButtonBox ? nextToLastRowAdHocData.q_row
+ : nextToNextToLastRowAdHocData.q_row;
+ if (!defaultSpacing.isUser() && !rowInfo.spacings.value(prevRow).isUser()) {
+ qreal windowMargin = styleInfo->windowMargin(orientation);
+ qreal &rowSpacing = rowData->spacings[prevRow];
+ rowSpacing = qMax(windowMargin, rowSpacing);
+ }
+ }
+}
+
+void QGridLayoutEngine::ensureEffectiveFirstAndLastRows() const
+{
+ if (q_cachedEffectiveFirstRows[Hor] == -1 && !q_items.isEmpty()) {
+ int rowCount = this->rowCount();
+ int columnCount = this->columnCount();
+
+ q_cachedEffectiveFirstRows[Ver] = rowCount;
+ q_cachedEffectiveFirstRows[Hor] = columnCount;
+ q_cachedEffectiveLastRows[Ver] = -1;
+ q_cachedEffectiveLastRows[Hor] = -1;
+
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ const QGridLayoutItem *item = q_items.at(i);
+
+ for (int j = 0; j < NOrientations; ++j) {
+ Qt::Orientation orientation = (j == Hor) ? Qt::Horizontal : Qt::Vertical;
+ if (item->firstRow(orientation) < q_cachedEffectiveFirstRows[j])
+ q_cachedEffectiveFirstRows[j] = item->firstRow(orientation);
+ if (item->lastRow(orientation) > q_cachedEffectiveLastRows[j])
+ q_cachedEffectiveLastRows[j] = item->lastRow(orientation);
+ }
+ }
+ }
+}
+
+void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox,
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const
+{
+ const int o = (orientation == Qt::Vertical ? Ver : Hor);
+ if (q_sizeHintValid[o] && !colPositions && !colSizes) {
+ if (totalBox != &q_totalBoxes[o])
+ *totalBox = q_totalBoxes[o];
+ return;
+ }
+ rowData->reset(rowCount(orientation));
+ fillRowData(rowData, colPositions, colSizes, orientation, styleInfo);
+ const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
+ rowData->distributeMultiCells(rowInfo);
+ *totalBox = rowData->totalBox(0, rowCount(orientation));
+
+ if (!colPositions && !colSizes) {
+ q_totalBoxes[o] = *totalBox;
+ q_sizeHintValid[o] = true;
+ }
+}
+
+/**
+ returns false if the layout has contradicting constraints (i.e. some items with a horizontal
+ constraint and other items with a vertical constraint)
+ */
+bool QGridLayoutEngine::ensureDynamicConstraint() const
+{
+ if (q_cachedConstraintOrientation == UnknownConstraint) {
+ for (int i = q_items.count() - 1; i >= 0; --i) {
+ QGridLayoutItem *item = q_items.at(i);
+ if (item->hasDynamicConstraint()) {
+ Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation();
+ if (q_cachedConstraintOrientation == UnknownConstraint) {
+ q_cachedConstraintOrientation = itemConstraintOrientation;
+ } else if (q_cachedConstraintOrientation != itemConstraintOrientation) {
+ q_cachedConstraintOrientation = UnfeasibleConstraint;
+ qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and"
+ " vertical constraint in the same layout");
+ return false;
+ }
+ }
+ }
+ if (q_cachedConstraintOrientation == UnknownConstraint)
+ q_cachedConstraintOrientation = NoConstraint;
+ }
+ return true;
+}
+
+bool QGridLayoutEngine::hasDynamicConstraint() const
+{
+ if (!ensureDynamicConstraint())
+ return false;
+ return q_cachedConstraintOrientation != NoConstraint;
+}
+
+/*
+ * return value is only valid if hasConstraint() returns \c true
+ */
+Qt::Orientation QGridLayoutEngine::constraintOrientation() const
+{
+ (void)ensureDynamicConstraint();
+ return (Qt::Orientation)q_cachedConstraintOrientation;
+}
+
+void QGridLayoutEngine::ensureGeometries(const QSizeF &size,
+ const QAbstractLayoutStyleInfo *styleInfo) const
+{
+ if (!styleInfo->hasChanged() && q_totalBoxesValid && q_cachedSize == size)
+ return;
+
+ q_totalBoxesValid = true;
+ q_cachedSize = size;
+
+ q_xx.resize(columnCount());
+ q_widths.resize(columnCount());
+ q_yy.resize(rowCount());
+ q_heights.resize(rowCount());
+ q_descents.resize(rowCount());
+
+ if (constraintOrientation() != Qt::Horizontal) {
+ //We might have items whose width depends on their height
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], NULL, NULL, Qt::Horizontal, styleInfo);
+ //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
+ //constraints to find the row heights
+ q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
+ 0, q_totalBoxes[Hor], q_infos[Hor] );
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], q_xx.data(), q_widths.data(), Qt::Vertical, styleInfo);
+ //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
+ q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
+ q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
+ } else {
+ //We have items whose height depends on their width
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo);
+ //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
+ //constraints to find the column widths
+ q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
+ q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], q_yy.data(), q_heights.data(), Qt::Horizontal, styleInfo);
+ //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
+ q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
+ 0, q_totalBoxes[Hor], q_infos[Hor]);
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/util/qgridlayoutengine_p.h b/src/gui/util/qgridlayoutengine_p.h
new file mode 100644
index 0000000000..9650e7fffe
--- /dev/null
+++ b/src/gui/util/qgridlayoutengine_p.h
@@ -0,0 +1,473 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRIDLAYOUTENGINE_P_H
+#define QGRIDLAYOUTENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the graphics view layout classes. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qalgorithms.h"
+#include "qbitarray.h"
+#include "qlist.h"
+#include "qmap.h"
+#include "qpair.h"
+#include <QtCore/qvector.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qrect.h>
+#include <float.h>
+#include "qlayoutpolicy_p.h"
+#include "qabstractlayoutstyleinfo_p.h"
+
+// #define QGRIDLAYOUTENGINE_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+class QStyle;
+class QWidget;
+
+// ### deal with Descent in a similar way
+enum {
+ MinimumSize = Qt::MinimumSize,
+ PreferredSize = Qt::PreferredSize,
+ MaximumSize = Qt::MaximumSize,
+ NSizes
+};
+
+// do not reorder
+enum {
+ Hor,
+ Ver,
+ NOrientations
+};
+
+// do not reorder
+enum LayoutSide {
+ Left,
+ Top,
+ Right,
+ Bottom
+};
+
+enum {
+ NoConstraint,
+ HorizontalConstraint, // Width depends on the height
+ VerticalConstraint, // Height depends on the width
+ UnknownConstraint, // need to update cache
+ UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints
+};
+
+template <typename T>
+class QLayoutParameter
+{
+public:
+ enum State { Default, User, Cached };
+
+ inline QLayoutParameter() : q_value(T()), q_state(Default) {}
+ inline QLayoutParameter(T value, State state = Default) : q_value(value), q_state(state) {}
+
+ inline void setUserValue(T value) {
+ q_value = value;
+ q_state = User;
+ }
+ inline void setCachedValue(T value) const {
+ if (q_state != User) {
+ q_value = value;
+ q_state = Cached;
+ }
+ }
+ inline T value() const { return q_value; }
+ inline T value(T defaultValue) const { return isUser() ? q_value : defaultValue; }
+ inline bool isDefault() const { return q_state == Default; }
+ inline bool isUser() const { return q_state == User; }
+ inline bool isCached() const { return q_state == Cached; }
+
+private:
+ mutable T q_value;
+ mutable State q_state;
+};
+
+class QStretchParameter : public QLayoutParameter<int>
+{
+public:
+ QStretchParameter() : QLayoutParameter<int>(-1) {}
+
+};
+
+class Q_GUI_EXPORT QGridLayoutBox
+{
+public:
+ inline QGridLayoutBox()
+ : q_minimumSize(0), q_preferredSize(0), q_maximumSize(FLT_MAX),
+ q_minimumDescent(-1), q_minimumAscent(-1) {}
+
+ void add(const QGridLayoutBox &other, int stretch, qreal spacing);
+ void combine(const QGridLayoutBox &other);
+ void normalize();
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+ void dump(int indent = 0) const;
+#endif
+ // This code could use the union-struct-array trick, but a compiler
+ // bug prevents this from working.
+ qreal q_minimumSize;
+ qreal q_preferredSize;
+ qreal q_maximumSize;
+ qreal q_minimumDescent;
+ qreal q_minimumAscent;
+ inline qreal &q_sizes(int which)
+ {
+ qreal *t;
+ switch (which) {
+ case Qt::MinimumSize:
+ t = &q_minimumSize;
+ break;
+ case Qt::PreferredSize:
+ t = &q_preferredSize;
+ break;
+ case Qt::MaximumSize:
+ t = &q_maximumSize;
+ break;
+ case Qt::MinimumDescent:
+ t = &q_minimumDescent;
+ break;
+ case (Qt::MinimumDescent + 1):
+ t = &q_minimumAscent;
+ break;
+ default:
+ t = 0;
+ break;
+ }
+ return *t;
+ }
+ inline const qreal &q_sizes(int which) const
+ {
+ const qreal *t;
+ switch (which) {
+ case Qt::MinimumSize:
+ t = &q_minimumSize;
+ break;
+ case Qt::PreferredSize:
+ t = &q_preferredSize;
+ break;
+ case Qt::MaximumSize:
+ t = &q_maximumSize;
+ break;
+ case Qt::MinimumDescent:
+ t = &q_minimumDescent;
+ break;
+ case (Qt::MinimumDescent + 1):
+ t = &q_minimumAscent;
+ break;
+ default:
+ t = 0;
+ break;
+ }
+ return *t;
+ }
+};
+
+bool operator==(const QGridLayoutBox &box1, const QGridLayoutBox &box2);
+inline bool operator!=(const QGridLayoutBox &box1, const QGridLayoutBox &box2)
+ { return !operator==(box1, box2); }
+
+class QGridLayoutMultiCellData
+{
+public:
+ inline QGridLayoutMultiCellData() : q_stretch(-1) {}
+
+ QGridLayoutBox q_box;
+ int q_stretch;
+};
+
+typedef QMap<QPair<int, int>, QGridLayoutMultiCellData> MultiCellMap;
+
+class QGridLayoutRowInfo;
+
+class QGridLayoutRowData
+{
+public:
+ void reset(int count);
+ void distributeMultiCells(const QGridLayoutRowInfo &rowInfo);
+ void calculateGeometries(int start, int end, qreal targetSize, qreal *positions, qreal *sizes,
+ qreal *descents, const QGridLayoutBox &totalBox,
+ const QGridLayoutRowInfo &rowInfo);
+ QGridLayoutBox totalBox(int start, int end) const;
+ void stealBox(int start, int end, int which, qreal *positions, qreal *sizes);
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+ void dump(int indent = 0) const;
+#endif
+
+ QBitArray ignore; // ### rename q_
+ QVector<QGridLayoutBox> boxes;
+ MultiCellMap multiCellMap;
+ QVector<int> stretches;
+ QVector<qreal> spacings;
+ bool hasIgnoreFlag;
+};
+
+class QGridLayoutRowInfo
+{
+public:
+ inline QGridLayoutRowInfo() : count(0) {}
+
+ void insertOrRemoveRows(int row, int delta);
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+ void dump(int indent = 0) const;
+#endif
+
+ int count;
+ QVector<QStretchParameter> stretches;
+ QVector<QLayoutParameter<qreal> > spacings;
+ QVector<Qt::Alignment> alignments;
+ QVector<QGridLayoutBox> boxes;
+};
+
+
+class Q_GUI_EXPORT QGridLayoutItem
+{
+public:
+ QGridLayoutItem(int row, int column, int rowSpan = 1, int columnSpan = 1,
+ Qt::Alignment alignment = 0);
+ virtual ~QGridLayoutItem() {}
+
+ inline int firstRow() const { return q_firstRows[Ver]; }
+ inline int firstColumn() const { return q_firstRows[Hor]; }
+ inline int rowSpan() const { return q_rowSpans[Ver]; }
+ inline int columnSpan() const { return q_rowSpans[Hor]; }
+ inline int lastRow() const { return firstRow() + rowSpan() - 1; }
+ inline int lastColumn() const { return firstColumn() + columnSpan() - 1; }
+
+ int firstRow(Qt::Orientation orientation) const;
+ int firstColumn(Qt::Orientation orientation) const;
+ int lastRow(Qt::Orientation orientation) const;
+ int lastColumn(Qt::Orientation orientation) const;
+ int rowSpan(Qt::Orientation orientation) const;
+ int columnSpan(Qt::Orientation orientation) const;
+ void setFirstRow(int row, Qt::Orientation orientation = Qt::Vertical);
+ void setRowSpan(int rowSpan, Qt::Orientation orientation = Qt::Vertical);
+
+ int stretchFactor(Qt::Orientation orientation) const;
+ void setStretchFactor(int stretch, Qt::Orientation orientation);
+
+ inline Qt::Alignment alignment() const { return q_alignment; }
+ inline void setAlignment(Qt::Alignment alignment) { q_alignment = alignment; }
+
+ virtual QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const = 0;
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const = 0;
+
+ virtual void setGeometry(const QRectF &rect) = 0;
+ /*
+ returns true if the size policy returns true for either hasHeightForWidth()
+ or hasWidthForHeight()
+ */
+ virtual bool hasDynamicConstraint() const { return false; }
+ virtual Qt::Orientation dynamicConstraintOrientation() const { return Qt::Horizontal; }
+
+
+ virtual QLayoutPolicy::ControlTypes controlTypes(LayoutSide side) const;
+
+ QRectF geometryWithin(qreal x, qreal y, qreal width, qreal height, qreal rowDescent, Qt::Alignment align) const;
+ QGridLayoutBox box(Qt::Orientation orientation, qreal constraint = -1.0) const;
+
+
+ void transpose();
+ void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical);
+ QSizeF effectiveMaxSize(const QSizeF &constraint) const;
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+ void dump(int indent = 0) const;
+#endif
+
+private:
+ int q_firstRows[NOrientations];
+ int q_rowSpans[NOrientations];
+ int q_stretches[NOrientations];
+ Qt::Alignment q_alignment;
+
+};
+
+class Q_GUI_EXPORT QGridLayoutEngine
+{
+public:
+ QGridLayoutEngine(Qt::Alignment defaultAlignment = Qt::Alignment(0));
+ inline ~QGridLayoutEngine() { qDeleteAll(q_items); }
+
+ int rowCount(Qt::Orientation orientation) const;
+ int columnCount(Qt::Orientation orientation) const;
+ inline int rowCount() const { return q_infos[Ver].count; }
+ inline int columnCount() const { return q_infos[Hor].count; }
+ // returns the number of items inserted, which may be less than (rowCount * columnCount)
+ int itemCount() const;
+ QGridLayoutItem *itemAt(int index) const;
+
+ int effectiveFirstRow(Qt::Orientation orientation = Qt::Vertical) const;
+ int effectiveLastRow(Qt::Orientation orientation = Qt::Vertical) const;
+
+ void setSpacing(qreal spacing, Qt::Orientations orientations);
+ qreal spacing(Qt::Orientation orientation, const QAbstractLayoutStyleInfo *styleInfo) const;
+ // ### setSpacingAfterRow(), spacingAfterRow()
+ void setRowSpacing(int row, qreal spacing, Qt::Orientation orientation = Qt::Vertical);
+ qreal rowSpacing(int row, Qt::Orientation orientation = Qt::Vertical) const;
+
+ void setRowStretchFactor(int row, int stretch, Qt::Orientation orientation = Qt::Vertical);
+ int rowStretchFactor(int row, Qt::Orientation orientation = Qt::Vertical) const;
+
+ void setRowSizeHint(Qt::SizeHint which, int row, qreal size,
+ Qt::Orientation orientation = Qt::Vertical);
+ qreal rowSizeHint(Qt::SizeHint which, int row,
+ Qt::Orientation orientation = Qt::Vertical) const;
+
+ void setRowAlignment(int row, Qt::Alignment alignment, Qt::Orientation orientation);
+ Qt::Alignment rowAlignment(int row, Qt::Orientation orientation) const;
+
+ Qt::Alignment effectiveAlignment(const QGridLayoutItem *layoutItem) const;
+
+
+ void insertItem(QGridLayoutItem *item, int index);
+ void addItem(QGridLayoutItem *item);
+ void removeItem(QGridLayoutItem *item);
+ void deleteItems()
+ {
+ const QList<QGridLayoutItem *> oldItems = q_items;
+ q_items.clear(); // q_items are used as input when the grid is regenerated in removeRows
+ // The following calls to removeRows are suboptimal
+ int rows = rowCount(Qt::Vertical);
+ removeRows(0, rows, Qt::Vertical);
+ rows = rowCount(Qt::Horizontal);
+ removeRows(0, rows, Qt::Horizontal);
+ qDeleteAll(oldItems);
+ }
+
+ QGridLayoutItem *itemAt(int row, int column, Qt::Orientation orientation = Qt::Vertical) const;
+ inline void insertRow(int row, Qt::Orientation orientation = Qt::Vertical)
+ { insertOrRemoveRows(row, +1, orientation); }
+ inline void removeRows(int row, int count, Qt::Orientation orientation)
+ { insertOrRemoveRows(row, -count, orientation); }
+
+ void invalidate();
+ void setGeometries(const QRectF &contentsGeometry, const QAbstractLayoutStyleInfo *styleInfo);
+ QRectF cellRect(const QRectF &contentsGeometry, int row, int column, int rowSpan, int columnSpan,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
+
+ // heightForWidth / widthForHeight support
+ QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
+ bool ensureDynamicConstraint() const;
+ bool hasDynamicConstraint() const;
+ Qt::Orientation constraintOrientation() const;
+
+
+ QLayoutPolicy::ControlTypes controlTypes(LayoutSide side) const;
+ void transpose();
+ void setVisualDirection(Qt::LayoutDirection direction);
+ Qt::LayoutDirection visualDirection() const;
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+ void dump(int indent = 0) const;
+#endif
+
+private:
+ static int grossRoundUp(int n) { return ((n + 2) | 0x3) - 2; }
+
+ void maybeExpandGrid(int row, int column, Qt::Orientation orientation = Qt::Vertical);
+ void regenerateGrid();
+ inline int internalGridRowCount() const { return grossRoundUp(rowCount()); }
+ inline int internalGridColumnCount() const { return grossRoundUp(columnCount()); }
+ void setItemAt(int row, int column, QGridLayoutItem *item);
+ void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical);
+ void fillRowData(QGridLayoutRowData *rowData,
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
+ void ensureEffectiveFirstAndLastRows() const;
+ void ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox,
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
+
+ void ensureGeometries(const QSizeF &size, const QAbstractLayoutStyleInfo *styleInfo) const;
+protected:
+ QList<QGridLayoutItem *> q_items;
+private:
+ // User input
+ QVector<QGridLayoutItem *> q_grid;
+ QLayoutParameter<qreal> q_defaultSpacings[NOrientations];
+ QGridLayoutRowInfo q_infos[NOrientations];
+ Qt::LayoutDirection m_visualDirection;
+ Qt::Alignment m_defaultAlignment;
+
+ // Lazily computed from the above user input
+ mutable int q_cachedEffectiveFirstRows[NOrientations];
+ mutable int q_cachedEffectiveLastRows[NOrientations];
+ mutable quint8 q_cachedConstraintOrientation : 3;
+
+ // Layout item input
+ mutable QGridLayoutRowData q_columnData;
+ mutable QGridLayoutRowData q_rowData;
+ mutable QGridLayoutBox q_totalBoxes[NOrientations];
+
+ // Output
+ mutable QSizeF q_cachedSize;
+ mutable bool q_totalBoxesValid;
+ mutable bool q_sizeHintValid[NOrientations];
+ mutable QVector<qreal> q_xx;
+ mutable QVector<qreal> q_yy;
+ mutable QVector<qreal> q_widths;
+ mutable QVector<qreal> q_heights;
+ mutable QVector<qreal> q_descents;
+
+ friend class QGridLayoutItem;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/util/qlayoutpolicy.cpp b/src/gui/util/qlayoutpolicy.cpp
new file mode 100644
index 0000000000..9a154768eb
--- /dev/null
+++ b/src/gui/util/qlayoutpolicy.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Layouts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlayoutpolicy_p.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_NAMESPACE
+
+void QLayoutPolicy::setControlType(ControlType type)
+{
+ /*
+ The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
+ etc. In memory, we pack it onto the available bits (CTSize) in
+ setControlType(), and unpack it here.
+
+ Example:
+
+ 0x00000001 maps to 0
+ 0x00000002 maps to 1
+ 0x00000004 maps to 2
+ 0x00000008 maps to 3
+ etc.
+ */
+
+ int i = 0;
+ while (true) {
+ if (type & (0x1 << i)) {
+ bits.ctype = i;
+ return;
+ }
+ ++i;
+ }
+}
+
+QLayoutPolicy::ControlType QLayoutPolicy::controlType() const
+{
+ return QLayoutPolicy::ControlType(1 << bits.ctype);
+}
+
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ \relates QLayoutPolicy
+
+ Writes the size \a policy to the data stream \a stream.
+
+ \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
+*/
+QDataStream &operator<<(QDataStream &stream, const QLayoutPolicy &policy)
+{
+ // The order here is for historical reasons. (compatibility with Qt4)
+ quint32 data = (policy.bits.horPolicy | // [0, 3]
+ policy.bits.verPolicy << 4 | // [4, 7]
+ policy.bits.hfw << 8 | // [8]
+ policy.bits.ctype << 9 | // [9, 13]
+ policy.bits.wfh << 14 | // [14]
+ //policy.bits.padding << 15 | // [15]
+ policy.bits.verStretch << 16 | // [16, 23]
+ policy.bits.horStretch << 24); // [24, 31]
+ return stream << data;
+}
+
+#define VALUE_OF_BITS(data, bitstart, bitcount) ((data >> bitstart) & ((1 << bitcount) -1))
+
+/*!
+ \relates QLayoutPolicy
+
+ Reads the size \a policy from the data stream \a stream.
+
+ \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
+*/
+QDataStream &operator>>(QDataStream &stream, QLayoutPolicy &policy)
+{
+ quint32 data;
+ stream >> data;
+ policy.bits.horPolicy = VALUE_OF_BITS(data, 0, 4);
+ policy.bits.verPolicy = VALUE_OF_BITS(data, 4, 4);
+ policy.bits.hfw = VALUE_OF_BITS(data, 8, 1);
+ policy.bits.ctype = VALUE_OF_BITS(data, 9, 5);
+ policy.bits.wfh = VALUE_OF_BITS(data, 14, 1);
+ policy.bits.padding = 0;
+ policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8);
+ policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8);
+ return stream;
+}
+#endif // QT_NO_DATASTREAM
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QLayoutPolicy &p)
+{
+ dbg.nospace() << "QLayoutPolicy(horizontalPolicy = " << p.horizontalPolicy()
+ << ", verticalPolicy = " << p.verticalPolicy() << ')';
+ return dbg.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qlayoutpolicy_p.h b/src/gui/util/qlayoutpolicy_p.h
new file mode 100644
index 0000000000..664afef1a4
--- /dev/null
+++ b/src/gui/util/qlayoutpolicy_p.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Layouts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUTPOLICY_H
+#define QLAYOUTPOLICY_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qnamespace.h>
+
+#ifndef QT_NO_DATASTREAM
+# include <QtCore/qdatastream.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+
+class QVariant;
+
+class Q_GUI_EXPORT QLayoutPolicy
+{
+ Q_ENUMS(Policy)
+
+public:
+ enum PolicyFlag {
+ GrowFlag = 1,
+ ExpandFlag = 2,
+ ShrinkFlag = 4,
+ IgnoreFlag = 8
+ };
+
+ enum Policy {
+ Fixed = 0,
+ Minimum = GrowFlag,
+ Maximum = ShrinkFlag,
+ Preferred = GrowFlag | ShrinkFlag,
+ MinimumExpanding = GrowFlag | ExpandFlag,
+ Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
+ Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
+ };
+
+ enum ControlType {
+ DefaultType = 0x00000001,
+ ButtonBox = 0x00000002,
+ CheckBox = 0x00000004,
+ ComboBox = 0x00000008,
+ Frame = 0x00000010,
+ GroupBox = 0x00000020,
+ Label = 0x00000040,
+ Line = 0x00000080,
+ LineEdit = 0x00000100,
+ PushButton = 0x00000200,
+ RadioButton = 0x00000400,
+ Slider = 0x00000800,
+ SpinBox = 0x00001000,
+ TabWidget = 0x00002000,
+ ToolButton = 0x00004000
+ };
+ Q_DECLARE_FLAGS(ControlTypes, ControlType)
+
+ QLayoutPolicy() : data(0) { }
+
+ QLayoutPolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType)
+ : data(0) {
+ bits.horPolicy = horizontal;
+ bits.verPolicy = vertical;
+ setControlType(type);
+ }
+ Policy horizontalPolicy() const { return static_cast<Policy>(bits.horPolicy); }
+ Policy verticalPolicy() const { return static_cast<Policy>(bits.verPolicy); }
+ ControlType controlType() const;
+
+ void setHorizontalPolicy(Policy d) { bits.horPolicy = d; }
+ void setVerticalPolicy(Policy d) { bits.verPolicy = d; }
+ void setControlType(ControlType type);
+
+ Qt::Orientations expandingDirections() const {
+ Qt::Orientations result;
+ if (verticalPolicy() & ExpandFlag)
+ result |= Qt::Vertical;
+ if (horizontalPolicy() & ExpandFlag)
+ result |= Qt::Horizontal;
+ return result;
+ }
+
+ void setHeightForWidth(bool b) { bits.hfw = b; }
+ bool hasHeightForWidth() const { return bits.hfw; }
+ void setWidthForHeight(bool b) { bits.wfh = b; }
+ bool hasWidthForHeight() const { return bits.wfh; }
+
+ bool operator==(const QLayoutPolicy& s) const { return data == s.data; }
+ bool operator!=(const QLayoutPolicy& s) const { return data != s.data; }
+
+ int horizontalStretch() const { return static_cast<int>(bits.horStretch); }
+ int verticalStretch() const { return static_cast<int>(bits.verStretch); }
+ void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
+ void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
+
+ void transpose();
+
+
+private:
+#ifndef QT_NO_DATASTREAM
+ friend QDataStream &operator<<(QDataStream &, const QLayoutPolicy &);
+ friend QDataStream &operator>>(QDataStream &, QLayoutPolicy &);
+#endif
+ QLayoutPolicy(int i) : data(i) { }
+
+ union {
+ struct {
+ quint32 horStretch : 8;
+ quint32 verStretch : 8;
+ quint32 horPolicy : 4;
+ quint32 verPolicy : 4;
+ quint32 ctype : 5;
+ quint32 hfw : 1;
+ quint32 wfh : 1;
+ quint32 padding : 1; // feel free to use
+ } bits;
+ quint32 data;
+ };
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QLayoutPolicy::ControlTypes)
+
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &, const QLayoutPolicy &);
+QDataStream &operator>>(QDataStream &, QLayoutPolicy &);
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QLayoutPolicy &);
+#endif
+
+inline void QLayoutPolicy::transpose() {
+ Policy hData = horizontalPolicy();
+ Policy vData = verticalPolicy();
+ int hStretch = horizontalStretch();
+ int vStretch = verticalStretch();
+ setHorizontalPolicy(vData);
+ setVerticalPolicy(hData);
+ setHorizontalStretch(vStretch);
+ setVerticalStretch(hStretch);
+}
+
+QT_END_NAMESPACE
+
+#endif // QLAYOUTPOLICY_H
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index ed3b3b6dd6..dbb8575397 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -401,7 +401,7 @@ static qlonglong pow10(int exp)
QValidator::State QIntValidator::validate(QString & input, int&) const
{
QByteArray buff;
- if (!locale().d->validateChars(input, QLocalePrivate::IntegerMode, &buff)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff)) {
return Invalid;
}
@@ -418,7 +418,7 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
return Intermediate;
bool ok, overflow;
- qlonglong entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
+ qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
if (overflow || !ok)
return Invalid;
@@ -440,11 +440,11 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
void QIntValidator::fixup(QString &input) const
{
QByteArray buff;
- if (!locale().d->validateChars(input, QLocalePrivate::IntegerMode, &buff)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff)) {
return;
}
bool ok, overflow;
- qlonglong entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
+ qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
if (ok && !overflow)
input = locale().toString(entered);
}
@@ -532,7 +532,7 @@ public:
QDoubleValidator::Notation notation;
- QValidator::State validateWithLocale(QString & input, QLocalePrivate::NumberMode numMode, const QLocale &locale) const;
+ QValidator::State validateWithLocale(QString & input, QLocaleData::NumberMode numMode, const QLocale &locale) const;
};
@@ -639,24 +639,24 @@ QValidator::State QDoubleValidator::validate(QString & input, int &) const
{
Q_D(const QDoubleValidator);
- QLocalePrivate::NumberMode numMode = QLocalePrivate::DoubleStandardMode;
+ QLocaleData::NumberMode numMode = QLocaleData::DoubleStandardMode;
switch (d->notation) {
case StandardNotation:
- numMode = QLocalePrivate::DoubleStandardMode;
+ numMode = QLocaleData::DoubleStandardMode;
break;
case ScientificNotation:
- numMode = QLocalePrivate::DoubleScientificMode;
+ numMode = QLocaleData::DoubleScientificMode;
break;
}
return d->validateWithLocale(input, numMode, locale());
}
-QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QLocalePrivate::NumberMode numMode, const QLocale &locale) const
+QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QLocaleData::NumberMode numMode, const QLocale &locale) const
{
Q_Q(const QDoubleValidator);
QByteArray buff;
- if (!locale.d->validateChars(input, numMode, &buff, q->dec))
+ if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec))
return QValidator::Invalid;
if (buff.isEmpty())
@@ -669,7 +669,7 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
return QValidator::Invalid;
bool ok, overflow;
- double i = QLocalePrivate::bytearrayToDouble(buff.constData(), &ok, &overflow);
+ double i = QLocaleData::bytearrayToDouble(buff.constData(), &ok, &overflow);
if (overflow)
return QValidator::Invalid;
if (!ok)
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
index dfb221667e..79c83599b9 100644
--- a/src/gui/util/util.pri
+++ b/src/gui/util/util.pri
@@ -3,8 +3,14 @@
HEADERS += \
util/qdesktopservices.h \
util/qhexstring_p.h \
- util/qvalidator.h
+ util/qvalidator.h \
+ util/qgridlayoutengine_p.h \
+ util/qabstractlayoutstyleinfo_p.h \
+ util/qlayoutpolicy_p.h
SOURCES += \
util/qdesktopservices.cpp \
- util/qvalidator.cpp
+ util/qvalidator.cpp \
+ util/qgridlayoutengine.cpp \
+ util/qabstractlayoutstyleinfo.cpp \
+ util/qlayoutpolicy.cpp