diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2014-02-13 09:35:08 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-13 09:35:08 +0100 |
commit | 7ac97d7efb1a1e75633ce31fbb03eb43a9b01670 (patch) | |
tree | 4284e5eff68c13cc52be1c658d6c2abffee3ece5 /src/gui | |
parent | 5b14bf342f43bd6cb02ad751db8da851850814bb (diff) | |
parent | a9c88c1f39c41215eb9d7288a1fd02aa865e8a04 (diff) |
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 2 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 19 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 14 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 128 |
4 files changed, 73 insertions, 90 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index e856959d51..629a7c9b69 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -1894,7 +1894,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_RGBA_to_RGB, convert_RGBA_to_ARGB, - convert_RGBA_to_ARGB_PM, + convert_RGBA_to_ARGB, 0, 0, 0, diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 9a9f277b1b..61b0f3b637 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -1111,6 +1111,17 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! + \enum QOpenGLTexture::Filter + This enum defines the filtering parameters for a QOpenGLTexture object. + \value Nearest Equivalent to GL_NEAREST + \value Linear Equivalent to GL_LINEAR + \value NearestMipMapNearest Equivalent to GL_NEAREST_MIPMAP_NEAREST + \value NearestMipMapLinear Equivalent to GL_NEAREST_MIPMAP_LINEAR + \value LinearMipMapNearest Equivalent to GL_LINEAR_MIPMAP_NEAREST + \value LinearMipMapLinear Equivalent to GL_LINEAR_MIPMAP_LINEAR +*/ + +/*! \enum QOpenGLTexture::Target This enum defines the texture target of a QOpenGLTexture object. @@ -1164,7 +1175,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum TextureUnitReset + \enum QOpenGLTexture::TextureUnitReset This enum defines options ot control texture unit activation. \value ResetTextureUnit The previous active texture unit will be reset @@ -1320,7 +1331,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum PixelType + \enum QOpenGLTexture::PixelType This enum defines the possible pixel data types for a pixel transfer operation \value NoPixelType Equivalent to GL_NONE @@ -1394,7 +1405,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum WrapMode + \enum QOpenGLTexture::WrapMode This enum defines the possible texture coordinate wrapping modes. \value Repeat Texture coordinate is repeated. Equivalent to GL_REPEAT @@ -1405,7 +1416,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target */ /*! - \enum CoordinateDirection + \enum QOpenGLTexture::CoordinateDirection This enum defines the possible texture coordinate directions \value DirectionS The horizontal direction. Equivalent to GL_TEXTURE_WRAP_S diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 52a6b5d211..928ff4e670 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5841,7 +5841,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, } } -static void qt_gradient_quint32(int count, const QSpan *spans, void *userData) +static void qt_gradient_argb32(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); @@ -6298,7 +6298,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB32, { blend_color_argb, - qt_gradient_quint32, + qt_gradient_argb32, qt_bitmapblit_quint32, qt_alphamapblit_quint32, qt_alphargbblit_quint32, @@ -6307,7 +6307,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB32, { blend_color_generic, - qt_gradient_quint32, + qt_gradient_argb32, qt_bitmapblit_quint32, qt_alphamapblit_quint32, qt_alphargbblit_quint32, @@ -6316,7 +6316,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB32_Premultiplied { blend_color_argb, - qt_gradient_quint32, + qt_gradient_argb32, qt_bitmapblit_quint32, qt_alphamapblit_quint32, qt_alphargbblit_quint32, @@ -6382,7 +6382,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBX8888 { blend_color_generic, - qt_gradient_quint32, + blend_src_generic, qt_bitmapblit_quint32, #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qt_alphamapblit_quint32, @@ -6396,7 +6396,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBA8888 { blend_color_generic, - qt_gradient_quint32, + blend_src_generic, qt_bitmapblit_quint32, #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qt_alphamapblit_quint32, @@ -6410,7 +6410,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB8888_Premultiplied { blend_color_generic, - qt_gradient_quint32, + blend_src_generic, qt_bitmapblit_quint32, #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN qt_alphamapblit_quint32, diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 8a1096c269..ea61f257a2 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -919,12 +919,9 @@ void QTextEngine::shapeText(int item) const QFontEngine *fontEngine = this->fontEngine(si, &si.ascent, &si.descent, &si.leading); // split up the item into parts that come from different font engines + // k * 3 entries, array[k] == index in string, array[k + 1] == index in glyphs, array[k + 2] == engine index QVector<uint> itemBoundaries; - itemBoundaries.reserve(16); - // k * 2 entries, array[k] == index in string, array[k + 1] == index in glyphs - itemBoundaries.append(0); - itemBoundaries.append(0); - + itemBoundaries.reserve(24); if (fontEngine->type() == QFontEngine::Multi) { // ask the font engine to find out which glyphs (as an index in the specific font) // to use for the text in one item. @@ -935,22 +932,31 @@ void QTextEngine::shapeText(int item) const if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags)) Q_UNREACHABLE(); - uint lastEngine = 0; + uint lastEngine = ~0u; for (int i = 0, glyph_pos = 0; i < itemLength; ++i, ++glyph_pos) { const uint engineIdx = initialGlyphs.glyphs[glyph_pos] >> 24; - if (lastEngine != engineIdx && glyph_pos > 0) { + if (lastEngine != engineIdx) { itemBoundaries.append(i); itemBoundaries.append(glyph_pos); + itemBoundaries.append(engineIdx); + + if (engineIdx != 0) { + QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx); + si.ascent = qMax(actualFontEngine->ascent(), si.ascent); + si.descent = qMax(actualFontEngine->descent(), si.descent); + si.leading = qMax(actualFontEngine->leading(), si.leading); + } - QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx); - si.ascent = qMax(actualFontEngine->ascent(), si.ascent); - si.descent = qMax(actualFontEngine->descent(), si.descent); - si.leading = qMax(actualFontEngine->leading(), si.leading); + lastEngine = engineIdx; } - lastEngine = engineIdx; + if (QChar::isHighSurrogate(string[i]) && i + 1 < itemLength && QChar::isLowSurrogate(string[i + 1])) ++i; } + } else { + itemBoundaries.append(0); + itemBoundaries.append(0); + itemBoundaries.append(0); } bool kerningEnabled; @@ -1027,16 +1033,6 @@ void QTextEngine::shapeText(int item) const si.width += glyphs.advances[i] * !glyphs.attributes[i].dontPrint; } -static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num) -{ - if (num > 0 && destination.glyphs != source.glyphs) { - memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t)); - memmove(destination.attributes, source.attributes, num * sizeof(QGlyphAttributes)); - memmove(destination.advances, source.advances, num * sizeof(QFixed)); - memmove(destination.offsets, source.offsets, num * sizeof(QFixedPoint)); - } -} - #ifdef QT_ENABLE_HARFBUZZ_NG QT_BEGIN_INCLUDE_NAMESPACE @@ -1063,20 +1059,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st uint glyphs_shaped = 0; int remaining_glyphs = itemLength; - for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries + for (int k = 0; k < itemBoundaries.size(); k += 3) { uint item_pos = itemBoundaries[k]; - uint item_length = itemLength; + uint item_length = (k + 4 < itemBoundaries.size() ? itemBoundaries[k + 3] : itemLength) - item_pos; uint item_glyph_pos = itemBoundaries[k + 1]; - if (k + 3 < itemBoundaries.size()) - item_length = itemBoundaries[k + 2]; - item_length -= item_pos; + uint engineIdx = itemBoundaries[k + 2]; QFontEngine *actualFontEngine = fontEngine; - uint engineIdx = 0; - if (fontEngine->type() == QFontEngine::Multi) { - engineIdx = availableGlyphs(&si).glyphs[glyphs_shaped] >> 24; + if (fontEngine->type() == QFontEngine::Multi) actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx); - } // prepare buffer @@ -1093,18 +1084,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st buffer_flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES; hb_buffer_set_flags(buffer, hb_buffer_flags_t(buffer_flags)); - const uint num_codes = hb_buffer_get_length(buffer); - { - // adjust clusters - hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0); - const ushort *uc = string + item_pos; - for (uint i = 0, code_pos = 0; i < item_length; ++i, ++code_pos) { - if (QChar::isHighSurrogate(uc[i]) && i + 1 < item_length && QChar::isLowSurrogate(uc[i + 1])) - ++i; - infos[code_pos].cluster = code_pos + item_glyph_pos; - } - } - // shape bool shapedOk = false; @@ -1127,8 +1106,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st if (si.analysis.bidiLevel % 2) hb_buffer_reverse(buffer); - - remaining_glyphs -= num_codes; + remaining_glyphs -= item_glyph_pos; // ensure we have enough space for shaped glyphs and metrics const uint num_glyphs = hb_buffer_get_length(buffer); @@ -1139,43 +1117,33 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st // fetch the shaped glyphs and metrics QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs); - if (num_glyphs > num_codes) - moveGlyphData(g.mid(num_glyphs), g.mid(num_codes), remaining_glyphs); ushort *log_clusters = logClusters(&si) + item_pos; hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0); hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, 0); - uint last_cluster = -1; + uint str_pos = 0; + uint last_cluster = ~0u; + uint last_glyph_pos = glyphs_shaped; for (uint i = 0; i < num_glyphs; ++i) { g.glyphs[i] = infos[i].codepoint; - log_clusters[i] = infos[i].cluster; 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); - if (infos[i].cluster != last_cluster) { - last_cluster = infos[i].cluster; + uint cluster = infos[i].cluster; + if (last_cluster != cluster) { + // fix up clusters so that the cluster indices will be monotonic + // and thus we never return out-of-order indices + while (last_cluster++ < cluster && str_pos < item_length) + log_clusters[str_pos++] = last_glyph_pos; + last_glyph_pos = i + glyphs_shaped; + last_cluster = cluster; g.attributes[i].clusterStart = true; } } - - { - // adjust clusters - uint glyph_pos = 0; - for (uint i = 0; i < item_length; ++i) { - if (i + item_pos != infos[glyph_pos].cluster) { - for (uint j = glyph_pos + 1; j < num_glyphs; ++j) { - if (i + item_pos <= infos[j].cluster) { - if (i + item_pos == infos[j].cluster) - glyph_pos = j; - break; - } - } - } - log_clusters[i] = glyph_pos + item_glyph_pos; - } - } + while (str_pos < item_length) + log_clusters[str_pos++] = last_glyph_pos; if (engineIdx != 0) { for (quint32 i = 0; i < num_glyphs; ++i) @@ -1211,6 +1179,12 @@ Q_STATIC_ASSERT(sizeof(HB_GlyphAttributes) == sizeof(QGlyphAttributes)); Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed)); Q_STATIC_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint)); +static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num) +{ + if (num > 0 && destination.glyphs != source.glyphs) + memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t)); +} + int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const { HB_ShaperItem entire_shaper_item; @@ -1239,14 +1213,12 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri int remaining_glyphs = entire_shaper_item.num_glyphs; int glyph_pos = 0; // for each item shape using harfbuzz and store the results in our layoutData's glyphs array. - for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries - + for (int k = 0; k < itemBoundaries.size(); k += 3) { HB_ShaperItem shaper_item = entire_shaper_item; - shaper_item.item.pos = itemBoundaries[k]; - if (k < itemBoundaries.size() - 3) { - shaper_item.item.length = itemBoundaries[k + 2] - shaper_item.item.pos; - shaper_item.num_glyphs = itemBoundaries[k + 3] - itemBoundaries[k + 1]; + if (k + 4 < itemBoundaries.size()) { + shaper_item.item.length = itemBoundaries[k + 3] - shaper_item.item.pos; + shaper_item.num_glyphs = itemBoundaries[k + 4] - itemBoundaries[k + 1]; } else { // last combo in the list, avoid out of bounds access. shaper_item.item.length -= shaper_item.item.pos - entire_shaper_item.item.pos; shaper_item.num_glyphs -= itemBoundaries[k + 1]; @@ -1255,10 +1227,9 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri if (shaper_item.num_glyphs < shaper_item.item.length) shaper_item.num_glyphs = shaper_item.item.length; + uint engineIdx = itemBoundaries[k + 2]; QFontEngine *actualFontEngine = fontEngine; - uint engineIdx = 0; if (fontEngine->type() == QFontEngine::Multi) { - engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24); actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx); if ((si.analysis.bidiLevel % 2) == 0) @@ -1275,7 +1246,7 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri return 0; const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos); - if (shaper_item.num_glyphs > shaper_item.item.length) + if (fontEngine->type() == QFontEngine::Multi && shaper_item.num_glyphs > shaper_item.item.length) moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); shaper_item.glyphs = reinterpret_cast<HB_Glyph *>(g.glyphs); @@ -1292,7 +1263,8 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri } while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz. QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs); - moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); + if (fontEngine->type() == QFontEngine::Multi) + moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs); for (quint32 i = 0; i < shaper_item.item.length; ++i) shaper_item.log_clusters[i] += glyph_pos; |