Skip to content

Commit f0e124c

Browse files
committed
1.2024.10.28: page layout: affine scale
1 parent 611b4c4 commit f0e124c

17 files changed

+149
-62
lines changed

src/stages/page_layout/ImageView.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ ImageView::onPaint(QPainter& painter, InteractionState const& interaction)
351351
painter.drawRect(m_innerRect);
352352
painter.drawRect(m_extraRect);
353353

354-
if (m_matchSizeMode.get() != MatchSizeMode::DISABLED)
354+
if (m_matchSizeMode.get() != MatchSizeMode::M_DISABLED)
355355
{
356356
pen.setStyle(Qt::DashLine);
357357
painter.setPen(pen);
@@ -606,7 +606,7 @@ ImageView::dragFinished()
606606
RelativeMargins const margins(calcHardMargins());
607607
AggregateSizeChanged const agg_size_changed(commitHardMargins(margins));
608608

609-
if (m_matchSizeMode == MatchSizeMode::SCALE)
609+
if (m_matchSizeMode == MatchSizeMode::M_SCALE)
610610
{
611611
// In this mode, adjusting the margins affects scaling applied to the image itself.
612612
recalcBoxesAndFit(margins);

src/stages/page_layout/ImageView.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,12 @@ public slots:
172172

173173
/**
174174
* AffineImageTransform extracted from \p affine_transformed_image constructor parameter.
175-
* This doesn't take image scaling as a result of MatchSizeMode::SCALE into account.
175+
* This doesn't take image scaling as a result of MatchSizeMode::M_SCALE into account.
176176
*/
177177
imageproc::AffineImageTransform const m_unscaledAffineTransform;
178178

179179
/**
180-
* ContentBox in virtual image coordinates, prior to scaling by MatchSizeMode::SCALE.
180+
* ContentBox in virtual image coordinates, prior to scaling by MatchSizeMode::M_SCALE.
181181
*/
182182
QRectF const m_unscaledContentRect;
183183

@@ -192,7 +192,7 @@ public slots:
192192

193193
/**
194194
* Content box in virtual image coordinates, possibly scaled
195-
* as a result of MatchSizeMode::SCALE.
195+
* as a result of MatchSizeMode::M_SCALE.
196196
*/
197197
QRectF m_innerRect;
198198

src/stages/page_layout/MatchSizeMode.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,20 @@ MatchSizeMode::MatchSizeMode(QDomElement const& el)
3030

3131
if (mode == "disabled")
3232
{
33-
m_mode = DISABLED;
33+
m_mode = M_DISABLED;
3434
}
3535
else if (mode == "scale")
3636
{
37-
m_mode = SCALE;
37+
m_mode = M_SCALE;
38+
}
39+
else if (mode == "affine")
40+
{
41+
m_mode = M_AFFINE;
3842
}
3943
else
4044
{
4145
// Default mode for backwards compatibility.
42-
m_mode = GROW_MARGINS;
46+
m_mode = M_GROW_MARGINS;
4347
}
4448
}
4549

@@ -50,15 +54,18 @@ MatchSizeMode::toXml(QDomDocument& doc, QString const& name) const
5054

5155
switch (m_mode)
5256
{
53-
case DISABLED:
57+
case M_DISABLED:
5458
mode = "disabled";
5559
break;
56-
case GROW_MARGINS:
60+
case M_GROW_MARGINS:
5761
mode = "margins";
5862
break;
59-
case SCALE:
63+
case M_SCALE:
6064
mode = "scale";
6165
break;
66+
case M_AFFINE:
67+
mode = "affine";
68+
break;
6269
}
6370

6471
QDomElement el(doc.createElement(name));

src/stages/page_layout/MatchSizeMode.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,25 @@ class MatchSizeMode
3232
enum Mode
3333
{
3434
/** The size of this page doesn't affect and is not affected by other pages. */
35-
DISABLED,
35+
M_DISABLED,
3636

3737
/**
3838
* To match the size of the widest / tallest page, soft margins grow as necessary.
3939
* This page will also compete for the widest / tallest page title itself.
4040
*/
41-
GROW_MARGINS,
41+
M_GROW_MARGINS,
4242

4343
/**
4444
* To match the size of the widest / tallest page, this page's content as well as
4545
* hard margins will be scaled. Because the scaling coefficients in horizontal and
4646
* vertical directions are locked to each other, soft margins may need to grow
4747
* as well. This page will also compete for the widest / tallest page title itself.
4848
*/
49-
SCALE
49+
M_SCALE,
50+
M_AFFINE
5051
};
5152

52-
MatchSizeMode(Mode mode = DISABLED) : m_mode(mode) {}
53+
MatchSizeMode(Mode mode = M_DISABLED) : m_mode(mode) {}
5354

5455
MatchSizeMode(QDomElement const& el);
5556

src/stages/page_layout/OptionsWidget.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ OptionsWidget::OptionsWidget(
160160
matchSizeScaleRb, SIGNAL(toggled(bool)),
161161
this, SLOT(matchSizeScaleToggled(bool))
162162
);
163+
connect(
164+
matchSizeAffineRb, SIGNAL(toggled(bool)),
165+
this, SLOT(matchSizeAffineToggled(bool))
166+
);
163167
connect(
164168
applyAlignmentBtn, SIGNAL(clicked()),
165169
this, SLOT(showApplyAlignmentDialog())
@@ -209,15 +213,18 @@ OptionsWidget::preUpdateUI(
209213

210214
switch (match_size_mode.get())
211215
{
212-
case MatchSizeMode::DISABLED:
216+
case MatchSizeMode::M_DISABLED:
213217
matchSizeDisabledRb->setChecked(true);
214218
break;
215-
case MatchSizeMode::GROW_MARGINS:
219+
case MatchSizeMode::M_GROW_MARGINS:
216220
matchSizeMarginsRb->setChecked(true);
217221
break;
218-
case MatchSizeMode::SCALE:
222+
case MatchSizeMode::M_SCALE:
219223
matchSizeScaleRb->setChecked(true);
220224
break;
225+
case MatchSizeMode::M_AFFINE:
226+
matchSizeAffineRb->setChecked(true);
227+
break;
221228
}
222229
}
223230

@@ -364,7 +371,7 @@ OptionsWidget::matchSizeDisabledToggled(bool selected)
364371
return;
365372
}
366373

367-
m_matchSizeMode.set(MatchSizeMode::DISABLED);
374+
m_matchSizeMode.set(MatchSizeMode::M_DISABLED);
368375

369376
enableDisableAlignmentButtons();
370377
emit matchSizeModeChanged(m_matchSizeMode);
@@ -379,7 +386,7 @@ OptionsWidget::matchSizeMarginsToggled(bool selected)
379386
return;
380387
}
381388

