From 0189fc2335c891373ce595a4a01e4a9d73cc5fe4 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Sun, 12 Dec 2010 17:33:12 +0100 Subject: Move advances for control character in Indic syllable shaping When handling control characters (ZWJ, ZWNJ) in Indic syllables, we only moved glyphs and attributes of the item, advances should also be moved forward, otherwise we will use the advance of ZWJ/ ZWNJ for the part of syllable, which is normally zero, it results some positioning problems. Task-number: QTBUG-14204 Reviewed-by: Lars Knoll --- src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp | 1 + tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp index 4a618da..bbf479e 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp @@ -1683,6 +1683,7 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv } item->glyphs[j] = item->glyphs[i]; item->attributes[j] = item->attributes[i]; + item->advances[j] = item->advances[i]; ++i; ++j; } diff --git a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp index 0a7458f..b0b6b1e 100644 --- a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp @@ -103,6 +103,7 @@ private slots: void khmer(); void linearB(); + void controlInSyllable_qtbug14204(); }; tst_QTextScriptEngine::tst_QTextScriptEngine() @@ -1111,6 +1112,22 @@ void tst_QTextScriptEngine::greek() #endif } +void tst_QTextScriptEngine::controlInSyllable_qtbug14204() +{ + QString s; + s.append(QChar(0x0915)); + s.append(QChar(0x094d)); + s.append(QChar(0x200d)); + s.append(QChar(0x0915)); + + QTextLayout layout(s); + QTextEngine *e = layout.d; + e->itemize(); + e->shape(0); + + QVERIFY(e->layoutData->items[0].num_glyphs == 2); + QVERIFY(e->layoutData->glyphLayout.advances_x[1] != 0); +} QTEST_MAIN(tst_QTextScriptEngine) #include "tst_qtextscriptengine.moc" -- cgit v0.12 From ad0841dfd89d08140b719098ecfec82881df63e6 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 14 Dec 2010 18:18:35 +0100 Subject: Disable certain GPOS features by default According to OpenType Layout tag registry, these features should be turned off by default. Leaving them on will cause some text layout problems in common UI widgets -- they are usually designed for better positioning in print publishing or full featured text layout programs, not for general usage. There is no way to turn them on in HarfBuzz now, it should be addressed later. Features like 'valt' are intended for vertical writing mode are also turned off, since HarfBuzz doesn't support it properly yet. Task-number: QTBUG-15754 Reviewed-by: Lars Knoll --- src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp | 41 +++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index ce4d4ac..ef86144 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -538,8 +538,20 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) #ifndef NO_OPENTYPE static const HB_OpenTypeFeature basic_features[] = { { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, - { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty }, - { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty }, + { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty }, + { HB_MAKE_TAG('c', 'l', 'i', 'g'), CligProperty }, + {0, 0} +}; + +static const HB_OpenTypeFeature disabled_features[] = { + { HB_MAKE_TAG('c', 'p', 'c', 't'), PositioningProperties }, + { HB_MAKE_TAG('h', 'a', 'l', 't'), PositioningProperties }, + // TODO: we need to add certain HB_ShaperFlag for vertical + // writing mode to enable these vertical writing features: + { HB_MAKE_TAG('v', 'a', 'l', 't'), PositioningProperties }, + { HB_MAKE_TAG('v', 'h', 'a', 'l'), PositioningProperties }, + { HB_MAKE_TAG('v', 'k', 'r', 'n'), PositioningProperties }, + { HB_MAKE_TAG('v', 'p', 'a', 'l'), PositioningProperties }, {0, 0} }; #endif @@ -1110,12 +1122,29 @@ HB_Bool HB_SelectScript(HB_ShaperItem *shaper_item, const HB_OpenTypeFeature *fe HB_UInt *feature_tag_list = feature_tag_list_buffer; while (*feature_tag_list) { HB_UShort feature_index; + bool skip = false; if (*feature_tag_list == HB_MAKE_TAG('k', 'e', 'r', 'n')) { - if (face->current_flags & HB_ShaperFlag_NoKerning) { - ++feature_tag_list; - continue; + if (face->current_flags & HB_ShaperFlag_NoKerning) + skip = true; + else + face->has_opentype_kerning = true; + } + features = disabled_features; + while (features->tag) { + if (*feature_tag_list == features->tag) { + skip = true; + break; } - face->has_opentype_kerning = true; + ++features; + } + // 'palt' should be turned off by default unless 'kern' is on + if (!face->has_opentype_kerning && + *feature_tag_list == HB_MAKE_TAG('p', 'a', 'l', 't')) + skip = true; + + if (skip) { + ++feature_tag_list; + continue; } error = HB_GPOS_Select_Feature(face->gpos, *feature_tag_list, script_index, 0xffff, &feature_index); if (!error) -- cgit v0.12 From 5d68753927ac6ba1445ceb6831da7e2346d91bf9 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 21 Dec 2010 13:26:54 +0100 Subject: Optimize texture glyph cache To avoid calling the bounding box function for the same non-printable characters in every call, we cache them as empty in the coords table and bail out before painting them. This patch also fixes some possible reads of uninitialized memory (reference to return value) and reference to a default constructed object consisting of uninitialized pods. Reviewed-by: Samuel --- src/gui/painting/qpaintengine_raster.cpp | 4 +++- src/gui/painting/qtextureglyphcache.cpp | 11 ++++++++--- src/gui/painting/qtextureglyphcache_p.h | 5 +++++ .../gl2paintengineex/qpaintengineex_opengl2.cpp | 20 ++++++++++++-------- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 97dfddf..ec5cef0 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3111,7 +3111,9 @@ void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, if (supportsSubPixelPositions) subPixelPosition = cache->subPixelPositionForX(positions[i].x); QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition); - const QTextureGlyphCache::Coord &c = cache->coords.value(glyph); + const QTextureGlyphCache::Coord &c = cache->coords[glyph]; + if (c.isNull()) + continue; int x = qFloor(positions[i].x) + c.baseLineX - margin; int y = qFloor(positions[i].y) - c.baseLineY - margin; diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 60300c3..670ca95 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -175,11 +175,16 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const metrics.yoff.toReal(), metrics.x.toReal(), metrics.y.toReal()); -#endif +#endif + GlyphAndSubPixelPosition key(glyph, subPixelPosition); int glyph_width = metrics.width.ceil().toInt(); int glyph_height = metrics.height.ceil().toInt(); - if (glyph_height == 0 || glyph_width == 0) + if (glyph_height == 0 || glyph_width == 0) { + // Avoid multiple calls to boundingBox() for non-printable characters + Coord c = { 0, 0, 0, 0, 0, 0 }; + coords.insert(key, c); continue; + } glyph_width += margin * 2 + 4; glyph_height += margin * 2 + 4; // align to 8-bit boundary @@ -192,7 +197,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const metrics.x.round().truncate(), -metrics.y.truncate() }; // baseline for horizontal scripts - listItemCoordinates.insert(GlyphAndSubPixelPosition(glyph, subPixelPosition), c); + listItemCoordinates.insert(key, c); rowHeight = qMax(rowHeight, glyph_height); } if (listItemCoordinates.isEmpty()) diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 4227e9a..7a0bdfd 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -107,6 +107,11 @@ public: int baseLineX; int baseLineY; + + bool isNull() const + { + return w == 0 || h == 0; + } }; bool populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs, diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index cdd785a..771d33f 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1556,7 +1556,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp } } - if (recreateVertexArrays) { vertexCoordinates->clear(); textureCoordinates->clear(); @@ -1569,7 +1568,10 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition); - const QTextureGlyphCache::Coord &c = cache->coords.value(glyph); + const QTextureGlyphCache::Coord &c = cache->coords[glyph]; + if (c.isNull()) + continue; + int x = staticTextItem->glyphPositions[i].x.toInt() + c.baseLineX - margin; int y = staticTextItem->glyphPositions[i].y.toInt() - c.baseLineY - margin; @@ -1580,10 +1582,12 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp staticTextItem->userDataNeedsUpdate = false; } - if (elementIndices.size() < staticTextItem->numGlyphs*6) { + int numGlyphs = vertexCoordinates->vertexCount() / 4; + + if (elementIndices.size() < numGlyphs*6) { Q_ASSERT(elementIndices.size() % 6 == 0); int j = elementIndices.size() / 6 * 4; - while (j < staticTextItem->numGlyphs*4) { + while (j < numGlyphs*4) { elementIndices.append(j + 0); elementIndices.append(j + 0); elementIndices.append(j + 1); @@ -1672,9 +1676,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, 0); + glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); #else - glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); + glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); #endif shaderManager->setMaskType(QGLEngineShaderManager::SubPixelMaskPass2); @@ -1722,10 +1726,10 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp } #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, 0); + glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #else - glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); + glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); #endif } -- cgit v0.12 From 254281dae38b932998eb8014a55177948842b78d Mon Sep 17 00:00:00 2001 From: Joshua Grauman Date: Tue, 4 Jan 2011 11:03:32 +0100 Subject: Add line spacing to QTextBlockFormat, get/set functions, CSS support The patch adds line spacing options to Qt, as in all modern word processors. I primarily checked OpenOffice as a reference for how to position the lines based on the various types of line spacing as well as where to do the page breaks. The following functions were added: void QTextBlockFormat::setLineHeight(qreal height, int heightType) qreal QTextBlockFormat::lineHeight() int QTextBlockFormat::lineHeightType() qreal QTextBlockFormat::lineHeight(qreal scriptLineHeight, qreal scaling) Here are the HeightTypes available: QTextBlockFormat::SingleHeight QTextBlockFormat::ProportionalHeight QTextBlockFormat::FixedHeight QTextBlockFormat::AtLeastHeight QTextBlockFormat::LineDistanceHeight The following CSS syntax was added: line-height:150% line-height:40px line-height:normal line-height:40al line-height:40ld Merge-request: 2305 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qcssparser.cpp | 1 + src/gui/text/qcssparser_p.h | 1 + src/gui/text/qtextdocumentlayout.cpp | 38 ++++++++++++++++---- src/gui/text/qtextformat.cpp | 67 ++++++++++++++++++++++++++++++++++++ src/gui/text/qtextformat.h | 35 +++++++++++++++++++ src/gui/text/qtexthtmlparser.cpp | 18 ++++++++++ 6 files changed, 154 insertions(+), 6 deletions(-) diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index dafc8e7..edb08ae 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -122,6 +122,7 @@ static const QCssKnownValue properties[NumProperties - 1] = { { "image", QtImage }, { "image-position", QtImageAlignment }, { "left", Left }, + { "line-height", LineHeight }, { "list-style", ListStyle }, { "list-style-type", ListStyleType }, { "margin" , Margin }, diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index ca9688e..6bcbdab 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -180,6 +180,7 @@ enum Property { TextTransform, QtListNumberPrefix, QtListNumberSuffix, + LineHeight, NumProperties }; diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index ff14490..5334ae8 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2506,6 +2506,23 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayout fd->currentLayoutStruct = 0; } +static inline void getLineHeightParams(const QTextBlockFormat &blockFormat, const QTextLine &line, qreal scaling, + QFixed *lineAdjustment, QFixed *lineBreakHeight, QFixed *lineHeight) +{ + *lineHeight = QFixed::fromReal(blockFormat.lineHeight(line.height(), scaling)); + if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight || blockFormat.lineHeightType() == QTextBlockFormat::AtLeastHeight) { + *lineBreakHeight = *lineHeight; + if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight) + *lineAdjustment = QFixed::fromReal(line.ascent() + qMax(line.leading(), 0.0)) - ((*lineHeight * 4) / 5); + else + *lineAdjustment = QFixed::fromReal(line.height()) - *lineHeight; + } + else { + *lineBreakHeight = QFixed::fromReal(line.height()); + *lineAdjustment = 0; + } +} + void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) { @@ -2639,8 +2656,12 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi } - QFixed lineHeight = QFixed::fromReal(line.height()); - if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineHeight > layoutStruct->pageBottom) { + QFixed lineBreakHeight, lineHeight, lineAdjustment; + qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ? + qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; + getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight); + + if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom) { layoutStruct->newPage(); floatMargins(layoutStruct->y, layoutStruct, &left, &right); @@ -2652,7 +2673,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi right -= text_indent; } - line.setPosition(QPointF((left - layoutStruct->x_left).toReal(), (layoutStruct->y - cy).toReal())); + line.setPosition(QPointF((left - layoutStruct->x_left).toReal(), (layoutStruct->y - cy - lineAdjustment).toReal())); layoutStruct->y += lineHeight; layoutStruct->contentsWidth = qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + line.naturalTextWidth()) + totalRightMargin); @@ -2672,11 +2693,16 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi QTextLine line = tl->lineAt(i); layoutStruct->contentsWidth = qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + tl->lineAt(i).naturalTextWidth()) + totalRightMargin); - const QFixed lineHeight = QFixed::fromReal(line.height()); + + QFixed lineBreakHeight, lineHeight, lineAdjustment; + qreal scaling = (q->paintDevice() && q->paintDevice()->logicalDpiY() != qt_defaultDpi()) ? + qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; + getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight); + if (layoutStruct->pageHeight != QFIXED_MAX) { - if (layoutStruct->absoluteY() + lineHeight > layoutStruct->pageBottom) + if (layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom) layoutStruct->newPage(); - line.setPosition(QPointF(line.position().x(), layoutStruct->y.toReal() - tl->position().y())); + line.setPosition(QPointF(line.position().x(), (layoutStruct->y - lineAdjustment).toReal() - tl->position().y())); } layoutStruct->y += lineHeight; } diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 945b012..719db7a 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -541,6 +541,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value TabPositions Specifies the tab positions. The tab positions are structs of QTextOption::Tab which are stored in a QList (internally, in a QList). \value BlockIndent + \value LineHeight + \value LineHeightType \value BlockNonBreakableLines \value BlockTrailingHorizontalRulerWidth The width of a horizontal ruler element. @@ -1856,6 +1858,10 @@ QFont QTextCharFormat::font() const indentation is set with setIndent(), the indentation of the first line with setTextIndent(). + Line spacing is set with setLineHeight() and retreived via lineHeight() + and lineHeightType(). The types of line spacing available are in the + LineHeightTypes enum. + Line breaking can be enabled and disabled with setNonBreakableLines(). The brush used to paint the paragraph's background @@ -1872,6 +1878,22 @@ QFont QTextCharFormat::font() const */ /*! + \since 4.7 + \enum QTextBlockFormat::LineHeightTypes + + This enum describes the various types of line spacing support paragraphs can have. + + \value SingleHeight This is the default line height: single spacing. + \value ProportionalHeight This sets the spacing proportional to the line (in percentage). + For example, set to 200 for double spacing. + \value FixedHeight This sets the line height to a fixed line height (in pixels). + \value AtLeastHeight This sets the minimum line height (in pixels). + \value LineDistanceHeight This adds the specified height between lines (in pixels). + + \sa lineHeight(), lineHeightType(), setLineHeight() +*/ + +/*! \fn QTextBlockFormat::QTextBlockFormat() Constructs a new QTextBlockFormat. @@ -2089,6 +2111,51 @@ QList QTextBlockFormat::tabPositions() const /*! + \fn void QTextBlockFormat::setLineHeight(qreal height, int heightType) + \since 4.7 + + This sets the line height for the paragraph to the value in height + which is dependant on heightType, described by the LineHeightTypes enum. + + \sa LineHeightTypes, lineHeight(), lineHeightType() +*/ + + +/*! + \fn qreal QTextBlockFormat::lineHeight(qreal scriptLineHeight, qreal scaling) const + \since 4.7 + + This returns what the height of the lines in the paragraph will be depending + on the given height of the script line and the scaling. The value that is returned + is also dependant on the given LineHeightType of the paragraph as well as the LineHeight + setting that has been set for the paragraph. The scaling is needed for the heights + that include a fixed number of pixels, to scale them appropriately for printing. + + \sa LineHeightTypes, setLineHeight(), lineHeightType() +*/ + + +/*! + \fn qreal QTextBlockFormat::lineHeight() const + \since 4.7 + + This returns the LineHeight property for the paragraph. + + \sa LineHeightTypes, setLineHeight(), lineHeightType() +*/ + + +/*! + \fn qreal QTextBlockFormat::lineHeightType() const + \since 4.7 + + This returns the LineHeightType property of the paragraph. + + \sa LineHeightTypes, setLineHeight(), lineHeight() +*/ + + +/*! \fn void QTextBlockFormat::setNonBreakableLines(bool b) If \a b is true, the lines in the paragraph are treated as diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index bb6e71d..41cc1d9 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -164,6 +164,8 @@ public: TextIndent = 0x1034, TabPositions = 0x1035, BlockIndent = 0x1040, + LineHeight = 0x1048, + LineHeightType = 0x1049, BlockNonBreakableLines = 0x1050, BlockTrailingHorizontalRulerWidth = 0x1060, @@ -531,6 +533,14 @@ inline void QTextCharFormat::setTableCellColumnSpan(int _tableCellColumnSpan) class Q_GUI_EXPORT QTextBlockFormat : public QTextFormat { public: + enum LineHeightTypes { + SingleHeight = 0, + ProportionalHeight = 1, + FixedHeight = 2, + AtLeastHeight = 3, + LineDistanceHeight = 4 + }; + QTextBlockFormat(); bool isValid() const { return isBlockFormat(); } @@ -568,6 +578,14 @@ public: inline int indent() const { return intProperty(BlockIndent); } + inline void setLineHeight(qreal height, int heightType) + { setProperty(LineHeight, height); setProperty(LineHeightType, heightType); } + inline qreal lineHeight(qreal scriptLineHeight, qreal scaling) const; + inline qreal lineHeight() const + { return doubleProperty(LineHeight); } + inline int lineHeightType() const + { return intProperty(LineHeightType); } + inline void setNonBreakableLines(bool b) { setProperty(BlockNonBreakableLines, b); } inline bool nonBreakableLines() const @@ -592,6 +610,23 @@ inline void QTextBlockFormat::setAlignment(Qt::Alignment aalignment) inline void QTextBlockFormat::setIndent(int aindent) { setProperty(BlockIndent, aindent); } +inline qreal QTextBlockFormat::lineHeight(qreal scriptLineHeight, qreal scaling = 1.0) const +{ + switch(intProperty(LineHeightType)) { + case SingleHeight: + return(scriptLineHeight); + case ProportionalHeight: + return(scriptLineHeight * doubleProperty(LineHeight) / 100.0); + case FixedHeight: + return(doubleProperty(LineHeight) * scaling); + case AtLeastHeight: + return(qMax(scriptLineHeight, doubleProperty(LineHeight) * scaling)); + case LineDistanceHeight: + return(scriptLineHeight + doubleProperty(LineHeight) * scaling); + } + return(0); +} + class Q_GUI_EXPORT QTextListFormat : public QTextFormat { public: diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 5b9ab90..769a509 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1250,6 +1250,24 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector case QCss::QtBlockIndent: blockFormat.setIndent(decl.d->values.first().variant.toInt()); break; + case QCss::LineHeight: { + qreal lineHeight; + if (decl.realValue(&lineHeight, "px")) + blockFormat.setLineHeight(lineHeight, QTextBlockFormat::FixedHeight); + else if (decl.realValue(&lineHeight, "al")) + blockFormat.setLineHeight(lineHeight, QTextBlockFormat::AtLeastHeight); + else if (decl.realValue(&lineHeight, "ld")) + blockFormat.setLineHeight(lineHeight, QTextBlockFormat::LineDistanceHeight); + else { + bool ok; + QString value = decl.d->values.first().toString(); + lineHeight = value.toDouble(&ok); + if (ok) + blockFormat.setLineHeight(lineHeight, QTextBlockFormat::ProportionalHeight); + else + blockFormat.setLineHeight(0, QTextBlockFormat::SingleHeight); + } + break; } case QCss::TextIndent: { qreal indent = 0; if (decl.realValue(&indent, "px")) -- cgit v0.12 From 09b06552f98f8ee8be4d156049a6a37a4abed6bd Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 4 Jan 2011 11:09:38 +0100 Subject: Rename QTextBlockFormat::AtLeastHeight -> MinimumHeight Make some alterations to merge request 2305: 1. Rename enum for consistency with other APIs in Qt. 2. Correct documentation with actual version number of features. 3. Remove unstandard css syntax in line-height specification. Reviewed-by: Jiang Jiang --- src/gui/text/qtextdocumentlayout.cpp | 2 +- src/gui/text/qtextformat.cpp | 12 ++++++------ src/gui/text/qtextformat.h | 4 ++-- src/gui/text/qtexthtmlparser.cpp | 8 ++------ 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 5334ae8..22c6b8c 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2510,7 +2510,7 @@ static inline void getLineHeightParams(const QTextBlockFormat &blockFormat, cons QFixed *lineAdjustment, QFixed *lineBreakHeight, QFixed *lineHeight) { *lineHeight = QFixed::fromReal(blockFormat.lineHeight(line.height(), scaling)); - if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight || blockFormat.lineHeightType() == QTextBlockFormat::AtLeastHeight) { + if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight || blockFormat.lineHeightType() == QTextBlockFormat::MinimumHeight) { *lineBreakHeight = *lineHeight; if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight) *lineAdjustment = QFixed::fromReal(line.ascent() + qMax(line.leading(), 0.0)) - ((*lineHeight * 4) / 5); diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 719db7a..b05a830 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -1878,7 +1878,7 @@ QFont QTextCharFormat::font() const */ /*! - \since 4.7 + \since 4.8 \enum QTextBlockFormat::LineHeightTypes This enum describes the various types of line spacing support paragraphs can have. @@ -1887,7 +1887,7 @@ QFont QTextCharFormat::font() const \value ProportionalHeight This sets the spacing proportional to the line (in percentage). For example, set to 200 for double spacing. \value FixedHeight This sets the line height to a fixed line height (in pixels). - \value AtLeastHeight This sets the minimum line height (in pixels). + \value MinimumHeight This sets the minimum line height (in pixels). \value LineDistanceHeight This adds the specified height between lines (in pixels). \sa lineHeight(), lineHeightType(), setLineHeight() @@ -2112,7 +2112,7 @@ QList QTextBlockFormat::tabPositions() const /*! \fn void QTextBlockFormat::setLineHeight(qreal height, int heightType) - \since 4.7 + \since 4.8 This sets the line height for the paragraph to the value in height which is dependant on heightType, described by the LineHeightTypes enum. @@ -2123,7 +2123,7 @@ QList QTextBlockFormat::tabPositions() const /*! \fn qreal QTextBlockFormat::lineHeight(qreal scriptLineHeight, qreal scaling) const - \since 4.7 + \since 4.8 This returns what the height of the lines in the paragraph will be depending on the given height of the script line and the scaling. The value that is returned @@ -2137,7 +2137,7 @@ QList QTextBlockFormat::tabPositions() const /*! \fn qreal QTextBlockFormat::lineHeight() const - \since 4.7 + \since 4.8 This returns the LineHeight property for the paragraph. @@ -2147,7 +2147,7 @@ QList QTextBlockFormat::tabPositions() const /*! \fn qreal QTextBlockFormat::lineHeightType() const - \since 4.7 + \since 4.8 This returns the LineHeightType property of the paragraph. diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index 41cc1d9..81b053b 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -537,7 +537,7 @@ public: SingleHeight = 0, ProportionalHeight = 1, FixedHeight = 2, - AtLeastHeight = 3, + MinimumHeight = 3, LineDistanceHeight = 4 }; @@ -619,7 +619,7 @@ inline qreal QTextBlockFormat::lineHeight(qreal scriptLineHeight, qreal scaling return(scriptLineHeight * doubleProperty(LineHeight) / 100.0); case FixedHeight: return(doubleProperty(LineHeight) * scaling); - case AtLeastHeight: + case MinimumHeight: return(qMax(scriptLineHeight, doubleProperty(LineHeight) * scaling)); case LineDistanceHeight: return(scriptLineHeight + doubleProperty(LineHeight) * scaling); diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 769a509..5d5e2b6 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1252,13 +1252,9 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector break; case QCss::LineHeight: { qreal lineHeight; - if (decl.realValue(&lineHeight, "px")) + if (decl.realValue(&lineHeight, "px")) { blockFormat.setLineHeight(lineHeight, QTextBlockFormat::FixedHeight); - else if (decl.realValue(&lineHeight, "al")) - blockFormat.setLineHeight(lineHeight, QTextBlockFormat::AtLeastHeight); - else if (decl.realValue(&lineHeight, "ld")) - blockFormat.setLineHeight(lineHeight, QTextBlockFormat::LineDistanceHeight); - else { + } else { bool ok; QString value = decl.d->values.first().toString(); lineHeight = value.toDouble(&ok); -- cgit v0.12 From 18447df1d021cfed69472b867cb7593401be27a6 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Wed, 5 Jan 2011 19:39:00 +0100 Subject: Make application font family names locale sensitive in X11 So that they will match the family names returned by QFontDatabase::families. Because the family names returned by FcFreeTypeQueryFace are not sorted with locale as the names returned by FcFontList, we have to find out the family name matching the system language in the former case. Task-number: QTBUG-14269 Reviewed-by: Eskil --- src/gui/text/qfontdatabase.cpp | 3 +++ src/gui/text/qfontdatabase_x11.cpp | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index bae2a20..ec94de9 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -664,6 +664,9 @@ public: } int count; +#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG) + QString systemLang; +#endif QtFontFamily **families; struct ApplicationFont { diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index 635d2cf..c67558b 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -1018,6 +1018,13 @@ static void loadFontConfig() QFontDatabasePrivate *db = privateDb(); FcFontSet *fonts; + FcPattern *pattern = FcPatternCreate(); + FcDefaultSubstitute(pattern); + FcChar8 *lang = 0; + if (FcPatternGetString(pattern, FC_LANG, 0, &lang) == FcResultMatch) + db->systemLang = QString::fromUtf8((const char *) lang); + FcPatternDestroy(pattern); + QString familyName; FcChar8 *value = 0; int weight_value; @@ -2037,6 +2044,7 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) int count = 0; QStringList families; + QFontDatabasePrivate *db = privateDb(); FcPattern *pattern = 0; do { @@ -2048,8 +2056,19 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) FcPatternDel(pattern, FC_FILE); FcPatternAddString(pattern, FC_FILE, (const FcChar8 *)fnt->fileName.toUtf8().constData()); - FcChar8 *fam = 0; - if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) { + FcChar8 *fam = 0, *familylang = 0; + int i, n = 0; + for (i = 0; ; i++) { + if (FcPatternGetString(pattern, FC_FAMILYLANG, i, &familylang) != FcResultMatch) + break; + QString familyLang = QString::fromUtf8((const char *) familylang); + if (familyLang.compare(db->systemLang, Qt::CaseInsensitive) == 0) { + n = i; + break; + } + } + + if (FcPatternGetString(pattern, FC_FAMILY, n, &fam) == FcResultMatch) { QString family = QString::fromUtf8(reinterpret_cast(fam)); families << family; } -- cgit v0.12 From 0faab4442040fdfe3790e3c02808fd45993f0265 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 10 Jan 2011 10:25:42 +0100 Subject: Compile when qreal != double Compile fix for devices where qreals are floats. Reviewed-by: Fabien Freling --- src/gui/text/qtextdocumentlayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 22c6b8c..c0f3fb4 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2513,7 +2513,7 @@ static inline void getLineHeightParams(const QTextBlockFormat &blockFormat, cons if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight || blockFormat.lineHeightType() == QTextBlockFormat::MinimumHeight) { *lineBreakHeight = *lineHeight; if (blockFormat.lineHeightType() == QTextBlockFormat::FixedHeight) - *lineAdjustment = QFixed::fromReal(line.ascent() + qMax(line.leading(), 0.0)) - ((*lineHeight * 4) / 5); + *lineAdjustment = QFixed::fromReal(line.ascent() + qMax(line.leading(), qreal(0.0))) - ((*lineHeight * 4) / 5); else *lineAdjustment = QFixed::fromReal(line.height()) - *lineHeight; } -- cgit v0.12 From 1e4197d2f2994d524116761046626bd430a2df3f Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 11 Jan 2011 09:45:03 +0100 Subject: Only test control character handling in X11 It was a issue in HarfBuzz only. Reviewed-by: Andy Shaw --- tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp index b0b6b1e..88212c6 100644 --- a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp @@ -1114,6 +1114,7 @@ void tst_QTextScriptEngine::greek() void tst_QTextScriptEngine::controlInSyllable_qtbug14204() { +#if defined(Q_WS_X11) QString s; s.append(QChar(0x0915)); s.append(QChar(0x094d)); @@ -1127,6 +1128,9 @@ void tst_QTextScriptEngine::controlInSyllable_qtbug14204() QVERIFY(e->layoutData->items[0].num_glyphs == 2); QVERIFY(e->layoutData->glyphLayout.advances_x[1] != 0); +#else + QSKIP("X11 specific test", SkipAll); +#endif } QTEST_MAIN(tst_QTextScriptEngine) -- cgit v0.12 From eaf2e2187d9fec2102e3301098f85efe93518761 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Wed, 12 Jan 2011 11:07:34 +0100 Subject: Doc: Fixing typo --- src/gui/text/qtextformat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index b05a830..15125b2 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -1858,7 +1858,7 @@ QFont QTextCharFormat::font() const indentation is set with setIndent(), the indentation of the first line with setTextIndent(). - Line spacing is set with setLineHeight() and retreived via lineHeight() + Line spacing is set with setLineHeight() and retrieved via lineHeight() and lineHeightType(). The types of line spacing available are in the LineHeightTypes enum. -- cgit v0.12