修改日期类型图元大小计算方式,以可能最长的长度计算
This commit is contained in:
+126
-2
@@ -1,9 +1,80 @@
|
||||
#include "PicDateItem.h"
|
||||
#include <QDebug>
|
||||
#include <QRegExp>
|
||||
#include <QPainter>
|
||||
#include <QElapsedTimer>
|
||||
#include "LogInfo.h"
|
||||
#include "ItemCommon.h"
|
||||
|
||||
// 生成可能的最长时间字符串供尺寸计算使用(基于像素宽度)
|
||||
static QString generateMaxDateTimeString(const DateItemModel &model, const QFont &font)
|
||||
{
|
||||
if (model.datetimePattern.isEmpty())
|
||||
return QString();
|
||||
|
||||
QString s = model.datetimePattern;
|
||||
|
||||
QFontMetrics fm(font);
|
||||
|
||||
auto longestFromList = [&fm] (const QStringList &lst, const QString &fallback) {
|
||||
int bestW = -1;
|
||||
QString best;
|
||||
for (const auto &v : lst) {
|
||||
int w = fm.horizontalAdvance(v);
|
||||
if (w > bestW) { bestW = w; best = v; }
|
||||
}
|
||||
return best.isEmpty() ? fallback : best;
|
||||
};
|
||||
|
||||
int i = s.indexOf("yyyy");
|
||||
if (i != -1) {
|
||||
QString repl;
|
||||
if (!model.yearsMap.isEmpty()) {
|
||||
for (auto v : model.yearsMap.values()) if (v.length() > repl.length()) repl = v;
|
||||
} else {
|
||||
repl = QString::number(QDate::currentDate().year());
|
||||
}
|
||||
s.replace(i, 4, repl);
|
||||
}
|
||||
|
||||
i = s.indexOf("YY");
|
||||
if (i != -1) {
|
||||
// 以像素宽度为准,'88' 通常足够宽
|
||||
s.replace(i, 2, QString("88"));
|
||||
}
|
||||
|
||||
i = s.indexOf("MM");
|
||||
if (i != -1) {
|
||||
s.replace(i, 2, longestFromList(model.monthsMap, QString("88")));
|
||||
}
|
||||
|
||||
i = s.indexOf("dd");
|
||||
if (i != -1) {
|
||||
s.replace(i, 2, longestFromList(model.daysMap, QString("88")));
|
||||
}
|
||||
|
||||
i = s.indexOf("HH");
|
||||
if (i != -1) {
|
||||
s.replace(i, 2, longestFromList(model.hoursMap, QString("88")));
|
||||
}
|
||||
|
||||
QRegExp minutePattern("mm");
|
||||
if (s.contains(minutePattern)) s.replace(minutePattern, QString("88"));
|
||||
|
||||
QRegExp secondPattern("ss");
|
||||
if (s.contains(secondPattern)) s.replace(secondPattern, QString("88"));
|
||||
|
||||
i = s.indexOf("w");
|
||||
if (i != -1) {
|
||||
s.replace(i, 1, longestFromList(model.weeksMap, QString("888")));
|
||||
}
|
||||
|
||||
QRegExp weekNumberPattern("c");
|
||||
if (s.contains(weekNumberPattern)) s.replace(weekNumberPattern, QString("88"));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
PicDateItem::PicDateItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
|
||||
:PicTextItem(parent, scene, type)
|
||||
{
|
||||
@@ -33,6 +104,27 @@ void PicDateItem::setSource(QVariant var)
|
||||
void PicDateItem::setModel(DateItemModel model)
|
||||
{
|
||||
m_model = std::move(model);
|
||||
|
||||
// 计时:测量生成最长字符串和字体度量两段耗时
|
||||
QElapsedTimer t1;
|
||||
t1.start();
|
||||
m_maxDateTimeStr = generateMaxDateTimeString(m_model, font());
|
||||
qint64 genUs = t1.nsecsElapsed() / 1000; // microseconds
|
||||
|
||||
QElapsedTimer t2;
|
||||
t2.start();
|
||||
if (m_maxDateTimeStr.isEmpty()) {
|
||||
m_maxSize = QSize();
|
||||
} else {
|
||||
QFontMetrics fm(font());
|
||||
int w = fm.horizontalAdvance(m_maxDateTimeStr);
|
||||
int h = fm.height();
|
||||
m_maxSize = QSize(w, h);
|
||||
}
|
||||
qint64 fmUs = t2.nsecsElapsed() / 1000; // microseconds
|
||||
|
||||
qDebug() << "PicDateItem::setModel timing(us): generate=" << genUs << ", fm=" << fmUs << ", total=" << (genUs + fmUs);
|
||||
|
||||
setSource(m_model.datetimePattern);
|
||||
}
|
||||
|
||||
@@ -84,6 +176,38 @@ QImage PicDateItem::itemImage()
|
||||
if(m_model.datetimePattern.isEmpty())
|
||||
return QImage();
|
||||
|
||||
auto ret = strToImage(m_currDateTimeStr);
|
||||
return ret;
|
||||
auto currImg = strToImage(m_currDateTimeStr);
|
||||
|
||||
if (m_maxSize.isEmpty())
|
||||
return currImg;
|
||||
|
||||
int width = qMax(currImg.width(), m_maxSize.width());
|
||||
int height = qMax(currImg.height(), m_maxSize.height());
|
||||
|
||||
QImage img(width, height, QImage::Format_ARGB32);
|
||||
img.fill(QColor(0,0,0,0).rgba());
|
||||
|
||||
QPainter painter(&img);
|
||||
int y = (height - currImg.height()) / 2;
|
||||
painter.drawImage(0, y, currImg);
|
||||
painter.end();
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
QRectF PicDateItem::boundingRect() const
|
||||
{
|
||||
// 优先使用已经应用变换后的 m_itemImage(与 PicTextItem 保持一致)
|
||||
if (!m_itemImage.isNull()) {
|
||||
return QRectF(0, 0, m_itemImage.width(), m_itemImage.height());
|
||||
}
|
||||
|
||||
// 否则基于缓存的最大像素尺寸和粗体倍数估算
|
||||
int w = m_maxSize.width();
|
||||
int h = m_maxSize.height();
|
||||
if (w <= 0 || h <= 0)
|
||||
return QGraphicsTextItem::boundingRect();
|
||||
|
||||
qreal bw = qreal(w) * qMax(1, m_boldMultiple);
|
||||
return QRectF(0, 0, bw, qreal(h));
|
||||
}
|
||||
Reference in New Issue
Block a user