Improve scaling / expanding for photos.

Fixes #25061.
This commit is contained in:
John Preston 2022-09-19 17:44:55 +04:00
parent f5bff22bb8
commit fc3810fd7f
3 changed files with 61 additions and 10 deletions

View file

@ -152,19 +152,31 @@ QSize Photo::countOptimalSize() {
_parent->skipBlockHeight());
}
const auto scaled = CountDesiredMediaSize(
{ _data->width(), _data->height() });
const auto dimensions = QSize(_data->width(), _data->height());
const auto scaled = CountDesiredMediaSize(dimensions);
const auto minWidth = std::clamp(
_parent->minWidthForMedia(),
(_parent->hasBubble() ? st::historyPhotoBubbleMinWidth : st::minPhotoSize),
(_parent->hasBubble()
? st::historyPhotoBubbleMinWidth
: st::minPhotoSize),
st::maxMediaSize);
const auto maxActualWidth = qMax(scaled.width(), minWidth);
auto maxWidth = qMax(maxActualWidth, scaled.height());
auto minHeight = qMax(scaled.height(), st::minPhotoSize);
if (_parent->hasBubble() && !_caption.isEmpty()) {
maxWidth = qMax(maxWidth, st::msgPadding.left()
+ _caption.maxWidth()
+ st::msgPadding.right());
maxWidth = qMax(
maxWidth,
(st::msgPadding.left()
+ _caption.maxWidth()
+ st::msgPadding.right()));
if (!dimensions.isEmpty()
&& ::Media::Streaming::FrameResizeMayExpand(
{ maxWidth, minHeight },
dimensions)) {
minHeight = qMax(
minHeight,
maxWidth * dimensions.height() / dimensions.width());
}
minHeight += st::mediaCaptionSkip + _caption.minHeight();
if (isBubbleBottom()) {
minHeight += st::msgPadding.bottom();
@ -180,10 +192,13 @@ QSize Photo::countCurrentSize(int newWidth) {
const auto thumbMaxWidth = qMin(newWidth, st::maxMediaSize);
const auto minWidth = std::clamp(
_parent->minWidthForMedia(),
(_parent->hasBubble() ? st::historyPhotoBubbleMinWidth : st::minPhotoSize),
(_parent->hasBubble()
? st::historyPhotoBubbleMinWidth
: st::minPhotoSize),
thumbMaxWidth);
const auto dimensions = QSize(_data->width(), _data->height());
auto pix = CountPhotoMediaSize(
CountDesiredMediaSize({ _data->width(), _data->height() }),
CountDesiredMediaSize(dimensions),
newWidth,
maxWidth());
newWidth = qMax(pix.width(), minWidth);
@ -195,6 +210,14 @@ QSize Photo::countCurrentSize(int newWidth) {
+ _caption.maxWidth()
+ st::msgPadding.right()));
newWidth = qMin(qMax(newWidth, maxWithCaption), thumbMaxWidth);
if (!dimensions.isEmpty()
&& ::Media::Streaming::FrameResizeMayExpand(
{ newWidth, newHeight },
dimensions)) {
newHeight = qMax(
newHeight,
newWidth * dimensions.height() / dimensions.width());
}
const auto captionw = newWidth
- st::msgPadding.left()
- st::msgPadding.right();

View file

@ -368,8 +368,7 @@ ExpandDecision DecideFrameResize(
return { .result = original, .expanding = true };
}
const auto big = original.scaled(outer, Qt::KeepAspectRatioByExpanding);
if ((big.width() * minVisibleNominator
<= outer.width() * minVisibleDenominator)
if ((big.width() <= outer.width())
&& (big.height() * minVisibleNominator
<= outer.height() * minVisibleDenominator)) {
return { .result = big, .expanding = true };
@ -377,6 +376,30 @@ ExpandDecision DecideFrameResize(
return { .result = original.scaled(outer, Qt::KeepAspectRatio) };
}
bool FrameResizeMayExpand(
QSize outer,
QSize original,
int minVisibleNominator,
int minVisibleDenominator) {
const auto min = std::min({
outer.width(),
outer.height(),
original.width(),
original.height(),
});
// Count for: (nominator / denominator) - (1 / min).
// In case the result is less than 1 / 2, just return.
if (2 * minVisibleNominator * min
< 2 * minVisibleDenominator + minVisibleDenominator * min) {
return false;
}
return DecideFrameResize(
outer,
original,
minVisibleNominator * min - minVisibleDenominator,
minVisibleDenominator * min).expanding;
}
ExpandDecision DecideVideoFrameResize(QSize outer, QSize original) {
return DecideFrameResize(outer, original, 1, 2);
}

View file

@ -75,6 +75,11 @@ struct ExpandDecision {
QSize original,
int minVisibleNominator = 3, // If we cut out no more than 0.25 of
int minVisibleDenominator = 4); // the original, let's expand.
[[nodiscard]] bool FrameResizeMayExpand(
QSize outer,
QSize original,
int minVisibleNominator = 3,
int minVisibleDenominator = 4);
[[nodiscard]] ExpandDecision DecideVideoFrameResize(
QSize outer,
QSize original);