fix: Kalenderraster mit einem gemeinsamen Faktor statt unabhängig in x/y skalieren
CI / build-and-test (push) Waiting to run

Breite und Höhe wurden bisher getrennt behandelt (Breite = volle reale
Boxbreite, Höhe = Größenwahl*Einheitenfaktor) - bei einer Box, deren
Seitenverhältnis vom Referenzentwurf abweicht, verzerrte das die Tageskacheln
sichtbar.

Das Raster wird jetzt komplett in einem festen 170mm-Referenzentwurf
berechnet und erst am Ende mit einem einzigen Faktor k = min(a_x, a_y,
Größenwahl) * millimeterScale in die Koordinaten der Vorlage skaliert - a_x/
a_y sind die Verhältnisse von realer Boxbreite/-höhe zum Referenzentwurf.
Dadurch bleiben die Kacheln immer proportional, auf Kosten von ungenutztem
Rand auf der Achse, die nicht der begrenzende Faktor ist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 15:42:56 +02:00
co-authored by Claude Sonnet 5
parent 4542f263fc
commit c128fc6741
2 changed files with 81 additions and 57 deletions
@@ -127,6 +127,33 @@ public sealed class ClassTeacherViewModelsTests
Assert.True(large.ContentHeight > small.ContentHeight);
}
// Regression: Breite und Höhe dürfen nur mit EINEM gemeinsamen Faktor skaliert werden (a =
// min(a_x, a_y)), nicht unabhängig voneinander - sonst verzerren die Tageskacheln, wenn das
// Seitenverhältnis der realen Box vom Referenzentwurf abweicht (z.B. eine sehr breite, aber
// niedrige DRAWBOX). Das Breiten-/Höhenverhältnis einer Kachel muss unabhängig von contentWidth
// gleich bleiben, solange die Höhe der begrenzende Faktor ist.
[Fact]
public void ElternbriefKalender_SkaliertKachelnGleichmaessigOhneVerzerrung()
{
var options = new AttendanceCalendarOptions(new DateOnly(2026, 9, 18), 3, AttendanceCalendarSize.Large);
var schmaleBox = StudentAttendanceCalendarDrawingBuilder.Build("Ada Müller", options, [], [],
contentWidth: 170, contentHeight: 60);
var sehrBreiteBox = StudentAttendanceCalendarDrawingBuilder.Build("Ada Müller", options, [], [],
contentWidth: 1000, contentHeight: 60);
var schmaleKachel = schmaleBox.Commands.OfType<DrawRoundedRectangle>().First();
var breiteKachel = sehrBreiteBox.Commands.OfType<DrawRoundedRectangle>().First();
var schmalesVerhaeltnis = schmaleKachel.Width / schmaleKachel.Height;
var breitesVerhaeltnis = breiteKachel.Width / breiteKachel.Height;
Assert.Equal(schmalesVerhaeltnis, breitesVerhaeltnis, 0.001f);
// Bei gleicher (begrenzender) Höhe muss die Kachelgröße selbst identisch sein - die
// zusätzliche Breite der zweiten Box bleibt ungenutzt (kein Verzerren, kein Zwang zum
// vollständigen Ausfüllen), statt die Kacheln künstlich in die Breite zu ziehen.
Assert.Equal(schmaleKachel.Width, breiteKachel.Width, 0.01f);
Assert.Equal(schmaleKachel.Height, breiteKachel.Height, 0.01f);
}
// Regression: DRAWBOX bricht anders als FLOWDRAWBOX nicht automatisch um - Inhalt, der die von
// der Vorlage deklarierte Höhe überschreitet, wird von QuestTemplateRenderer stillschweigend am
// unteren Rand abgeschnitten (kein Fehler, keine Warnung). "Größe" muss deshalb automatisch so