File indexing completed on 2024-04-14 14:21:00

0001 /*
0002     SPDX-FileCopyrightText: 2005, 2009, 2014 Albert Astals Cid <aacid@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "kfontutils.h"
0008 
0009 #include <QPainter>
0010 #include <qmath.h>
0011 
0012 static bool checkFits(QPainter &painter, const QString &string, qreal width, qreal height, qreal size, KFontUtils::AdaptFontSizeOptions flags)
0013 {
0014     QFont f = painter.font();
0015     f.setPointSizeF(size);
0016     painter.setFont(f);
0017     int qtFlags = Qt::AlignCenter | Qt::TextWordWrap;
0018     if (flags & KFontUtils::DoNotAllowWordWrap) {
0019         qtFlags &= ~Qt::TextWordWrap;
0020     }
0021     const QRectF boundingRect = painter.boundingRect(QRectF(0, 0, width, height), qtFlags, string);
0022     if (boundingRect.width() == 0.0 || boundingRect.height() == 0.0) {
0023         return false;
0024     } else if (boundingRect.width() > width || boundingRect.height() > height) {
0025         return false;
0026     }
0027     return true;
0028 }
0029 
0030 qreal KFontUtils::adaptFontSize(QPainter &painter,
0031                                 const QString &string,
0032                                 qreal width,
0033                                 qreal height,
0034                                 qreal maxFontSize,
0035                                 qreal minFontSize,
0036                                 AdaptFontSizeOptions flags)
0037 {
0038     // A invalid range is an error (-1)
0039     if (maxFontSize < minFontSize) {
0040         return -1;
0041     }
0042 
0043     // If the max font size already fits, return it
0044     if (checkFits(painter, string, width, height, maxFontSize, flags)) {
0045         return maxFontSize;
0046     }
0047 
0048     qreal fontSizeDoesNotFit = maxFontSize;
0049 
0050     // If the min font size does not fit, try to see if a font size of 1 fits,
0051     // if it does not return error (-1)
0052     // if it does, we'll return a fontsize smaller than the minFontSize as documented
0053     if (!checkFits(painter, string, width, height, minFontSize, flags)) {
0054         fontSizeDoesNotFit = minFontSize;
0055 
0056         minFontSize = 1;
0057         if (!checkFits(painter, string, width, height, minFontSize, flags)) {
0058             return -1;
0059         }
0060     }
0061 
0062     qreal fontSizeFits = minFontSize;
0063     qreal nextFontSizeToTry = (fontSizeDoesNotFit + fontSizeFits) / 2;
0064 
0065     while (qFloor(fontSizeFits) != qFloor(nextFontSizeToTry)) {
0066         if (checkFits(painter, string, width, height, nextFontSizeToTry, flags)) {
0067             fontSizeFits = nextFontSizeToTry;
0068             nextFontSizeToTry = (fontSizeDoesNotFit + fontSizeFits) / 2;
0069         } else {
0070             fontSizeDoesNotFit = nextFontSizeToTry;
0071             nextFontSizeToTry = (nextFontSizeToTry + fontSizeFits) / 2;
0072         }
0073     }
0074 
0075     QFont f = painter.font();
0076     f.setPointSizeF(fontSizeFits);
0077     painter.setFont(f);
0078 
0079     return fontSizeFits;
0080 }
0081 
0082 qreal KFontUtils::adaptFontSize(QPainter &painter,
0083                                 const QString &text,
0084                                 const QSizeF &availableSize,
0085                                 qreal maxFontSize,
0086                                 qreal minFontSize,
0087                                 AdaptFontSizeOptions flags)
0088 {
0089     return adaptFontSize(painter, text, availableSize.width(), availableSize.height(), maxFontSize, minFontSize, flags);
0090 }