replaced qt font scaling

remove the qt font scaling and added code that uses the actual scale/dpi value
This commit is contained in:
fourtf
2017-12-23 21:18:13 +01:00
parent c9aa716f58
commit fc81b118c7
21 changed files with 298 additions and 155 deletions
+8 -4
View File
@@ -83,13 +83,15 @@ void AddCurrentTimestamp(Message *message)
strftime(timeStampBuffer, 69, "%H:%M", localtime(&t));
QString timestampNoSeconds(timeStampBuffer);
message->getWords().push_back(Word(timestampNoSeconds, Word::TimestampNoSeconds,
MessageColor(MessageColor::System), QString(), QString()));
MessageColor(MessageColor::System), FontManager::Medium,
QString(), QString()));
// Add word for timestamp with seconds
strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&t));
QString timestampWithSeconds(timeStampBuffer);
message->getWords().push_back(Word(timestampWithSeconds, Word::TimestampWithSeconds,
MessageColor(MessageColor::System), QString(), QString()));
MessageColor(MessageColor::System), FontManager::Medium,
QString(), QString()));
}
} // namespace
@@ -101,7 +103,8 @@ Message *Message::createSystemMessage(const QString &text)
AddCurrentTimestamp(message);
Word word(text, Word::Type::Default, MessageColor(MessageColor::Type::System), text, QString());
Word word(text, Word::Flags::Default, MessageColor(MessageColor::Type::System),
FontManager::Medium, text, QString());
message->getWords().push_back(word);
@@ -142,7 +145,8 @@ Message *Message::createTimeoutMessage(const QString &username, const QString &d
}
text.append(".");
Word word(text, Word::Type::Default, MessageColor(MessageColor::Type::System), text, QString());
Word word(text, Word::Flags::Default, MessageColor(MessageColor::Type::System),
FontManager::Medium, text, QString());
message->getWords().push_back(word);
+4 -2
View File
@@ -42,13 +42,15 @@ void MessageBuilder::appendTimestamp(time_t time)
strftime(timeStampBuffer, 69, "%H:%M", localtime(&time));
QString timestampNoSeconds(timeStampBuffer);
this->appendWord(Word(timestampNoSeconds, Word::TimestampNoSeconds,
MessageColor(MessageColor::System), QString(), QString()));
MessageColor(MessageColor::System), FontManager::Medium, QString(),
QString()));
// Add word for timestamp with seconds
strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&time));
QString timestampWithSeconds(timeStampBuffer);
this->appendWord(Word(timestampWithSeconds, Word::TimestampWithSeconds,
MessageColor(MessageColor::System), QString(), QString()));
MessageColor(MessageColor::System), FontManager::Medium, QString(),
QString()));
}
QString MessageBuilder::matchLink(const QString &string)
+37 -53
View File
@@ -4,10 +4,10 @@
#include <QDebug>
#define MARGIN_LEFT (int)(8 * this->dpiMultiplier)
#define MARGIN_RIGHT (int)(8 * this->dpiMultiplier)
#define MARGIN_TOP (int)(4 * this->dpiMultiplier)
#define MARGIN_BOTTOM (int)(4 * this->dpiMultiplier)
#define MARGIN_LEFT (int)(8 * this->scale)
#define MARGIN_RIGHT (int)(8 * this->scale)
#define MARGIN_TOP (int)(4 * this->scale)
#define MARGIN_BOTTOM (int)(4 * this->scale)
using namespace chatterino::messages;
@@ -32,11 +32,11 @@ int MessageRef::getHeight() const
}
// return true if redraw is required
bool MessageRef::layout(int width, float dpiMultiplyer)
bool MessageRef::layout(int width, float scale)
{
auto &emoteManager = EmoteManager::getInstance();
bool layoutRequired = false;
bool rebuildRequired = false, layoutRequired = false;
// check if width changed
bool widthChanged = width != this->currentLayoutWidth;
@@ -60,11 +60,11 @@ bool MessageRef::layout(int width, float dpiMultiplyer)
this->currentWordTypes = SettingsManager::getInstance().getWordTypeMask();
// check if dpi changed
bool dpiChanged = this->dpiMultiplier != dpiMultiplyer;
layoutRequired |= dpiChanged;
this->dpiMultiplier = dpiMultiplyer;
imagesChanged |= dpiChanged;
textChanged |= dpiChanged;
bool scaleChanged = this->scale != scale;
layoutRequired |= scaleChanged;
this->scale = scale;
imagesChanged |= scaleChanged;
textChanged |= scaleChanged;
// update word sizes if needed
if (imagesChanged) {
@@ -119,7 +119,7 @@ void MessageRef::actuallyLayout(int width)
Word &word = *it;
// Check if given word is supposed to be rendered by comparing it to the current setting
if ((word.getType() & flags) == Word::None) {
if ((word.getFlags() & flags) == Word::None) {
continue;
}
@@ -135,7 +135,7 @@ void MessageRef::actuallyLayout(int width)
/// }
// word wrapping
if (word.isText() && word.getWidth() + MARGIN_LEFT > right) {
if (word.isText() && word.getWidth(this->scale) + MARGIN_LEFT > right) {
// align and end the current line
alignWordParts(lineStart, lineHeight, width, firstLineHeight);
y += lineHeight;
@@ -145,17 +145,17 @@ void MessageRef::actuallyLayout(int width)
// go through the text, break text when it doesn't fit in the line anymore
for (int i = 1; i <= word.getText().length(); i++) {
currentLineWidth += word.getCharWidth(i - 1);
currentLineWidth += word.getCharWidth(i - 1, this->scale);
if (currentLineWidth + MARGIN_LEFT > right) {
// add the current line
QString mid = word.getText().mid(currentPartStart, i - currentPartStart - 1);
this->wordParts.push_back(WordPart(word, MARGIN_LEFT, y, currentLineWidth,
word.getHeight(), lineNumber, mid, mid,
false, currentPartStart));
word.getHeight(this->scale), lineNumber, mid,
mid, false, currentPartStart));
y += word.getFontMetrics().height();
y += word.getFontMetrics(this->scale).height();
currentPartStart = i - 1;
@@ -165,27 +165,27 @@ void MessageRef::actuallyLayout(int width)
}
QString mid(word.getText().mid(currentPartStart));
currentLineWidth = word.getFontMetrics().width(mid);
currentLineWidth = word.getFontMetrics(this->scale).width(mid);
this->wordParts.push_back(WordPart(word, MARGIN_LEFT, y - word.getHeight(),
currentLineWidth, word.getHeight(), lineNumber, mid,
mid, true, currentPartStart));
this->wordParts.push_back(WordPart(word, MARGIN_LEFT, y - word.getHeight(this->scale),
currentLineWidth, word.getHeight(this->scale),
lineNumber, mid, mid, true, currentPartStart));
x = currentLineWidth + MARGIN_LEFT + spaceWidth;
lineHeight = word.getHeight();
lineHeight = word.getHeight(this->scale);
lineStart = this->wordParts.size() - 1;
first = false;
}
// fits in the current line
else if (first || x + word.getWidth() + xOffset <= right) {
this->wordParts.push_back(
WordPart(word, x, y - word.getHeight(), lineNumber, word.getCopyText()));
else if (first || x + word.getWidth(this->scale) + xOffset <= right) {
this->wordParts.push_back(WordPart(word, x, y - word.getHeight(this->scale), scale,
lineNumber, word.getCopyText()));
x += word.getWidth() + xOffset;
x += word.getWidth(this->scale) + xOffset;
x += spaceWidth;
lineHeight = std::max(word.getHeight(), lineHeight);
lineHeight = std::max(word.getHeight(this->scale), lineHeight);
first = false;
}
@@ -198,14 +198,14 @@ void MessageRef::actuallyLayout(int width)
lineNumber++;
this->wordParts.push_back(
WordPart(word, MARGIN_LEFT, y - word.getHeight(), lineNumber, word.getCopyText()));
this->wordParts.push_back(WordPart(word, MARGIN_LEFT, y - word.getHeight(this->scale),
this->scale, lineNumber, word.getCopyText()));
lineStart = this->wordParts.size() - 1;
lineHeight = word.getHeight();
lineHeight = word.getHeight(this->scale);
x = word.getWidth() + MARGIN_LEFT;
x = word.getWidth(this->scale) + MARGIN_LEFT;
x += spaceWidth;
}
}
@@ -213,7 +213,7 @@ void MessageRef::actuallyLayout(int width)
// align and end the current line
alignWordParts(lineStart, lineHeight, width, firstLineHeight);
this->collapsedHeight = firstLineHeight == -1 ? (int)(24 * dpiMultiplier)
this->collapsedHeight = firstLineHeight == -1 ? (int)(24 * this->scale)
: firstLineHeight + MARGIN_TOP + MARGIN_BOTTOM;
// update height
@@ -236,37 +236,21 @@ void MessageRef::actuallyLayout(int width)
void MessageRef::updateTextSizes()
{
for (auto &word : this->message->getWords()) {
if (!word.isText())
if (!word.isText()) {
continue;
}
QFontMetrics &metrics = word.getFontMetrics();
word.setSize((int)(metrics.width(word.getText()) * this->dpiMultiplier),
(int)(metrics.height() * this->dpiMultiplier));
word.updateSize();
}
}
void MessageRef::updateImageSizes()
{
const int mediumTextLineHeight =
FontManager::getInstance().getFontMetrics(FontManager::Medium).height();
const qreal emoteScale = SettingsManager::getInstance().emoteScale.get() * this->dpiMultiplier;
const bool scaleEmotesByLineHeight = SettingsManager::getInstance().scaleEmotesByLineHeight;
for (auto &word : this->message->getWords()) {
if (!word.isImage())
continue;
auto &image = word.getImage();
qreal w = image.getWidth();
qreal h = image.getHeight();
if (scaleEmotesByLineHeight) {
word.setSize(w * mediumTextLineHeight / h * emoteScale,
mediumTextLineHeight * emoteScale);
} else {
word.setSize(w * image.getScale() * emoteScale, h * image.getScale() * emoteScale);
}
word.updateSize();
}
}
@@ -406,7 +390,7 @@ int MessageRef::getSelectionIndex(QPoint position)
}
index++;
x = part.getX() + part.getWord().getFontMetrics().width(text, j + 1);
x = part.getX() + part.getWord().getFontMetrics(this->scale).width(text, j + 1);
}
}
+5 -3
View File
@@ -22,7 +22,7 @@ public:
Message *getMessage();
int getHeight() const;
bool layout(int width, float dpiMultiplier);
bool layout(int width, float scale);
const std::vector<WordPart> &getWordParts() const;
@@ -36,6 +36,7 @@ public:
bool isCollapsed() const;
void setCollapsed(bool value);
int getCollapsedHeight() const;
int getCollapsedLineCount() const;
private:
// variables
@@ -47,14 +48,15 @@ private:
int currentLayoutWidth = -1;
int fontGeneration = -1;
int emoteGeneration = -1;
float dpiMultiplier = -1;
float scale = -1;
Word::Type currentWordTypes = Word::None;
Word::Flags currentWordTypes = Word::None;
bool collapsed;
int collapsedHeight = 32;
// methods
void rebuild();
void actuallyLayout(int width);
void alignWordParts(int lineStart, int lineHeight, int width, int &firstLineHeight);
void updateTextSizes();
+76 -23
View File
@@ -1,11 +1,12 @@
#include "messages/word.hpp"
#include "settingsmanager.hpp"
#include "util/benchmark.hpp"
namespace chatterino {
namespace messages {
// Image word
Word::Word(LazyLoadedImage *image, Type type, const QString &copytext, const QString &tooltip,
Word::Word(LazyLoadedImage *image, Flags type, const QString &copytext, const QString &tooltip,
const Link &link)
: image(image)
, _isImage(true)
@@ -14,15 +15,15 @@ Word::Word(LazyLoadedImage *image, Type type, const QString &copytext, const QSt
, tooltip(tooltip)
, link(link)
{
image->getWidth(); // professional segfault test
}
// Text word
Word::Word(const QString &text, Type type, const MessageColor &color, const QString &copytext,
const QString &tooltip, const Link &link)
Word::Word(const QString &text, Flags type, const MessageColor &color, FontManager::Type font,
const QString &copytext, const QString &tooltip, const Link &link)
: image(nullptr)
, text(text)
, color(color)
, font(font)
, _isImage(false)
, type(type)
, copyText(copytext)
@@ -41,20 +42,54 @@ const QString &Word::getText() const
return this->text;
}
int Word::getWidth() const
int Word::getWidth(float scale) const
{
return this->width;
return this->getSize(scale).width();
}
int Word::getHeight() const
int Word::getHeight(float scale) const
{
return this->height;
return this->getSize(scale).height();
}
void Word::setSize(int width, int height)
QSize Word::getSize(float scale) const
{
this->width = width;
this->height = height;
auto &data = this->getDataByScale(scale);
if (data.size.isEmpty()) {
// no size found
if (this->isText()) {
QFontMetrics &metrics = this->getFontMetrics(scale);
data.size.setWidth((int)(metrics.width(this->getText())));
data.size.setHeight((int)(metrics.height()));
} else {
const int mediumTextLineHeight =
FontManager::getInstance().getFontMetrics(this->font, scale).height();
const qreal emoteScale = SettingsManager::getInstance().emoteScale.get() * scale;
const bool scaleEmotesByLineHeight =
SettingsManager::getInstance().scaleEmotesByLineHeight;
auto &image = this->getImage();
qreal w = image.getWidth();
qreal h = image.getHeight();
if (scaleEmotesByLineHeight) {
data.size.setWidth(w * mediumTextLineHeight / h * emoteScale);
data.size.setHeight(mediumTextLineHeight * emoteScale);
} else {
data.size.setWidth(w * image.getScale() * emoteScale);
data.size.setHeight(h * image.getScale() * emoteScale);
}
}
}
return data.size;
}
void Word::updateSize()
{
this->dataByScale.clear();
}
bool Word::isImage() const
@@ -77,17 +112,17 @@ bool Word::hasTrailingSpace() const
return this->_hasTrailingSpace;
}
QFont &Word::getFont() const
QFont &Word::getFont(float scale) const
{
return FontManager::getInstance().getFont(this->font);
return FontManager::getInstance().getFont(this->font, scale);
}
QFontMetrics &Word::getFontMetrics() const
QFontMetrics &Word::getFontMetrics(float scale) const
{
return FontManager::getInstance().getFontMetrics(this->font);
return FontManager::getInstance().getFontMetrics(this->font, scale);
}
Word::Type Word::getType() const
Word::Flags Word::getFlags() const
{
return this->type;
}
@@ -97,7 +132,7 @@ const QString &Word::getTooltip() const
return this->tooltip;
}
const MessageColor &Word::getColor() const
const MessageColor &Word::getTextColor() const
{
return this->color;
}
@@ -128,24 +163,42 @@ int Word::getCharacterLength() const
return this->isImage() ? 2 : this->getText().length() + 1;
}
short Word::getCharWidth(int index) const
short Word::getCharWidth(int index, float scale) const
{
return this->getCharacterWidthCache().at(index);
return this->getCharacterWidthCache(scale).at(index);
}
std::vector<short> &Word::getCharacterWidthCache() const
std::vector<short> &Word::getCharacterWidthCache(float scale) const
{
auto &data = this->getDataByScale(scale);
// lock not required because there is only one gui thread
// std::lock_guard<std::mutex> lock(this->charWidthCacheMutex);
if (this->charWidthCache.size() == 0 && this->isText()) {
if (data.charWidthCache.size() == 0 && this->isText()) {
for (int i = 0; i < this->getText().length(); i++) {
this->charWidthCache.push_back(this->getFontMetrics().charWidth(this->getText(), i));
data.charWidthCache.push_back(
this->getFontMetrics(scale).charWidth(this->getText(), i));
}
}
// TODO: on font change
return this->charWidthCache;
return data.charWidthCache;
}
Word::ScaleDependantData &Word::getDataByScale(float scale) const
{
// try to find and return data for scale
for (auto it = this->dataByScale.begin(); it != this->dataByScale.end(); it++) {
if (it->scale == scale) {
return *it;
}
}
// create new data element and return that
this->dataByScale.emplace_back(scale);
return this->dataByScale.back();
}
} // namespace messages
+36 -20
View File
@@ -4,6 +4,7 @@
#include "messages/lazyloadedimage.hpp"
#include "messages/link.hpp"
#include "messages/messagecolor.hpp"
//#include "wordflags.hpp"
#include <stdint.h>
#include <QRect>
@@ -15,7 +16,7 @@ namespace messages {
class Word
{
public:
enum Type : uint32_t {
enum Flags : uint32_t {
None = 0,
Misc = (1 << 0),
Text = (1 << 1),
@@ -92,33 +93,36 @@ public:
{
}
explicit Word(LazyLoadedImage *_image, Type getType, const QString &copytext,
explicit Word(LazyLoadedImage *_image, Flags getFlags, const QString &copytext,
const QString &tooltip, const Link &getLink = Link());
explicit Word(const QString &_text, Type getType, const MessageColor &getColor,
const QString &copytext, const QString &tooltip, const Link &getLink = Link());
LazyLoadedImage &getImage() const;
const QString &getText() const;
int getWidth() const;
int getHeight() const;
void setSize(int _width, int _height);
explicit Word(const QString &_text, Flags getFlags, const MessageColor &textColor,
FontManager::Type font, const QString &copytext, const QString &tooltip,
const Link &getLink = Link());
bool isImage() const;
bool isText() const;
LazyLoadedImage &getImage() const;
const QString &getText() const;
const QString &getCopyText() const;
bool hasTrailingSpace() const;
QFont &getFont() const;
QFontMetrics &getFontMetrics() const;
Type getType() const;
Flags getFlags() const;
const QString &getTooltip() const;
const MessageColor &getColor() const;
const MessageColor &getTextColor() const;
const Link &getLink() const;
int getXOffset() const;
int getYOffset() const;
void setOffset(int _xOffset, int _yOffset);
int getCharacterLength() const;
short getCharWidth(int index) const;
void updateSize();
QFont &getFont(float scale) const;
QFontMetrics &getFontMetrics(float scale) const;
int getWidth(float scale) const;
int getHeight(float scale) const;
QSize getSize(float scale) const;
short getCharWidth(int index, float scale) const;
private:
LazyLoadedImage *image;
@@ -126,12 +130,10 @@ private:
MessageColor color;
bool _isImage;
Type type;
Flags type;
QString copyText;
QString tooltip;
int width = 16;
int height = 16;
int xOffset = 0;
int yOffset = 0;
@@ -139,8 +141,22 @@ private:
FontManager::Type font = FontManager::Medium;
Link link;
std::vector<short> &getCharacterWidthCache() const;
mutable std::vector<short> charWidthCache;
struct ScaleDependantData {
float scale;
QSize size;
mutable std::vector<short> charWidthCache;
ScaleDependantData(float _scale)
: scale(_scale)
, size()
{
}
};
mutable std::list<ScaleDependantData> dataByScale;
inline ScaleDependantData &getDataByScale(float scale) const;
std::vector<short> &getCharacterWidthCache(float scale) const;
};
} // namespace messages
+1
View File
@@ -0,0 +1 @@
#pragma once
+6 -6
View File
@@ -4,15 +4,15 @@
namespace chatterino {
namespace messages {
WordPart::WordPart(Word &_word, int _x, int _y, int _lineNumber, const QString &_copyText,
bool _allowTrailingSpace)
WordPart::WordPart(Word &_word, int _x, int _y, float scale, int _lineNumber,
const QString &_copyText, bool _allowTrailingSpace)
: word(_word)
, copyText(_copyText)
, text(_word.isText() ? _word.getText() : QString())
, x(_x)
, y(_y)
, width(_word.getWidth())
, height(_word.getHeight())
, width(_word.getWidth(scale))
, height(_word.getHeight(scale))
, lineNumber(_lineNumber)
, _trailingSpace(!_word.getCopyText().isEmpty() &&
_word.hasTrailingSpace() & _allowTrailingSpace)
@@ -115,9 +115,9 @@ int WordPart::getCharacterLength() const
return this->getWord().isImage() ? 2 : this->getText().length() + 1;
}
short WordPart::getCharWidth(int index) const
short WordPart::getCharWidth(int index, float scale) const
{
return this->getWord().getCharWidth(index + this->wordCharOffset);
return this->getWord().getCharWidth(index + this->wordCharOffset, scale);
}
} // namespace messages
} // namespace chatterino
+3 -3
View File
@@ -11,8 +11,8 @@ class Word;
class WordPart
{
public:
WordPart(Word &getWord, int getX, int getY, int _lineNumber, const QString &getCopyText,
bool allowTrailingSpace = true);
WordPart(Word &getWord, int getX, int getY, float scale, int _lineNumber,
const QString &getCopyText, bool allowTrailingSpace = true);
WordPart(Word &getWord, int getX, int getY, int getWidth, int getHeight, int _lineNumber,
const QString &getCopyText, const QString &customText, bool allowTrailingSpace = true,
@@ -33,7 +33,7 @@ public:
const QString &getText() const;
int getLineNumber() const;
int getCharacterLength() const;
short getCharWidth(int index) const;
short getCharWidth(int index, float scale) const;
private:
Word &word;