382-
m_matchSizeMode.set(MatchSizeMode::GROW_MARGINS);
389+
m_matchSizeMode.set(MatchSizeMode::M_GROW_MARGINS);
383390

384391
enableDisableAlignmentButtons();
385392
emit matchSizeModeChanged(m_matchSizeMode);
@@ -394,7 +401,22 @@ OptionsWidget::matchSizeScaleToggled(bool selected)
394401
return;
395402
}
396403

397-
m_matchSizeMode.set(MatchSizeMode::SCALE);
404+
m_matchSizeMode.set(MatchSizeMode::M_SCALE);
405+
406+
enableDisableAlignmentButtons();
407+
emit matchSizeModeChanged(m_matchSizeMode);
408+
updateSizeDisplay();
409+
}
410+
411+
void
412+
OptionsWidget::matchSizeAffineToggled(bool selected)
413+
{
414+
if (!selected || m_ignoreMatchSizeModeChanges)
415+
{
416+
return;
417+
}
418+
419+
m_matchSizeMode.set(MatchSizeMode::M_AFFINE);
398420

399421
enableDisableAlignmentButtons();
400422
emit matchSizeModeChanged(m_matchSizeMode);
@@ -541,7 +563,7 @@ OptionsWidget::updateSizeDisplay()
541563
float const exheight = m_framings.getFramingHeight();
542564
float agwidth = agg_size.width();
543565
float agheight = agg_size.height();
544-
if(m_matchSizeMode == MatchSizeMode::DISABLED)
566+
if(m_matchSizeMode == MatchSizeMode::M_DISABLED)
545567
{
546568
QSizeF const content_size = m_ptrSettings->getContentSize(m_pageId);
547569
RelativeMargins const hard_magrins = m_ptrSettings->getHardMargins(m_pageId);

src/stages/page_layout/OptionsWidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ private slots:
127127

128128
void matchSizeScaleToggled(bool selected);
129129

130+
void matchSizeAffineToggled(bool selected);
131+
130132
void alignmentButtonClicked();
131133

132134
void showApplyFramingsDialog();

src/stages/page_layout/PageLayout.cpp

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,42 +42,53 @@ PageLayout::PageLayout(
4242
RelativeMargins const& margins)
4343
{
4444
m_innerRect = unscaled_content_rect;
45-
m_scaleFactor = 1.0;
45+
m_scaleFactor_X = 1.0;
46+
m_scaleFactor_Y = 1.0;
4647

4748
// An empty unscaled_content_rect is a special case to indicate
4849
// a missing content box. In this case, we want the geometry
49-
// we would get with zero hard margins and MatchSizeMode::GROW_MARGINS.
50+
// we would get with zero hard margins and MatchSizeMode::M_GROW_MARGINS.
5051
bool const have_content_box = !unscaled_content_rect.isEmpty();
5152

52-
if (have_content_box && match_size_mode.get() == MatchSizeMode::SCALE)
53+
if (have_content_box && (match_size_mode.get() == MatchSizeMode::M_SCALE || match_size_mode.get() == MatchSizeMode::M_AFFINE))
5354
{
5455
// aggregate_size = content_size * scale + margins * width * scale
5556
// Solving for scale:
5657
// scale = aggregate_size / (content_size + margins * width)
57-
double const pagewidthx = m_innerRect.width();
58-
double const pagewidthy = m_innerRect.height() * 0.7071067811865475244;
59-
double const pagewidth = (pagewidthx < pagewidthy) ? pagewidthy : pagewidthx;
60-
double const x_scale = aggregate_hard_size.width() /
61-
(m_innerRect.width() + (margins.left() + margins.right()) * pagewidth);
62-
double const y_scale = aggregate_hard_size.height() /
63-
(m_innerRect.height() + (margins.top() + margins.bottom()) * pagewidth);
64-
65-
if (x_scale > 1.0 && y_scale > 1.0)
58+
double const agwidth = aggregate_hard_size.width();
59+
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)
6667
{
67-
m_scaleFactor = std::min(x_scale, y_scale);
68+
if (x_scale > 1.0 && y_scale > 1.0)
69+
{
70+
m_scaleFactor_X = std::min(x_scale, y_scale);
71+
}
72+
else if (x_scale < 1.0 && y_scale < 1.0)
73+
{
74+
m_scaleFactor_X = std::max(x_scale, y_scale);
75+
}
76+
m_scaleFactor_Y = m_scaleFactor_X;
6877
}
69-
else if (x_scale < 1.0 && y_scale < 1.0)
78+
else
7079
{
71-
m_scaleFactor = std::max(x_scale, y_scale);
80+
m_scaleFactor_X = x_scale;
81+
m_scaleFactor_Y = y_scale;
7282
}
7383

7484
// The rectangle needs to be both shifted and scaled,
7585
// as that's what AbstractImageTransform::scale() does,
7686
// which we call in absorbScalingIntoTransform().
77-
m_innerRect = QRectF(
78-
m_innerRect.topLeft() * m_scaleFactor,
79-
m_innerRect.bottomRight() * m_scaleFactor
80-
);
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);
8192
}
8293

8394
if (have_content_box)
@@ -117,9 +128,9 @@ PageLayout::extraRect(Framings const& framings) const
117128
void
118129
PageLayout::absorbScalingIntoTransform(AbstractImageTransform& transform) const
119130
{
120-
if (m_scaleFactor != 1.0)
131+
if ((m_scaleFactor_X != 1.0) || (m_scaleFactor_Y != 1.0))
121132
{
122-
transform.scale(m_scaleFactor, m_scaleFactor);
133+
transform.scale(m_scaleFactor_X, m_scaleFactor_Y);
123134
}
124135
}
125136

src/stages/page_layout/PageLayout.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class PageLayout
6565
QRectF const extraRect(Framings const& framings) const;
6666

6767
/**
68-
* If match_size_mode passed into the constructor was set to SCALE,
68+
* If match_size_mode passed into the constructor was set to M_SCALE,
6969
* the 3 rectangles already incorporate the appropriate scaling factor.
7070
* This method incorporates that scaling factor into the provided transform.
7171
*/
@@ -80,8 +80,9 @@ class PageLayout
8080
/** Rectangle around content plus hard and soft margins, in transformed coordinates. */
8181
QRectF m_outerRect;
8282

83-
/** Scaling applied as a result of MatchSizeMode::SCALE. */
84-
double m_scaleFactor;
83+
/** Scaling applied as a result of MatchSizeMode::M_SCALE. */
84+
double m_scaleFactor_X;
85+
double m_scaleFactor_Y;
8586

8687
};
8788

