KD Reports API Documentation 2.2
Loading...
Searching...
No Matches
KDReportsFontScaler.cpp
Go to the documentation of this file.
1/****************************************************************************
2**
3** This file is part of the KD Reports library.
4**
5** SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6**
7** SPDX-License-Identifier: MIT
8**
9****************************************************************************/
10
12#include <QDebug>
13#include <QFont>
14#include <QFontMetricsF>
15
16using namespace KDReports;
17
18FontScaler::FontScaler(const QFont &initialFont)
19 : m_font(initialFont)
20 , m_fontMetrics(m_font)
21 , m_initialFontMetrics(m_fontMetrics)
22 , m_scalingFactor(1.0)
23{
24}
25
26void FontScaler::setFontAndScalingFactor(const QFont &font, qreal scalingFactor)
27{
28#ifdef DEBUG_LAYOUT
29 // qDebug() << "setFontAndScalingFactor scalingFactor=" << scalingFactor;
30#endif
31 m_font = font;
32 m_scalingFactor = scalingFactor;
33 if (m_font.pixelSize() == -1)
34 m_font.setPointSizeF(m_font.pointSizeF() * scalingFactor);
35 else
36 m_font.setPixelSize(qRound(m_font.pixelSize() * scalingFactor));
37 m_fontMetrics = QFontMetricsF(m_font);
38 m_initialFontMetrics = m_fontMetrics;
39}
40
42{
43 // TODO this should be calculated in the end, using finalWidth/initialWidth. It's currently messed up by the -0.1 below for instance.
44 m_scalingFactor *= factor;
45
46 if (m_font.pixelSize() == -1) {
47 if (factor > 0.99 && factor < 1.000) // applying 0.999 forever can take a very long time ;)
48 m_font.setPointSizeF(m_font.pointSizeF() - 0.1);
49 else
50 m_font.setPointSizeF(m_font.pointSizeF() * factor);
51 } else {
52 if (m_font.pixelSize() > 2 && factor > 0.99 && factor < 1.000)
53 m_font.setPixelSize(m_font.pixelSize() - 1);
54 else
55 m_font.setPixelSize(int(m_font.pixelSize() * factor));
56 }
57#ifdef DEBUG_LAYOUT
58 qDebug() << " applyAdditionalScalingFactor" << factor << "combined factor:" << m_scalingFactor << "pointSize:" << m_font.pointSizeF() << "pixelSize:" << m_font.pixelSize();
59#endif
60 m_fontMetrics = QFontMetricsF(m_font);
61}
62
63static qreal textWidthForMetrics(const QFontMetricsF &fm, const QString &text)
64{
65#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
66 return fm.width(text);
67#else
68 return fm.size(Qt::TextSingleLine, text).width();
69#endif
70}
71
72qreal FontScaler::textWidth(const QString &text) const
73{
74 return textWidthForMetrics(m_fontMetrics, text);
75}
76
77void FontScaler::setFactorForHeight(qreal wantedHeight)
78{
79#ifdef DEBUG_LAYOUT
80 qDebug() << " FontScaler::setFactorForHeight" << wantedHeight;
81#endif
82 Q_ASSERT(wantedHeight > 0);
83 qreal height = m_fontMetrics.height();
84 int iterations = 0;
85
86 while (height > wantedHeight && height > 3.0 /* seems to be the min we can get */) {
87 const qreal factor = wantedHeight / height;
89 qreal prevHeight = height;
90 height = m_fontMetrics.height();
91#ifdef DEBUG_LAYOUT
92 qDebug() << " FontScaler: height=" << height << factor << m_scalingFactor;
93#endif
94 if (++iterations > 10 && height == prevHeight) {
95 // We're not getting anywhere, probably we're hitting a minimum width when
96 // trying to use a very, very small font (see unittest testFontScalerVerySmall)
97 break;
98 }
99 if (m_font.pixelSize() == 1) {
100 break;
101 }
102 }
103}
104
105void FontScaler::setFactorForWidth(qreal wantedFactor, const QString &sampleText)
106{
107#ifdef DEBUG_LAYOUT
108 qDebug() << " FontScaler::setFactorForWidth" << wantedFactor;
109#endif
110 // Just applying that scaling factor for the font size isn't enough,
111 // fonts do not scale proportionnally. We need do this like
112 // "scale the font so that this text fits into this width"
113 const qreal initialWidth = textWidthForMetrics(m_initialFontMetrics, sampleText);
114 const qreal wantedWidth = initialWidth * wantedFactor;
115 qreal width = textWidth(sampleText);
116#ifdef DEBUG_LAYOUT
117 qDebug() << " FontScaler: sampleText with initialFontMetrics:" << initialWidth << "with current fontMetrics:" << width << "wanted:" << wantedWidth;
118#endif
119
120 int iterations = 0;
121
122 while (width > wantedWidth) {
123 qreal factor = wantedWidth / width;
125 qreal prevWidth = width;
126 width = textWidth(sampleText);
127#ifdef DEBUG_LAYOUT
128 qDebug() << " FontScaler: width=" << width << "factor=" << factor << "m_scalingFactor=" << m_scalingFactor;
129#endif
130 if (++iterations > 10 && width == prevWidth) {
131 // We're not getting anywhere, probably we're hitting a minimum width when
132 // trying to use a very, very small font (see unittest testFontScalerVerySmall)
133 break;
134 }
135 }
136}
static qreal textWidthForMetrics(const QFontMetricsF &fm, const QString &text)
qreal textWidth(const QString &text) const
void applyAdditionalScalingFactor(qreal factor)
void setFactorForWidth(qreal wantedFactor, const QString &sampleText)
void setFactorForHeight(qreal wantedHeight)
FontScaler(const QFont &initialFont)
void setFontAndScalingFactor(const QFont &font, qreal scalingFactor)
int pixelSize() const const
qreal pointSizeF() const const
void setPixelSize(int pixelSize)
void setPointSizeF(qreal pointSize)
qreal width(const QString &text) const const
qreal height() const const
QSizeF size(int flags, const QString &text, int tabStops, int *tabArray) const const
qreal width() const const
TextSingleLine

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-reports/
Generated on Wed Apr 24 2024 04:08:14 for KD Reports API Documentation by doxygen 1.9.8