diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp index 4834c2fc..74b4bedc 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp @@ -27,6 +27,7 @@ MxcImageProvider::requestImageResponse(const QString &id, const QSize &requested auto id_ = id; bool crop = true; double radius = 0; + auto size = requestedSize; auto queryStart = id.lastIndexOf('?'); if (queryStart != -1) { @@ -39,11 +40,14 @@ MxcImageProvider::requestImageResponse(const QString &id, const QSize &requested crop = false; } else if (b.startsWith("radius=")) { radius = b.mid(7).toDouble(); + } else if (b.startsWith("height=")) { + size.setHeight(b.mid(7).toInt()); + size.setWidth(0); } } } - return new MxcImageResponse(id_, crop, radius, requestedSize); + return new MxcImageResponse(id_, crop, radius, size); } void @@ -120,7 +124,12 @@ MxcImageProvider::download(const QString &id, if (fileInfo.exists()) { QImage image = utils::readImageFromFile(fileInfo.absoluteFilePath()); if (!image.isNull()) { - image = image.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + if (requestedSize.width() <= 0) { + image = image.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation); + } else { + image = + image.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } if (radius != 0) { image = clipRadius(std::move(image), radius); @@ -151,8 +160,13 @@ MxcImageProvider::download(const QString &id, auto data = QByteArray(res.data(), (int)res.size()); QImage image = utils::readImage(data); if (!image.isNull()) { - image = - image.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + if (requestedSize.width() <= 0) { + image = + image.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation); + } else { + image = + image.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + } if (radius != 0) { image = clipRadius(std::move(image), radius); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index b9941dfa..0bec9505 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -561,14 +561,39 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r } // TODO(Nico): Don't parse html with a regex - const static QRegularExpression matchImgUri("(]*)src=\"mxc://([^\"]*)\"([^>]*>)"); - formattedBody_.replace(matchImgUri, "\\1 src=\"image://mxcImage/\\2\"\\3"); - // Same regex but for single quotes around the src - const static QRegularExpression matchImgUri2("(]*)src=\'mxc://([^\']*)\'([^>]*>)"); - formattedBody_.replace(matchImgUri2, "\\1 src=\"image://mxcImage/\\2\"\\3"); - const static QRegularExpression matchEmoticonHeight( - "(]*)height=\"([^\"]*)\"([^>]*>)"); - formattedBody_.replace(matchEmoticonHeight, QString("\\1 height=\"%1\"\\3").arg(ascent)); + const static QRegularExpression matchIsImg("]+>"); + auto itIsImg = matchIsImg.globalMatch(formattedBody_); + while (itIsImg.hasNext()) { + // The current tag. + const QString curImg = itIsImg.next().captured(0); + // The replacement for the current . + auto imgReplacement = curImg; + + // Construct image parameters later used by MxcImageProvider. + QString imgParams; + if (curImg.contains("height")) { + const static QRegularExpression matchImgHeight("height=([\"\']?)(\\d+)([\"\']?)"); + // Make emoticons twice as high as the font. + if (curImg.contains("data-mx-emoticon")) { + imgReplacement = + imgReplacement.replace(matchImgHeight, "height=\\1%1\\3").arg(ascent * 2); + } + const auto height = matchImgHeight.match(imgReplacement).captured(2).toInt(); + imgParams = QString("?scale&height=%1").arg(height); + } + + // Replace src in current . + const static QRegularExpression matchImgUri("src=\"mxc://([^\"]*)\""); + imgReplacement.replace(matchImgUri, + QString("src=\"image://mxcImage/\\1%1\"").arg(imgParams)); + // Same regex but for single quotes around the src + const static QRegularExpression matchImgUri2("src=\'mxc://([^\']*)\'"); + imgReplacement.replace(matchImgUri2, + QString("src=\'image://mxcImage/\\1%1\'").arg(imgParams)); + + // Replace in formattedBody_ with our new . + formattedBody_.replace(curImg, imgReplacement); + } return QVariant( utils::replaceEmoji(utils::linkifyMessage(utils::escapeBlacklistedHtml(formattedBody_))));