diff options
Diffstat (limited to 'src/gui/text/qtextlayout.cpp')
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 187 |
1 files changed, 51 insertions, 136 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 9919ce6bb4..d7f66e241b 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1,40 +1,32 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** 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$ +** $QT_BEGIN_LICENSE:LGPL21$ ** 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 +** 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. +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** 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 +** 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$ ** ****************************************************************************/ @@ -2021,79 +2013,6 @@ int QTextLine::textLength() const return eng->lines[index].length + eng->lines[index].trailingSpaces; } -static void drawMenuText(QPainter *p, QFixed x, QFixed y, const QScriptItem &si, QTextItemInt &gf, QTextEngine *eng, - int start, int glyph_start) -{ - int ge = glyph_start + gf.glyphs.numGlyphs; - int gs = glyph_start; - int end = start + gf.num_chars; - unsigned short *logClusters = eng->logClusters(&si); - QGlyphLayout glyphs = eng->shapedGlyphs(&si); - QFixed orig_width = gf.width; - - int *ul = eng->underlinePositions; - if (ul) - while (*ul != -1 && *ul < start) - ++ul; - bool rtl = si.analysis.bidiLevel % 2; - if (rtl) - x += si.width; - - do { - int gtmp = ge; - int stmp = end; - if (ul && *ul != -1 && *ul < end) { - stmp = *ul; - gtmp = logClusters[*ul-si.position]; - } - - gf.glyphs = glyphs.mid(gs, gtmp - gs); - gf.num_chars = stmp - start; - gf.chars = eng->layoutData->string.unicode() + start; - QFixed w = 0; - while (gs < gtmp) { - w += glyphs.effectiveAdvance(gs); - ++gs; - } - start = stmp; - gf.width = w; - if (rtl) - x -= w; - if (gf.num_chars) - QPainterPrivate::get(p)->drawTextItem(QPointF(x.toReal(), y.toReal()), gf, eng); - if (!rtl) - x += w; - if (ul && *ul != -1 && *ul < end) { - // draw underline - gtmp = (*ul == end-1) ? ge : logClusters[*ul+1-si.position]; - ++stmp; - gf.glyphs = glyphs.mid(gs, gtmp - gs); - gf.num_chars = stmp - start; - gf.chars = eng->layoutData->string.unicode() + start; - gf.logClusters = logClusters + start - si.position; - w = 0; - while (gs < gtmp) { - w += glyphs.effectiveAdvance(gs); - ++gs; - } - ++start; - gf.width = w; - gf.underlineStyle = QTextCharFormat::SingleUnderline; - if (rtl) - x -= w; - QPainterPrivate::get(p)->drawTextItem(QPointF(x.toReal(), y.toReal()), gf, eng); - if (!rtl) - x += w; - gf.underlineStyle = QTextCharFormat::NoUnderline; - ++gf.chars; - ++ul; - } - } while (gs < ge); - - gf.width = orig_width; -} - - static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const QTextCharFormat &chf, const QRectF &r) { QBrush c = chf.foreground(); @@ -2483,52 +2402,48 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR Q_ASSERT(gf.fontEngine); - if (eng->underlinePositions) { - // can't have selections in this case - drawMenuText(p, iterator.x, itemBaseLine, si, gf, eng, iterator.itemStart, iterator.glyphsStart); - } else { - QPointF pos(iterator.x.toReal(), itemBaseLine.toReal()); - if (format.penProperty(QTextFormat::TextOutline).style() != Qt::NoPen) { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - - if (gf.glyphs.numGlyphs) - gf.fontEngine->addOutlineToPath(pos.x(), pos.y(), gf.glyphs, &path, gf.flags); - if (gf.flags) { - const QFontEngine *fe = gf.fontEngine; - const qreal lw = fe->lineThickness().toReal(); - if (gf.flags & QTextItem::Underline) { - qreal offs = fe->underlinePosition().toReal(); - path.addRect(pos.x(), pos.y() + offs, gf.width.toReal(), lw); - } - if (gf.flags & QTextItem::Overline) { - qreal offs = fe->ascent().toReal() + 1; - path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); - } - if (gf.flags & QTextItem::StrikeOut) { - qreal offs = fe->ascent().toReal() / 3; - path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); - } + QPointF pos(iterator.x.toReal(), itemBaseLine.toReal()); + if (format.penProperty(QTextFormat::TextOutline).style() != Qt::NoPen) { + QPainterPath path; + path.setFillRule(Qt::WindingFill); + + if (gf.glyphs.numGlyphs) + gf.fontEngine->addOutlineToPath(pos.x(), pos.y(), gf.glyphs, &path, gf.flags); + if (gf.flags) { + const QFontEngine *fe = gf.fontEngine; + const qreal lw = fe->lineThickness().toReal(); + if (gf.flags & QTextItem::Underline) { + qreal offs = fe->underlinePosition().toReal(); + path.addRect(pos.x(), pos.y() + offs, gf.width.toReal(), lw); + } + if (gf.flags & QTextItem::Overline) { + qreal offs = fe->ascent().toReal() + 1; + path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); + } + if (gf.flags & QTextItem::StrikeOut) { + qreal offs = fe->ascent().toReal() / 3; + path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw); } - - p->save(); - p->setRenderHint(QPainter::Antialiasing); - //Currently QPen with a Qt::NoPen style still returns a default - //QBrush which != Qt::NoBrush so we need this specialcase to reset it - if (p->pen().style() == Qt::NoPen) - p->setBrush(Qt::NoBrush); - else - p->setBrush(p->pen().brush()); - - p->setPen(format.textOutline()); - p->drawPath(path); - p->restore(); - } else { - if (noText) - gf.glyphs.numGlyphs = 0; // slightly less elegant than it should be - QPainterPrivate::get(p)->drawTextItem(pos, gf, eng); } + + p->save(); + p->setRenderHint(QPainter::Antialiasing); + //Currently QPen with a Qt::NoPen style still returns a default + //QBrush which != Qt::NoBrush so we need this specialcase to reset it + if (p->pen().style() == Qt::NoPen) + p->setBrush(Qt::NoBrush); + else + p->setBrush(p->pen().brush()); + + p->setPen(format.textOutline()); + p->drawPath(path); + p->restore(); + } else { + if (noText) + gf.glyphs.numGlyphs = 0; // slightly less elegant than it should be + QPainterPrivate::get(p)->drawTextItem(pos, gf, eng); } + if (si.analysis.flags == QScriptAnalysis::Space && (eng->option.flags() & QTextOption::ShowTabsAndSpaces)) { QBrush c = format.foreground(); @@ -2578,7 +2493,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const } int lineEnd = line.from + line.length + line.trailingSpaces; - int pos = *cursorPos; + int pos = qBound(0, *cursorPos, lineEnd); int itm; const QCharAttributes *attributes = eng->attributes(); if (!attributes) { |