diff --git a/src/stage/model/zoom-window.hpp b/src/stage/model/zoom-window.hpp index 544187266..7d2a19a49 100644 --- a/src/stage/model/zoom-window.hpp +++ b/src/stage/model/zoom-window.hpp @@ -679,39 +679,21 @@ namespace model { /** Assertion helper: resulting pxWidth matches expectations */ static void - __assertMatchesExpectedPixWidth (Rat zoomFactor, FSecs duration, uint pxWidth) + ENSURE_matchesExpectedPixWidth (Rat zoomFactor, FSecs duration, uint pxWidth) { - auto sizeAtRequestedScale = calcPixelsForDurationAtScale (zoomFactor, duration); + auto sizeAtRequestedScale = approx(zoomFactor) * approx(duration); ENSURE (abs(pxWidth - sizeAtRequestedScale) <= 1 ,"ZoomWindow: established size or metric misses expectation " "by more than 1px. %upx != %1.6f expected pixel." , pxWidth, sizeAtRequestedScale); } - static void - __assertMetricConforms2pxWidth (Rat zoomFactor, FSecs duration, uint pxWidth) - { - if (util::can_represent_Product(zoomFactor, duration)) - { - ENSURE (pxWidth == rational_cast (zoomFactor*duration) - ,"ZoomWindow: established zoom factor misses expected " - "width in pixels: %upx != %upx (resulting)" - , pxWidth, rational_cast (zoomFactor*duration)); - } - else - { - auto sizeAtRequestedScale = approx(zoomFactor) * approx(duration); - ENSURE (pxWidth == uint(sizeAtRequestedScale + 0.5) - ,"ZoomWindow: established zoom factor misses expected " - "width in pixels: %upx != %1.8f px (resulting)" - , pxWidth, sizeAtRequestedScale); - } - } - - /** @remark indirect calculation path to avoid overflow on large durations */ + /** calculate `rational_cast (zoomFactor * duration)` + * @remark indirect calculation path to avoid overflow on large durations + */ static int64_t calcPixelsForDurationAtScale (Rat zoomFactor, FSecs duration) - {// calculate rational_cast (zoomFactor * duration) + {// break down the integer division into several steps... auto zn = zoomFactor.numerator(); auto zd = zoomFactor.denominator(); auto dn = duration.numerator(); @@ -776,7 +758,7 @@ namespace model { REQUIRE (changedMetric > 0); REQUIRE (afterWin_> startWin_); FSecs dur{afterWin_-startWin_}; - uint pxWidth = rational_cast (px_per_sec_*dur); + uint pxWidth = calcPixelsForDurationAtScale (px_per_sec_, dur); dur = Rat(pxWidth) / detox (changedMetric); dur = min (dur, MAX_TIMESPAN); dur = max (dur, MICRO_TICK); // prevent window going void @@ -791,7 +773,7 @@ namespace model { // re-check metric to maintain precise pxWidth px_per_sec_ = conformMetricToWindow (pxWidth); ENSURE (_FSecs(afterWin_-startWin_) < MAX_TIMESPAN); - __assertMatchesExpectedPixWidth (changedMetric, dur, pxWidth); + ENSURE_matchesExpectedPixWidth (changedMetric, afterWin_-startWin_, pxWidth); } /** @@ -939,18 +921,7 @@ namespace model { changedMetric = max (changedMetric, px / maxSaneWinExtension(px)); changedMetric = min (detox(changedMetric), ZOOM_MAX_RESOLUTION); if (changedMetric == px_per_sec_) return; - - Rat changeFactor{changedMetric / px_per_sec_}; - FSecs dur{afterWin_ - startWin_}; - dur /= changeFactor; - if (dur > FSecs{afterAll_ - startAll_}) - {// limit to the overall timespan... - startWin_ = startAll_; - afterWin_ = afterAll_; - px_per_sec_ = conformMetricToWindow(px); - } - else - mutateDuration (dur, px); + conformWindowToMetric (changedMetric); ensureInvariants (px); } diff --git a/tests/stage/model/zoom-window-test.cpp b/tests/stage/model/zoom-window-test.cpp index fb98b4411..5737c5205 100644 --- a/tests/stage/model/zoom-window-test.cpp +++ b/tests/stage/model/zoom-window-test.cpp @@ -743,6 +743,14 @@ namespace test { CHECK (rational_cast(100000000000_r/109951052826533333) == 9.09495611e-07f); // theoretical value CHECK (rational_cast(win.px_per_sec()) == 9.09503967e-07f); // value actually chosen CHECK (win.px_per_sec() == 508631_r/559239974093); + + /*--Test-6-----------*/ + win.setMetric (bruteZoom); // And now put one on top by requesting excessive zoom-out: + CHECK (_raw(win.overallSpan().duration()) == 614891469123651720); // overall canvas duration not changed + CHECK (_raw(win.visible().duration()) == 109951162777600000); // window duration only slightly increased + CHECK (508631_r/559239974093 > 15625_r/17179869184); // zoom factor slightly reduced + CHECK (win.px_per_sec() == 15625_r/17179869184); // and now hitting again the minimum limit + CHECK (win.pxWidth() == MAX_PX_WIDTH); // pixel count unchanged at maximum } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 87839c7fa..a4ffeeda8 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -40057,7 +40057,9 @@ - + + + @@ -40227,17 +40229,18 @@

+
- + - + @@ -40362,6 +40365,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ eindeutig: wrap-around in der relativen Änderung +

+ +
+ +
+
+ + + + + + + + + + + + + + +

+ ...welche ich inzwischen nahezu komplett einmal umgepflügt habe... +

+ +
+
+ + + + + + + + + +

+ weil hier... +

+
    +
  • + zum Einen eine sehr große Zahl auf einen beliebigen Bruchfaktor trifft +
  • +
  • + und außerdem als Resultat eine Beliebige Zahl entsteht, die nicht auf Time::SCALE quantisiert ist +
  • +
+ +
+
+ + + + + + +

+ und redundant: macht nicht conformWindowToMetric()  inzwischen genau dassselbe?? +

+ +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +

+ und die Testsuite ist auf Anhieb GRÜN +

+ +
+
+ + + +
+
+ + + + + + + + + + + + + + + + + +