summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2014-02-13 09:35:08 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-13 09:35:08 +0100
commit7ac97d7efb1a1e75633ce31fbb03eb43a9b01670 (patch)
tree4284e5eff68c13cc52be1c658d6c2abffee3ece5 /src/gui
parent5b14bf342f43bd6cb02ad751db8da851850814bb (diff)
parenta9c88c1f39c41215eb9d7288a1fd02aa865e8a04 (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.cpp2
-rw-r--r--src/gui/opengl/qopengltexture.cpp19
-rw-r--r--src/gui/painting/qdrawhelper.cpp14
-rw-r--r--src/gui/text/qtextengine.cpp128
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;