src/stages/page_layout/Settings.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class Settings::Item
8080
*/
8181
bool alignedWithOthers() const
8282
{
83-
return matchSizeMode.get() != MatchSizeMode::DISABLED;
83+
return matchSizeMode.get() != MatchSizeMode::M_DISABLED;
8484
}
8585
};
8686

@@ -443,13 +443,13 @@ Settings::Item::hardHeight() const
443443
double
444444
Settings::Item::influenceHardWidth() const
445445
{
446-
return matchSizeMode.get() == MatchSizeMode::DISABLED ? 0.0 : hardWidth();
446+
return matchSizeMode.get() == MatchSizeMode::M_DISABLED ? 0.0 : hardWidth();
447447
}
448448

449449
double
450450
Settings::Item::influenceHardHeight() const
451451
{
452-
return matchSizeMode.get() == MatchSizeMode::DISABLED ? 0.0 : hardHeight();
452+
return matchSizeMode.get() == MatchSizeMode::M_DISABLED ? 0.0 : hardHeight();
453453
}
454454

455455

@@ -462,7 +462,7 @@ Settings::Impl::Impl()
462462
m_descHeightOrder(m_items.get<DescHeightTag>()),
463463
m_invalidSize(),
464464
m_defaultHardMargins(page_layout::Settings::defaultHardMargins()),
465-
m_defaultMatchSizeMode(MatchSizeMode::GROW_MARGINS),
465+
m_defaultMatchSizeMode(MatchSizeMode::M_GROW_MARGINS),
466466
m_defaultAlignment(Alignment::TOP, Alignment::HCENTER),
467467
m_defaultFramings(0.24, 0.16)
468468
{
@@ -908,7 +908,7 @@ Settings::Impl::getAggregateHardSize(
908908
MatchSizeMode const& match_size_mode) const
909909
{
910910
QSizeF influence_hard_size = QSize(0.0, 0.0);
911-
if (match_size_mode.get() != MatchSizeMode::DISABLED)
911+
if (match_size_mode.get() != MatchSizeMode::M_DISABLED)
912912
{
913913
influence_hard_size = hard_size;
914914
}

src/stages/page_layout/Settings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class Settings : public RefCountable
123123
* the size of other pages and whether it will affect the size of other pages.
124124
* \par
125125
* If no match size mode was specified, the default mode is returned,
126-
* which is MatchSizeMode::GROW_MARGINS.
126+
* which is MatchSizeMode::M_GROW_MARGINS.
127127
*/
128128
MatchSizeMode getMatchSizeMode(PageId const& page_id) const;
129129

0 commit comments

Comments
 (0)