Navigation Menu

Skip to content

Commit

Permalink
Fix font size calculation in headings in StyledText.
Browse files Browse the repository at this point in the history
Calculate the font size correctly even when the size is specified
in pixels and update this size when the font changes.
Also make sure that the text layout's font is set before parsing.

Task-number: QTBUG-24458

Change-Id: Ida7723f6e4f4b9fd3a6878076f4beaf5bda8f7f7
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
  • Loading branch information
Yann Bodson authored and Qt by Nokia committed Feb 23, 2012
1 parent a085465 commit 12f0663
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 81 deletions.
15 changes: 12 additions & 3 deletions src/quick/items/qquicktext.cpp
Expand Up @@ -85,7 +85,7 @@ QQuickTextPrivate::QQuickTextPrivate()
, maximumLineCountValid(false), updateOnComponentComplete(true), richText(false)
, styledText(false), singleline(false), internalWidthUpdate(false), requireImplicitWidth(false)
, truncated(false), hAlignImplicit(true), rightToLeftText(false)
, layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false)
, layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
{
}

Expand Down Expand Up @@ -298,7 +298,11 @@ void QQuickTextPrivate::updateLayout()
if (!richText) {
if (textHasChanged) {
if (styledText && !text.isEmpty()) {
QDeclarativeStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid);
layout.setFont(font);
// needs temporary bool because formatModifiesFontSize is in a bit-field
bool fontSizeModified = false;
QDeclarativeStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid, &fontSizeModified);
formatModifiesFontSize = fontSizeModified;
} else {
layout.clearAdditionalFormats();
multilengthEos = text.indexOf(QLatin1Char('\x9c'));
Expand Down Expand Up @@ -1252,8 +1256,13 @@ void QQuickText::setFont(const QFont &font)
d->font.setPointSizeF(size/2.0);
}

if (oldFont != d->font)
if (oldFont != d->font) {
// if the format changes the size of the text
// with headings or <font> tag, we need to re-parse
if (d->formatModifiesFontSize)
d->textHasChanged = true;
d->updateLayout();
}

emit fontChanged(d->sourceFont);
}
Expand Down
1 change: 1 addition & 0 deletions src/quick/items/qquicktext_p_p.h
Expand Up @@ -148,6 +148,7 @@ class Q_AUTOTEST_EXPORT QQuickTextPrivate : public QQuickImplicitSizeItemPrivate
bool layoutTextElided:1;
bool textHasChanged:1;
bool needToUpdateLayout:1;
bool formatModifiesFontSize:1;

static const QChar elideChar;

Expand Down
43 changes: 30 additions & 13 deletions src/quick/util/qdeclarativestyledtext.cpp
Expand Up @@ -69,6 +69,8 @@

QT_BEGIN_NAMESPACE

Q_GUI_EXPORT int qt_defaultDpi();

class QDeclarativeStyledTextPrivate
{
public:
Expand All @@ -85,9 +87,10 @@ class QDeclarativeStyledTextPrivate
QList<QDeclarativeStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QDeclarativeContext *context,
bool preloadImages)
bool preloadImages,
bool *fontSizeModified)
: text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl), hasNewLine(false), nbImages(0), updateImagePositions(false)
, preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), context(context)
, preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), fontSizeModified(fontSizeModified), context(context)
{
}

Expand All @@ -103,7 +106,7 @@ class QDeclarativeStyledTextPrivate
void parseImageAttributes(const QChar *&ch, const QString &textIn, QString &textOut);
QPair<QStringRef,QStringRef> parseAttribute(const QChar *&ch, const QString &textIn);
QStringRef parseValue(const QChar *&ch, const QString &textIn);

void setFontSize(int size, QTextCharFormat &format);

