Skip to content

Commit 1be02b9

Browse files
committed
1.2024.11.18: page layout: fix margins for Scaling and Affine
1 parent 88a97f9 commit 1be02b9

File tree

5 files changed

+72
-44
lines changed

5 files changed

+72
-44
lines changed

src/stages/page_layout/ImageView.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ namespace page_layout
5050

5151
ImageView::ImageView(
5252
std::shared_ptr<AcceleratableOperations> const& accel_ops,
53-
IntrusivePtr<Settings> const& settings, PageId const& page_id,
53+
IntrusivePtr<Settings> const& settings,
54+
PageId const& page_id,
5455
std::shared_ptr<AbstractImageTransform const> const& orig_transform,
5556
AffineTransformedImage const& affine_transformed_image,
5657
ImagePixmapUnion const& downscaled_image,
@@ -606,7 +607,7 @@ ImageView::dragFinished()
606607
RelativeMargins const margins(calcHardMargins());
607608
AggregateSizeChanged const agg_size_changed(commitHardMargins(margins));
608609

609-
if (m_matchSizeMode == MatchSizeMode::M_SCALE)
610+
if ((m_matchSizeMode == MatchSizeMode::M_SCALE) || (m_matchSizeMode == MatchSizeMode::M_AFFINE))
610611
{
611612
// In this mode, adjusting the margins affects scaling applied to the image itself.
612613
recalcBoxesAndFit(margins);
@@ -713,7 +714,7 @@ RelativeMargins
713714
ImageView::calcHardMargins() const
714715
{
715716
double pagewidth = m_innerRect.width();
716-
double pagewidthheight = m_innerRect.height() * 0.7071067811865475244;
717+
double const pagewidthheight = m_innerRect.height() * 0.7071067811865475244;
717718
pagewidth = (pagewidth < pagewidthheight) ? pagewidthheight : pagewidth;
718719
double const scale = 1.0 / pagewidth;
719720
return RelativeMargins(

src/stages/page_layout/ImageView.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
#ifndef PAGE_LAYOUT_IMAGEVIEW_H_
2020
#define PAGE_LAYOUT_IMAGEVIEW_H_
2121

22+
#include <memory>
2223
#include <QTransform>
2324
#include <QSizeF>
2425
#include <QRectF>
2526
#include <QPointF>
2627
#include <QPoint>
2728
#include <QPainterPath>
28-
#include <memory>
2929
#include "ImageViewBase.h"
3030
#include "ImagePixmapUnion.h"
3131
#include "InteractionHandler.h"
@@ -63,7 +63,8 @@ class ImageView :
6363
public:
6464
ImageView(
6565
std::shared_ptr<AcceleratableOperations> const& accel_ops,
66-
IntrusivePtr<Settings> const& settings, PageId const& page_id,
66+
IntrusivePtr<Settings> const& settings,
67+
PageId const& page_id,
6768
std::shared_ptr<imageproc::AbstractImageTransform const> const& orig_transform,
6869
imageproc::AffineTransformedImage const& affine_transformed_image,
6970
ImagePixmapUnion const& downscaled_image,

src/stages/page_layout/PageLayout.cpp

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -50,49 +50,73 @@ PageLayout::PageLayout(
5050
// we would get with zero hard margins and MatchSizeMode::M_GROW_MARGINS.
5151
bool const have_content_box = !unscaled_content_rect.isEmpty();
5252

53-
if (have_content_box && (match_size_mode.get() == MatchSizeMode::M_SCALE || match_size_mode.get() == MatchSizeMode::M_AFFINE))
53+
if (have_content_box)
5454
{
55-
// aggregate_size = content_size * scale + margins * width * scale
56-
// Solving for scale:
57-
// scale = aggregate_size / (content_size + margins * width)
5855
double const agwidth = aggregate_hard_size.width();
5956
double const agheight = aggregate_hard_size.height();
60-
double const aghx = agheight * 0.7071067811865475244;
61-
double const agsize = (agwidth < aghx) ? agwidth : aghx;
62-
double const agx = (agwidth - (margins.left() + margins.right()) * agsize);
63-
double const agy = (agheight - (margins.top() + margins.bottom()) * agsize);
64-
double const x_scale = (agx > 0.0) ? (agx / m_innerRect.width()) : 1.0;
65-
double const y_scale = (agy > 0.0) ? (agy / m_innerRect.height()) : 1.0;
66-
if (match_size_mode.get() == MatchSizeMode::M_SCALE)
57+
double const pagew = m_innerRect.width();
58+
double const pageh = m_innerRect.height();
59+
double const margins_w = margins.left() + margins.right();
60+
double const margins_h = margins.top() + margins.bottom();
61+
if ((match_size_mode.get() == MatchSizeMode::M_SCALE) || (match_size_mode.get() == MatchSizeMode::M_AFFINE))
6762
{
68-
if (x_scale > 1.0 && y_scale > 1.0)
63+
double const pagewidthx = pagew;
64+
double const pagewidthy = pageh * 0.7071067811865475244;
65+
double const pagewidth = (pagewidthx < pagewidthy) ? pagewidthy : pagewidthx;
66+
double const pagewm = pagew + margins_w * pagewidth;
67+
double const pagehm = pageh + margins_h * pagewidth;
68+
if (match_size_mode.get() == MatchSizeMode::M_SCALE)
6969
{
70-
m_scaleFactor_X = std::min(x_scale, y_scale);
70+
// aggregate_size = content_size * scale + margins * width * scale
71+
// Solving for scale:
72+
// scale = aggregate_size / (content_size + margins * width)
73+
double const x_scale = (pagewm > 0.0) ? (agwidth / pagewm) : 1.0;
74+
double const y_scale = (pagehm > 0.0) ? (agheight / pagehm) : 1.0;
75+
76+
if (x_scale > 1.0 && y_scale > 1.0)
77+
{
78+
m_scaleFactor_X = std::min(x_scale, y_scale);
79+
}
80+
else if (x_scale < 1.0 && y_scale < 1.0)
81+
{
82+
m_scaleFactor_X = std::max(x_scale, y_scale);
83+
}
84+
m_scaleFactor_Y = m_scaleFactor_X;
7185
}
72-
else if (x_scale < 1.0 && y_scale < 1.0)
86+
else
7387
{
74-
m_scaleFactor_X = std::max(x_scale, y_scale);
88+
double const pgx = (pagewm < agwidth) ? agwidth : pagewm;
89+
double const pgy = (pagehm < agheight) ? agheight : pagehm;
90+
double const cgx = pgx / (1.0 + margins_w);
91+
double const cgy = pgy / (1.0 + margins_h * 0.7071067811865475244);
92+
double const cghx = cgy * 0.7071067811865475244;
93+
double const cgsize = (cgx < cghx) ? cghx : cgx;
94+
double const margins_ws = margins_w * cgsize;
95+
double const margins_hs = margins_h * cgsize;
96+
double const agx = pgx - margins_ws;
97+
double const agy = pgy - margins_hs;
98+
99+
double const x_scale = (agx > 0.0) ? (agx / pagew) : 1.0;
100+
double const y_scale = (agy > 0.0) ? (agy / pageh) : 1.0;
101+
102+
m_scaleFactor_X = x_scale;
103+
m_scaleFactor_Y = y_scale;
75104
}
76-
m_scaleFactor_Y = m_scaleFactor_X;
77-
}
78-
else
79-
{
80-
m_scaleFactor_X = x_scale;
81-
m_scaleFactor_Y = y_scale;
105+
// The rectangle needs to be both shifted and scaled,
106+
// as that's what AbstractImageTransform::scale() does,
107+
// which we call in absorbScalingIntoTransform().
108+
QPointF const p_tl = m_innerRect.topLeft();
109+
QPointF const p_br = m_innerRect.bottomRight();
110+
double const p_tl_xs = p_tl.x() * m_scaleFactor_X;
111+
double const p_tl_ys = p_tl.y() * m_scaleFactor_Y;
112+
double const p_br_xs = p_br.x() * m_scaleFactor_X;
113+
double const p_br_ys = p_br.y() * m_scaleFactor_Y;
114+
115+
QPointF const p_tl_s(p_tl_xs, p_tl_ys);
116+
QPointF const p_br_s(p_br_xs, p_br_ys);
117+
m_innerRect = QRectF(p_tl_s, p_br_s);
82118
}
83119

84-
// The rectangle needs to be both shifted and scaled,
85-
// as that's what AbstractImageTransform::scale() does,
86-
// which we call in absorbScalingIntoTransform().
87-
QPointF const p_tl = m_innerRect.topLeft();
88-
QPointF const p_br = m_innerRect.bottomRight();
89-
QPointF const p_tl_s(p_tl.x() * m_scaleFactor_X, p_tl.y() * m_scaleFactor_Y);
90-
QPointF const p_br_s(p_br.x() * m_scaleFactor_X, p_br.y() * m_scaleFactor_Y);
91-
m_innerRect = QRectF(p_tl_s, p_br_s);
92-
}
93-
94-
if (have_content_box)
95-
{
96120
m_middleRect = margins.extendContentRect(m_innerRect);
97121
}
98122
else

src/stages/page_layout/Utils.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,24 @@
1616
along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
*/
1818

19-
#include "Utils.h"
20-
#include "MatchSizeMode.h"
21-
#include "Alignment.h"
2219
#include <QColor>
2320
#include <QPointF>
2421
#include <QSizeF>
2522
#include <QRectF>
2623
#include <QMarginsF>
24+
#include "Utils.h"
25+
#include "MatchSizeMode.h"
26+
#include "Alignment.h"
2727

2828
namespace page_layout
2929
{
3030

3131
QMarginsF
3232
Utils::calcSoftMarginsPx(
33-
QSizeF const& hard_size_px, QSizeF const& aggregate_hard_size_px,
34-
MatchSizeMode const& match_size_mode, Alignment const& alignment)
33+
QSizeF const& hard_size_px,
34+
QSizeF const& aggregate_hard_size_px,
35+
MatchSizeMode const& match_size_mode,
36+
Alignment const& alignment)
3537
{
3638
if (match_size_mode.get() == MatchSizeMode::M_DISABLED)
3739
{

src/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@
2020
#define SCANTAILOR_VERSION_H_
2121

2222
#define STFAMILY "experimental"
23-
#define VERSION "1.2024.11.17" // Must be "x.x.x.x" or an empty string.
23+
#define VERSION "1.2024.11.18" // Must be "x.x.x.x" or an empty string.
2424

2525
#endif

0 commit comments

Comments
 (0)