#include "PicCounterItem.h" #include #include #include #include #include #include QHash defCharWidthMap; int charWidth(QFont font, int height) { font.setLetterSpacing(QFont::AbsoluteSpacing, 0); font.setPixelSize(height); QFontMetrics fm(font); return fm.horizontalAdvance("0123456789") / 10; } PicCounterItem::PicCounterItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type) :PicTextItem(parent, scene, type) { } QVariant PicCounterItem::source() { return PicTextItem::source(); } void PicCounterItem::setSource(QVariant var) { PicTextItem::setSource(var); setCounter(counterType(), digitalNum(), m_displayNum); } void PicCounterItem::setCounter(COUNTER_TYPE type, int digitalNum, int displayNum) { if(type != COUNTER_TYPE_1 && type != COUNTER_TYPE_2) { qWarning() << "Missing counter type: " << type; return; } // 直接修改字体,生成新的HTML占位图 auto font = this->font(); QString fontname = font.family(); int pixelSize = 9; QString numStr = ""; for(int i = fontname.length() - 1; i >= 0; --i) { if(fontname[i].isDigit()) { numStr.prepend(fontname[i]); } else { break; } } if(!numStr.isEmpty()) { pixelSize = numStr.toInt(); } font.setFamily(fontname); font.setPixelSize(pixelSize); font.setWeight(false && (pixelSize<=16) ? QFont::Bold : QFont::Normal); font.setLetterSpacing(QFont::AbsoluteSpacing, 0); QFontMetrics fontMetrics(font); int width = (fontMetrics.horizontalAdvance("0123456789")) / 10; int height = font.pixelSize(); width += letterSpace(); // 计算像素长度最长的数字 0 - 9 int digital = 0; int digitalWidth = 0; for(int i = 0; i <= 9; ++i) { auto w = fontMetrics.horizontalAdvance(QString::number(i)); if(w > digitalWidth) { digitalWidth = w; digital = i; } } m_counterType = type; m_digitalNum = qBound(1, digitalNum, 8); m_digitalImg = strToImage(QString::number(digital).repeated(m_digitalNum)); m_displayNum = displayNum; // 临时使用这种手法显示当前值吧 m_digitalImg.fill(0x00000000); auto displayNumImage = strToImage(QString::number(displayNum).rightJustified(m_digitalNum, '0').right(m_digitalNum)); QPainter p; p.begin(&m_digitalImg); p.drawImage(QPoint(0, 0), displayNumImage); p.end(); applyModify(); qInfo() << "Counter item set to " << type ; qInfo() << ">\tdigitalNum: " << m_digitalNum << ", font name: " << fontname << ", pixel size: " << pixelSize; qInfo() << ">\tletterSpace: " << letterSpace() << "charRom width: " << m_digitalNum * width << " width: " << width; } int PicCounterItem::charWidth() { if(!m_charWidthMap.contains(font().family())) return 0; return m_charWidthMap[font().family()]; } void PicCounterItem::setCharWidth(int width) { m_charWidthMap[font().family()] = width; setCounter(counterType(), digitalNum(), m_displayNum); } QImage PicCounterItem::itemImage() { return m_digitalImg; } void PicCounterItem::setCustomAttrs(const QXmlStreamAttributes &attrs) { auto typeRef = attrs.value("counter_type"); auto digitalNumRef = attrs.value("digital_num"); auto displayNumRef = attrs.value("display_num"); bool ok = false; int counterType = typeRef.toInt(&ok); if(!ok || (counterType != COUNTER_TYPE_1 && COUNTER_TYPE_2 != counterType)) { qWarning() << "Invalied counter type: " << counterType; return; } ok = false; int digitalNum = digitalNumRef.toInt(&ok); if(!ok || digitalNum <= 0) { qWarning() << "Invalied counter digital number: " << digitalNum; return; } ok = false; int displayNum = displayNumRef.toInt(&ok); if(!ok || displayNum <= 0) { qWarning() << "Invalied counter display number: " << displayNum; return; } setCounter(static_cast(counterType), digitalNum, displayNum); qInfo() << "Loaded attrs from xml: " << " counter type: " << counterType << ", digitalNum: " << digitalNum; } void PicCounterItem::saveCustomAttrs(QXmlStreamAttributes &attrs) { attrs.append("counter_type", QString::number(counterType())); attrs.append("digital_num", QString::number(digitalNum())); attrs.append("display_num", QString::number(m_displayNum)); qInfo() << "Set attrs to xml: " << " counter type: " << counterType() << ", digitalNum: " << digitalNum(); } void PicCounterItem::letterSpaceChanged() { setSource(source()); }