inline void skipSpace(const QChar *&ch) {
while (ch->isSpace() && !ch->isNull())
Expand All @@ -126,6 +129,7 @@ class QDeclarativeStyledTextPrivate
bool prependSpace;
bool hasSpace;
bool preloadImages;
bool *fontSizeModified;
QDeclarativeContext *context;

static const QChar lessThan;
Expand Down Expand Up @@ -160,8 +164,9 @@ QDeclarativeStyledText::QDeclarativeStyledText(const QString &string, QTextLayou
QList<QDeclarativeStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QDeclarativeContext *context,
bool preloadImages)
: d(new QDeclarativeStyledTextPrivate(string, layout, imgTags, baseUrl, context, preloadImages))
bool preloadImages,
bool *fontSizeModified)
: d(new QDeclarativeStyledTextPrivate(string, layout, imgTags, baseUrl, context, preloadImages, fontSizeModified))
{
}

Expand All @@ -174,11 +179,12 @@ void QDeclarativeStyledText::parse(const QString &string, QTextLayout &layout,
QList<QDeclarativeStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QDeclarativeContext *context,
bool preloadImages)
bool preloadImages,
bool *fontSizeModified)
{
if (string.isEmpty())
return;
QDeclarativeStyledText styledText(string, layout, imgTags, baseUrl, context, preloadImages);
QDeclarativeStyledText styledText(string, layout, imgTags, baseUrl, context, preloadImages, fontSizeModified);
styledText.d->parse();
}

Expand Down Expand Up @@ -298,6 +304,20 @@ void QDeclarativeStyledTextPrivate::appendText(const QString &textIn, int start,
hasNewLine = false;
}

//
// Calculates and sets the correct font size in points
// depending on the size multiplier and base font.
//
void QDeclarativeStyledTextPrivate::setFontSize(int size, QTextCharFormat &format)
{
static const qreal scaling[] = { 0.7, 0.8, 1.0, 1.2, 1.5, 2.0, 2.4 };
if (baseFont.pointSizeF() != -1)
format.setFontPointSize(baseFont.pointSize() * scaling[size - 1]);
else
format.setFontPointSize(baseFont.pixelSize() * qreal(72.) / qreal(qt_defaultDpi()) * scaling[size - 1]);
*fontSizeModified = true;
}

bool QDeclarativeStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn, QString &textOut, QTextCharFormat &format)
{
skipSpace(ch);
Expand Down Expand Up @@ -353,12 +373,11 @@ bool QDeclarativeStyledTextPrivate::parseTag(const QChar *&ch, const QString &te
} else if (char0 == QLatin1Char('h') && tagLength == 2) {
int level = tag.at(1).digitValue();
if (level >= 1 && level <= 6) {
static const qreal scaling[] = { 2.0, 1.5, 1.2, 1.0, 0.8, 0.7 };
if (!hasNewLine)
textOut.append(QChar::LineSeparator);
hasSpace = true;
prependSpace = false;
format.setFontPointSize(baseFont.pointSize() * scaling[level - 1]);
setFontSize(7 - level, format);
format.setFontWeight(QFont::Bold);
return true;
}
Expand Down Expand Up @@ -550,10 +569,8 @@ bool QDeclarativeStyledTextPrivate::parseFontAttributes(const QChar *&ch, const
int size = attr.second.toString().toInt();
if (attr.second.at(0) == QLatin1Char('-') || attr.second.at(0) == QLatin1Char('+'))
size += 3;
if (size >= 1 && size <= 7) {
static const qreal scaling[] = { 0.7, 0.8, 1.0, 1.2, 1.5, 2.0, 2.4 };
format.setFontPointSize(baseFont.pointSize() * scaling[size-1]);
}
if (size >= 1 && size <= 7)
setFontSize(size, format);
}
} while (!ch->isNull() && !attr.first.isEmpty());

Expand Down
6 changes: 4 additions & 2 deletions src/quick/util/qdeclarativestyledtext_p.h
Expand Up @@ -85,14 +85,16 @@ class Q_AUTOTEST_EXPORT QDeclarativeStyledText
QList<QDeclarativeStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QDeclarativeContext *context,
bool preloadImages);
bool preloadImages,
bool *fontSizeModified);

private:
QDeclarativeStyledText(const QString &string, QTextLayout &layout,
QList<QDeclarativeStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QDeclarativeContext *context,
bool preloadImages);
bool preloadImages,
bool *fontSizeModified);
~QDeclarativeStyledText();

QDeclarativeStyledTextPrivate *d;
Expand Down

0 comments on commit 12f0663

Please sign in to comment.