Tu znajdziesz pełną historię wszystkich wydań imPRESS Studio z opisem nowych funkcji, ulepszeń i poprawek. Format zgodny z Keep a Changelog, wersjonowanie Semantic Versioning.
Preflight dostaje kontrole, których dział prepress spodziewa się zastać i których brak zauważa, dwie naprawy na usterki zatrzymujące plik na cudzej bramce, a oba okna preflightu są przebudowane wokół decyzji, której mają służyć. Po drodze dwie rzeczy, do których operator po prostu nie mógł dotrzeć: writer raportu, który pojechał w 1.5.12 bez niczego, co by go wołało, i menedżer szablonów nigdy nie pokazujący szablonu, na którym działa zadanie
Nowości
- Dziesięć kontroli — każda czyta coś, co analizator wydobywał od dawna. Obrót stron, szyfrowanie, wersja PDF wobec standardu docelowego, wymagania PDF/X co do tytułu i XMP, rozdzielczość kreski i reguły separacji dały się policzyć z danych, które już były w raporcie — tylko nikt na nie nie patrzył. To luka szczególnego rodzaju: żadnej awarii, żadnego wpisu w logu, po prostu reguła, której nigdy nie napisano.
- Obrót stron (
PAGE_ROTATION_SET, PAGE_ROTATION_MIXED). Obrót w PDF to instrukcja wyświetlania, nie geometria: ramki zachowują wartości, z jakimi je zapisano, a obrót nakłada dopiero czytnik. Wszyscy go honorują i różnią się w tym, co z niego wynika dla ramek — więc strona obrócona o 90° z TrimBoxem 210×297 imponuje się jako pionowa i drukuje na boku, a operator nie ma powodu tego podejrzewać, bo na ekranie widzi stronę już obróconą. Różne kąty raportowane są osobno i jako błąd: jeden obrót na całym dokumencie da się skompensować, dokumentu, w którym część stron się obraca, a część nie, nie da się poprawnie zaimponować przy żadnej interpretacji. Kąt jest wcześniej normalizowany, bo /Rotate jest zdefiniowany modulo 360 i plik może legalnie napisać 450 tam, gdzie ma na myśli 90. - Szyfrowanie i puste dokumenty (
PDF_ENCRYPTED, PDF_NO_PAGES). Plik z flagami uprawnień otwiera się w czytniku bez zarzutu, a potem odmawia osadzenia, impozycji i naświetlenia. Zgłoszenie tego na preflighcie zamienia późną, zagadkową awarię eksportu w fakt, na który operator może zareagować, póki klient jest jeszcze osiągalny. Pusty dokument zatrzymuje resztę kontroli, zamiast produkować stronę znalezisk wyprowadzonych z niczego. - Wersja PDF wobec celu (
PDF_VERSION_ABOVE_TARGET). Każda odmiana PDF/X jest zdefiniowana na konkretnej wersji — X-1a i X-3 na 1.4, X-4 na 1.6 — a plik powyżej niej niesie konstrukcje, których standard nie opisuje. - Dwa wymagania metadanych PDF/X (
DOC_TITLE_MISSING, XMP_MISSING). Najtańsza możliwa niezgodność: z grafiką jest wszystko w porządku, plik po prostu nie mówi, czym jest — a walidator po drugiej stronie odrzuca go, choć strony wyglądają bez zarzutu. Zgłaszane tylko wtedy, gdy faktycznie wybrano cel PDF/X: poza nim to kwestia porządku, a preflight raportujący porządek równie głośno jak wady uczy operatorów, żeby przestali go czytać. - Rozdzielczość kreski (
IMAGE_LINEART_DPI_LOW) z własnym progiem. Obraz 1-bitowy ma dwie wartości i nic pomiędzy, więc każdą krawędź buduje z całych pikseli: 300 dpi chowa próbkowanie w zdjęciu, a na każdym skosie zeskanowanego podpisu czy wykrojnika stawia widoczne schodki. Wartość branżowa to około czterokrotność progu półtonowego — i dlatego mierzenie obu jedną miarą raportuje dwa razy nie to, co trzeba. Kontrola półtonu pomija teraz obrazy 1-bitowe, więc jedna bitmapa o niskiej rozdzielczości daje jedno znalezisko z właściwą liczbą, a nie dwa, które się ze sobą nie zgadzają. - Kolorant
All (SPOT_ALL_COLORANT). Separacja o nazwie All jest z definicji (PDF 1.7 §8.6.6.4) drukowana na wszystkich formach naraz. Istnieje dla znaczników pasowania, a w grafikę od klienta trafia przypadkiem — znacznik skopiowany z szablonu, próbka wzięta z niewłaściwego końca panelu. Na ekranie nic nie wygląda nietypowo, a na maszynie obiekt wchodzi we wszystkie cztery formy procesowe i każdy dodatek. Dopasowanie jest dokładne: dodatek nazwany naprawdę „Allura Red” to kolor, a błąd na poprawnym pliku kosztuje więcej zaufania, niż kontrola zyskuje. - Liczba form wobec maszyny (
SPOT_COUNT_OVER_LIMIT). Ile dodatków może nieść praca, jest właściwością maszyny, nie pliku: dziewięć jest całkowicie legalne w PDF i po prostu nie do wydrukowania na prasie o sześciu zespołach. Liczone po odrębnych kolorantach, bo ta sama farba nazwana na trzech stronach to wciąż jeden zespół — a kolorant All jest wyłączony, bo to wada do usunięcia, nie farba do zaplanowania.
- Dwie nowe naprawy. Obie zmieniają deklaracje na poziomie dokumentu, a nie znaki na stronie — i to czyni je bezpiecznymi do zaproponowania oraz wartymi zaproponowania: plik może być bezbłędną grafiką i zostać odrzucony za to, czego o sobie nie mówi.
- Metadane dokumentu wpisują tytuł (z nazwy pliku) i deklarację
/Trapped, której wymaga ISO 15930 — /Unknown i brak klucza są tak samo niezgodne. Deklaracja jest twierdzeniem, nie domysłem: /False to zdanie, na które RIP reaguje, więc naprawa wycofuje się w chwili, gdy raport wykazuje w pliku sieci trappingu. Powiedzenie o pliku z trappingiem, że go nie ma, kończy się trappingiem podwójnym — a to już problem maszyny, nie walidacji. - Stan druku warstw zatrzymuje warstwy ukryte na ekranie przed drukiem. Treść opcjonalna niesie dwa niezależne stany — widoczność i druk — a pliki projektowe regularnie kończą z rozjazdem między nimi, bo ukrycie warstwy nie dotyka ustawienia druku, które domyślnie jest włączone. Operator widzi czystą grafikę, a z naświetlarni wraca forma z wykrojnikiem. Nic nie jest usuwane: treść zostaje, warstwę można z powrotem włączyć — i to odróżnia tę naprawę od spłaszczania. Warstwy widoczne pozostają nietknięte: warstwa, którą widać, to warstwa, o której już zdecydowano.
- Hot foldery przyjmują bilety zleceń CIP4 — JDF 1.x i XJDF 2.x. System MIS drukarni i tak opisuje każde planowane zlecenie: format netto, arkusz, oprawę, zadruk i plik do wydrukowania. Dotąd ten opis zatrzymywał się na hot folderze, a operator przepisywał go do szablonu albo godził się na to, co akurat mówił stały szablon folderu. Folder z włączonymi biletami czyta bilet i imponuje wskazany w nim PDF.
- Bilet opisuje pracę, nie jest pracą. Wrzucenie
.jdf nie imponuje biletu — rozwiązuje wskazaną w nim grafikę, imponuje ją i odkłada oba pliki razem. Najpierw PDF, potem bilet to konwencja, którą stosuje każdy MIS, a przy odwrotnej kolejności folder i tak poczeka na grafikę.
- Szablon folderu jest podłogą, bilet nadpisaniem. Hot folder niesie ustalenia drukarni co do znaczników, spadów, gutterów, marginesów arkusza i pełzania. Bilet mówi o jednym produkcie kilka rzeczy — i tylko one się zmieniają: format netto, arkusz, oprawa, jedno- lub dwustronność. Zbudowanie szablonu z biletu wyrzuciłoby każdą decyzję operatora. Każde nadpisanie trafia do logu zadania z wartością przed i po, bo arkusz, który wyszedł 700 mm szeroki, musi dać się powiązać z biletem, który o to poprosił.
- Obie generacje i oba sposoby zapisu w 1.x. JDF 1.x pakuje wartości w podelementy z atrybutami
Actual i Preferred — wartość uzgodniona wygrywa z żądaną — a wielu producentów zapisuje je wprost na elemencie intencji. Pliki, które drukarnie faktycznie dostają, zawierają jedno i drugie, więc czytane jest jedno i drugie. Spłaszczona forma XJDF 2.0 tak samo.
- Punkty, nie milimetry. CIP4 podaje każdy wymiar w punktach 1/72 cala. Bilet mówiący 595.276 oznacza szerokość A4, a przeliczenie dzieje się w czytniku, żeby nikt dalej nie mógł o nim zapomnieć. Liczby są parsowane niezmiennie kulturowo — to różnica między funkcją, która działa, a taką, która na maszynie ustawionej na polski czyta 595.276 jako 595276.
- Oprawa, której aplikacja nie imponuje, jest nazwana, nie przybliżona. CIP4 ma kilkanaście opraw — pierścieniową, taśmową, szytą nićmi, twardą — a odwzorowanie ich na najbliższego sąsiada zaimponowałoby oprawę pierścieniową jako zeszytową. Nierozpoznana oprawa zostawia oprawę z szablonu, a słowo biletu ląduje w logu.
- Liczba stron nigdy nie pochodzi z biletu. O impozycji decyduje liczba stron, którą PDF faktycznie ma; rozbieżność jest raportowana i nie jest przyjmowana na wiarę.
- Bilety zleceń są traktowane jak dane wrogie, bo takie są. Hot folder przyjmuje pliki od każdego, kto może pisać do obserwowanego katalogu, a XML-owy bilet zlecenia to jedyny format w tej aplikacji, który osoba z zewnątrz zarazem tworzy i oczekuje, że zostanie sparsowany. Dlatego DTD są zakazane, a resolver nie jest dostarczany — to zamyka jednym ruchem odczyt encji zewnętrznych (
file:///C:/… albo połączenie otwarte z wnętrza sieci drukarni) oraz odmowę usługi przez rozwijanie encji; rozmiar i długość dokumentu też mają limit. Odwołania do grafiki są rozwiązywane, normalizowane i dopiero potem sprawdzane, czy mieszczą się w katalogu dozwolonym przez operatora — w tej kolejności, bo normalizacja po sprawdzeniu to sposób, w jaki obchodzi się zabezpieczenia przed wyjściem z katalogu. Ścieżki bezwzględne wewnątrz dozwolonego katalogu przechodzą, więc typowa instalacja z MIS-em działa, a odwołania http, https i ftp są odrzucane wprost.
- Hot foldery mogą działać jako usługa Windows. Hot folder to infrastruktura produkcyjna — drukarnia zakłada, że plik wrzucony o 4:00 zostanie zaimponowany o 4:00 — a uruchamiany z aplikacji okienkowej zatrzymywał się w chwili wylogowania operatora; stacja zrestartowana w nocy wracała, nie obserwując niczego, dopóki ktoś tego nie zauważył.
hotfolder service install / start / stop / uninstall / status rejestruje usługę i nią steruje, a menedżer hot folderów daje te same cztery akcje wraz z paskiem stanu, podnosząc uprawnienia przez UAC — bo aplikacja poza tym działa bez uprawnień administratora i tak ma zostać.
- Usługa dostaje wskazanie, gdzie leżą dane operatora. Konfiguracja, licencja i zapisane szablony siedzą w profilu tego, kto foldery skonfigurował, a usługa nie działa jako ta osoba: jako LocalSystem ma
%APPDATA% pod C:\Windows\System32\config, gdzie zastałaby pustą konfigurację, brak licencji i po cichu nie obserwowała niczego — awaria bez objawu. Instalator zapisuje tę ścieżkę i przekazuje jako --data-dir, parsowane przed czymkolwiek innym, żeby cały proces rozwiązywał jeden komplet katalogów, a nie dwa.
- Można wskazać konto usługi, bo LocalSystem uwierzytelnia się jako maszyna i serwer plików rutynowo mu odmawia — a to sytuacja większości drukarni, których hot foldery leżą na udziale sieciowym.
- Restart po awarii jest konfigurowany przy instalacji: trzy próby co minutę, licznik zerowany dobowo. Sens usługi polega na tym, że folder, który padł o 2:00 na zadławieniu sieci, nie zostaje martwy do 8:00.
- Uzgodnienie z Menedżerem usług potraktowane jak realne ograniczenie. SCM daje kilka sekund na potwierdzenie startu, zanim uzna usługę za zawieszoną, a start hosta to operacje wejścia-wyjścia — konfiguracja, baza rejestru zadań, katalogi robocze, przegląd folderów wejściowych, być może na wolnym udziale. Start jest więc potwierdzany natychmiast i wykonywany w tle, a start nieudany zatrzymuje usługę z niezerowym kodem wyjścia, zamiast trwać w stanie „działa", nie obserwując niczego.
- Lista szablonów hot foldera zawiera wbudowane punkty startowe, nie tylko zapisane pliki. Na świeżej instalacji lista była pusta, więc konfiguracja pierwszego hot foldera oznaczała wejście do menedżera szablonów, zbudowanie broszury i zapisanie jej, zanim dało się wrócić. Wybrany preset zapisuje się teraz do zwykłego katalogu szablonów i folder jest na niego wskazywany — od tej chwili to szablon jak każdy inny, widoczny w menedżerze i edytowalny, bo preset, którego operator nie może poprawić, jest gorszy niż brak presetu. Istniejący plik o tej samej nazwie zostaje nietknięty: nadpisanie szablonu, który ktoś zdążył dostroić, bo wybrał ten sam preset po raz drugi, byłoby ciche i destrukcyjne.
- Dwa kolejne progi w profilu prasy, według tej samej zasady co reszta: rozdzielczość kreski i limit kolorów dodatkowych opisują maszynę, więc należą do profilu, a nie do zadania. Offset dostaje próg 1200 dpi dla kreski i limit dwóch dodatków, gazetowy 800 dpi i jeden, cyfra i wielki format żadnego limitu form — separują do procesu albo drukują z rolki, gdzie liczba dodatków nie jest ograniczeniem.
Zmienione
- Okno preflightu przy eksporcie przebudowane wokół decyzji, której ma służyć. Podawało znaleziska zdaniem — czyli jedyną rzeczą, której operator z klientem za plecami nie czyta — i renderowało je płaską listą w kolorach zaszytych w hexie, przez co było jedynym oknem w aplikacji zostającym w tym samym odcieniu niezależnie od wybranego motywu. Teraz werdykt jest nagłówkiem, liczniki stoją obok niego jako plakietki (a waga, której nic nie znaleziono, nie dostaje plakietki, bo „0 błędów” obok „3 ostrzeżeń” każe czytać dwie liczby, żeby dowiedzieć się jednej rzeczy), znaleziska są grupowane od najcięższych pod nagłówkami mówiącymi, co dana waga oznacza dla eksportu, a każdy kolor pochodzi z semantycznych zasobów motywu. Filtr wagi pojawia się, gdy jest co zawężać — raport na czterdzieści pozycji czyta się od pytania „co mnie blokuje” — a wagi, której nic nie znaleziono, nie da się wybrać, więc żadne kliknięcie nie ląduje na pustej liście. Listę można też skopiować do schowka: przekazanie znaleziska autorowi pliku oznaczało dotąd przepisywanie go z modalnego okna.
- Zakładka walidacji w oknie informacji dostała ten sam filtr oraz licznik przy każdym nagłówku kategorii, więc kształt długiego raportu widać bez liczenia wierszy. Panel „co poprawić najpierw” jest świadomie nadal liczony z całego raportu, nigdy z przefiltrowanego podzbioru — odpowiada na pytanie o pracę, a przeliczenie go wewnątrz filtra po cichu odpowiadałoby na inne.
Naprawione
- Hot foldery wymagały Ghostscripta do pracy, która już go nie potrzebuje. Od 1.5.12 silnik imPRESS pakuje PDF/X-1a, X-3 i X-4 samodzielnie, ale walidator hot folderów wciąż odmawiał zapisania konfiguracji z PDF/X bez ścieżki do
gswin64c.exe — pliku, którego ta aplikacja nie dystrybuuje i którego większość maszyn nie ma, bo Ghostscript to osobno licencjonowane oprogramowanie AGPL. Wskazana ścieżka prowadząca donikąd nadal jest błędem; wybór silnika Ghostscript bez ścieżki jest teraz ostrzeżeniem, bo instalacja może zostać znaleziona w PATH w czasie działania. Poprawione zostały też trzy widoczne dla użytkownika teksty, które opisywały Ghostscripta jako dołączony do aplikacji — w obu językach.
- Eksporty natywne stały w kolejce za limitem przeznaczonym dla Ghostscripta. Dławik współbieżności istnieje po to, żeby N równoległych procesów Ghostscripta nie położyło maszyny; był pobierany przy każdym zadaniu PDF/X niezależnie od silnika, więc folder ustawiony na silnik natywny szeregował swoją pracę za limitem chroniącym go przed narzędziem, którego nigdy nie uruchamia. Tryb automatyczny nadal pobiera slot — decyduje per plik, wewnątrz potoku, i może jeszcze przełączyć się na Ghostscripta.
- Instalacja usługi z menedżera nie robiła nic, a okno UAC pokazywało „.NET Host". Zarówno podniesienie uprawnień, jak i rejestracja usługi zakładały, że
Environment.ProcessPath to aplikacja — a jest nią tylko wtedy, gdy program wystartował przez własny apphost. Uruchomiony jako dotnet "imPRESS Studio.dll" — czyli tak, jak robi to dotnet run, i tak, jak można zeskryptować instalację na serwerze — procesem jest dotnet.exe, którego opis pliku brzmi dosłownie „.NET Host". Operator był więc proszony o podniesienie uprawnień dla hosta .NET, a host dostawał argumenty hotfolder service install, których nie rozumie: kończył się natychmiast, bez okna, a menedżer nie zgłaszał niczego. Zarejestrowana usługa cierpiałaby na to samo, tylko gorzej — startuje, nie potrafi rozebrać własnej linii poleceń i zatrzymuje się, nie mówiąc nigdzie dlaczego. Komenda uruchomieniowa jest teraz ustalana, a nie zakładana, i dokłada ścieżkę do zestawu zarządzanego, gdy host jej potrzebuje; menedżer sprawdza po wszystkim stan usługi, więc operacja bez efektu mówi o tym wraz z kodem wyjścia, zamiast zostawiać niezmienione okno.
- Usługa nazwana od produktu, a nie od schematu. Klucz w Menedżerze usług to
ImpressStudioHotFolders — czysty ASCII, bez spacji, pisany jak nazwa typu, bo klucz usługi wpisuje się do konsoli i wkleja do skryptów, robiąc to często bez znajomości stylizowanej pisowni produktu. W oknie Usługi widnieje jako imPRESS Studio Hot Folders: najpierw nazwa produktu, żeby wpis sortował się razem ze wszystkim, co ta aplikacja jeszcze zarejestruje, i bez końcówki „Service", którą lista usług i tak już zakłada.
- Nieudana operacja na usłudze nie zgłaszała niczego. Instalacja usługi wymaga uprawnień administratora, więc praca dzieje się w drugim procesie uruchomionym przez UAC — osobnej instancji bez konsoli, której wyjście nie trafia nigdzie, a kodem wyjścia jest liczba. Operacja odrzucona z całkowicie zwyczajnego powodu (zła nazwa konta, usługa oznaczona do usunięcia, zakaz z zasad grupy) docierała więc do operatora jako okno, które się nie zmieniło — najmniej użyteczna postać awarii, jaką program może wyprodukować. Podniesiony proces zapisuje teraz wynik do katalogu danych operatora, a menedżer go odczytuje i pokazuje; plik wędruje w dół przez granicę poziomów integralności, czyli w kierunku, który działa, i jest kasowany zaraz po odczycie, żeby stary wynik nie mógł zostać podany jako rezultat bieżącej próby. Brak wyniku też jest komunikowany — oznacza, że podniesiony proces w ogóle nie doszedł do komendy.
- Każda komenda CLI zgłaszała sukces także wtedy, gdy zawiodła.
Environment.ExitCode ustawiony w handlerze System.CommandLine jest odrzucany, gdy Main zwraca liczbę, więc hotfolder service install kończył się kodem 0 mimo odmowy — a każdy skrypt sprawdzający kod dostawał informację, że się udało. Wynik parsera i kod z handlera są teraz łączone: gorszy wygrywa.
- Żadna operacja na usłudze zlecona z menedżera hot folderów faktycznie się nie wykonywała. Instalacja, uruchomienie i usunięcie dawały okno UAC i żadnej zmiany — usługa zostawała dokładnie taka, jaka była.
--data-dir decyduje o tym, skąd czytany jest każdy trwały plik, więc jest parsowany ręcznie w Program.Main, zanim istnieje parser komend i kontener zależności — i nigdy nie został zadeklarowany w drzewie komend. Każde wywołanie z tą opcją było więc odrzucane jako błąd składni, a podniesiony proces drukował pomoc do konsoli, której nie miał, i kończył pracę. Z pulpitu awaria była niewidoczna; z konsoli ta sama komenda działała, bo wywołanie z konsoli tej opcji nie przekazuje. Teraz jest to opcja globalna komendy głównej, przyjmowana (i ignorowana) wszędzie, a opcja faktycznie nieznana parserowi nadal jest odrzucana. status dostał przy okazji --result-file, które cztery pozostałe komendy już przyjmowały: podkomenda odmawiająca opcji akceptowanej przez rodzeństwo to przycisk, który po cichu nic nie robi — i właśnie tak to znaleziono.
- CLI działał poprawnie i nie wypisywał nic. Każda komenda uruchomiona z konsoli nie dawała żadnego wyjścia — ani błędu, ani wyniku — a operatorowi zostawał wniosek, że program się nie uruchomił. Uruchamiał się: log pokazuje każde wywołanie i wykonaną pracę. Plik wykonywalny podsystemu Windows nie dostaje od
cmd.exe standardowych uchwytów, a .NET wiąże Console.Out z tym, co zwróci GetStdHandle przy pierwszym użyciu; gdy to uchwyt nieprawidłowy, każdy zapis idzie donikąd do końca życia procesu. AttachConsole dawało konsolę do rysowania, ale nie naprawiało tych uchwytów — czyli obecna od początku połowa rozwiązania była tą, która sama z siebie nic nie znaczy. Uchwyty są teraz otwierane wprost na CONOUT$ / CONIN$ i instalowane przed przepięciem strumieni, a uchwyt dostarczony przez wywołującego zostaje nietknięty, więc przekierowanie do pliku lub potoku nadal trafia tam, gdzie wywołujący czyta.
- Komenda usługi zostawia ślad w logu. Rejestracja usługi to czynność administracyjna, a zarazem operacja, której wyjścia operator najczęściej nie zobaczy — podniesiony proces nie ma konsoli w ogóle. Każdy wynik trafia teraz do logu aplikacji obok konsoli i pliku wyniku.
- Warstwa usługi mówi językiem operatora. Dwadzieścia trzy komunikaty komend usługi Windows — te, które trafiają teraz na pasek stanu menedżera i do wyjścia CLI — były po angielsku niezależnie od języka interfejsu, w aplikacji poza tym dwujęzycznej na wskroś. Są rozwiązywane przez tę samą usługę lokalizacji co wszystko inne. Wpis w logu zachowuje angielską strukturę, więc czytający wsparcie techniczne nadal rozpoznaje zdarzenie, choć komunikat w środku jest po polsku.
- PDF-y dokumentacji były cztery wydania w tyle. Powstały 31 sierpnia, opisywały 1.5.12 i nie zawierały ani biletów CIP4, ani trybu usługi, ani przepisanego rozdziału o preflighcie — podczas gdy leżący obok HTML, do którego strona linkuje w pierwszej kolejności, miał wszystkie trzy. Wszystkie cztery zostały wygenerowane z aktualnych źródeł, a liczba stron podana na kartach pobierania zgadza się teraz z tym, co faktycznie jest w pliku, a nie z tym, co było kiedyś.
- Zrzuty hot folderów pokazywały nie to okno i nie tę wersję. Obrazek podpisany „menedżer hot folderów" był w istocie edytorem, zrobionym przed 1.5.12 — razem z polem „Ścieżka Ghostscript", które to wydanie usunęło, na stronie tłumaczącej czytelnikowi, że PDF/X Ghostscripta nie potrzebuje. Menedżer ilustruje teraz menedżera (wraz z paskiem usługi Windows), edytor dostał własną ilustrację z wbudowanymi punktami startowymi, a obie istnieją po polsku i po angielsku.
- Menedżer szablonów nie pokazywał szablonu, który jest w użyciu.
TemplateEditorViewModel jest singletonem i nikt nigdy nie wkładał do niego aktywnego szablonu — więc każdy sposób wyboru, który nie przechodzi przez ten edytor (sugestia zastosowana z okna sugestii, domyślny szablon wczytany przy starcie, przywrócona sesja), zostawiał w menedżerze to, co akurat trzymał ostatnio. Operator, który zastosował podpowiedzianą wizytówkę i wszedł do menedżera ją sprawdzić, widział inny szablon i nic nie mówiło mu, że to nie ten w użyciu. Menedżer otwiera się teraz na aktywnym szablonie, zasilany w jednym miejscu, przez które przechodzą wszystkie cztery ścieżki. Przejmuje kopię, więc edycja tam wciąż niczego nie zmienia aż do Użyj szablonu, i zostawia edytor w spokoju, gdy ten już pokazuje ten sam układ — inaczej ponowne wejście gubiłoby plik, z którego szablon pochodzi, i zamieniało kolejny Zapisz w Zapisz jako. Porównanie świadomie pomija Id szablonu: Validate() dostempluje je, gdy go brakuje, więc ten sam układ regularnie nosi dwa różne identyfikatory, a szablon zaadaptowany z innego nosi identyfikator źródła — identyfikator nie odpowiada na żadne z tych pytań.
- Raportu preflight nie dało się zapisać.
PreflightReportWriter pojechał w 1.5.12 kompletny — z jedenastoma własnymi zielonymi testami i wpisem w changelogu mówiącym, że raport można zapisać — i nic w aplikacji go nie wołało. Przycisku nie było. Każdy test podstawiał własnego wywołującego i właśnie dlatego żaden nie mógł zobaczyć, że produkt nie ma żadnego: klasa bez wywołującego jest niewidzialna dla zestawu testów, który zawsze go dostarcza. Informacje o pliku → Walidacja ma teraz Zapisz raport, obok napraw działających na tych samych znaleziskach, i zapisuje raport w takiej postaci, w jakiej stoi — te same znaleziska, ta sama kolejność, ten sam profil prasowy — więc do klienta trafia to, na co patrzył operator. Jeden test zadaje teraz pytanie odwrotne niż zwykle: czy UI w ogóle to woła.
- Naprawy były oceniane względem progów domyślnych, nie tych z profilu drukarni. Okno informacji o pliku pytało silnik napraw, co się stosuje, podając świeżo utworzony profil zamiast tego, z którym powstał raport — i tak samo uruchamiało wybrane naprawy. Drukarnia, której profil podnosi RGB do błędu albo obniża próg rozdzielczości, dostawała znaleziska ze swojego profilu, a naprawy z cudzego.
Testy
- 188 nowych testów. Warte wymienienia są te o granicach, nie o ścieżkach szczęśliwych: że różne kąty obrotu wyciszają zwykłe znalezisko o obrocie, zamiast raportować jeden problem dwa razy; że
/Rotate 450 i -270 są rozpoznawane jako te same 90°, zanim cokolwiek zostanie ocenione; że dodatek „Allura Red” nie jest zarezerwowanym kolorantem All; że kolorant All nie zajmuje zespołu maszyny; że naprawa metadanych odmawia ogłoszenia pliku z trappingiem za nietrapowany; i że naprawa warstw niczego nie usuwa oraz nie rusza warstw widocznych. Osiem obejmuje przejmowanie aktywnego szablonu przez menedżera, w tym dwa dotyczące pułapki, przez którą oczywista implementacja była błędna: ten sam układ regularnie nosi dwa różne Id, a szablon zaadaptowany z innego nosi identyfikator źródła — identyfikator trzeba było całkowicie pominąć w porównaniu. Dwa zadają pytania, których zwykły test jednostkowy nie zada: jeden przypina wywołanie między dwoma view-modelami, z których każdy był poprawny, a brakowało wywołania między nimi; drugi przeszukuje źródła UI pod kątem odwołań do writera raportu i silnika napraw, bo usterka, przed którą chroni, to brak wywołującego, a nie zły wywołujący. Jeden test został napisany błędnie i wyłapała go własna kontrola zębów: twierdził, że kontrola półtonu pomija kreskę, używając obrazu 300 dpi — który i tak mieści się w paśmie akceptowalnym — więc przechodził także po usunięciu pominięcia. Rozdzielczość jest teraz poniżej obu progów, gdzie asercja coś znaczy. Zestaw testów biletów zleceń jest ważony tak samo: większość dotyczy tego, co czytnik i resolver odrzucają, bo tam siedzi wartość obu komponentów. Jeden z tych testów też był napisany błędnie — umieszczał encję zewnętrzną w wartości atrybutu, czego XML zabrania wprost, więc przechodził po usunięciu każdego zabezpieczenia i niczego nie dowodził. Odwołanie w treści elementu, gdzie jest poprawne składniowo i rozwinęłoby się, pada w chwili zdjęcia którejkolwiek z osłon. Dodatki do hot folderów są przypięte tam, gdzie się da: że PDF/X waliduje się bez Ghostscripta dla wszystkich trzech odmian, że --data-dir jest parsowane zanim aplikacja istnieje i nie bierze za katalog ani zawieszonej opcji, ani następnej flagi, oraz że dwukrotny wybór presetu nie nadpisuje szablonu, który operator zdążył zmienić. Każdy wbudowany preset przechodzi też walidację szablonu — preset, na którym hot folder pracuje bez nadzoru, ma się wyłożyć tutaj, a nie o 4:00. Ustalanie komendy uruchomieniowej jest przypięte na obu gałęziach, co wymagało dwóch podejść: pierwsza wersja czytała ścieżkę procesu sama, więc pod runnerem testowym wykonywała wyłącznie gałąź apphosta i przechodziła po usunięciu gałęzi hosta .NET. Przyjęcie obu wejść jako parametrów jest tym, co czyni zepsutą gałąź osiągalną.
Dwa wątki prac. Ghostscript przestaje być zależnością — imPRESS Export Engine pakuje natywnie wszystkie trzy standardy PDF/X, więc nic w produkcie nie wymaga już zewnętrznego, osobno licencjonowanego narzędzia. Do tego preflight doprowadzony do poziomu profesjonalnego: panel porad rozjechał się z regułami, o których miał doradzać, tryb ostry odrzucał zwyczajne broszury, a drukarnia nie miała jak powiedzieć, że dana kontrola jej nie dotyczy
Nowości
- PDF/X-1a:2001 i PDF/X-3:2003 pakowane natywnie. To były dwie ostatnie funkcje wymuszające ścieżkę przez Ghostscripta. Oba standardy są zdefiniowane na PDF 1.4 i różnią się od X-4 dokładnie trzema rzeczami, obsługiwanymi teraz w jednym miejscu: wersją PDF stemplowaną na pliku, deklaracją zgodności w słowniku informacyjnym i pakiecie XMP oraz zakazem żywej przezroczystości. Ghostscript nadal można wybrać, ale jest opcją, a nie wymogiem — i nie jest dystrybuowany z aplikacją, bo to osobno licencjonowane oprogramowanie AGPL.
- Przezroczystość obsłużona uczciwie, bez udawania spłaszczania. Zamiana faktycznie półprzezroczystej grafiki na kryjącą oznacza kompozycję strony — to zadanie rasteryzatora, a jego wykonanie po cichu zamieniłoby tekst wektorowy w piksele, czyli w jedyną rzecz, o której operator prepress nie może dowiedzieć się po fakcie. Zamiast tego silnik usuwa konstrukcje przezroczystości, które są dowodliwie nieaktywne, a gdy plik niesie przezroczystość, która faktycznie maluje — odmawia, nazywając to, co znalazł.
- To pokrywa przypadek, który naprawdę występuje. Zdecydowana większość grafiki gotowej do druku nie zawiera żadnej żywej przezroczystości, a mimo to nie przechodzi walidacji PDF/X-1a — bo cokolwiek przeszło przez Illustratora albo InDesigna, dziedziczy grupę
/Group << /S /Transparency >> na stronie i garść wpisów stanu graficznego /ca 1, /BM /Normal, /SMask /None. Każdy z nich jest operacją pustą: grupa przezroczystości, której wszyscy członkowie są w pełni kryjący i komponowani w trybie Normal, renderuje się identycznie jak treść bez grupy. Usunięcie ich nie zmienia ani jednego piksela, a czyni plik zgodnym.
- Zachowawczość wpisana w konstrukcję. Nieaktywne wpisy są usuwane wyłącznie wtedy, gdy cały dokument jest wolny od prawdziwej przezroczystości. Pojedyncze
/ca 0.5 gdziekolwiek oznacza, że nie usuwa się nic, a eksport zostaje odrzucony: grupa izolowana albo z wybijaniem staje się obserwowalna, gdy w grę wchodzi prawdziwa przezroczystość, a ciche usunięcie jej w takiej sytuacji zmieniłoby wydrukowany rezultat.
- Kolor w X-1a jest weryfikowany, a nie zakładany. Standard dopuszcza wyłącznie DeviceCMYK, DeviceGray i kolory dodatkowe. Zamiast ufać flagom konwersji przekazanym przez wywołującego, silnik ponownie skanuje plik, który właśnie zapisał, i przerywa eksport, jeśli został w nim jakikolwiek DeviceRGB. Błędna flaga albo konstrukcja pominięta przez konwerter nie mogą już wyprodukować pliku deklarującego zgodność „tylko CMYK”, który w środku niesie RGB.
- Drukarnia decyduje, ile waży każda kontrola — łącznie z jej wyłączeniem. Profil niesie teraz politykę wagi per kod findings (
Off, Info, Warning, Error). Zakład trapujący w RIP-ie może wyciszyć doradztwo o trappingu; pracujący wyłącznie w CMYK-u podnieść RGB z ostrzeżenia do błędu; świadomie dopełniający broszury usunąć tę notkę zupełnie. Dotąd jedyną kontrolą per reguła były trzy zaszyte w kodzie przełączniki, więc każda pozostała reguła krzyczała z wagą wybraną przez jej autora — dla wszystkich drukarni, na zawsze.
- Egzekwowane w jednym miejscu. Polityka działa w
PrepressValidationContext.Add, przez które przechodzi każdy walidator, więc wszystkie dwadzieścia reguł — i każda dopisana w przyszłości — dziedziczą ją, nie wiedząc nawet, że mechanizm istnieje.
Off znaczy „nie ma”, a nie „zdegradowane”. Wyciszone znalezisko nie jest ani wypisywane, ani liczone, więc nie może zablokować ostrego eksportu zza filtra.
- Profil z nowszego wydania nadal się wczytuje. Nieznane kody i nierozpoznane nazwy polityki są pomijane, a nie odrzucane, więc plik ustawień wspominający kontrolę, której ta wersja nie zna, degraduje do zachowania domyślnego zamiast nie otworzyć się wcale.
- Raport można zapisać.
PreflightReportWriter renderuje wynik jako czysty tekst: nagłówek (plik, profil, znacznik czasu, werdykt), potem znaleziska od najcięższych, powtórzenia jednego kodu zwinięte, a kolejne strony złożone w zakresy — 1-3, 7, 11-13 zamiast linii czterdziestu liczb. Znalezisko prepressowe to spór z klientem o to, czyj plik jest zły, i chce podróżować z dowodem; dotąd jedynym sposobem przekazania go było opowiedzenie z pamięci. Czysty tekst świadomie: otwiera się wszędzie, wkleja do maila bez zamieniania się w załącznik, którego nikt nie otworzy, i pozostaje przeszukiwalny w archiwum po latach. Komunikat, którego argumenty nie pasują do szablonu, degraduje do samego kodu, zamiast wywalić zapis.
- Lewy panel konfiguracji też się chowa. Inspektor miał uchwyt zwijania na styku z płótnem już wcześniej; panel po drugiej stronie nie miał żadnego, więc na ekranie laptopa płótno zostawało z tym, co zostało po 312 px, których nie mogło odzyskać. Teraz ma lustrzany uchwyt, a strzałka wskazuje kierunek, w którym panel się chowa (
‹ zwija, › przywraca), zamiast pokazywać po obu stronach ten sam znak. Obie kolumny boczne są Auto, a szerokość siedzi na samym panelu — i to dopiero sprawia, że schowanie panelu faktycznie oddaje miejsce płótnu, zamiast zostawiać pas pustego tła tam, gdzie był.
Poprawki
- Każdy arkusz zapisany przez komponer niósł grupę przezroczystości w RGB. PdfSharpCore stempluje
/Group << /CS /DeviceRGB /S /Transparency >> na każdej serializowanej stronie — zmierzone na pustej stronie, bez treści i bez jakiejkolwiek przezroczystości, zapisany plik nadal to zawiera. W pliku PDF/X-1a jest to błędne podwójnie: funkcja przezroczystości w pliku PDF 1.4 oraz przestrzeń barw DeviceRGB w standardzie dopuszczającym wyłącznie CMYK. Usunięcie klucza przez model obiektowy nic nie daje, bo zapisujący dopisuje go z powrotem przy następnym zapisie — więc grupy są teraz wycinane z gotowego pliku. Zamiennik ma dokładnie tę samą długość w bajtach (spacje są legalnym białym znakiem między tokenami PDF), dzięki czemu wszystkie przesunięcia w tablicy referencji pozostają poprawne, zamiast wymuszać jej pełną przebudowę.
- Zmiana w bibliotece nie może już wyprodukować pliku, który kłamie o swojej zgodności. Usuwanie tych grup zależy od tego, jak PdfSharpCore serializuje strony, więc ścieżka pakowania czyta ponownie plik, który właśnie zapisała, i przerywa eksport, jeśli przezroczystość przetrwała. Przyszła aktualizacja biblioteki, która zepsuje tę technikę, objawi się teraz odmową eksportu, a nie plikiem PDF/X-1a z grupą przezroczystości w środku.
- Panel „co poprawić najpierw” dawał ogólnikową poradę dla 47 z 60 znalezisk. Porady są rozwiązywane po kodzie findings, a słownik porad rozjechał się z kodami, które faktycznie wystawiają walidatory — osiem szablonów nosiło nazwy, których nic nie potrafi wyprodukować (
MIXED_COLOR_SPACE wobec prawdziwego MIXED_COLOR_SPACES, SPOT_COLOR_FORBIDDEN wobec SPOT_FORBIDDEN, IMAGE_DPI_VERY_LOW i IMAGE_DPI_HIGH wobec IMAGE_DPI_LOW i IMAGE_DPI_OVER_MAX, a do tego RGB_IN_CMYK_TARGET, TRANSPARENCY_FLATTEN, PDFX_NONCONFORMANT i FONT_SUBSET_INCOMPLETE). Obie strony były wewnętrznie spójne, więc nic się nie wywalało i nic nie trafiało do logu: panel, który operator czyta jako pierwszy, po prostu przestał doradzać, a każde znalezisko dodane od tamtej pory — cały zestaw prepress z 1.5.8, łącznie ze wszystkimi o randze błędu — spadało do zdania „wykryto N problemów, sprawdź listę poniżej”. Każdy kod ma teraz własną poradę w obu językach, martwe szablony zniknęły, a test porównuje oba słowniki, żeby nie mogły rozejść się ponownie.
- Ostry preflight odrzucał zwyczajne broszury. W trybie bezokienkowym i w CLI przełącznik przerywał pracę przy
Issues.Count > 0, czyli liczył także wpisy informacyjne — a dwa z nich opisują całkowicie normalną produkcję. SIGNATURE_PADDING pojawia się zawsze, gdy liczba stron broszury nie jest wielokrotnością składki, czyli dokładnie w przypadku, dla którego istnieje dopełnianie w strategii zeszytowej; DUPLEX_ODD_PAGES przy każdej dwustronnej pracy o nieparzystej liczbie stron. Sześciostronicowa broszura A5 przy składce ośmiostronicowej nie przechodziła więc ostrego eksportu, co czyniło przełącznik bezużytecznym w tej właśnie automatyzacji, dla której powstał. Błędy i tak przerywają eksport bezwarunkowo, więc tryb ostry dokłada — i dokłada wyłącznie — ostrzeżenia; komunikat przerwania wymienia teraz kody zamiast mówić „są ostrzeżenia”.
- Niezgodność formatu netto raportowana osobno dla każdej strony. Każda inna reguła agreguje, a ta wystawiała wiersz na stronę — a dokument, którego trim nie zgadza się z szablonem, zwykle nie zgadza się na wszystkich stronach, więc czterdziestostronicowa praca grzebała resztę raportu pod czterdziestoma identycznymi liniami. Teraz jest to jedno znalezisko: pierwsza niezgodna strona niesie zmierzone wartości, a lista stron — zasięg.
- Dialog sugestii szablonów ucinał karty — w obu osiach. W poziomie dziewięć pól tekstowych karty nie miało zawijania: nazwa produktu niesie swoje wymiary („Notes / kalendarz A5 — spirala (148×210 mm)") i dzieli wiersz z plakietką dopasowania, więc przy szerokości okna uciekała poza kartę zamiast przełamać się na drugi wiersz. W pionie — i to zauważył operator — lista trzymała swój margines wewnętrzny na ScrollViewerze jako
Padding="16,12". ScrollViewer odejmuje własny padding od mierzonej treści, ale nie dolicza go z powrotem do zakresu przewijania, więc zakres wychodził o 24 px krótszy od listy: po zjechaniu na sam dół ostatnia karta wisiała wciąż 36 px pod widocznym obszarem i nie było sposobu, żeby ją tam wciągnąć. Margines siedzi teraz na treści, gdzie jest mierzony jako część tego, co się przewija. Ten sam atrybut robił to samo edytorowi profili znaczników i raportowi preflight, któremu ucinał ostatnie znalezisko.
Zmiany
- Skan pokrycia farbą jest natywny — i kod wreszcie to mówi. Sam skan działa na PDFium plus prawdziwej transformacji ICC od wersji 1.5.0, ale mieszkał w klasie nazwanej
GhostscriptInkScanner, która nosiła też nieużywaną implementację ghostscriptowego inkcov. Martwy kod zniknął; model pokrycia i próg ostrzeżenia przeniosły się do NativeInkScanner, gdzie ich miejsce, a wyszukiwanie Ghostscripta trafiło do GhostscriptLocator, który robi wyłącznie to jedno.
- Wyszukiwanie Ghostscripta nie szuka już kopii dołączonej. Sprawdzało dwie ścieżki wewnątrz katalogu instalacji w poszukiwaniu kopii, która nie jest dystrybuowana — Ghostscript to oprogramowanie AGPL i nie może być redystrybuowane wewnątrz zamkniętego produktu komercyjnego. Teraz szuka tam, gdzie kopia zainstalowana przez użytkownika faktycznie leży: skonfigurowana ścieżka, potem
PATH (którego poprzednia implementacja nigdy nie sprawdzała, mimo że pomoc w aplikacji każe operatorowi go tam dodać), a na końcu standardowy układ %ProgramFiles%\gs.
- Okno eksportu nie opisuje już silnika natywnego jako „tylko X-4”, a porada preflightu dotycząca przezroczystości w X-1a / X-3 odróżnia teraz konstrukcje nieaktywne, które silnik usuwa sam, od przezroczystości, która faktycznie maluje.
Testy
- 32 nowych testów. Dwa najważniejsze porównują słowniki, a nie zachowanie: każdy wystawiany kod musi mieć poradę, a każda porada musi należeć do kodu, który cokolwiek potrafi wystawić. Obie strony tej pary były wewnętrznie spójne, myląc się co do drugiej — czyli dokładnie taki kształt defektu, jakiego żaden jednostronny test nie zobaczy. Przypięte też: szablony porad używają wyłącznie dwóch argumentów, które podaje generator (szablon sięgający po trzeci wywala się w chwili, gdy operator czyta raport), wartości enuma polityki pokrywają się z wagami, które reprezentują (mapowanie jest rzutowaniem), a wpisy informacyjne nigdy nie bramkują ostrego eksportu. Para od przewijania jest behawioralna plus strukturalna: jeden test przewija listę sugestii do końca i sprawdza, że ostatnia karta mieści się w widocznym obszarze, drugi zakazuje pionowego paddingu na jakimkolwiek ScrollViewerze w UI — bo ta pomyłka jest w każdym dialogu odległa o jeden atrybut i milczy, dopóki treść nie przerośnie okna. Headlessowa aplikacja testowa ładuje też teraz FluentTheme: bez niego ScrollViewer nie ma ScrollContentPresentera i po cichu przycina zamiast przewijać — dlatego ten zestaw testów nie widział tego defektu. Uchwyty paneli są przypięte strukturalnie, bo o działaniu zwijania decyduje to, gdzie zapisana jest stała szerokość — na panelu, nigdy na kolumnie siatki — a błędny zapis wygląda poprawnie, nie oddając płótnu niczego.
Ulotki składane przestają być wymiarowane arkuszem — szerokość panelu bierze się z produktu, tak jak przy każdej innej oprawie, a menedżer szablonów rysuje arkusz, zanim ten trafi na maszynę
Poprawki
- Panele falcu były rozstawiane przez dzielenie arkusza, a nie z wymiaru produktu. Z-fold, harmonijka i altarka wyliczały szerokość panelu jako
(arkusz − marginesy − odstępy) ÷ liczba paneli, a format netto był tylko prostokątem, w który wpasowywano grafikę. Linie falcu wędrowały więc razem z podłożem: ulotka DL (panele 99 mm) impozycjonowana na SRA3 wychodziła z panelami co 143,33 mm, więc falcerka bigująca na 99 mm zaginała w poprzek grafiki. Nie było też jak powiedzieć „produkt to A4 składane do DL” — wejściem był wyłącznie arkusz, co jest dokładnie odwrotnie niż przy produkcie, którego geometrię ustala maszyna introligatorska. Panele układają się teraz w podanym rozmiarze, stykając się liniami falcu, a cały blok jest centrowany na arkuszu i reszta papieru zostaje pusta. FoldGeometry jest jedynym miejscem, które to liczy — dzielą je strategia, walidacja, podgląd i renderer znaczników, więc wszystkie cztery zgadzają się co do tego, gdzie arkusz zostanie zbigowany.
- Falc, którego panele wychodziły poza arkusz, przechodził walidację. Kontrolę mieszczenia miała wyłącznie altarka; Z-fold i harmonijka spadały do ogólnego testu N-up, który — przy
NUpX = 1, z jakim wychodzi każdy preset falcu — pytał, czy mieści się jeden panel. Trzy panele po 210 mm na arkuszu 297 mm przechodziły walidację i docierały do strategii, która produkowała panele zachodzące na siebie o 114 mm, z pierwszym zaczynającym się 52 mm od lewej krawędzi papieru i ostatnim wystającym poza prawą. Wszystkie trzy oprawy falcowane mają teraz jedną wspólną kontrolę i nazywa ona to, co zmierzyła: „3 panele po 210,0mm” albo „wyrób rozłożony 297×210mm = 3×99,0mm”.
- Wbudowany preset DL Z-fold był wewnętrznie sprzeczny — arkusz A4 poziomo z formatem netto 210 × 99 mm, czyli dokładnie przypadek powyżej — i tak został wydany. Teraz jest produktem A4 poziomo (podawanym jako ulotka rozłożona) na SRA3, co daje panele 99 × 210 mm obiecywane przez nazwę. Harmonijka DL dostaje 10 mm marginesu arkusza, żeby jej cztery panele zmieściły się w podłożu.
- Listy rozmiarów nie podążały za szablonem, który opisują. Lista papieru i jej znacznik orientacji poziomej były przestawiane na szablon wyłącznie przez Wczytaj, Nowy i przyciski presetów; przy starcie i po każdej innej podmianie znacznik zostawał na „pionowo”, choć szablon niósł arkusz poziomy. Kolejny rozmiar wybrany z listy wychodził więc obrócony względem tego, na co operator patrzył. Obie listy — arkusza i użytku — synchronizują się teraz przy każdej zmianie szablonu, łącznie z tą, z którą edytor się otwiera.
- Znaczniki falcu były rysowane wyłącznie dla zeszytówki. Każdy preset falcu ma je włączone, a ani podgląd, ani wyeksportowany PDF nie pokazywał choćby jednego dla ulotki składanej — czyli dla tej jednej oprawy, której nazwa mówi o składaniu. Kreskowane znaczniki są teraz rysowane przy górnej i dolnej krawędzi każdego bigu, w miejscach, gdzie panele faktycznie się stykają — i w podglądzie, i w PDF-ie. Zeszytówka zachowuje swój znacznik grzbietu.
- Siatka Step & Repeat z rozstawem osi, która wychodziła poza arkusz, przechodziła walidację. W trybie centerline-to-centerline strategia centruje blok
(N−1) × pitch + użytek i ignoruje odstęp oraz margines arkusza — a jedyną działającą kontrolą mieszczenia był ogólny wzór z marginesami, opisujący zupełnie inny układ. Siatka 4 kolumn naklejek 50 mm przy rozstawie 60 mm na A4 (potrzeba 230 mm, dostępne 210) przechodziła walidację i drukowała się ze skrajnymi kolumnami uciętymi na krawędzi arkusza; odwrotnie — poprawny szablon z niezerowym marginesem mógł zostać odrzucony za miejsce, którego strategia nigdy nie używa.
- Amerykański preset harmonijki produkował paski 2,13 × 11″. Składał Letter pionowo w poprzek jego szerokości 8,5″ na cztery wysokie i wąskie panele — kształt, którego nie oczekuje żadna kaseta falcerki. Teraz odpowiada orientacji presetu tri-fold: Letter poziomo na 11×17, cztery standardowe panele 2,75 × 8,5″.
- Wyjście z gangingu mogło zostawić szablon w trybie work-and-turn. Lista trybu dupleksu ma sens wyłącznie dla gangingu, ale wybrany tryb przeżywał zmianę oprawy, a przycisk OK wywalał się potem na walidacji wartości, dla której operator nie miał już żadnej widocznej kontrolki. Tryb wraca teraz do sheetwise, gdy oprawa przestaje być gangingiem, a sama lista pokazuje się tylko tam, gdzie ma zastosowanie.
- Pięć produktów z biblioteki sugestii wychodziło na arkuszu, na którym nie mieścił się ich własny spad. Presety plakatów B2, Tabloid, ANSI C i ANSI D zestawiały plakat z arkuszem dokładnie tego samego formatu, a ulotka Half-Letter (szeroka jak arkusz Letter) próbowała gangować się na Letterze — każdy z nich budował szablon, który wywalał walidację w momencie zastosowania. Plakaty idą teraz na arkusz klasę wyżej (B2→B1, Tabloid→ANSI C, ANSI C→D, D→E), ulotka Half-Letter gangaje się 2-up na Tabloidzie pionowo, a nowy test podaje każdemu wpisowi biblioteki jego własny kanoniczny rozmiar i sprawdza, że powstały szablon się waliduje — więc ta klasa błędu nie ma jak wyjść ponownie.
Nowości
- Menedżer szablonów dostał podgląd arkusza na żywo. Trzecia kolumna rysuje schemat pierwszego arkusza drukarskiego — gniazda użytków z numerami stron, puste sloty, linie falcu w miejscach bigowania, obszar użytkowy — odświeżany w trakcie pisania, z linią wydajności (sztuk × pokrycie) pod spodem. Jest planowany tymi samymi strategiami opraw, które planują produkcję, więc miniatura nie ma jak rozjechać się z tym, co wyjdzie w eksporcie; podgląd rolki przycina się do czytelnej garści rzędów, a niepoprawny szablon degraduje do zwykłej informacji „popraw błędy powyżej” zamiast pokazywać nieaktualny rysunek.
- Walidacja działa na żywo, nie dopiero przy OK. Baner błędu pojawia się, kiedy operator jeszcze edytuje — i znika w chwili poprawienia pola — zamiast czekać na kliknięcie Użyj szablonu. Odświeżanie porównuje treść, więc baner nie mruga przy spokojnym takcie zegara.
- Rozmiar użytku wybierzesz z listy formatów standardowych, tak jak dotąd arkusz. Karta formatu netto dostaje tę samą listę i znacznik orientacji poziomej, opartą na tym samym rejestrze — więc rozmiary własne dodane przy arkuszu pojawiają się i tutaj, i tak samo przeżywają restart. Wpisanie wymiarów ręcznie ponownie zaznacza pasujący format standardowy albo czyści wybór, zamiast zostawiać nazwę, która kłamie o rozmiarze użytku. Dotyczy każdej oprawy, nie tylko falcowanych.
- Szablony falcowane można opisać z obu stron. Nowy selektor Podany rozmiar to czyta format netto jako jeden panel (rozmiar strony przychodzącego PDF-a) albo jako wyrób rozłożony — „A4 składane do DL” to sposób, w jaki trafia większość prac — i wtedy panel to szerokość podzielona przez liczbę paneli. Szablony zapisane przed tym wydaniem wczytują się jako panel, czyli dokładnie to, co ich format netto już znaczył.
- Presety zostały nazwane produktem i pogrupowane według rodzaju. Dwadzieścia kilka pozycji w jednej płaskiej kolumnie, nazwanych mechanizmem („A4 Ganging 2-up”, „DL Ulotka Z-fold”), kazało operatorowi tłumaczyć żargon opraw na robotę leżącą na biurku. Każdy preset zaczyna się teraz od produktu i formatu gotowego — „Ulotka DL — falc Z, 3 panele”, „Wizytówki 85×55 mm — 12 na arkuszu”, „Broszura A4 — zeszytowa” — a lista dzieli się na cztery nagłówki: broszury i książki, ulotki składane, wiele użytków na arkuszu, etykiety i naklejki.
- Lista mówi wprost, że jej liczby to punkt wyjścia. Podpis w rodzaju „SRA3 poziomo → A4, składka 8 stron” opisuje preset tak, jak specyfikacja opisuje gotową pracę, co zaprasza do odczytania, że kliknięcie zabetonowuje te rozmiary. Sekcja nazywa się teraz Punkty startowe, ma pod sobą jedno zdanie wyjaśnienia, każdy preset powtarza je w dymku, a status po kliknięciu mówi, że parametry są do zmiany.
- Trzy opisy zdążyły się zdezaktualizować i mówiły nieprawdę: DL Z-fold nadal reklamował arkusz A4 po tym, jak to wydanie przeniosło go na SRA3, a preset naklejek A4 twierdził, że ma rozstaw 55 mm, gdy szablon niesie 52 mm.
- Każda oprawa ma wreszcie swój punkt startowy. Spirala i altarka były dwiema oprawami bez presetu — niewidocznymi dla operatora przeglądającego listę. Cztery nowe pozycje: Notes A5 — spirala (wiro) i Ulotka altarka — 4 panele 100×210 mm w zestawie metrycznym oraz ich amerykańskie odpowiedniki. Test pilnuje teraz reguły: każdy typ oprawy musi być osiągalny z co najmniej jednego presetu w obu zestawach jednostek.
- Katalog presetów jest udowodniony testami, a nie komentarzami. Odręczny dowód mieszczenia przy każdej fabryce jest teraz wykonywalny: każdy preset musi przejść
Template.Validate(), mieć unikalny identyfikator i przetrwać zapis do JSON oraz odczyt bez zmian.
- Okno „O programie” podaje adresy projektu. Strona i repozytorium GitHub są klikalne, a podpisem przycisku jest sam adres, żeby pozostał czytelny na maszynie bez skonfigurowanej przeglądarki. Adres strony jest kluczem lokalizacji, nie stałą, więc polski interfejs otwiera polską wersję, a angielski
/en/.
- Sugestie szablonów zrobiły się wyraźnie mądrzejsze.
- Wykrywanie spadu. PDF oddający MediaBox zamiast TrimBoxa przychodzi jako format netto + spad — wizytówka 85×55 jako 91×61 — i dotąd był kwitowany wzruszeniem ramion w postaci bliskich trafień. Kiedy surowy rozmiar nie pasuje do niczego, a „rozmiar − 2×spad” pasuje dokładnie (próby przy 3, 2 i 5 mm, w celowo ciasnym pasie 1 mm, żeby legalny rozmiar własny nigdy nie został odczytany jako cudzy produkt), silnik koryguje wejście, buduje szablon na prawdziwym formacie netto z wykrytym spadem i mówi to na karcie.
- Progi odległości skalują się z formatem. Sztywny promień 25 mm lokalizował wizytówki bezbłędnie i czynił plakaty nieznajdywalnymi — plik B1 odbiegający o 30 mm od nominału dostawał „brak dopasowań”. Oba progi zachowują stare wartości jako podłogi i rosną z przekątną wejścia, więc zachowanie przy małych formatach jest nietknięte.
- Nowe produkty: notesy i kalendarze na spirali A5 i A4, czteropanelowa harmonijka DL i czteropanelowa altarka (bramkowane na dokumenty 7-8-stronicowe, żeby nie tłoczyły się przy 6-stronicowym Z-foldzie), plakaty A1 i B1 oraz ulotka 105×297. Adaptacja do kontekstu zachowuje teraz styl altarki i geometrię falcu, zamiast po cichu redukować produkt czteropanelowy do domyślnego trzypanelowego.
- Spinner składki chowa się przy oprawach, które go ignorują. Stron na sygnaturę steruje wyłącznie zeszytówką i oprawą klejoną; przy gangingu, spirali, falcach, rolce i step & repeat było to pole, które nic nie robiło.
- DL i rozmiary wizytówek dołączyły do rejestru formatów standardowych (DL 99 × 210, BC 85×55, BC 90×50, BC US 3,5×2″), więc lista rozmiaru użytku nazywa to, co ustawiają presety, zamiast się czyścić.
Zmiany
- Optymalizuj N-up odmawia teraz ruszania opraw, które nie mają siatki N-up (falce, zeszytówka, rolka), zamiast wpisywać liczby, których ich strategie nigdy nie czytają.
- Pomoc i edytor profili znaczników nie opisują już znaczników falcu jako dostępnych wyłącznie dla zeszytówki, a pomoc do szablonów wymienia listę rozmiaru użytku i dwa sposoby opisania produktu składanego.
Ganging przestaje być kserokopiarką — siatka N-up potrafi nieść kolejne strony dokumentu zamiast tej samej strony w kółko
Nowości
- Kolejność stron źródłowych ustawisz przeciągając miniatury. Przeciągnij stronę na pasku podglądu w nowe miejsce, a wczytany dokument zostaje przepisany w tej kolejności — i to ona jest planowana, impozycjonowana, eksportowana i zapisywana; nie ma osobnego kroku „zastosuj”, który można przegapić. Po ruszeniu kolejności pojawia się baner z przyciskiem Przywróć kolejność.
- Przeciąganie mówi, gdzie strona wyląduje. Kafelek podąża za kursorem jako duch, kafelek źródłowy blaknie, żeby jego pochodzenie zostało widoczne, a kursor wstawienia zaznacza dokładną szczelinę, w którą strona wpadnie — siatka łudząco podobnych kafelków nie daje inaczej w co celować. Kursor nakłada się na kafelek, zamiast zajmować własne kolumny: rezerwowanie na niego miejsca poszerzało każdy kafelek o 6 px, co przy szerokości inspektora wystarczało, by zepchnąć kafelek do następnego rzędu.
- Kolejność przeżywa edycje stron, które przebudowują dokument. Obrót albo konwersja strony składa wczytany dokument na nowo z plików źródłowych, w kolejności plików, więc układ jest trzymany jako permutacja i nakładany ponownie po każdym złożeniu. Inaczej operator zmieniłby kolejność, obrócił jedną stronę i dostał swój układ po cichu cofnięty — zauważone dopiero na wydrukowanym arkuszu.
- Zapis też honoruje kolejność. Zapisz PDF czytał plik źródłowy, a Scal i zapisz scalał od nowa z listy plików — oba oddałyby oryginalną sekwencję.
- Pomoc w aplikacji została napisana od nowa pod to, co program faktycznie robi, w obu językach. Nadal opisywała wersję z trzema oprawami i rozmiarami własnymi ginącymi po zamknięciu. Dziesięć sekcji jest nowych — pasek kroków, pliki źródłowe i edycje stron, tryby gniazd gangingu, optymalizacja układu i doradca arkusza, sugestie szablonów, ręczna edycja gniazd, profile znaczników, preflight, hot foldery i ustawienia aplikacji — a istniejące zostały zaktualizowane: dziewięć opraw zamiast trzech i słowniczek obejmujący ganging, work-and-turn, TAC, trapping i odmiany PDF/X.
- Ganging potrafi teraz wypełniać gniazda kolejnymi stronami dokumentu, a nie tylko kopiami jednej. Miał dokładnie jedno zachowanie: każde gniazdo na arkuszu niesie tę samą stronę źródłową. To jest poprawne dla nakładu wizytówek — jeden projekt, dwanaście kopii, rewers na tyle — i błędne dla tego, od czego presety wzięły nazwę: 5-stronicowy dokument ganged 2-up wychodził jako trzy arkusze jednej powielonej strony, z połową dokumentu na rewersach i operatorem przekonanym, że strony 2 i 4 zostały zgubione. Kolejne strony wypełniają gniazda w kolejności czytania: 1+2, 3+4, 5. Przy dupleksie każde gniazdo staje się osobną kartką.
- Dla istniejących szablonów nie zmienia się nic. Tryb domyślnie ustawia się na powielanie użytku, czyli to, co robił każdy zapisany szablon i każdy hot folder; szablon zapisany przed tym wydaniem wczytuje się w dokładnie te arkusze, które produkował wczoraj.
Zmiany
- Przełączenie języka lub jednostek zmienia teraz to, co jest na ekranie, natychmiast. Ustawienie było już wpychane do działającej aplikacji; nie działało wiązanie, którego używa niemal każdy napis w programie.
{loc:Loc} wiązał się z indeksatorem serwisu lokalizacji i polegał na powiadomieniu w stylu WPF, którego Avalonia nie traktuje jako unieważnienia ścieżki indeksatora. Każde menu, przycisk, etykieta, zakładka, okno i dymek renderowały się poprawnie przy pierwszym rysowaniu, a potem zamarzały w języku, w którym aplikacja wystartowała — na cały czas życia procesu.
- Krok (4) nazywa się teraz „Ustawienia eksportu”, nie „Eksport”. Otwiera okno opcji; plik zapisuje zielony przycisk po prawej tego samego paska. Dwa przyciski na szerokość dłoni od siebie, oba podpisane eksportem i tylko jeden eksportujący, to pułapka, którą pasek kroków zastawiał za każdym razem.
Poprawki
- Edycja gniazda przesuwała obrysy, ale nie stronę. Zmiany pozycji, rozmiaru, obrotu i strony źródłowej docierały do planu poprawnie, po czym wyglądały, jakby nic nie robiły: kanwa cache'uje całą złożoną scenę do jednej bitmapy i przerysowuje ją, dopóki nic w kluczu migawki się nie zmieni — a ten klucz niósł NUMER arkusza i nic o jego zawartości.
- Obrót strony w prawo, a potem w lewo zostawiał ją na stałe w poziomie. Obrót jest nakładany na kopię roboczą przez zmianę
/Rotate, a zapisanie tego przez opakowanie strony w PdfSharp każe bibliotece rozwiązać WIZUALNY rozmiar strony i wypiec go w MediaBox przy zapisie. Obrót jest teraz wpisywany prosto do słownika strony.
- Świeżo wczytany dokument zostawał miękki, dopóki nie zgasła plakietka „Str. N”. Dwie niezależne wady — kanwa przerysowywała nieaktualną scenę, a pasek miniatur anulował render kanwy, bo obie dzieliły jeden slot „najnowszej żądanej skali” na stronę.
- „Optymalizuj N-up” zostawiał pola N-up pokazujące stary układ. Optymalizator wpisywał nowy układ prosto do szablonu, który jest zwykłym obiektem bez powiadamiania o zmianie, więc pasek statusu ogłaszał „4×5”, a spinnery obok nadal pokazywały „4×3”.
- Kliknięcie miniatury strony źródłowej wyrzucało z listy stron źródłowych. Skok kanwy do arkusza, na który trafiła strona, jest sensem kliknięcia; przełączanie nawigatora także na listę arkuszy oznaczało, że operator tracił swoje miejsce po każdym kliknięciu.
Arkusz, który wybierasz, jest arkuszem, który dostajesz — trzy wady w menedżerze szablonów spiskowały, żeby impozycjonować na arkuszu, którego nikt nie wybrał
Poprawki
- Arkusz wybrany w menedżerze szablonów mógł zostać zignorowany, a praca zaplanowana na arkuszu presetu. Kliknięcie presetu podmieniało szablon — łącznie z arkuszem — ale nigdy nie mówiło o tym liście papieru, więc lista dalej wskazywała poprzedni wybór. Ponowne zaznaczenie tej samej pozycji nie podnosi żadnego powiadomienia o zmianie, co zostawiało operatora bez sposobu na odzyskanie swojego arkusza: „Wizytówki 12-up, potem B1 poziomo” impozycjonowało się na SRA3. Lista i znacznik orientacji podążają teraz za tym, jaki arkusz szablon faktycznie niesie.
- Lista papieru robiła się pusta po zastosowaniu dowolnego presetu poziomego. Synchronizacja szukała nazwy arkusza dosłownie, a arkusz poziomy nazywa się „SRA3 (L)”, co nie jest nazwą presetu papieru — więc każdy preset ISO z listy szybkiego startu (a wszystkie są poziome) zostawiał puste pole, opisując się jednocześnie jako „SRA3(L) → 12× wizytówka”. Nazwa jest teraz czytana razem z przyrostkiem orientacji, a dopasowywana po wymiarach, gdy nazwa nie mówi nic użytecznego.
- „Optymalizuj N-up” nie potrafił zmniejszyć układu. Porównywał bieżące N-up z gęstszym upakowaniem i na tym kończył, więc szablon przeniesiony na mniejszy arkusz — wizytówki 12-up z SRA3 na A4, 374 mm układu przy 210 mm papieru — dostawał odpowiedź „już optymalny”, a niezgodność wychodziła znacznie później jako błąd walidacji przy eksporcie. Przycisk dopasowuje teraz układ do arkusza w obie strony, tą samą arytmetyką (i tą samą tolerancją), której używa walidacja.
- Nie stosuje już siatki zakładającej obrócony użytek. Optymalizator rozważa obie orientacje, a gęstsza często wymaga obrócenia użytku o 90° — ale pola N-up i format netto opisują razem jeden układ, więc wpisanie obróconej siatki przy pozostawieniu formatu netto dawało układ mieszczący się gorzej niż ten, który zastępował.
- Karta arkusza pokazuje teraz arkusz, który trzyma — nazwę i wymiary w aktywnej jednostce. Lista była jedyną informacją zwrotną w tej karcie, więc arkusz, którego nie potrafiła nazwać, pokazywał się jako nic.
Sugestie szablonów przestają być rankingiem odległości, a zaczynają być rekomendacją — sześć ważonych sygnałów, uzasadnienie przy każdej pozycji i pamięć tego, co ta drukarnia naprawdę drukuje
Nowości
- Sugestie szablonów są teraz szeregowane według sześciu ważonych czynników, a nie samej odległości wymiarowej. Odległość nadal dominuje — i tak ma być, bo operator wybrał produkt, którym jego PDF jest, a nie ten, który najgęściej się pakuje — ale swoje dokładają też zgodność proporcji, liczba stron, dopasowanie do arkusza, dopasowanie do bieżącego ustawienia i to, jak bardzo preset jest dedykowany konkretnemu produktowi. Każda waga leży w jednym miejscu jako nazwana stała, a ich suma wynosi dokładnie 1,0 — pilnuje tego test, żeby przyszła zmiana nie przesunęła po cichu wszystkich progów jakości.
- Wykorzystanie arkusza świadomie nie ma prawa przestawiać produktów w rankingu. Wizytówka 90×50 i etykieta z rolki 90×50 mają ten sam rozmiar i pakują się zupełnie inaczej; dopuszczenie wydajności do decyzji podmieniałoby operatorowi produkt pod rękami. Wpływa więc na liczbę pokazaną na karcie i na nic więcej. Porównywanie uzysku ma sens wyłącznie między arkuszami dla jednego produktu — i od tego jest osobny panel z alternatywnymi arkuszami.
- Każda sugestia sama się tłumaczy. Na karcie pojawia się krótka checklista — „wymiary zgadzają się co do milimetra”, „liczba stron pasuje do tego produktu”, „pasuje do bieżącego arkusza i oprawy”, „zgodne z Twoim systemem jednostek” — zbudowana wyłącznie z powodów, które faktycznie zachodzą. Lista dopchana słabymi wpisami uczy operatorów, żeby przestać ją czytać, więc preset, którego proporcje po prostu się zgadzają, nie podaje tego jako powodu, kiedy wymiary i tak pasowały dokładnie.
- Alternatywne arkusze, gdy dałyby zauważalnie więcej sztuk. Karta, której układ zostawia pół arkusza pustego, mówi teraz, na którym innym arkuszu produkt zaganguje się gęściej — z liczbą sztuk i współczynnikiem poprawy. Nigdy nie zmienia arkusza, który sugestia zastosuje — to, na czym drukarnia drukuje, zależy od maszyny, magazynu i introligatorni, a silnik nie widzi żadnej z tych rzeczy. Pokazuje kompromis i zostawia decyzję tam, gdzie jej miejsce. Produkty z rolki są pomijane: długość segmentu jest wyliczana, a nie wybierana, więc „większy arkusz” nie jest czymś, co operator mógłby zrobić.
- Produkty mają kategorie, a lista biblioteki jest według nich pogrupowana. Wizytówki, ulotki, broszury, plakaty, etykiety, naklejki, bilety, metki i reszta dostają własne nagłówki, ułożone według najlepiej ocenionej pozycji w grupie — najbardziej prawdopodobny produkt nadal jest pierwszy, a wewnątrz grupy nic się nie przestawia. „Pokaż mi pozostałe etykiety” to realne pytanie, a wcześniej wymagało przeczytania płaskiej listy czterdziestu pozycji.
- Cztery poziomy jakości dopasowania zamiast dwóch. Na zewnątrz silnik nadal raportuje „dokładne / bliskie” — ten kontrakt się nie zmienił — ale karta pokazuje teraz Idealne, Bardzo dobre, Dobre albo Do sprawdzenia, więc remis i naciągnięcie przestają wyglądać identycznie. Dopasowanie co do wymiaru nigdy nie schodzi poniżej „Bardzo dobre”: bycie dokładnie tym rozmiarem to najmocniejszy dostępny dowód i żaden zestaw słabszych sygnałów nie powinien nas z niego wyperswadować.
- Silnik uczy się, który preset ta drukarnia wybiera dla danego rozmiaru. Otwórz plik 85×55, wybierz „Wizytówka” — następny plik 85×55 pokaże ten preset wyżej. Trzy świadome wybory dla tego samego rozmiaru to już nawyk, a nie przypadek, więc bonus szybko dochodzi do pełnej siły — i jest ograniczony na tyle nisko, że wyuczony nawyk potrafi rozstrzygnąć remis, ale nigdy nie przebije wyraźnej niezgodności wymiarów. Drukarnia, która wydrukowała sto wizytówek, nadal musi się dowiedzieć, że plik przed nią to ulotka A4. Rozmiary są kubełkowane, więc eksport tej samej wizytówki jako 85,04×54,98 zasila tę samą historię zamiast budować drugą, o połowę słabszą, a obrócony PDF trafia w ten sam wpis.
- Zapisuje się na stałe. Historia trafia do pliku
suggestion-preferences.json w profilu użytkownika i przetrwa zamknięcie aplikacji — preferencja, której trzeba uczyć od nowa każdego ranka, jest tym samym co jej brak. Nic nie opuszcza komputera, a w Ustawienia → Uczenie sugestii widać, ile zapamiętano, i jest przycisk kasujący wszystko — dla drukarni, która zmienia maszynę albo profil produkcji.
- Potrafi zmienić zdanie. Liczniki mają sufit, a przy każdym wyborze konkurencyjne presety dla tego samego rozmiaru tracą punkt — przejście z wizytówek na etykiety przy 90×50 wymaga więc tych samych trzech świadomych wyborów, które ustanowiły stary nawyk, zamiast przegłosowywania licznika rosłego przez rok. Ręcznie podrasowany plik historii też nie kupi nieprzebijalnej preferencji: liczniki są przycinane przy wczytaniu.
- Kompensacja pełzania przyjmuje gramaturę zamiast grubości. Papier można teraz opisać tak, jak się go realnie zamawia — „90 g” z ryzy — zamiast grubością, której nikt nie zmierzył. Obowiązuje jedno albo drugie, nigdy oba naraz: wybór trybu blokuje drugie pole, a impozycja czyta jedną wynikową wartość — dwie na pół zapamiętane liczby nie mają jak się rozjechać.
- Gramatura wymaga rodzaju papieru i nie jest to formalność. Masa na metr kwadratowy sama w sobie nie mówi nic o grubości: 90 g kredy błysk to około 0,072 mm, a 90 g papieru pulchnego około 0,162 mm — ponad dwa razy więcej. Pełzanie to przesunięcie treści strony, więc pomyłka o czynnik 2 oddala grafikę od poprawnej bardziej, niż zrobiłoby to wyłączenie kompensacji. Pięć rodzajów ma wpisane typowe spulchnienie (kreda błysk, kreda mat, offset niepowlekany, makulaturowy, pulchny), a Własne przyjmuje wartość z karty technicznej producenta.
- Okno pokazuje, co z opisu wychodzi — „0,117 mm (117 µm)” — w obu trybach, więc przeliczenie jest widoczne, a nie domyślne. Ustawienie, z którego nie wychodzi żadna sensowna grubość, jest odrzucane przy walidacji, zamiast po cichu impozycjonować bez kompensacji.
- Istniejące szablony są nietknięte: niosą samą grubość, tryb domyślnie ustawia się na grubość i impozycja wychodzi dokładnie tak jak wcześniej.
- Preflight sprawdza teraz strefę bezpieczną. Tekst przechodzący przez linię cięcia jest zgłaszany jako błąd, a tekst, który mieści się w formacie, ale leży bliżej niż strefa bezpieczna — jako ostrzeżenie. Gilotyna pracuje z tolerancją kilku dziesiątych milimetra, a ściskany stos się przesuwa, więc tekst milimetr od krawędzi przechodzi na proofie i gubi końcówkę gdzieś w środku nakładu — to najczęstszy pojedynczy powód, dla którego praca wraca. Mierzony jest wyłącznie tekst, nigdy cała treść: tło wychodzące poza netto to cały sens spadu, a sprawdzanie go dawałoby uwagę praktycznie na każdym poprawnie przygotowanym pliku. Strefa z szablonu ma pierwszeństwo, bo zawieszka dziurkowana przy krawędzi potrzebuje więcej miejsca niż wizytówka.
- Preflight sprawdza teraz całkowite pokrycie farbą względem limitu maszyny. Za dużo farby w jednym miejscu nie wysycha: odbija się na spodzie kolejnego arkusza, blokuje się na wykładaniu, a na zwoju potrafi wyrywać włókna papieru. To jedna z niewielu wad, która psuje cały nakład, a nie jeden egzemplarz — i nic w preflighcie jej wcześniej nie szukało. Mały ciężki element to ostrzeżenie; to samo krycie na powierzchni wielkości pocztowki albo cokolwiek piątą część ponad limitem — błąd.
- Wartości są czytane z pliku, a nie mierzone z renderu. Kontrola bierze wartości CMYK zadeklarowane w content streamie, więc panel zbudowany na 370% raportuje 370%. Odzyskanie tego z rastra jest niemożliwe z zasady — renderowanie spłaszcza do RGB, a konwersja z powrotem do CMYK odbudowuje prawie-czerń głównie z K. Zmierzone na pliku testowym tego wydania: ten sam panel 370% wraca przez raster jako około 105%. Kontrola farby zbudowana w ten sposób po cichu przepuszczałaby pliki zalewające maszynę, co jest gorsze niż brak kontroli.
- Mówi też, czego nie sprawdziła. Osadzone obrazy niosą własne piksele i nie są badane, więc jeśli na zgłoszonej stronie są także obrazy, raport to zaznacza zamiast sugerować, że strona została przepuszczona. Skan pokrycia w oknie informacji o pliku zostaje jako względny sygnał „która strona jest najcięższa” i wprost mówi teraz, że jego średnie zaniżają.
- Preflight sprawdza teraz budowę czerni — dwa przeciwstawne błędy, oba warte dodruku. Drobny tekst w czerni z czterech farb pokazuje każdy błąd spasowania jako barwną obwódkę i powinien iść samą czernią K; duża plama w płaskiej czerni 100% bez niczego pod spodem wysycha na wypraną, niejednolitą szarość i potrzebuje podkładu z pozostałych farb. Zgłaszane, nigdy nie naprawiane: właściwe wartości podkładu zależą od maszyny, podłoża i limitu farby, a projektant mógł wybrać płaską czerń świadomie, żeby nie zabrudzić falcu albo kodu kreskowego.
- Preflight raportuje teraz trapping — wyłącznie to, co plik o sobie deklaruje. Trzy fakty, z których każdy zmienia dalsze postępowanie: czy dokument w ogóle deklaruje stan
/Trapped (PDF/X-1a i PDF/X-3 wymagają jednoznacznego True albo False, a „Unknown” jest raportowane osobno od „nikt tego nie ustawił”); czy w stronach siedzą już gotowe siatki trappingu — związane z rozbarwieniami i rozdzielczością, dla których powstały, więc dezaktualizujące się po konwersji koloru albo zmianie impozycji, a przez PDF/X-4 w ogóle niedopuszczalne; oraz czy plik deklarujący brak trappingu używa kolorów dodatkowych, bo styki koloru dodatkowego z procesowym to dokładnie te miejsca, gdzie błąd pasowania wychodzi białą linią.
- Nie rozstrzyga, gdzie trap ma być — i nie udaje, że to robi. To wymaga porównania każdej pary sąsiadujących obiektów pod kątem wspólnych rozbarwień na całej stronie, czyli silnika trappingu, a nie reguły preflightowej. Kontrola zgadująca położenie trapów myliłaby się w kierunku, który kosztuje dodruk — więc ta trzyma się tego, co faktycznie może wiedzieć.
- Prace jednorozbarwieniowe są zwolnione: jedna farba nie ma jak rozjechać się sama ze sobą, a zgłaszanie prac w skali szarości byłoby hałasem dokładnie tam, gdzie porada i tak nic nie daje.
- Ostrzeżenie o kolorach dodatkowych jest przełącznikiem w profilu — włączonym dla trzech profili offsetowych, wyłączonym dla cyfry i wielkiego formatu. Drukarnie trapujące w RIP-ie dostawałyby inaczej komunikat przy każdej pracy ze spotem, a tak reguła szybko traci wiarygodność.
- Poprawka: naprawa adnotacji mogła usunąć trapping z pliku. Czyściła całą tablicę
/Annots, a siatki trappingu i znaczniki drukarskie siedzą tam obok komentarzy i pól formularza — więc prośba o posprzątanie adnotacji mogła po cichu wyciąć trapping, z którym plik przyszedł, albo pasery i paski kontrolne umieszczone jako adnotacje. Teraz usuwa wyłącznie adnotacje interaktywne i komentarze, a zostawia produkcyjne — w tym każdą, której nie potrafi rozpoznać: koszt zostawienia zabłąkanego komentarza jest kosmetyczny, koszt wyrzucenia nierozpoznanego trappingu to dodruk.
- Preflight wyłapuje teraz ten sam kolor dodatkowy zapisany na kilka sposobów.
PANTONE 185 C, PANTONE 185C i Pantone 185 C w jednym dokumencie to dla RIP-a trzy rozbarwienia — trzy formy i trzy zmywania dla farby zamówionej raz. Plik sklejony z logo od klienta, linii wykrojnika od introligatora i panelu ze starszej pracy dochodzi do tego bez niczyjej złej woli, a wychodzi to zwykle dopiero przy przygotowaniu maszyny. Sufiks podłoża jest świadomie zachowany: 185 C i 185 U to naprawdę różne farby, a ich sklejenie zamieniłoby wykrywacz literówek w źródło złych porad.
- Preflight raportuje teraz warstwy, a zwłaszcza to, kiedy same ze sobą się nie zgadzają. Warstwa wyłączona w przeglądarce może być oznaczona do druku — tak właśnie warstwa „komentarze klienta” albo linia wykrojnika, której nikt nie widzi na proofie, ląduje na płycie — i odwrotnie: warstwa widoczna może nieść
PrintState /OFF, więc to, co zaakceptowano na ekranie, nigdy nie dojdzie do maszyny. Oba przypadki są zgłaszane z nazwami warstw, pierwszy jako błąd. Podstawowa analiza od zawsze wiedziała, czy plik ma warstwy; dopiero informacja, która i czy się drukuje, daje się wykorzystać.
- Preflight zgłasza teraz kodowania obrazów, których RIP może nie przyjąć. JPEG 2000 i JBIG2 to poprawny PDF i wyświetlają się bez zarzutu w każdej przeglądarce — dlatego docierają do naświetlania niezauważone; sporo RIP-ów produkcyjnych nadal ich nie przyjmuje, PDF/X-1a zabrania JPEG 2000 wprost, a do tego są to formaty, których nie umie skonwertować własna naprawa RGB tej aplikacji. Obrazy 16-bitowe są odnotowywane osobno — poprawne, czasem świadome, podwajają dane dla precyzji, której żadna maszyna nie odda.
- Biblioteka sugestii przyjmuje własne produkty. Ustawienia → Własne produkty pozwala dodać firmową kartę składaną, stały format etykiety klienta albo wykrojnik, który zamawia pół miasta — z własną nazwą, wymiarem, kategorią i arkuszem. Pojawiają się obok wbudowanych, grupują pod tymi samymi nagłówkami i biorą udział w tym samym uczeniu.
- To domyka lukę, którą samo to wydanie otworzyło. 1.5.8 nauczyło ranking preferencji drukarni — ale tylko wśród czterdziestu wbudowanych presetów, więc karta składana 100×210 nadal wracała jako „Bilet” albo „Zakładka”, operator wybierał najmniej złą pozycję, a silnik sumiennie uczył się złej nazwy i zapisywał ją na szablonie. Pamięć preferencji bez możliwości dodania produktu była połową mechanizmu.
- Własne produkty domyślnie nie należą do żadnego systemu miar, więc pozostają widoczne i w milimetrach, i w calach — ukrywanie przed operatorem jego własnego produktu byłoby nie do obrony. Dodanie produktu o istniejącej nazwie aktualizuje go, zamiast tworzyć konkurenta dla tego samego rozmiaru, a nazwa jest tożsamością produktu: zmiana nazwy zaczyna jego wyuczoną historię od nowa.
- Profile prepress. Progi, według których preflight ocenia pliki, są teraz nazwanym i edytowalnym zestawem, a nie stałymi w kodzie — limit farby, strefa bezpieczna, trzy progi rozdzielczości oraz polityki koloru i czerni. Pięć profili jest wbudowanych: offset arkuszowy na papierze powlekanym i niepowlekanym, gazetowy, cyfra i wielki format, każdy z limitem farby i progami rozdzielczości, których ten proces faktycznie wymaga. Baner w 120 dpi to poprawna robota, a ocenianie go progiem odpowiednim dla wizytówki odrzucało każdą dobrze przygotowaną pracę wielkoformatową.
- Profil opisuje maszynę; szablon i opcje eksportu nadal dostarczają tego, co należy do pracy — oczekiwanego formatu netto, głębokości spadu i celu PDF/X. Rozdzielenie tych dwóch rzeczy sprawia, że jeden profil obsługuje każdą pracę na tej maszynie, zamiast być przyspawany do wymiarów, przy których powstał.
- Edycja profilu wbudowanego i zapis tworzą profil własny; profilów fabrycznych nie da się nadpisać, dzięki czemu przyszłe wydanie nadal może poprawić próg wszędzie. Usunięcie aktywnego profilu cofa do domyślnego, zamiast zostawiać preflight bez żadnego.
- Hot foldery mogą uruchamiać pełną inspekcję prepress, każdy z własnym profilem — folder przyjmujący grafikę od klientów może być rygorystyczny, a folder karmiony przez sprawdzony system zostaje szybki. Domyślnie wyłączona i to świadomie: głęboka inspekcja parsuje każdy plik ponownie, a 1.5.7 włożyło realną pracę w usunięcie dokładnie takiego zdublowanego parsowania z potoku. Uwagi trafiają do logu; zatrzymują pracę tylko przy włączonym Ostrym preflighcie, więc włączenie inspekcji nigdy nie zmienia tego, co przechodzi — zmienia tylko to, o czym się dowiadujesz.
Zmiany
- Okno ustawień przewija się zamiast ucinać zawartość. Doszedł w tym wydaniu panel profilu prepress i całość przestała mieścić się na niższych ekranach; przy mniejszej liczbie sekcji okno nadal kurczy się do treści.
- Karty sugestii pokazują poziom dopasowania obok procentu, a kolor bierze się z poziomu, a nie z surowej liczby — słowo i kolor nie mają jak się rozjechać.
- Silnik sugestii nadal nie prowadzi żadnej walidacji prepressowej. Spady, strefy bezpieczne, znaczniki cięcia, błędy stron i drukowalność pozostają wyłącznie w gestii Preflightu — druga opinia od silnika dopasowującego rozmiary byłaby gorsza, a dwa komponenty kłócące się o to, czy plik nadaje się do druku, to najkrótsza droga do tego, żeby operator przestał ufać obu.
Jedno miejsce do przeglądania pracy — pasek arkuszy wędruje do inspektora, a kliknięcie miniatury przestaje kasować plan
Nowości
- Preflight potrafi teraz naprawiać, a nie tylko raportować. W zakładce walidacji w oknie informacji o pliku pojawił się panel „Naprawy”, który proponuje wyłącznie to, co da się naprawić w konkretnym pliku: brakujące ramki TrimBox / BleedBox, konwersję RGB → CMYK przez profil ICC oraz usunięcie adnotacji i pól formularza. Każda naprawa działa na kopii — oryginał nigdy nie jest otwierany do zapisu — a wynik trafia pod wskazaną przez Ciebie ścieżkę.
- Naprawiony plik jest sprawdzany ponownie, a raport pokazuje, co faktycznie się zmieniło — wypisuje kody uwag, które realnie zniknęły z zapisanego pliku. Narzędzie, które mówi „wykonano 3 naprawy”, prosi, żeby mu uwierzyć; to pokazuje dowód i wprost przyznaje, kiedy naprawa niczego nie zmieniła.
- Konwersja kolorów używa dokładnie tego samego silnika co eksport PDF/X-4, więc naprawiony plik zachowuje się identycznie jak wyeksportowany. Bez profilu ICC CMYK naprawa w ogóle się nie pojawia, zamiast schodzić do przybliżenia. Obraz w formacie, którego konwerter nie odczyta (JPEG 2000, 16-bit), jest raportowany jako nieskonwertowany, a nie podawany za CMYK.
- Naprawa RGB jest proponowana także wtedy, gdy walidator nic nie zgłasza: reguła RGB bada wyłącznie obrazy, więc grafika wektorowa — logo, tło, wykres — nigdy nie wywoływała uwagi. Naprawa sama skanuje plik.
- Uwagi, których nie da się poprawnie naprawić w pliku — brak osadzonych fontów, za niska rozdzielczość obrazów, żywa przezroczystość — świadomie nie mają naprawy. Zgadywanie postawiłoby na maszynie plik, który wygląda dobrze i jest zły.
- Opisy znaczników w podglądzie po najechaniu myszą. Wskazanie znacznika na arkuszu wyjaśnia teraz, czym jest i po co go tam umieszczono — linie cięcia, markery plotera tnącego (OPOS), pasery, pasek kontrolny, linie falcowania, opis techniczny (slug), kod kreskowy/QR arkusza oraz prowadnice formatu netto i spadu. Sloty stron miały podpowiedź od początku; otaczające je znaczniki — czyli najmniej oczywiste symbole na arkuszu — nie miały żadnej. Dostępne po polsku i angielsku, tak jak reszta interfejsu. Znaczniki mają pierwszeństwo przed slotem pod spodem, więc cienka linia leżąca na grafice nadal daje się wskazać.
Poprawki
- Zastosowanie zasugerowanego szablonu zostawiało w nagłówku „Brak szablonu”. Silnik sugestii budował szablony z pustą nazwą i komentarzem, że UI uzupełni ją z klucza lokalizacji — nikt tego nigdy nie robił. Operator, który przed sekundą wybrał „Ulotka A4”, dostawał informację, że szablonu nie ma, i po „Planuj” zaimponowana praca nadal twierdziła to samo. Nazwa jest teraz ustawiana przy wyborze sugestii. Celowo bez dopisku z wymiarami, który widnieje na karcie: szablon trafia na dysk, a nazwa z wbitym „in” czyta się źle w dniu przełączenia na milimetry — wymiary i tak siedzą w samym szablonie i renderują się w aktywnej jednostce.
- Sugestie szablonów uwzględniają teraz ustawioną jednostkę. Drukarnia pracująca w calach dostawała propozycje A4, DL i SRA3, choć presety startowe w edytorze szablonów już wcześniej przełączały się na zestaw US przy tym samym ustawieniu — dwie połowy aplikacji mówiły co innego. Sugestie są teraz filtrowane do pasującej rodziny. Dwa świadome wyjątki utrzymują listę użyteczną: presety spoza standardów narodowych (etykiety z rolki, naklejki, zawieszki, bilety) pokazują się zawsze, a dokładne dopasowanie wymiarowe przechodzi filtr niezależnie od preferencji — drukarnia w USA otwierająca faktycznie A4-owy plik nadal musi się dowiedzieć, że to A4.
- Podpowiedzi i zaznaczanie slotów potrafiły na jedną klatkę trafiać kilkadziesiąt pikseli obok. W klatce, w której podgląd odbudowywał swój bufor sceny, prostokąty trafień z przebiegu rysującego do bufora (we współrzędnych bufora, przesuniętych o margines nadmiarowy) zostawały obok tych policzonych poprawnie — wygrywał ten, który dopasował się pierwszy. Nieaktualny zestaw jest teraz czyszczony przed przeliczeniem.
- Aktualizacja z poziomu aplikacji nie ubija już programu w trakcie zamykania. Zaakceptowanie aktualizacji uruchamiało instalator i natychmiast wywoływało
Environment.Exit, które niczego nie zwija: ścieżka wyjścia aplikacji w ogóle się nie wykonywała, więc przepadała niewysłana diagnostyka, ostatnie wpisy zostawały w buforze logu, a zlecenia hot folderów „w locie” były porzucane — pliki zostawały w katalogu .work, a wiersze w rejestrze w stanie reserved do czasu odzyskania przy następnym starcie. Do tego instalator działał już na żywym procesie, ścigając się z jego własnym zamykaniem. Teraz aplikacja zamyka się normalną ścieżką (hot foldery drenowane, telemetria wysłana, logi zamknięte), a instalator startuje dopiero potem — na bezczynnej instalacji. Jego suma SHA-256 jest sprawdzana ponownie tuż przed uruchomieniem, więc plik podmieniony po pobraniu zostaje odrzucony zamiast wykonany.
- Statystyki użycia funkcji w ogóle nie docierały na serwer. Liczniki z Ustawienia → Diagnostyka (eksport, menedżer szablonów, hot foldery, edycja stron, Zapisz PDF, preflight) były naliczane poprawnie, po czym ginęły razem z procesem: jedyna wysyłka odbywała się przy starcie aplikacji — zanim operator zdążył cokolwiek otworzyć — więc każda paczka wychodziła z pustą listą funkcji. Nie było ani cyklicznej wysyłki, ani wysyłki przy zamykaniu, mimo że kod opisywał obie. Teraz liczniki lecą co 5 minut i jeszcze raz przy zamknięciu, a nieudana wysyłka oddaje je do kolejki — chwilowy brak sieci nie kasuje już całej sesji. Puste paczki nie są wysyłane w ogóle.
- Kliknięcie miniatury strony nie kasuje już impozycji. Przy zaplanowanej pracy lewy klik na miniaturze strony źródłowej przebudowywał płótno w tryb zwykłego podglądu stron: impozycja znikała, pasek arkuszy na dole płótna znikał razem z nią, a przy okazji — bez słowa — przepadały wszystkie ręczne zmiany slotów (przesunięcie / obrót / wyczyszczenie) wraz z historią cofania. Teraz klik przeskakuje na arkusz, na którym ta strona wylądowała (i przerzuca na rewers, jeśli leży tylko tam), a plan i zmiany zostają nietknięte. Jeśli strony nie ma w planie (wyczyszczony slot, zakres stron), aplikacja mówi to na pasku statusu zamiast zmieniać widok.
- Wyjście z impozycji do podglądu stron źródłowych jest teraz jawną akcją („Pokaż strony źródłowe”), która z góry ostrzega, jeśli ma odrzucić ręczne zmiany slotów.
- Preflight zgłasza teraz RGB także w grafice wektorowej, nie tylko w obrazach. Reguła badała wyłącznie obiekty graficzne, więc plik, którego RGB siedziało w logo, tle albo wykresie — czyli w przypadku najczęstszym — przechodził preflight zupełnie czysto i zaskakiwał operatora dopiero przy eksporcie. Jest to teraz osobna uwaga, a naprawa RGB ją obsługuje.
- Hot foldery: ta sama treść mogła zostać wyeksportowana dwa razy. Sprawdzenie „czy to już przetworzono?” i wstawienie rezerwacji były dwoma niezależnymi poleceniami, więc przy
maxConcurrentJobs powyżej 1 dwóch konsumentów mogło przejść kontrolę dla pliku, którego treść już wcześniej wyeksportowano. Teraz jest to jedna transakcja, a unikalny indeks egzekwuje to dodatkowo na poziomie bazy. Zweryfikowane na realnej bazie: osiem równoległych prób na zakończonym odcisku daje zero rezerwacji, a trzydzieści różnych odcisków nadal przechodzi równolegle.
- Hot foldery: wyścig mógł po cichu zawiesić obserwator odpytujący. Migawka katalogu była zwykłym słownikiem zapisywanym równocześnie przez pętlę odpytującą i skan startowy przez cały czas uruchamiania folderu. Równoległy zapis do tego typu to zachowanie nieokreślone — w praktyce wyjątek albo nieskończona pętla trzymająca wątek na 100% CPU bez śladu w logu, objawiająca się jako „hot folder przestał widzieć pliki”.
- Hot foldery: obserwator potrafił wstać z powrotem po zatrzymaniu. Procedura odzyskiwania po błędzie systemowym nie sprawdzała, czy folder nie został w międzyczasie zamknięty — zostawał osierocony obserwator z otwartym uchwytem katalogu (co blokuje też odmontowanie udziału sieciowego), wysyłający zdarzenia do martwego potoku.
- Hot foldery: jeden zły folder nie blokuje już przeładowania na stałe. Runner, który nie wstał, przerywał całe przeładowanie konfiguracji, zostawiając stan wewnętrzny opisujący jedną generację, a listę runnerów — inną. Każde kolejne przeładowanie kończyło się wtedy błędem aż do restartu aplikacji. Awarie są teraz izolowane per folder, tak jak zawsze były przy pierwszym uruchomieniu.
- Zablokowany
hotfolders.json nie zatrzymuje już startu aplikacji. Obsłużony był wyłącznie uszkodzony JSON; plik chwilowo trzymany przez kopię zapasową, antywirusa lub synchronizację chmury wychodził na zewnątrz i kończył proces kodem 2 — zanim pojawiło się jakiekolwiek okno, więc operator nie widział nic.
- OutputIntent w PDF/X mógł deklarować CMYK dla profilu RGB lub w skali szarości. Nagłówek ICC czytano wywołaniem, któremu wolno zwrócić mniej bajtów niż zażądano; krótki odczyt schodził do domyślnego CMYK, dając niezgodny plik, który przechodził nasz eksport i padał w RIP-ie odbiorcy.
- Konwersja do skali szarości po cichu pomijała obrazy z uszkodzoną paletą
/Indexed, zostawiając kolorową grafikę w pliku, który miał być monochromatyczny. Zabezpieczenie, które konwerter RGB miał od dawna, obowiązuje teraz i tutaj.
- Nieudane wczytanie profilu ICC przeciekało uchwyt systemu kolorów. Konstruktor otwierał najpierw profil sRGB, więc odrzucenie profilu wyjściowego zostawiało ten pierwszy otwarty na zawsze — nie istniał obiekt, na którym można by wywołać zwolnienie, a finalizatora nie ma. Hot folder wskazujący zły profil przeciekał jeden uchwyt na każde zlecenie, w pętli.
Zmiany
- Nawigacja po arkuszach przeniesiona z płótna do zakładki „Podgląd” w inspektorze. Pływający pasek w lewym dolnym rogu płótna i siatka miniatur w inspektorze były dwoma nawigatorami, które wyglądały tak samo, a zachowywały się inaczej — pasek poruszał się wewnątrz planu, miniatury plan burzyły. Teraz jest to jedna lista pod przełącznikiem Arkusze / Strony źródłowe, który po zaplanowaniu sam ustawia się na arkusze.
- Kafelek arkusza niesie więcej niż numer: liczbę zapełnionych slotów, znacznik
2× dla arkuszy dwustronnych oraz wyróżnioną ramkę na arkuszu aktualnie pokazywanym. Stary pasek nie miał żadnego wskaźnika bieżącego arkusza — przy długim nakładzie nie dało się stwierdzić, gdzie się jest, bez czytania licznika w pasku narzędzi.
Bezpieczeństwo
- Pola zakresu arkuszy i stron mogły wyczerpać pamięć przez literówkę. Zakres był rozwijany element po elemencie bez żadnego limitu, zanim mogła się wykonać jakakolwiek kontrola względem liczby stron:
1-20000000 — dziesięć znaków — alokowało około 726 MB, a nieco większa liczba kończyła proces. Zakresy są teraz ograniczone do 100 000 numerów z czytelnym komunikatem. Zmierzone przed i po.
- Zamknięto path traversal w profilach znaczników. Pole
marksProfileRef z szablonu trafiało do budowy ścieżki bez sprawdzenia, więc zaimportowany szablon mógł skierować odczyt poza katalog profili. Walidację miał wyłącznie zapis; teraz mają ją także odczyt i usuwanie, a sam konstruktor ścieżki stanowi ostatnią linię obrony.
- Zaktualizowano zależności z opublikowanymi podatnościami —
System.Text.Json do 8.0.5 (dwie o wysokiej wadze) i SQLitePCLRaw do 3.0.4 / 3.50.3 (jedna wysoka). Audyt zależności działa teraz przy każdej kompilacji, w trybie obejmującym zależności przechodnie, a dwie podatności bez dostępnej poprawki są wypisane jawnie — dzięki czemu każda nowa nadal krzyczy, zamiast ginąć w ścianie znanych ostrzeżeń.
- Ghostscript uruchamiany jest przez listę argumentów zamiast ręcznie cytowanej linii poleceń, co usuwa całą klasę błędów przy ścieżkach ze spacjami, ścieżkach UNC i końcowych separatorach.
- Zmienna środowiskowa nie może już obniżyć adresu serwera licencji ani telemetrii do zwykłego HTTP. Te żądania niosą odcisk sprzętowy maszyny; akceptowane jest wyłącznie HTTPS lub pętla zwrotna na potrzeby developmentu.
- Obie usługi sieciowe korzystają teraz ze wspólnego klienta HTTP na proces zamiast tworzyć nowego na każde żądanie, co zostawiało gniazda w stanie
TIME_WAIT i wymuszało pełny handshake TLS za każdym razem.
Wydajność
- Przepustowość hot folderów: dwa zapytania WMI zdjęte sprzed każdego zlecenia. Sprawdzenie licencji przed każdym zleceniem odczytywało za każdym razem numer seryjny dysku i UUID płyty — sam
Win32_DiskDrive kosztuje regularnie setki milisekund, a przy uśpionych dyskach sekundy. Partia 500 plików płaciła ponad minutę czystego narzutu, a start aplikacji płacił to samo, zanim pojawiło się okno. Sprzęt nie zmienia się w trakcie życia procesu, więc odcisk jest buforowany; podpis licencji i data wygaśnięcia nadal sprawdzane są przed każdym zleceniem.
- Ten sam PDF nie jest już parsowany dwa lub trzy razy na eksport. Analiza — najdroższa operacja w aplikacji — wykonywała się przy dodaniu pliku, ponownie przy preflighcie i jeszcze raz w potoku eksportu. Wynik jest teraz wykorzystywany ponownie tak długo, jak plik na dysku się nie zmienił.
- Konwersja kolorów buforuje wyniki per kolor. Każdy operator
rg w strumieniu treści kosztował wcześniej osobne wywołanie systemowego silnika kolorów plus cztery alokacje tablic; realny dokument używa kilkudziesięciu odrębnych kolorów.
- Konwersja obrazów czyta piksele wierszami, a nie pojedynczo, i dekoduje bez kanału alfa, który i tak natychmiast odrzucała — 12 mln zbędnych sprawdzeń zakresu i o 25% większy bufor na jednym zdjęciu 4000×3000.
- Diagnostyka nie czyta już pliku ustawień przy każdym zdarzeniu. Flaga rezygnacji była wczytywana i deserializowana z dysku przy każdym sprawdzeniu, także z wątku interfejsu.
Usunięte
- Pływający pasek arkuszy na dole płótna wraz z flagą
ShowSheetStrip, która go włączała.
- Siedem nieużywanych składowych publicznych, w tym jedyne wejście renderera rasteryzujące synchronicznie — omijało bramkę współbieżności, więc każde przyszłe użycie zamroziłoby interfejs na dużej stronie.
- Cztery katalogi tworzone przy każdym starcie i nigdy niezapisywane, z których jeden sugerował wsparcie dla własnych paczek językowych, którego nie ma.
Konwersja obrazów DeviceRGB w silniku imPRESS — PDF/X-4 z plików RGB bez Ghostscripta
Konwersja obrazów RGB → CMYK w silniku natywnym
- Obrazy w DeviceRGB nie wypychają już eksportu na Ghostscript. Silnik imPRESS konwertuje je teraz sam, przez ten sam profil ICC, który trafia do OutputIntent (silnik kolorów Windows, intent kolorymetryczny względny). Obsługiwane: JPEG (DCTDecode), 8-bitowe rastry Flate/RAW oraz palety Indexed z bazą RGB — konwertowane piksel po pikselu do 8-bitowego DeviceCMYK z kompresją Flate, w porcjach ograniczających zużycie pamięci.
- Bramka bez zmian w filozofii: nietypowe konstrukcje (JPEG2000, 16-bit) nie są zgadywane — jeśli którykolwiek obraz RGB pozostałby nieskonwertowany, silnik przerywa z czytelnym komunikatem zamiast wydać plik z fałszywą deklaracją zgodności. Egzotyczne użycia /DeviceRGB (operatory cs/CS, cieniowania) nadal kierują na Ghostscript.
- Zweryfikowane e2e: 4-stronicowy plik ze zdjęciami RGB → natywny PDF/X-4, wszystkie obrazy w DeviceCMYK, kolory i znaczniki zachowane (render kontrolny), nagłówek PDF 1.6 + GTS_PDFX + OutputIntent.
Poprawki
- Aplikacja nie uruchamiała się ponownie po aktualizacji z poziomu programu. Aktualizator uruchamia instalator w trybie cichym, a krok „uruchom aplikację" był w instalatorze oznaczony jako pomijany właśnie w trybie cichym — aktualizacja podmieniała pliki i zostawiała użytkownika bez działającego programu. Teraz po cichej instalacji instalator sam startuje aplikację (na uprawnieniach użytkownika, który ją wywołał), a kreator uruchamiany ręcznie zachowuje zwykły znacznik na ostatniej stronie.
- Eksport PDF/X-4 kończył się błędem „wybierz profil ICC" — po zakończonym składaniu arkuszy. Praca była już zaimponowana i zapisana, a dopiero pakowanie PDF/X przerywało z błędem, jeśli w opcjach nie wskazano profilu. Teraz silnik sam sięga po dołączony profil produkcyjny (PSO Coated v3 → ISO Coated v2 → dowolny CMYK z katalogu profili), zapisuje to w logu i kończy eksport poprawnie. Twardy błąd zostaje wyłącznie wtedy, gdy w systemie nie ma żadnego profilu CMYK.
Anonimowa diagnostyka (opcjonalna) + drobne poprawki UI
Anonimowa telemetria diagnostyczna (opt-out)
- Lekka, anonimowa diagnostyka pomagająca rozwijać aplikację. Wysyłane wyłącznie: losowy identyfikator instalacji (przypadkowy GUID generowany lokalnie — nie jest to identyfikator sprzętowy i nie da się go z nim powiązać), wersja aplikacji i systemu, wersja .NET, typ licencji, język, czas uruchamiania oraz liczniki użycia modułów (eksport, menedżer szablonów, hot foldery, edycja stron, Zapisz PDF, preflight — tylko ile razy).
- Z założenia nic nie wycieka: aplikacja wysyła wyłącznie stały, z góry ustalony zestaw pól — nigdy nazw plików, ścieżek, nazw ani zawartości prac, wpisywanych danych, historii kliknięć czy informacji o awariach. Dane crashy świadomie pominięte.
- Pełna kontrola: domyślnie włączone, z jednorazowym powiadomieniem przy pierwszym starcie i przełącznikiem w Ustawienia → Diagnostyka. Wysyłka jest w tle, z krótkim timeoutem i nie blokuje aplikacji; przy braku sieci po prostu pomijana. Zaktualizowana polityka prywatności (PL/EN).
Poprawki
- Pusty podgląd po starcie nie pokazuje już mylącego „SRA3 · 450 × 320 mm" (to był tylko fallback, gdy żaden szablon nie jest wczytany) — zastąpiony neutralną podpowiedzią „Wczytaj plik i wybierz szablon"; realny rozmiar arkusza pojawia się dopiero, gdy szablon jest aktywny.
Automatyczna 30-dniowa wersja próbna przy pierwszym uruchomieniu — bez klikania
Wersja próbna bez formularza
- 30 dni startuje samo przy pierwszym uruchomieniu: aplikacja bez ważnej licencji wysyła do serwera licencji wyłącznie odcisk sprzętowy (hash MAC/dysku/UUID — żadnych danych osobowych, żadnego e-maila ani zgód) i otrzymuje podpisaną 30-dniową licencję próbną, która zapisuje się automatycznie. Zero klikania.
- Raz na komputer — reinstalacja systemu nie pomaga: ewidencja „jeden trial na maszynę" jest po stronie serwera i kluczowana odciskiem sprzętowym, więc ponowna instalacja Windows ani format dysku nie resetują 30 dni. Dodatkowa deduplikacja komponentowa łapie też podmianę pojedynczego elementu (np. karty sieciowej).
- Tylko pierwszy start wymaga internetu; potem licencja działa offline (jak dotąd, z ochroną przed cofnięciem zegara). Gdy przy pierwszym uruchomieniu brak sieci — czytelny komunikat i możliwość ręcznej aktywacji; gdy trial już wykorzystano — informacja i przejście do aktywacji licencji płatnej. Formularz web i ręczna aktywacja pozostają jako alternatywa.
Pakiet poprawek UX: czysty start bez szablonu, uczciwy pasek statusu, informacje o pliku na zakładkach
Poprawki
- Start bez narzuconego szablonu: aplikacja nie ładuje już automatycznie przykładowej „A4 saddle-stitched booklet" — szablon wybiera użytkownik (menedżer, sugestie albo własny plik). Auto-ładowanie działa tylko dla świadomie zapisanego domyślnego
template.json w profilu użytkownika.
- Uczciwy pasek statusu: zniknęła zawsze-zielona pigułka „Walidacja OK" (nic jeszcze nie sprawdzono) i statyczna dekoracja „3.0 mm · CMYK · 300dpi" pokazywana przed załadowaniem czegokolwiek. Pigułka spadu pojawia się dopiero przy aktywnym szablonie i pokazuje jego rzeczywisty spad.
- „Druk dwustronny: true" po polsku: wartości logiczne w inspektorze wyświetlają się jako „Tak / Nie" (wspólny konwerter, działa też po angielsku jako Yes / No).
- „Avalonia.Data.Binding" zamiast pustego pola: cztery miejsca (kafel kroku Szablon, inspektor, nagłówek menedżera szablonów) używały
FallbackValue={loc:Loc …} — rozszerzenie znaczników daje tam obiekt Binding i przy pustym stanie UI renderował jego ToString(). Nowy konwerter LocFallbackConverter pokazuje zlokalizowany tekst zastępczy („brak szablonu" / „niezapisany").
Plik → „Zapisz PDF…" z opcjami eksportu
- Zapis pliku źródłowego bez impozycji — z zastosowanymi edycjami stron (obrót, skala szarości). Nowy dialog opcji daje te same wybory co eksport po impozycji: format (zwykły PDF / PDF/X-1a / X-3 / X-4), silnik (Auto / imPRESS Export Engine / Ghostscript), wersja PDF (1.4–1.7) oraz profil ICC. Zwykły zapis to kopia z edycjami (opcjonalnie ze zmianą samego nagłówka wersji); PDF/X przygotowuje plik zgodny ze standardem druku — X-4 natywnie silnikiem imPRESS, X-1a/X-3 przez Ghostscript. Ustawienia zapisują się osobno od opcji eksportu; oryginał na dysku pozostaje nietknięty.
Pigułka pliku źródłowego
- Po załadowaniu pliku pasek górny pokazuje jego realne parametry: wersję PDF, przestrzenie barw (CMYK / RGB / CMYK+RGB) i — gdy plik ma obrazy — najniższą efektywną rozdzielczość („PDF 1.7 · RGB · min 287 dpi"). DPI liczone z proporcji pikseli do rozmiaru osadzenia podczas standardowej analizy pliku, bez dodatkowego skanu.
Zakładka „Podgląd" — miniatury stron z edycją
- Nowa pierwsza zakładka inspektora: miniatury wszystkich stron wczytanego pliku — bez limitu liczby stron. Bitmapy istnieją tylko dla miniatur w oknie widoczności (viewport + margines, ~90 pozycji): przy przewijaniu okno się przesuwa, a miniatury poza nim zwalniają swoje referencje — 1000-stronicowa książka kosztuje tyle pamięci co ulotka, a przewinięte strony wracają natychmiast z cache'u renderera. Prawy przycisk na miniaturze otwiera menu edycji: obrót 90° w prawo / w lewo / 180° (bezstratna zmiana flagi /Rotate), skala szarości tej strony oraz skala szarości całego pliku. Zastąpione kopie robocze edycji są sprzątane z katalogu tymczasowego.
- Zakładka pojawia się dopiero po wczytaniu pliku, a kliknięcie miniatury pokazuje tę stronę na głównej kanwie (przy aktywnej impozycji kanwa przełącza się na podgląd stron — plan zostaje, „Planuj" wraca do arkuszy). Skoro miniatury nawigują po stronach, dolny pasek zmiany stron na kanwie pokazuje się już tylko dla zaplanowanej impozycji (numeracja arkuszy) — w podglądzie stron znika.
- Odporny dekoder strumieni: część plików z narzędzi projektowych ma strumienie Flate zakończone bez finalnego bloku — standardowy dekoder PdfSharp rzucał na nich „Unexpected EOF" i konwersja szarości padała. Silnik omija teraz zachłanne dekodowanie i w razie potrzeby używa tolerancyjnego inflate (.NET), odzyskując zdekodowaną część — dokładnie tak, jak robią to RIP-y. Pokryte testem regresyjnym.
- Znikająca plakietka numeru strony: nadruk numeracji „n / N" na kanwie podglądu pokazuje się przez 2 sekundy po każdej zmianie strony/arkusza i płynnie gaśnie — nie zasłania już na stałe treści. Sam eksport drukuje numerację normalnie, pełnym kryciem.
- Skala szarości w całości na silniku imPRESS — bez Ghostscripta: wektorowe operatory kolorów (RGB i CMYK) są przepisywane na szarość luminancyjnie w strumieniach treści stron i form, a obrazy (JPEG/DCT, rastry Flate 8-bit RGB/CMYK, palety Indexed) konwertowane piksel po pikselu do 8-bitowego DeviceGray z kompresją Flate. Przy edycji pojedynczej strony konwersja działa na wyciętej stronie i wkleja ją z powrotem, więc obrazy współdzielone z innymi stronami pozostają nietknięte. Nietypowe formaty obrazów (JPX, 16-bit) są pozostawiane w kolorze zamiast psuć plik. Zweryfikowane e2e renderem.
- Nieniszcząco: każda edycja tworzy kopię roboczą w katalogu tymczasowym — oryginalny plik nigdy nie jest modyfikowany. Analiza, podgląd, scalanie, impozycja i eksport automatycznie używają wersji edytowanej; baner nad miniaturami przypomina o aktywnych zmianach, a „Cofnij zmiany pliku" przywraca oryginał. Edycje można łańcuchować (dwa obroty po 90° = 180°).
Informacje o pliku — przeprojektowane
- Zakładki zamiast rozwijanych pól: Przegląd (plik, metadane, właściwości) / Walidacja / Kolory i PDF/X (standard, OutputIntent, kolory dodatkowe, przezroczystość) / Zawartość stron (ramki, obrazy, fonty) / Pokrycie farbą — ten sam wzorzec zakładek co inspektor okna głównego, bez klikania w expandery.
- Kolory z motywu aplikacji: stary dialog miał zaszyte kolory jasnego motywu i rozjeżdżał się w trybie ciemnym — wszystkie karty, badge'e ważności i pigułka statusu używają teraz słownika motywu.
Hot foldery 2.0: silnik imPRESS, szablony z listy, prostszy dialog; komplet ramek stron w eksporcie
Hot foldery
- imPRESS Export Engine w hot folderach: wybór silnika PDF/X (Auto / natywny / Ghostscript) i wersji PDF dla zwykłego eksportu (1.4–1.7) per folder — te same opcje co w dialogu eksportu, zapisywane w hotfolders.json.
- Szablon z listy: zamiast wpisywać ścieżkę, wybierasz szablon z listy zapisanych (ta sama biblioteka co menedżer szablonów) — przycisk „Z pliku…" i edytowalne pole ścieżki zostają dla szablonów spoza biblioteki.
- Prostszy dialog: podstawowy przepływ to nazwa → folder wejściowy → wyjściowy → szablon → eksport; foldery roboczy/archiwum/błędów (tworzone automatycznie), filtry plików, zachowanie po sukcesie/błędzie, wzorzec nazwy i ścieżka Ghostscripta przeniesione do sekcji „Zaawansowane".
- Ghostscript bez konfiguracji: ścieżka nie jest już wymagana dla PDF/X — pipeline sam znajduje dołączoną kopię (ustawienia → kopia w aplikacji → Program Files); dotyczy też GUI i CLI.
Poprawki
- Wyeksportowany arkusz deklaruje komplet ramek stron (CropBox = BleedBox = TrimBox = MediaBox, także strona makiety cięcia) — dotąd re-import własnego arkusza kończył się ostrzeżeniami „brak deklaracji BleedBox" i błędem „cały dokument nie deklaruje spadów". Dodatkowo głęboka walidacja rozpoznaje własne arkusze imPRESS (po polu Producer) i zamiast fałszywych błędów spadu pokazuje jedną informację: arkusz jest formatem docelowym, spady użytków leżą wewnątrz.
Poprawki po 1.5.0: preflight po polsku, koniec cichej rozbieżności szablonu menedżer ↔ praca, okno „O programie"
Preflight po polsku
- Wszystkie komunikaty szybkiego preflightu eksportu przeszły na system lokalizacji (PL/EN wg języka aplikacji): BLEED_LOW, RGB_ONLY, TRIM_MISMATCH/ROTATED, SIGNATURE_PADDING, SADDLE_TOO_THICK, DUPLEX_ODD_PAGES, ENCRYPTED, NO_ICC, reguły PDF/X i pozostałe. Głęboka walidacja prepress miała już polskie kategorie i zalecenia.
Poprawki
- Spad 3 mm po cichu zamieniał się w 0 przy każdym „Użyj szablonu" (główna przyczyna zgłoszeń BLEED_LOW). Pigułki statusowe okna głównego (spad, odstęp, format arkusza) bindowały
Run.Text do pól szablonu — a Run.Text w Avalonii binduje domyślnie dwukierunkowo (dziedzictwo WPF). Przy podmianie aktywnego szablonu stara wyświetlana wartość była wpisywana do świeżo zastosowanego szablonu: preset niósł spad 3 mm, a praca dostawała 0. Błąd odtworzony testem headless UI (dokładny markup pigułki) i naprawiony wymuszeniem Mode=OneWay na wszystkich polach wyświetlających; test regresyjny pilnuje wzorca. Diagnozę umożliwiły nowe logi łańcucha szablonu (preset → zatwierdzenie → przejęcie → planowanie), które zostają w aplikacji.
- Czytelność „szablon w menedżerze ≠ szablon pracy": zamknięcie menedżera bez „Użyj szablonu" wypisuje na pasku stanu, który szablon pozostaje aktywny; komunikat BLEED_LOW podaje nazwę ocenianego szablonu i podpowiada, gdzie go poprawić.
- Współdzielona referencja szablonu: edytor szablonów (singleton) oddawał oknu głównemu żywą referencję — późniejsza edycja w menedżerze (nawet porzucona Anulujem) mogła po cichu zmutować szablon aktywnej pracy. „Użyj szablonu" przekazuje teraz głęboką kopię.
- Komunikat RGB_ONLY doprecyzowany: jasno mówi, że przy eksporcie PDF/X kolory są konwertowane automatycznie (silnik imPRESS / Ghostscript), a zwykły eksport zachowuje RGB bez zmian.
- Okno „O programie": sztywna wysokość ucinała stopkę z przyciskiem „Zamknij" — okno dopasowuje teraz wysokość do zawartości.
imPRESS Export Engine: natywny PDF/X-4 z konwersją kolorów ICC — bez Ghostscripta, natywny skan pokrycia farbą i przeprojektowany menedżer szablonów
imPRESS Export Engine — natywny PDF/X-4 bez Ghostscripta
- Nowy, własny silnik pakowania PDF/X-4: osadza OutputIntent z wybranym profilem ICC, pełne metadane XMP (pdfxid:GTS_PDFXVersion, identyfikatory, daty, tytuł),
/Trapped, TrimBox na każdej stronie i wersję PDF 1.6 — w całości natywnie, zero Ghostscripta. Uczciwy zakres: silnik pakuje pliki gotowe do druku (CMYK/ICC) i konwertuje wektorowe RGB (poniżej); spłaszczanie przezroczystości, obrazy RGB oraz PDF/X-1a i X-3 pozostają domeną silnika Ghostscript.
- Konwersja kolorów ICC bez zewnętrznych bibliotek: wektorowe wypełnienia i obrysy RGB w skomponowanym pliku są przepisywane na DeviceCMYK przez wybrany profil ICC (silnikiem kolorów systemu Windows — WCS/mscms, intent kolorymetryczny względny). Czysto wektorowa grafika RGB nie wymusza już ścieżki Ghostscript — silnik natywny konwertuje ją sam i raportuje to w logu eksportu.
- Dwustopniowa bramka zgodności: analiza źródła (teksty/obrazy RGB, szyfrowanie, rastrowa nakładka loga) plus głęboki skan skomponowanego pliku — zdekodowane strumienie treści stron i form XObjects są przeszukiwane pod kątem operatorów DeviceRGB. Wektorowe RGB → konwersja natywna; obrazy RGB lub nieczytelny strumień → Ghostscript. Kierunek błędu bezpieczny: wątpliwość nigdy nie kończy się niezgodnym plikiem z fałszywą deklaracją.
- Wybór silnika w dialogu eksportu i CLI (
--engine auto|native|gs): Auto sam wybiera natywny, gdy plik się kwalifikuje; wymuszenie natywnego na pliku z obrazami RGB kończy się czytelnym komunikatem, nie cichym błędem zgodności.
- Wybór wersji PDF dla zwykłego eksportu — 1.4 / 1.5 / 1.6 / 1.7 (
--pdf-version w CLI, combo w dialogu). Tryby PDF/X narzucają wersję ze specyfikacji (X-1a/X-3 → 1.4, X-4 → 1.6).
- Cały rysunek kompozytora przeszedł na DeviceCMYK — tła, numery, makieta cięcia, kody kreskowe; przy okazji wykryta i naprawiona pułapka PdfSharpCore: domyślny (i „Undefined") ColorMode przepisywał każdy kolor na RGB — wymuszony tryb CMYK (bezstratny, bo wszystkie nasze pędzle są definiowane w CMYK). Zweryfikowane e2e: natywny X-4 z pliku CMYK i z pliku z wektorowym RGB przechodzi i renderuje się poprawnie (czerwień przekonwertowana wg SWOP), nagłówki i markery (GTS_PDFX, XMP, OutputIntents, TrimBox) potwierdzone w plikach wynikowych.
Natywny skan pokrycia farbą
- „Skanuj pokrycie farbą" działa teraz na silniku imPRESS — strony są renderowane wewnętrznym rasteryzatorem, a piksele przeliczane na CMYK przez profil ICC ustawiony w eksporcie (domyślnie SWOP). Ghostscript nie jest już potrzebny do skanu; wyniki (średnie C/M/Y/K + suma Σ, próg ostrzeżenia 250%) prezentowane jak dotąd, z uczciwym opisem: średnia strony z kompozytu, nie densytometria separacji.
Przeprojektowany menedżer szablonów
- Stylistyka okna głównego: pasek nagłówka z nazwą szablonu, pigułką aktywnej oprawy i przyciskami zapisu; edytor podzielony na zakładki „Ogólne" / „Znaczniki" / „Oprawa i specjalne" / „Dodatki" (ten sam wzorzec co inspektor w oknie głównym) — koniec z jednym długim przewijanym formularzem.
- Sekcje kontekstowe: karty specyficzne dla oprawy (zeszytowa, gatefold, falcowanie, rolka, Step & Repeat, creep) pokazują się tylko wtedy, gdy wybrana oprawa faktycznie z nich korzysta — operator nie widzi już opcji, które silnik by zignorował. Aktywna sekcja rolki nigdy nie znika (widoczna też, gdy rolka jest włączona przy innej oprawie), a oprawa bez opcji specjalnych dostaje czytelne wyjaśnienie zamiast pustej strony.
- Baner walidacji nad zakładkami — błędy widoczne niezależnie od aktywnej zakładki; wszystkie dotychczasowe funkcje (presety, zapisane szablony, doradca arkusza, własne formaty, profile znaczników) zachowane bez zmian.
Poprawki
- Metadane eksportu: pliki wynikowe podpisują się teraz „imPRESS Studio" (Creator) i „imPRESS Export Engine" (Producer) — dotąd wychodziła wewnętrzna nazwa modułu „Imposition.App".
- Mylący komunikat preflight X4_VERSION przy eksporcie z wybraną wersją PDF 1.7: raport jasno mówi, że PDF 1.6 dotyczy wyłącznie kopii PDF/X-4 (
.pdfx4.pdf, wymóg ISO 15930-7), a główny eksport zachowuje wybraną wersję.
Duże wydanie: numeracja biletów, work-and-turn, podgląd spasowania przód/tył, doradca arkusza, skan pokrycia farbą, PDF/X-3, Preflight 2.0, parytet CLI i pakiet napraw
Numeracja biletów (dane zmienne lite)
- Kolejny numer na każdym użytku — bilety, kupony, losy: numer startowy, krok (także ujemny), format .NET z tokenem
{0} (np. „Nr {0:0000}"), pozycja (9 kotwic), odsunięcia i rozmiar czcionki. Numeracja jest ciągła przez wszystkie arkusze (kolejność: arkusz → slot), stemplowana na frontach; podgląd pokazuje dokładnie te same numery co eksport. Nowa sekcja „Numeracja biletów" w edytorze szablonów, walidacja formatu/kroku, zweryfikowane e2e renderem (Nr 0100–0114 na arkuszu 15-up).
Work-and-turn — druk obu stron z jednej formy
- Nowy tryb duplexu dla Ganging: jedna forma niesie fronty na lewej połowie siatki i rewersy na prawej (w dokładnie lustrzanych pozycjach); arkusz jest drukowany, obracany przez bok i drukowany ponownie tą samą formą — o połowę mniej płyt CTP, a po rozcięciu każdy użytek jest kompletnym produktem dwustronnym. Wybór trybu (Sheetwise / WorkAndTurn) przy checkboxie Duplex; walidacja pilnuje parzystego N-up X. Zweryfikowane e2e: lustrzana geometria potwierdzona testami i renderem.
Podgląd spasowania przód/tył
- Nowy przełącznik w pasku narzędzi kanwy: tył arkusza nakładany lustrzanie (50% krycia) na przód — jak arkusz oglądany pod światło. Błędy pasowania układu przód/tył widać natychmiast, bez drukowania próbnego. Nakładka nie zakłóca zaznaczania slotów ani kroplomierza (obszary klikalne wyłączone dla warstwy lustrzanej), współpracuje z cache'em sceny.
Doradca doboru arkusza + skan pokrycia farbą
- „Porównaj arkusze…" w edytorze szablonów — ranking wszystkich formatów papieru wg wykorzystania dla bieżącego użytku (spad/odstęp/margines uwzględnione, także wariant z obrotem itemu o 90°): „SRA3: 15 szt. · 86% · 3×5". Czysta matematyka na LayoutOptimizerze (nowy
SheetAdvisor w Core, z testami).
- „Skanuj pokrycie farbą" w oknie informacji o pliku — opcjonalny skan Ghostscript
inkcov: średnie pokrycie C/M/Y/K per strona + suma Σ, strony powyżej 250% oznaczone ⚠. Uczciwie opisany jako średnia strony (nie maksimum punktowe) — bez udawania pełnej kontroli TAC.
PDF/X-3, parytet CLI i hot foldery
- Eksport PDF/X-3:2003 — trzeci standard obok X-1a i X-4 (PDF 1.4, kolory ICC, bez przezroczystości); pełny łańcuch: dialog eksportu, PDFX_def, argumenty GS, sufiks
.pdfx3.pdf, reguły preflight (X3_TRANSPARENCY / X3_VERSION), hot foldery i CLI.
- CLI dorównuje GUI: nowe opcje
--pdfx none|x1a|x3|x4, --icc, --sheet-range, --page-range, --numbering, --strict-preflight (stary --pdfx4 nadal działa).
- Hot foldery: numeracja arkuszy i makieta cięcia per folder (dwa nowe checkboxy w dialogu edycji + pola w hotfolders.json).
- Ctrl+Z / Ctrl+Y dla edycji slotów — dotąd nieużywany UndoRedoStack podpięty pod inspektor: każda edycja (przesunięcie/obrót/wygaszenie) jest cofalna; stos czyści się przy nowym planie.
- Własne rozmiary papieru przeżywają restart — zapisywane w settings.json i rejestrowane przy starcie (dotąd żyły tylko w pamięci procesu).
- Aktywacja licencji: sekcja „Odnowienie i przeniesienie" — e-mail z wypełnionym identyfikatorem maszyny oraz dezaktywacja na tym komputerze (z potwierdzeniem) jako pierwszy krok przeniesienia.
Pakiet napraw
- Wyścig ewikcji bitmap podglądu — zwalnianie wypieranych bitmap przeniesione na wątek UI (między klatki); koniec ryzyka ObjectDisposedException przy agresywnym zoomowaniu dużych prac.
- Kroplomierz bez zacięć — próbkowanie wyłącznie z bitmap w cache'u (bez synchronicznego renderu na wątku UI).
- Step & Repeat duplex: rewersy lustrzane w poprzek arkusza z parowaniem rotacji (AlternatingColumns/Checkerboard przy parzystych kolumnach spasowują się poprawnie) i flagą IsBackSide.
- Scalanie robocze do katalogu tymczasowego — koniec z
merged_imposition.pdf nadpisywanym obok plików źródłowych; domyślna ścieżka wyjścia nadal przy plikach użytkownika, stary plik roboczy sprzątany.
- Ostrzeżenie „zakres stron × edycje slotów" — eksport z zakresem stron źródła jawnie informuje (status + historia), że ręczne edycje slotów nie wejdą do tego eksportu.
- Wycieki subskrypcji zdarzeń — MainWindowViewModel i PreviewViewModel implementują IDisposable i odpinają się od singletonów (renderer, jednostki, lokalizacja) przy zamknięciu okna.
Sugestie szablonów sterowane liczbą stron
- Broszury z liczby stron dokumentu. Dotąd biblioteka sugestii znała wyłącznie produkty płaskie i rolki — 16-stronicowy PDF A5 dostawał propozycję „ulotka". Silnik respektuje teraz liczbę stron źródła: przy ≥ 5 stronach pojawiają się broszury zeszytowe A4/A5/A6 (rozkładówka 2-up na SRA3, sygnatura 8, duplex), przy 49+ stronach — katalogi klejone A4/A5, a dokument dokładnie 5–6-stronicowy w formacie DL proponuje ulotkę składaną w „Z” z poprawną geometrią falcu (panele stykają się liniami falcu: spad 0, margines 0, arkusz A4 poziomo). Każda propozycja niesie dedykowane uzasadnienie, czemu się pojawiła.
- Ranking rozumie produkt. Przy remisie wymiarowym (broszura A5 i ulotka A5 to ten sam trim) produkt uzasadniony liczbą stron wygrywa — 16-stronicowy dokument to najpierw broszura, potem ulotka. Presety o stałej pojemności (Z-fold = 6 stron) znikają dla dłuższych dokumentów.
- Nowe presety płaskie: ulotki kwadratowe 148×148 i 210×210, zakładka do książki 50×200 oraz plakat B2 (1-up na arkuszu B2).
Głęboki preflight — nowa kategoria „Zawartość stron i elementy interaktywne"
- Drobny tekst (TEXT_TOO_SMALL) — glify poniżej 4 pt (rozmiar liczony z przetransformowanej macierzy tekstu, więc odporny na skalowanie treści); komunikat podaje najmniejszy wykryty stopień pisma.
- Tekst w registration black (TEXT_REGISTRATION_BLACK) — glify wypełnione C=M=Y=K=100%: 400% farby i barwne obwódki przy spasowaniu; tekst powinien być czernią K-100.
- Hairline'y (HAIRLINE_STROKES) — ścieżki kreślone jawną szerokością 0 („0 w"), znikające na naświetlarce. Flagowane jest wyłącznie literalne zero — jedyna wartość odporna na transformacje strumienia treści (PdfPig raportuje szerokości surowe, bez CTM), więc bez fałszywych alarmów.
- Puste strony (BLANK_PAGES) — zbiorcza informacja z listą stron bez tekstu i obrazów; celowe separatory łatwo zignorować, przypadkowo pusta strona nie przejdzie niezauważona.
- Adnotacje i formularze — nowy spis warstwy interaktywnej per strona: komentarze/stemple (
ANNOTATIONS_MARKUP, ostrzeżenie — na ekranie widać, RIP zwykle nie drukuje), pola formularzy (FORM_FIELDS, także gdy AcroForm zadeklarowany tylko w katalogu dokumentu) oraz hiperłącza (ANNOTATIONS_LINKS, informacja — niedrukowalne, nieszkodliwe).
Szybki preflight — diagnostyka oprawy i orientacji
TRIM_ROTATED — strony pasujące do trimu szablonu tylko po obrocie 90° dostają jeden zbiorczy komunikat z podpowiedzią („obróć szablon albo strony") zamiast lawiny mylących TRIM_MISMATCH.
SIGNATURE_PADDING — zeszytówka/klejona z liczbą stron niepodzielną przez sygnaturę: informacja, ile pustych stron zostanie dodanych na końcu.
SADDLE_TOO_THICK — zeszytówka powyżej 64 stron: ostrzeżenie z sugestią oprawy klejonej.
DUPLEX_ODD_PAGES — ganging dwustronny z nieparzystą liczbą stron: ostatni arkusz będzie miał pusty tył.
Twardsza walidacja szablonu
- Ujemny grzbiet (
SpineMm) — dotąd jedyny margines bez kontroli ujemności; strefa bezpieczna pochłaniająca cały użytek (2×safe ≥ krótszy bok trimu) — czytelny błąd zamiast wybuchu głęboko w geometrii; sanity znaczników legacy: zerowa długość linii cięcia, ujemne odsunięcia, zerowy rozmiar markera OPOS przy włączonych funkcjach.
Build: 0 warnings / 0 errors. Testy: 275/275 (40 nowych w tym wydaniu), w tym integracyjny test end-to-end przez PdfPreflightAnalyzer na prawdziwym PDF. Weryfikacje wizualne (CLI + render Ghostscript): numeracja biletów Nr 0100–0114 na arkuszu 15-up, forma work-and-turn z lustrzanymi rewersami, nowe kody preflight (SIGNATURE_PADDING, TRIM_ROTATED), format inkcov potwierdzony na żywym Ghostscripcie.
Przegląd całego kodu: poprawna skala przy rotacji 90° na roli, verso nie znika przy Duplex=off, eksport 1:1 z edycjami slotów, jeden układ współrzędnych dla stron z /Rotate
Rotacja 90° na roli — zawartość w pełnej skali
- Etykiety obracane automatycznie (RollFed + „Zezwól na rotację") renderowały się w złej skali. Kompozytor i podgląd wpasowywały nieobróconą stronę w obrócony slot, a dopiero potem ją obracały — niekwadratowy item (np. etykieta 100×50 mm) lądował w
min(w/h, h/w) skali, czyli przy 2:1 w połowie wielkości, z białymi pasami wewnątrz slotu. Teraz przy rotacji 90°/270° dopasowanie celuje w slot o zamienionych wymiarach (ten sam środek obrotu), więc trim wypełnia slot co do punktu. Poprawka w PdfComposer i ImpositionCanvas — eksport i podgląd zgodne. Zweryfikowane wizualnie na wyrenderowanej roli 6-up.
Verso nie znika przy odznaczonym Duplex
- Odznaczenie „Duplex" przy oprawie zeszytowej/klejonej/falcowanej gubiło połowę stron w eksporcie. Strategie opraw dwustronnych zawsze planują strony verso, ale kompozytor pomijał je gdy
Template.Duplex=false — podgląd pokazywał pełną broszurę, a wyeksportowany PDF zawierał same fronty, bez żadnego ostrzeżenia. Teraz o jednostronności decydują wyłącznie strategie (puste BackPlacements); kompozytor renderuje każdą stronę, którą plan zawiera. Zweryfikowane: 8-stronicowa zeszytówka z Duplex=off daje 4 strony wyjściowe (2 arkusze × przód+tył) w poprawnym układzie [8,1]/[2,7].
Eksport = podgląd: ręczne edycje slotów już nie giną
- Edycje slotów z inspektora (przesunięcie, rotacja, wygaszenie) były po cichu odrzucane przy eksporcie. Pipeline eksportu bezwarunkowo przeplanowywał pracę od zera, a edycje żyły tylko w podglądzie. Teraz przed eksportem edytowane arkusze są przepisywane do zadania, a pipeline planuje wyłącznie prace bez gotowego planu (CLI, hot foldery i zakres stron źródłowych planują się jak dotąd). Uwaga: po zmianie szablonu należy kliknąć „Planuj" przed eksportem — eksport komponuje dokładnie to, co widać na kanwie.
Strony z /Rotate — jeden układ współrzędnych (geometria + preflight)
PdfBoxParser mieszał dwa układy współrzędnych: MediaBox/CropBox przychodziły z PdfPig już obrócone (układ wizualny), a TrimBox/BleedBox/ArtBox były czytane surowo ze słownika strony. Skutki dla plików z /Rotate 90/270: fałszywe ostrzeżenia TRIM_MISMATCH, błędna geometria bleed-fit w kompozycji i podglądzie (podwójne zamiany szer./wys. w SourceTrimReader i podglądzie prostym) oraz przekłamane porównania w walidatorach spadów. Parser mapuje teraz wszystkie boxy do układu wizualnego (transformacje 90°/180°/270° zweryfikowane empirycznie na współrzędnych glifów PdfPig), a konsumenci używają wymiarów wprost — bez własnych zamian.
TRIM_MISMATCH działa poprawnie dla obróconych stron: strona zgodna wizualnie z trimem szablonu nie generuje już ostrzeżenia; strona z faktycznie innym TrimBoxem raportuje wymiary wizualne (takie, jakie widzi operator).
Stabilność i pamięć
- Wyciek pamięci w podglądzie z aktywnym filtrem kanałów CMYK / symulacją nadruku: cache przefiltrowanych bitmap rósł bez ograniczeń przy zoomowaniu (każdy próg zoomu dokładał wielomegabajtową kopię). Teraz cache jest ograniczony (FIFO, 8 wpisów, wypierane bitmapy są zwalniane) i czyszczony przy każdej zmianie pracy; usunięty też martwy warunek przy zwalnianiu.
PdfPreviewRenderer.Dispose() niszczył współdzielony singleton PDFium (DocLib.Instance) — procesowa biblioteka natywna była zamykana pod trwającymi renderami i pod każdym innym konsumentem. Renderer nie zwalnia już singletona.
Spójność modelu i walidacji
- Placementy verso w Step & Repeat i Ganging mają wreszcie
IsBackSide=true — spójnie z pozostałymi strategiami (Wiro, RollFed, zeszytowa).
- Walidacja zeszytówki uwzględnia spady na krawędziach zewnętrznych (2×spad na wymiar; grzbiet i linie cięcia między kopiami bez zmian). Szablony skrojone „na styk" bez zapasu na spad zgłoszą teraz błąd dopasowania do arkusza.
- Dokumentacja: opis kolejności rozstrzygania profili znaczników (
MarksProfileResolver) i schemat harmonijki w FoldingStrategy zgodne z faktycznym, przetestowanym zachowaniem.
Build: 0 warnings / 0 errors. Testy: 235/235. Poprawki zweryfikowane end-to-end (CLI + render Ghostscript): rola 6-up z rotacją, zeszytówka 8 str. z Duplex=off, pliki z /Rotate 90 z jawnym i domyślnym TrimBoxem.
Poprawki odporności: przywracanie backupu po nieudanym eksporcie, ochrona przed błędnym base64 w kluczu licencji, zawężenie catch w odczycie ICC i TrimBox
Przywracanie backupu po nieudanym eksporcie
- Utrata pliku wyjściowego przy błędzie rename — naprawione. W
PdfExporter kopia zapasowa istniejącego pliku (.bak) była tworzona przed atomic rename nowego pliku; jeśli rename się nie udał (np. brak miejsca na dysku, blokada antywirusowa), catch usuwał tylko plik tymczasowy, ale nie przywracał backupu — operator tracił plik wyjściowy. Teraz catch wykrywa sytuację (backup istnieje, plik docelowy nie) i przywraca oryginał, logując ewentualny błąd przywracania osobno.
Ochrona przed błędnym base64 w SaveLicense
LicenseValidator.SaveLicense rzucała niezłapany FormatException gdy klucz aktywacyjny zawierał nieprawidłowe znaki base64 (np. błąd schowka, obcięcie). W normalnym przepływie UI niemożliwe (klucz przechodzi przez ValidateKey() wcześniej), ale przy złym stanie UI realne. Teraz Convert.FromBase64String jest objęty try-catch rzucającym czytelny InvalidOperationException z opisem przyczyny.
Zawężenie catch — ICC i TrimBox nie maskują błędów krytycznych
ExportPipeline.ReadIccChannelCount i SourceTrimReader.Read miały gołe catch {} przechwytujące dosłownie wszystko, w tym OutOfMemoryException i StackOverflowException — system działał na zdegradowanym fallbacku nie wiedząc, że jest w stanie krytycznym. Oba bloki zmienione na catch (Exception ex) when (ex is not OutOfMemoryException and not StackOverflowException).
Build: 0 warnings / 0 errors. Testy: 235/235. Bez zmian w silniku impozycji ani eksportu — wyłącznie odporność i obsługa błędów.
Presety szablonów przełączają się na amerykańskie przy jednostkach calowych + reset zakresu stron przy każdej nowej pracy
Amerykańskie presety szablonów (gdy jednostki = cale)
- Zmiana jednostek na cale przełącza wbudowane presety na odpowiedniki US. Lista „Gotowe presety" w menedżerze szablonów słucha aktywnej jednostki: dla milimetrów pokazuje zestaw ISO (A4/A5/SRA3/DL), a po przełączeniu na cale podmienia go na amerykański (Letter / Half-Letter / wizytówki / tri-fold). Powrót na mm przywraca zestaw ISO — bez restartu.
- Pełny zestaw US: Letter broszura zeszytowa, Half-Letter broszura zeszytowa, Letter oprawa klejona, Letter ganging 2-up, Half-Letter ganging 4-up, Letter tri-fold (11×17), Letter harmonijka 4-panele, rack card 3-up (3.5×8.5″), wizytówki 6/8/12-up na wizytówce US 3.5×2″, naklejki 2×2″ na rolce 8.5″ oraz Step & Repeat.
- Amerykańska geometria: spad 0.125″, safe 0.25″, margines arkusza 0.25″, arkusz roboczy 13×19″ (analog SRA3 dla druku cyfrowego) — każdy preset zweryfikowany, że mieści się na arkuszu. Do biblioteki rozmiarów dodano
Half Letter, 12×18 i 13×19.
Reset zakresu stron przy nowej pracy
- Zakres stron zeruje się przy każdym wczytaniu nowego źródła. Dotąd zakres ustawiony dla poprzedniego pliku potrafił przenieść się na kolejną pracę i po cichu obciąć lub przekroczyć liczbę stron nowego dokumentu. Teraz przy wczytaniu plików zakres stron jest czyszczony. Pozostałe ustawienia eksportu (Ghostscript, ICC, PDF/X) i przywracanie zapisanej sesji pozostają nietknięte.
Build: 0 warnings / 0 errors. Testy: 235/235.
Pasek kontrolny CMYK zsunięty z pasera + nowy klin szarości na arkuszu
Pasek CMYK nie nachodzi już na paser
- Pasek kontrolny CMYK przesunięty na pierwszą połowę arkusza. Dotąd pasek był wyśrodkowany na całej krawędzi — czyli dokładnie tam, gdzie siedzi środkowy paser. Teraz jest wyśrodkowany na środku pierwszej połowy krawędzi (¼ długości), więc nie zakrywa znacznika pasowania.
Klin szarości (skala K) na drugiej połowie
- Drugi pasek kontrolny — klin szarości. Na środku drugiej połowy krawędzi (¾ długości) rysowany jest nowy pasek: 8 pól tylko z kanału K, krokiem co 12,5% od czerni do bieli (100 / 87,5 / 75 / 62,5 / 50 / 37,5 / 25 / 12,5%). Służy do kontroli reprodukcji tonalnej i przyrostu punktu na czarnej rozbarwieniu.
- Oba paski rysowane wzdłuż tej samej krawędzi co dotąd (wg profilu znaczników); układ działa dla każdej krawędzi — przy górnej/dolnej dzieli wzdłuż szerokości, przy bocznych wzdłuż wysokości.
- Podgląd 1:1 z eksportem — kanwa podglądu rysuje oba paski w tym samym układzie co wyjściowy PDF (klin szarości jako odpowiedniki sRGB).
Build: 0 warnings / 0 errors. Testy: 235/235.
Znaczniki w podglądzie rozdzielone i sterowane szablonem + ostrzeżenie, gdy kod kreskowy nachodzi na pole zadruku
Znaczniki w podglądzie — per-typ, sterowane szablonem
- Jeden przycisk „Znaczniki" rozbity na osobne przełączniki — linie cięcia, pasery, falc, slug, kod kreskowy/QR (paski CMYK miały już swój). Koniec z jednym masterem włączającym wszystko naraz.
- Podgląd słucha szablonu. Każdy przełącznik to filtr widoku ograniczony profilem znaczników: znacznik rysuje się tylko gdy włączony i w szablonie, i w podglądzie. Gdy wyłączysz dany typ w szablonie, jego przycisk w podglądzie automatycznie gaśnie (staje się nieaktywny) i znacznik znika z arkusza. Koniec z rozjazdem „podgląd pokazuje co innego niż szablon".
- Profil odświeża się na żywo — po zatwierdzeniu edycji szablonu podgląd przelicza aktywny profil (wymuszony re-resolve przy planowaniu, także gdy edytowano ten sam szablon w miejscu), więc zmiany znaczników widać od razu.
Ostrzeżenie: kod kreskowy / QR na polu zadruku
- Wykrywanie nachodzenia kodu na treść. Kod jest pozycjonowany względem rogu arkusza, więc przy gęstych układach lub dużym spadzie potrafił wejść na pole zadruku. Po naciśnięciu Planuj aplikacja sprawdza wszystkie arkusze (przód i tył) i — gdy kod nachodzi na niepuste pole — pokazuje ostrzeżenie na pasku stanu i w historii: „kod kreskowy/QR nachodzi na pole zadruku — zmień narożnik, odstęp lub rozmiar w profilu znaczników".
- Czerwona ramka w podglądzie — gdy kod na bieżącym arkuszu nachodzi na treść, jest obrysowany czerwoną przerywaną ramką (sygnał natychmiastowy, jeszcze przed eksportem).
- Geometria nachodzenia liczona przez wspólny
BarcodeMarkLayout.BoxOverlapsPlacements (top-left vs bottom-left z odwróceniem osi), pokryta testami jednostkowymi (różne narożniki, pola pełne/puste).
Build: 0 warnings / 0 errors. Testy: 235/235.
Duże rozszerzenie produkcyjne: zakresy stron i arkuszy, makieta cięcia, kody śledzenia, nowe układy opraw — plus twarde poprawki montażu i utwardzenie aplikacji
Eksport — dwa niezależne zakresy
- Zakres stron źródłowych — wybór, które strony źródłowego PDF trafią do impozycji (przed montażem). Wybrane strony są wycinane do tymczasowego pliku i montowane jak osobny dokument. Przydatne dla N-up / gangingu / wiro. Format
1-2, 1,3,5-8.
- Zakres arkuszy wyjściowych — wybór, które gotowe arkusze zapisać (po montażu) — do dodruku pojedynczego uszkodzonego arkusza bez eksportu całego nakładu. Numery arkuszy w znacznikach pozostają oryginalne. Wcześniej oba pola były obecne w UI, ale nie działały — zakres był zbierany i zapisywany, ale nigdy nie stosowany.
- Wspólny parser
RangeExpression (walidacja, błędne wyrażenia odrzucane od razu przed wolnym montażem) + ikonki ⓘ z podpowiedziami przy obu polach.
Eksport PDF/X — zgodny OutputIntent + profil ICC (wcześniej martwa opcja)
- Wybór profilu ICC i tryb PDF/X faktycznie działają. Wcześniej okno eksportu pozwalało wybrać profil i standard, ale argumenty Ghostscripta ich nie zawierały — wynik nie był zgodny z PDF/X i bywał odrzucany przez drukarnię. Teraz aplikacja generuje plik kontrolny
PDFX_def z OutputIntent i osadza wybrany profil jako DestOutputProfile (lub identyfikator CGATS TR 001, gdy profilu nie wskazano). Obsługa PDF/X-1a (PDF 1.4) i PDF/X-4 (PDF 1.6).
- Naprawiony deadlock Ghostscripta — stdout/stderr są teraz czytane równolegle z oczekiwaniem na proces (pełny bufor potoku potrafił zawiesić eksport na zawsze). Realny błąd PostScriptu (idzie na stdout) trafia do komunikatu.
- SAFER (GS 10.x) — odczyt profilu ICC z poziomu PostScriptu wymaga
--permit-file-read; dodane, inaczej konwersja kończyła się /invalidfileaccess.
- Anulowanie zabija proces GS (koniec z osieroconymi procesami) oraz poprawiona nazwa pliku wynikowego (modyfikowana tylko nazwa, nie ścieżka — katalog z „.pdf" w nazwie nie jest już zniekształcany).
Makieta cięcia dla gilotyny
- Opcjonalna strona na końcu PDF-a ze schematem arkusza i ponumerowaną tabelą pozycji noża w mm — cięcia pionowe mierzone od lewej krawędzi (V1, V2…), poziome od górnej (H1, H2…), jak nastawia się gilotynę. Arkusze o identycznym układzie dostają jedną wspólną makietę. Czysty kalkulator
CutLineCalculator + renderer CuttingGuideRenderer. Dostępne też w CLI (--cutting-guide).
Kod kreskowy / QR na arkuszu
- Kod śledzenia w profilu znaczników — Code 128 lub QR z metadanymi zlecenia (te same placeholdery co slug:
{jobid}, {sheet}, {sheets}, {side}, {filename}, {date}) do skanowania przy krajarce / falcerce / zszywarce. Wybór narożnika, odstępu, rozmiaru; strefy ciszy zgodne z normami. Rysowany wektorowo (ZXing.Net do enkodowania) i widoczny także w podglądzie — wspólna geometria BarcodeMarkLayout dla eksportu i kanwy.
Zeszytówka N-up i style gatefold
- Układy zeszytówki: TwoUp (klasyczne 2-up), StackedCopies (N kopii rozkładówki w rzędach — cięcie na paski → falc, druk cyfrowy) oraz EightPageSignature (prawdziwa forma 8-stronicowa 2×2, górny rząd obrócony 180°, falc dwukrotny; poprawne zagnieżdżanie arkuszy).
- Style gatefold: 3-panelowy (6 stron) i 4-panelowy (8 stron) z konfigurowalną zwężką falcu — skrzydła/drzwi są zwężane przy krawędzi spotkania, by nie zaginały się na grzbiecie.
Poprawki montażu opraw
- Kompensacja pełzania — naprawiony kierunek i obustronność. Wcześniej maksymalne przesunięcie dostawał arkusz zewnętrzny (gradient odwrotny do fizyki — błąd był podwajany) i tylko jedna kartka strony arkusza. Teraz arkusz zewnętrzny jest odniesieniem (0), przesunięcie rośnie do środka składki o grubość papieru, a dosunięcie do grzbietu obejmuje obie kartki — na przodzie i na tyle. Zweryfikowane pomiarem.
- Z-fold — kolejność stron na tyle. Tył to teraz
[5, 6, 1] (było [6, 1, 5], co dawało niemożliwą fizycznie parę kartek). Zweryfikowane symulacją składania.
- RollFed duplex — odbicie lustrzane tyłu względem szerokości wstęgi + poprawna flaga strony; przy kilku wzorach front/tył rewersy nie rozjeżdżają się już względem awersów.
- Wiro — obsługa druku dwustronnego (wcześniej zawsze jednostronnie); sąsiednie strony dzielą liść, rewers lustrzany.
Utwardzenie i higiena
- Licencja: walidacja wklejonego klucza odbywa się w pamięci — koniec z zapisem licencji do stałego pliku tymczasowego w
%TEMP%.
- Aktualizacje: pobrany instalator jest weryfikowany sumą SHA-256 z pola
digest wydania GitHub przed uruchomieniem; niezgodność = odrzucenie pliku.
- Numeracja arkuszy (
{1} w formacie) pokazuje teraz prawdziwą sumę zaplanowanych arkuszy zamiast bieżącej liczby stron wyjściowych.
- Token anulowania w głównym oknie jest zwalniany i przechwytywany lokalnie (koniec z wyciekiem i wyścigiem przy kolejnych operacjach).
- Kompozytor PDF nie parsuje już zbędnie całego pliku źródłowego tylko po to, by odczytać liczbę stron.
- Profile znaczników zapisują enumy jako czytelne nazwy (stary zapis liczbowy nadal wczytywany) — wcześniej ręcznie wpisany typ kodu wypadał z listy.
Dokumentacja i strona
- Przebudowana dwujęzyczna pomoc (PL + EN) — sekcja „Scenariusze pracy" z 6 gotowymi recepturami (broszura zeszytowa, wizytówki 4×4 dwustronne, etykiety na rolce z QR, Z-fold/gatefold, dodruk jednego arkusza, hot folder), nowe sekcje wszystkich funkcji oraz wpięte ilustracje (okno główne, menedżer szablonów, hot foldery).
Testy
- 231 testów jednostkowych przechodzi (m.in. parser zakresów, ekstrakcja podzbioru stron, generator PDFX_def i ścieżka wyjściowa, kalkulator cięć, enkoder kodów, placementy creep, układy zeszytówki i gatefold, RollFed/Wiro duplex, walidacja licencji w pamięci). Przy okazji odkryto i usunięto martwy projekt testów (
tests/Imposition.Math.Tests bez pliku .csproj — nigdy się nie uruchamiał), przenosząc jego testy do aktywnego zestawu.
Build: 0 warnings / 0 errors. Nowa zależność: ZXing.Net (enkodowanie kodów kreskowych/QR).
Spad respektuje linię cięcia — montaż prepressowo poprawny w wydruku i podglądzie
Obsługa spadu (bleed) w montażu arkusza
- Spad wychodzi teraz poza linię cięcia, tak jak należy. Wcześniej kompozytor skalował całą stronę (z bleedem) do komórki trim, więc spad lądował wewnątrz linii cięcia, a treść była zmniejszana. Teraz na komórkę mapowany jest TrimBox strony, a spad nachodzi na gutter / sąsiada — jak w profesjonalnej impozycji. Pliki bez spadu pozostają bez zmian.
- Jedno wspólne źródło geometrii. Nowy helper
BleedFit (czysta matematyka trim→komórka) jest używany jednocześnie przez eksport (PdfComposer, wektor) i podgląd na ekranie (ImpositionCanvas, raster), a wymiary trim źródła czyta wspólny SourceTrimReader. Dzięki temu podgląd zgadza się z wydrukiem co do spadu, zamiast utrzymywać dwie rozjeżdżające się implementacje.
- Podgląd przycina spad do krawędzi arkusza — nadmiar bleedu na zewnętrznym brzegu papieru jest obcinany do arkusza (jak strona wyjściowego PDF), zamiast wylewać się na tło kanwy.
Preflight — fałszywe ostrzeżenia o niezgodności trim
- Analizator PDF raportował CropBox jako „trim". Dla poprawnie przygotowanego pliku ze spadem CropBox = trim + bleed, więc check
TRIM_MISMATCH fałszywie alarmował na każdym pliku ze spadem. Teraz czytany jest faktyczny TrimBox (z łańcuchem default Trim→Crop→Media wg PDF 1.7 §14.11.2). Pliki bez TrimBox — bez zmian.
Skala (linijka) podglądu respektuje motyw jasny
- Linijka po górnej i lewej krawędzi podglądu miała zaszyte ciemne kolory — w motywie jasnym wychodziła ciemny pasek z jasnym tekstem, nieczytelny na jasnym tle. Teraz ma dwie palety wybierane wg aktywnego motywu (
ActualThemeVariant): jasny pasek z ciemnymi podziałkami w trybie jasnym, ciemny w ciemnym. Ten sam problem co wcześniejsze „karty nie respektują motywu".
Testy regresyjne warstwy PDF
- Pierwsze pokrycie testami składania PDF (wcześniej 0): jednostkowe
BleedFit, różnicowy test composera (compose → rasteryzacja → asercja, że spad wystaje poza komórkę), wierność rotacji /Rotate między PdfPig / PdfSharpCore / PDFium oraz odczyt TrimBox. Zweryfikowano przy okazji, że PdfSharpCore obraca /Rotate identycznie jak PDFium — żadnej kompensacji nie trzeba (i nie dodano).
Historia operacji — dziennik sesji w prawym panelu z cofnięciem do wybranego punktu
Historia operacji (zakładka „Historia")
- Zakładka „Historia" w prawym inspektorze ożyła — wcześniej był tam tylko placeholder „pojawi się w przyszłej wersji". Teraz pokazuje chronologiczny dziennik wszystkich istotnych operacji bieżącej sesji: najnowszy wpis na górze, z godziną (
HH:mm:ss), ikoną kategorii i krótkim opisem jednoliniowym.
- Logowane operacje: wczytanie pliku źródłowego (nazwa + liczba stron), dodanie plików do listy, usunięcie pliku / odznaczonych plików, wczytanie zaznaczonych (liczba stron i plików), zaplanowanie impozycji (liczba arkuszy), zakończony / anulowany / błędny eksport, łączenie plików PDF (Połącz…), zmiana szablonu, aktualizacja opcji eksportu, przypisanie pliku do slotu (drag&drop) oraz reset projektu.
- Opisy w aktywnym języku — i przełączają się żywcem. Każdy wpis przechowuje klucz lokalizacyjny i argumenty (nie gotowy tekst), więc przy zmianie języka PL ↔ EN cała historia natychmiast re-renderuje się w nowym języku, bez restartu okna. Ta sama technika co lokalizowane nazwy presetów i profili znaczników z v1.3.4 (
HistoryEntry.RefreshLocalization() + subskrypcja LocalizationService.PropertyChanged w MainWindowViewModel).
- Przycisk „Wyczyść" opróżnia dziennik sesji. Lista jest ograniczona do 200 ostatnich wpisów (
MaxHistoryEntries) — długa sesja nie rozrasta jej w nieskończoność; po przekroczeniu limitu najstarsze wpisy są odcinane. Gdy dziennik jest pusty, widać podpowiedź zamiast pustego panelu.
- Cofnięcie do wybranej operacji (hover → ↺). Po najechaniu na wpis pojawia się przycisk „↺", który przywraca cały stan projektu do momentu tej operacji: plik źródłowy, szablon, opcje eksportu, lista plików oraz zaplanowany układ arkuszy — wraz z ręcznymi zmianami slotów wykonanymi później (zostają cofnięte). Każdy wpis przechowuje lekki snapshot (
WorkspaceSnapshot) złożony z referencji do niezmienialnych obiektów (SheetLayout/PagePlacement nigdy nie są mutowane w miejscu — edycja tworzy nowe instancje), więc checkpoint jest tani pamięciowo i nie wymaga głębokiego klonowania. Ograniczenie z założenia: wyeksportowany już plik PDF na dysku NIE jest usuwany — przywracany jest wyłącznie stan w pamięci aplikacji.
- 19 nowych kluczy lokalizacyjnych PL + EN (
Hist.*, w tym Hist.RestoreTip / Hist.Restored). Nowe klasy HistoryEntry (ObservableObject) i WorkspaceSnapshot; kolekcja MainWindowViewModel.History + helper LogHistory(glyph, key, args) (robi snapshot przez CaptureSnapshot()) wpinany w istniejące ścieżki operacji obok ustawiania StatusText, oraz RestoreToHistoryEntry(entry) wywoływane z przycisku ↺.
Zwijany panel boczny (inspektor)
- Smukły uchwyt na styku podglądu i prawego panelu — chevron „›" zwija inspektor (podgląd odzyskuje całą szerokość), „‹" przywraca go. Uchwyt jest zawsze widoczny, wyśrodkowany w pionie. Stan trzymany w
MainWindowViewModel.IsInspectorCollapsed + ToggleInspectorCommand; trzecia kolumna układu zmieniona na Auto, a panel (stała szerokość 280) chowa się przez IsVisible, więc kolumna kurczy się do zera bez konwerterów. Nowy klucz Insp.ToggleTip + styl Button.inspector-toggle.
Okno aktywacji — czytelniejsze i poprawne w obu motywach
- Status licencji koloruje się semantycznie — zielony (tło + tekst) gdy licencja aktywna, czerwony gdy nieaktywna. Wcześniej pole statusu miało wpisane na sztywno ciemne tło (
#0a2e1a / #1a1a2e), które w jasnym motywie wyglądało jak czarny blok. Teraz używa motywozależnych zasobów SuccessSoft/Success i DangerSoft/Danger (sterowane klasami stylów lic-status.active / .inactive), więc wygląda dobrze i w jasnym, i w ciemnym motywie. Ten sam tint dostał baner komunikatów (sukces/błąd).
- Karty respektują motyw — styl
Border.card miał wpisane #FFFFFF + jasną ramkę (białe karty na ciemnym tle w trybie dark). Przepięty na {DynamicResource Surface} / Border.
- Wczytywanie pliku .lic nad kluczem aktywacyjnym — sekcja „Plik licencji" przeniesiona ponad pole klucza (to szybsza, główna ścieżka). Przyciski przemianowane z „JSON" na właściwe rozszerzenie .lic (ten sam plik JSON niesie zarówno fingerprint maszyny, jak i licencję): „Wczytaj plik .lic…" oraz „Eksportuj .lic…". Obie ścieżki (wczytaj plik / wklej klucz) mają teraz spójny przycisk akcji w kolorze akcentu i krótkie podpowiedzi.
- Nowy klucz
Act.LoadFileHint, przeredagowane Act.OrLoadFile / Act.LoadFileBtn / Act.ExportJsonBtn / Act.KeyHint (PL + EN). Logika walidacji/aktywacji bez zmian — to wyłącznie warstwa UI.
Build: 0 warnings / 0 errors. Bez zmian w silniku impozycji i eksportu — funkcja czysto UI/obserwacyjna.
Poprawka aktywacji licencji
Naprawione
- Błędna blokada „Plik kontrolny licencji został zmodyfikowany" przy zmianie licencji na tym samym komputerze (np. trial → płatna, ponowne wydanie). Strażnik cofania zegara (
LicenseClockGuard) zapisuje plik kontrolny powiązany z podpisem konkretnej licencji; przy wgrywaniu innej licencji stary plik nie pasował i był traktowany jak sabotaż. Teraz niedopasowany plik kontrolny jest rozpoznawany jako „należący do innej licencji" i zapisywany od nowa — sama blokada cofania zegara działa bez zmian. Plik kontrolny jest dodatkowo czyszczony przy każdej aktywacji.
Dodane
- Przypomnienie o restarcie — po wczytaniu klucza lub pliku licencji aplikacja informuje, że należy ją zamknąć i uruchomić ponownie, aby licencja zaczęła obowiązywać.
- Panel admina (serwer licencji) — w akcjach przy każdej licencji doszły przyciski Pobierz plik .lic oraz Kopiuj klucz do schowka, obok wysyłki ponownej i blokady.
Hotfix do 1.3.5 — bez zmian w silniku impozycji. Build: 0 warnings / 0 errors.
Eksport identyfikatora do .lic, łączenie plików PDF
Eksport identyfikatora maszyny do pliku .lic
- Nowy przycisk Eksportuj JSON… w oknie Aktywacja licencji, pod przyciskiem Kopiuj. Zapisuje identyfikator sprzętowy do pliku
.lic (natywne okno „Zapisz jako", rozszerzenie .lic a nie .json) — wygodniejsze niż ręczne kopiowanie długiego ciągu, gdy zamawiasz licencję. Plik zawiera składniki MAC/DISK/UUID oraz gotowy ciąg fingerprint (to samo, co kopiuje przycisk Kopiuj) plus nazwę maszyny i znacznik czasu eksportu
- Strona z generatorem licencji próbnej (impressstudio.pl) przyjmuje teraz ten plik — zamiast wklejać identyfikator, wgrywasz
.lic i pole wypełnia się samo. Obsługa po obu stronach: wklejenie ciągu nadal działa
Łączenie plików PDF (Połącz…)
- Przycisk Połącz… w panelu plików źródłowych, obok + Dodaj. Aktywny gdy zaznaczysz co najmniej dwa pliki. Scala je w jeden PDF i zapisuje na dysk przez natywne okno „Zapisz jako" — operacja samodzielna, niezależna od impozycji (nie ładuje wyniku do projektu)
- Sugerowana nazwa według wzorca
merged_<data>_<liczba_plików>_<liczba_stron>.pdf (np. merged_2026-06-06_3_48.pdf) — liczba stron liczona od razu z analizy, bez wcześniejszego scalania. Pliki łączone w kolejności z listy. Wykorzystuje istniejący silnik scalania, ten sam co dotychczasowe automatyczne łączenie zaznaczonych plików
Build: 0 warnings / 0 errors. Nowe klucze lokalizacyjne PL + EN dla obu funkcji. Część serwerowa (panel admina trial-servera) zyskała generator licencji płatnych — trial / 6 mies. / rok / wieczysta / custom — niezależnie od aplikacji desktopowej.
Step & Repeat, profile znaczników, lokalizowane nazwy
Step & Repeat — dedykowany binding
- Nowy typ oprawy
StepAndRepeat obok istniejących Ganging / RollFed / SaddleStitch / PerfectBound / Wiro / fold-leaflets. Powiela jedną stronę źródłowego PDF w siatce NxM na arkuszu — kompletuje zestaw bindingów dla operatorów etykiet, wizytówek, naklejek gdzie produkujesz jeden item w wielu kopiach z konkretnym pitchem maszyny. Odróżnia się od Ganging w dwóch wymiarach: Ganging cykluje przez kolejne strony źródła, S&R zawsze powiela tę samą (page 1 na froncie, page 2 na backu przy duplexie); Ganging zawsze 0°, S&R wspiera wzory rotacji per kopia
- Cztery wzory rotacji per kopia (
StepAndRepeatRotation): None (wszystkie 0°), AlternatingRows (parzyste rzędy 0°, nieparzyste 180° — nesting dla itemów z osią symetrii), AlternatingColumns (analogicznie po kolumnach), Checkerboard (szachownica — najlepszy nesting dla asymetrycznych kształtów, np. butelek czy listków). Rotacja per-copy honorowana zarówno w eksporcie PDF, jak i w podglądzie canvasu (PagePlacement.RotationDegrees już istnieje od v1.0)
- Dwa tryby odstępu (
StepAndRepeatSpacing): GapBetween (jak Ganging — dzielenie użytecznej powierzchni przez N, gutter + margines), CenterToCenter (centra itemów w dokładnie pitch-mm odstępie, siatka centrowana na arkuszu, gutter ignorowany). Pitch C-to-C to standardowa konwencja w przemyśle etykietowym — operator wprowadza wartość z karty maszyny (np. die-cutting roll z pitch 52mm), nie przelicza w głowie gap-from-edge
- Walidacja łapie przypadki nakładania kopii — gdy pitch jest mniejszy niż wymiar itemu w danej osi,
Template.Validate rzuca konkretną wiadomość („Pitch poziomy 45mm jest mniejszy niż szerokość itemu 50mm — kopie zachodzą na siebie") zamiast cichego błędnego wyniku eksportu
- Nowa sekcja w edytorze szablonów (osobna karta między Roll a Cutter marks) z dropdownami dla wzoru rotacji i trybu odstępu, plus pola pitch X/Y aktywne tylko przy CenterToCenter. Wszystkie wartości honorują aktywną jednostkę mm/cale przez ten sam
MmConverter i UnitLabelExtension co reszta edytora
- Preset „Naklejki 50×50 — Step & Repeat" w bibliotece quick-start: A4 portrait, 4×5 siatka itemów 50×50mm z pitch 52mm i tryb CenterToCenter. Math zweryfikowana: 3×52+50 = 206 ≤ 210 (W) oraz 4×52+50 = 258 ≤ 297 (H). Pokazuje krok-po-kroku jak skonfigurować typowe zadanie etykietowe
- Testy (
StepAndRepeatStrategyTests, 7 nowych) pokrywają: grid count (single-page → NxM placements), duplex (page 1 front + page 2 back), graceful degradation (duplex z 1-stronicowego źródła → empty back), wzory rotacji per-cell, dokładność matematyki center-to-center (start X/Y + odstępy między sąsiadami)
Lokalizowane nazwy presetów i profili znaczników
- 12 wbudowanych presetów szablonów (A4/A5 broszura, perfect bound, ganging 2/4-up, DL Z-fold/harmonijka/3-up, wizytówki 6/8/12-up, naklejki rolka) — labelki i opisy w lewym panelu Menedżera szablonów teraz przeskakują na EN gdy przełączysz język.
TemplatePreset przepisana z record na klasę z LabelKey/DescriptionKey + computed Label/Description (przez LocalizationService) + INPC. TemplateEditorViewModel subskrybuje LocalizationService.PropertyChanged i notyfikuje każdy preset przy zmianie języka, więc lista refreshuje się żywcem bez restartu okna. Template.Name pieczętowany w momencie aplikowania presetu jest w aktywnym języku — już zapisane szablony zachowują swoją nazwę (to user data)
- 5 wbudowanych profili znaczników (Domyślny / Offset / Druk cyfrowy / Wielkoformat / Bez znaczników) — display layer ignoruje persistent Name pole z seeded JSON i pokazuje localized name przez
MarksProfileDisplay.LocalizedName() (mapuje stabilne ID na klucze loc). Dotyczy zarówno dropdownu w edytorze szablonu jak i lewej listy w edytorze profili znaczników (przez MarksProfileNameConverter w XAML). User-defined profile używają persistent Name jak dotąd
- 30 nowych kluczy lokalizacyjnych PL + EN (24 dla
TM.Preset.* × 12 presetów × label+desc, 6 dla MPL.* × 5 built-inów + Legacy)
Marks v2 — profile zamiast pojedynczych checkboxów
- Profil znaczników to nazwany pakiet ustawień (crop / pasery / pasek kontrolny / slug / fold / contour-cut) zapisany jako jeden plik JSON w
%APPDATA%\imPRESS Studio\marks-profiles\. Szablon trzyma tylko referencję (marksProfileRef); zmiana profilu propaguje się od razu do każdego szablonu, który z niego korzysta. Pięć wbudowanych profili seedowanych przy pierwszym uruchomieniu: Domyślny (zachowanie v1.3.x 1:1), Offset (powlekany) z paskiem GATF-11 i slugiem u góry, Druk cyfrowy (sam crop + slug, bez paserów ani paska — cyfra sama się kalibruje), Wielkoformat (corner registration plus, pasek CMYK przy dolnej krawędzi) i Bez znaczników
- Pasek kontrolny w czterech wariantach: CMYK process (4 pola), CMYK + tinty (8 pól, legacy default), GATF-11 (paper + CMYK solid + CM/CY/MY overprints + K 25/50/75%) i Brunner-21 (paper + CMYK po cztery stopnie tinta + 3 overprinty + chromatic CMY). Każdy wariant rysowany przez
XColor.FromCmyk bezpośrednio w PDF — separacje C/M/Y/K są prawdziwe. Wybór krawędzi (góra/dół/lewa/prawa) dla każdego paska. Komentarz w kodzie jasno mówi że GATF-11 i Brunner-21 to rozsądne aproksymacje, nie certyfikowane bary referencyjne (oryginały są pod paywallem System Brunner AG / PIA)
- Pasery w czterech stylach × trzech pozycjach: Target (kółko + krzyż, klasyczny offset), Plus (sam krzyż, lepszy na inkjet bo nie rozmazuje się przez ink spread), Diamond (romb + krzyż) i Crosshair (Heidelberg-style — krzyż w małej ramce). Pozycja: środki krawędzi, narożniki, lub oba. Rozmiar i odstęp od krawędzi sterowane z profilu
- Slug — pasek opisowy na krawędzi arkusza. Format z placeholderami:
{filename}, {date}, {date:yyyy-MM-dd} (lub dowolny .NET format), {sheet}, {sheets}, {side}, {template}, {jobid}. Domyślnie: "{filename} · {date} · Arkusz {sheet}/{sheets} · {template}". Wybór krawędzi z auto-rotacją tekstu na lewej/prawej. Nieznane tokeny pozostają w formacie (lepiej żeby operator zobaczył literówkę niż żeby ją po cichu wyciąć)
- Kolor farby per znacznik — wybór process black (K=100) lub registration black (C=M=Y=K=100). Registration black drukuje się na każdej separacji w offsecie, więc pasery i crop dla offsetu domyślnie używają registration black, slug w druku cyfrowym — process
- Pełna kompatybilność wstecz — szablony v1.3.x bez
marksProfileRef renderują się dokładnie tak jak wcześniej. MarksProfileResolver.AdaptLegacy() buduje syntetyczny profil ze starych boolean flag (Marks.Crop, Marks.Registration, ...) — żaden plik szablonu nie wymaga migracji. Brakujący profil w referencji (np. user usunął plik) też nie blokuje renderingu, tylko cicho cofa się do legacy lub Default
Edytor profili w aplikacji
- Nowe okno Edytor profili znaczników otwierane przyciskiem Zarządzaj… obok dropdownu profilu w edytorze szablonu. Lista profili po lewej (z odróżnieniem wbudowanych), formularz z pięcioma akordeonami po prawej: Cięcia · Pasery · Pasek kontrolny · Slug · Inne (fold + contour-cut). Wszystkie pola w jednostce mm/cale zgodnie z aktywnym ustawieniem, wszystkie enumy w dropdownach
- Operacje: Zapisz / Zapisz jako… / Przywróć domyślne / Usuń. Profile wbudowane można dowolnie edytować i przywracać do bundled defaults — ale nie usuwać. Zapisz jako… prompty o nazwę i tworzy nowy plik z kebab-cased id. Profile użytkownika — pełna swoboda. Po zamknięciu edytora dropdown w edytorze szablonu odświeża się automatycznie
- Plumbing:
%APPDATA%\imPRESS Studio\marks-profiles\ zarządzany przez AppPaths.GetMarksProfilesDir() + EnumerateAllDirectories() (tworzy się przy starcie). MarksProfileFileStore tolerancyjny na uszkodzone pliki — jeden malformed nie blokuje listy. Przycisk Otwórz folder profili dla użytkowników którzy wolą edytować JSON ręcznie
- Renderer i podgląd zsynchronizowane —
PrinterMarksRenderer (export) i ImpositionCanvas.DrawMarksOverlay (preview) konsumują ten sam MarksProfile przez MarksProfileResolver. Operator widzi w canvasie dokładnie to co wyląduje w PDF (z aproksymacją sRGB → CMYK bo Avalonia nie ma CMYK pipeline). Pole PreviewViewModel.ActiveMarksProfile re-rezolwuje się przy każdej zmianie szablonu
- Loc: 38 nowych kluczy PL + EN (
MPE.* + TM.MarksProfileManage / TM.MarksProfileHint / TM.MarksProfileOpenFolder / TM.Section.MarksProfile). Komunikaty o błędach zapisu (zła nazwa id, duplikat, błąd I/O) wyświetlane w status banerze edytora
Build: 0 warnings / 0 errors. Testy: 146/146 zielone (+18 od v1.3.2 — MarksProfileResolverTests, SlugFormatterTests, StepAndRepeatStrategyTests). Smoke test: aplikacja startuje czysto, 5 wbudowanych profili znaczników seeduje się do %APPDATA%, legacy szablony renderują się identycznie jak przed migracją, przełączenie języka żywcem aktualizuje labelki presetów i nazwy profili.
Pełna obsługa cali, profile ICC w File Info i presety US/ANSI
Pełna obsługa jednostek mm / cale w całym UI
- Architektura: model zostaje w mm — konwersja tylko na granicy UI. Wszystkie
*Mm properties w modelu (SheetSize, TrimSize, LayoutMargins, RollOptions, MarksOptions, OverlayOptions) zostają w milimetrach — to kanoniczna jednostka przechowywania, szablony JSON nieruszone. Konwersja dzieje się wyłącznie w warstwie XAML przez nowy MmConverter (mm ↔ aktywna jednostka) i markup {loc:UnitLabel} (label z aktywnym suffiksem). Round-trip bez dryfu: czynnik 25.4 jest dokładny dla każdego double, a model nigdy nie jest nadpisywany zaokrąglonym display-value
DisplayUnitsService rozszerzony — dodane ToMm() (odwrotność FromMm), IsInches, DefaultDecimals, FormatLengthMm() (jeden helper dla walidatorów); klasa implementuje teraz INotifyPropertyChanged, więc bindowania do Suffix w XAML auto-refreshują się przy toggle bez restartu
- Edytor szablonów (Template Manager) — wszystkie ~20 pól wymiarowych (sheet W/H, trim, bleed, safe zone, gutter, spine, sheet margin, rolka MaxRollLength/GapX/GapY, custom size, długości i offsety znaczników, cutter mark size/offset, overlay max width/offset X/Y, paper thickness) wpięte do
MmConverter. Wpisujesz 3.5 w calach — w modelu siedzi 88.9 mm; przełączasz na mm — pole pokazuje 88.9. Każdy NumericUpDown działa w jednostce aktywnej
- Labelki dynamiczne — ~20 wpisów loc (PL + EN) zmienione z literalnego
"Szerokość (mm)" na "Szerokość ({0})"; UnitLabelExtension + UnitLabelConverter robią multi-binding (loc + suffiks) tak że label refresuje się i na zmianę języka, i na zmianę jednostki. Settings dropdown z opcjami jednostek (Metryczne (mm) / Cale (in)) celowo zostawiony z literalami — to label opcji, nie wartości
- Inspektor zaznaczenia (X/Y/W/H placementu) w prawym panelu główno-okiennym — 4 NumericUpDown'y konwertują, X i Y dostały nowe loc klucze
Insp.X/Insp.Y
- Wszystkie display-bindings sheet-size w toolbarze, statusbar, empty-state mockup, stat-block Bleed/Gutter — twardo zakodowane
Run Text=" mm" wymienione na Run bindowane do DisplayUnitsService.Instance.Suffix. Linijka canvasu już respektowała preferencję (jedyne miejsce z wcześniejszej iteracji)
- Raport walidacji preflight w File Info —
BleedValidator (BLEED_LOW, BLEED_CONTENT_UNUSED, BLEED_CONTENT_OVERFLOWS_BLEEDBOX) i PageSizeValidator (TRIM_MISMATCH) emitują wartości przez FormatLengthMm() + suffiks jako kolejny placeholder. Templates loc HF.PV.Issue.* przerobione: "{1} mm" → "{1} {3}" z suffiksem jako dodatkowy arg. Sekcje "PAGE BOXES" i "IMAGES" w dialogu File Info — formaty FI.Boxes.Row i FI.Img.Row dostały dodatkowy slot {7} na jednostkę; PrepressDisplay.Mm() teraz konwertuje + precyzja zależna od jednostki (mm: F1, cale: F3 — 0.001 in ≈ 0.025 mm, finer niż realne tolerancje prepress)
- Dialog sugestii szablonu — wymiary wejściowego PDF, komunikat "brak dopasowań" i tekst "Różnica X mm" wszystkie w aktywnej jednostce. Nazwy ~30 presetów (PL + EN) przerobione z
"Wizytówka standard (85×55 mm)" na placeholder "Wizytówka standard ({0}×{1} {2})"; TemplateSuggestion dostała PresetWidthMm/PresetHeightMm żeby dialog mógł wstawić wymiary w jednostce użytkownika
- VM-y re-emitują display values na
DisplayUnitsService.Changed — TemplateEditorViewModel, MainWindowViewModel i PreviewViewModel subskrybują event i wołają OnPropertyChanged dla ROOT bound properties (Template, CurrentTemplate, Preview, SelectedXmm/Ymm/Wmm/Hmm). Reguła jest taka że re-notify musi iść do roota a NIE do leaf *Mm, bo leafy siedzą na POCO bez INotifyPropertyChanged — Avalonia re-walkuje ścieżki bindingu tylko gdy root fire'uje. To jeden z subtelniejszych haczyków przy podpinaniu konwertera do nested-path bindings na POCO
Informacje o profilu ICC w File Info
- Sekcja OUTPUT INTENT pokazuje teraz realne dane osadzonego profilu ICC, nie tylko "tak/nie". Wcześniejsze 4 pola (Subtype, Condition, Identifier, Embedded) uzupełnione o RegistryName oraz — co najważniejsze — nazwę profilu (z tagu
desc dla ICC v2, mluc dla v4) i przestrzeń barw (CMYK / RGB / Gray / Lab / N-channel) odczytane z nagłówka profilu
- Nowy parser
IccProfileReader (Imposition.Pdf) — minimalny, tylko to co dialog faktycznie pokazuje: data colour space signature spod offsetu 16 i tag desc/mluc. Best-effort: uszkodzony lub okrojony profil zwraca nulle, nie rzuca wyjątku. Zweryfikowany na realnym sRGB Color Space Profile.icm z Windows — offsety i mapowania zgadzają się 1:1 ze specem ICC
PdfStandardDetector rozwiązuje pośrednie odwołanie /DestOutputProfile przez Structure.GetObject(IndirectReference), dekoduje filtry strumienia (ICC są standardowo FlateDecode-compressed) przez DefaultFilterProvider.Instance i wrzuca surowy bufor do parsera. Wcześniejsze pola EmbeddedProfileName i EmbeddedProfileComponents w modelu były zawsze null z komentarzem "expensive and rarely surfaced" — teraz faktycznie się wypełniają. Nowe pole EmbeddedProfileColorSpace dla czytelnej etykiety przestrzeni barw. Błędy parsowania (nieobsługiwany filtr, malformed) trafiają do diagnostyki — nie przerywają analizy
- Nowe klucze loc
FI.Oi.Registry, FI.Oi.ProfileName, FI.Oi.ColorSpace (PL + EN)
Wbudowane profile ICC (plumbing)
- Folder źródłowy
Imposition.App/icc/ + reguła kopiowania w .csproj — każdy .icc / .icm wrzucony do tego folderu trafia automatycznie do {install}/icc/ przy każdym buildzie i dotnet publish. IccProfileManager już je czytał z dysku i pokazywał w dropdownie eksportu — brakowało plumbingu do bundlingu
- README z dokładnymi nazwami plików ECI do pobrania (zestaw zalecany: PSO Coated v3 / FOGRA51, PSO Uncoated v3 / FOGRA52, eciRGB v2 z eci.org) wraz z ostrzeżeniem licencyjnym żeby NIE bundlować profili Adobe (SWOP, GRACoL, Japan Color, Adobe RGB) — są objęte prawami Adobe i nielegalne do redystrybucji w komercyjnym produkcie. Użytkownik może je sam zaimportować przyciskiem "Przeglądaj" (lądują wtedy w
%APPDATA%\imPRESS Studio\icc)
Presety i formaty zagraniczne (rynek US)
PaperPresets rozszerzone o ANSI A–E — ANSI A (=Letter), ANSI B (=Tabloid, aliasy żeby joby celujące w serię inżynieryjną resolwowały się czysto), ANSI C (431.8×558.8 mm), ANSI D (558.8×863.6 mm), ANSI E (863.6×1117.6 mm). Letter / Legal / Tabloid / Ledger były już wcześniej
TemplateSuggestionEngine — 6 nowych presetów dla wejść w wymiarach US:
- Ulotka US Letter (8.5×11") 1-up na Tabloid (typowa amerykańska prasa)
- Ulotka US Half-Letter (8.5×5.5") gangowana 2-up na Letter
- Ulotka US Quarter-Letter (4.25×5.5") gangowana 4-up na Letter
- Plakat US Tabloid (11×17") 1-up
- Plakat ANSI C (17×22") 1-up
- Plakat ANSI D (22×34") 1-up
Razem z istniejącymi BusinessCardUS i PostcardUS to pełniejszy zestaw dla operatorów obsługujących klientów spoza UE. Nazwy presetów (PL + EN) używają placeholder ({0}×{1} {2}), więc wymiary pokazują się w jednostce aktywnej — operator US widzi "8.5×11 in", EU operator widzi "215.9×279.4 mm"
Build: 0 warnings / 0 errors. Smoke test: aplikacja startuje czysto, logi bez wyjątków. Reguły rekomendacji w narracyjnych "Action" templates (np. "ustaw bleed ≥ 3 mm") celowo zostawione z mm jako branżową konstantą — to porada, nie zmierzona wartość.
Dopracowanie topbara — przyciski Planuj i Eksportuj czytelniejsze
Przyciski akcji w topbarze
- Przycisk Planuj dostał własny styl zamiast neutralnego ghost — jasnoniebieskie tło (
#DBF1FF), granatowy tekst i ikona (#004AA9) oraz subtelna, półprzezroczysta obwódka (#006AC5 z ~25% alfą). Czytelny jako akcja, ale wizualnie nie konkuruje z głównym CTA Eksportuj. Nowa klasa stylu Button.plan w App.axaml — nie rusza pozostałych przycisków ghost
- Tekst przycisku Eksportuj wymuszony na biały (label + skrót
Ctrl+E) — pełny kontrast na akcentowym tle niezależnie od motywu
Wydanie kosmetyczne — bez zmian w silniku impozycji ani eksportu. Build: 0 warnings / 0 errors. Testy: 123/123 zielone.
UI redesign: onboarding, floating toolbar, drag-and-drop fix (STA), pasek postępu eksportu, OPOS w canvasie
Drag-and-drop z Eksploratora wreszcie działa
- Root cause:
[STAThread] tracony przez async Task<int> Main — atrybut sticky-uje się do entry methodu tylko dopóki nie wykonano żadnego await. hotFolderHost.StartAsync(...) przerzucał kontynuację na thread pool (MTA), więc BuildAvaloniaApp().StartWithClassicDesktopLifetime() startował na wątku MTA. RegisterDragDrop (Win32 OLE) wymaga STA — wywoływany z MTA cicho odrzucał rejestrację, kursor pokazywał czerwony zakaz a żaden drag event nie docierał do Avalonia. Fix: Main wraca do sync, ścieżka GUI woła hotFolderHost.StartAsync(...).GetAwaiter().GetResult(); CLI dispatch wydzielony do prywatnego RunCliAsync (CLI nie potrzebuje STA)
- Window-level + root-Grid + empty-state-Grid
DragDrop.AllowDrop=True jako defense-in-depth + OnWindowOpened wywołuje DragDrop.SetAllowDrop(this, true) po utworzeniu OS-level handle (obchodzi historyczny race w Avalonia 11.0.x)
- Detekcja elevation przy starcie — jeśli aplikacja jest uruchomiona z UAC (manifest mówi
asInvoker ale ktoś odpalił Run as Administrator), StatusText ostrzega: "UWAGA: uruchomiono z uprawnieniami administratora — drag & drop z Eksploratora będzie zablokowany przez UAC" (UIPI block z medium IL do high IL)
- Avalonia 11.0.10 → 11.2.7 + SkiaSharp 2.88.7 → 2.88.9. Razem z STA fixem domyka klasę bugów DnD na Windows. Brak breaking changes w istniejących stylach / bindings / source-genowanych properties
Empty state — onboarding zamiast martwej przestrzeni
- Makieta arkusza SRA3 + drop zone + checklist 1·2·3 w centrum canvasu zamiast suchej etykiety "Brak podglądu". Makieta = Viewbox 450:320 z dashed-stroke Rectangle + ItemsControl z UniformGrid placeholderów slotów według aktualnego
NUpX/NUpY z fallback'iem 2×2. Drop zone = klikalny przycisk (otwiera file picker) z ikoną PDF + "Przeciągnij plik PDF tutaj · lub kliknij, aby wybrać · Ctrl+O". Checklist po prawej: ① Wczytaj PDF (✓ gdy są pliki) ② Wybierz strony (akcent gdy step 1 zrobiony) ③ Eksportuj
- Drag-hover overlay — pełnokanwasowy półprzezroczysty Accent-tint z napisem "Upuść, aby dodać do listy" + ikona PDF, widoczny gdy PDF jest przeciągany nad oknem.
IsHitTestVisible=False żeby nie blokować dropu pod spodem
- Inspektor empty state z cheat-sheet — zamiast "Brak danych" widzisz: 3-paskowy skeleton imitujący strukturę bloku Utilization (krótki label, pełnowymiarowy value, średni sub), tekst "Statystyki pojawią się po wczytaniu pliku" i kartę "Skróty klawiszowe" z chipami mono-font: Ctrl+O Otwórz · Ctrl+P Planuj · Ctrl+E Eksportuj
Floating toolbar canvasu — 4 wyraźne grupy zamiast jednej kolumny
- Grupa A (top-left): zoom controls (−/+/50%/200%/Dopasuj/Rotate). Bez zmian.
- Grupa B (top-right): view toggles — znaczniki cięcia / bleed-trim guides / CMYK / overprint / creep
- Grupa C (pod B): segmented PRZÓD / TYŁ jako dwa ToggleButtony z one-way bindingiem do
Preview.ShowBackSide (klik handluje w code-behind żeby uniknąć rebound flicker'a). Rozkładówka wydzielona do osobnego Border ftbar — wizualnie ortogonalna do side-switch
- Grupa D (bottom-center): poziomy CMYK strip z 5-tym przyciskiem "Wsz." (włącza wszystkie 4 kanały naraz przez nowy
ShowAllChannelsCommand). Chipsy CMYK gdy odznaczone tracą kolorowe tło — przezroczyste z neutralną obwódką, łatwiej zauważyć który kanał jest hidden
Pasek postępu eksportu z fazami
- Status bar pokazuje aktualną fazę: Analiza PDF → Walidacja preflight → Planowanie impozycji → Składanie wynikowego PDF → Konwersja do PDF/X (Ghostscript). Jeśli operator nie widzi fazy "Konwersja", od razu wie że PDF/X nie był nawet próbowany (najczęściej PdfXMode = None w opcjach).
ExportPipeline.RunAsync dostał parametr IProgress<double>?, raportuje boundary'a per faza (15/25/30/85/100%); MainWindowViewModel.ExportAsync mapuje wartość na fazę-label dla StatusText
- Mini-ProgressBar w prawej części statusbara (80×4 px, accent foreground) widoczny przez
IsVisible="{Binding IsBusy}". Odróżnia się od zielonego paska wykorzystania (utilization)
- Auto-detekcja Ghostscript — przy otwarciu Eksport→Opcje skanuje
%ProgramFiles%\gs\gs*\bin\gswin64c.exe, %ProgramFiles(x86)%\gs\gs*\bin\gswin32c.exe i PATH, wpisuje najnowszą znalezioną wersję do pola GS path. Eliminuje "Eksport: błąd Ghostscript not found" dla operatorów którzy zainstalowali GS standardowo
- Success message zawiera nazwy obu plików gdy PDF/X był włączony: "Eksport zakończony · zapisano X.pdf i X.pdfx1a.pdf" — koniec szukania gdzie poszedł plik PDF/X (sufix
.pdfx1a.pdf / .pdfx4.pdf obok regularnego .pdf)
Znaczniki cięcia + paserki + OPOS w canvasie
- Canvas renderuje teraz Summa OPOS markery (czarne kwadraty wokół bounding-boxa wszystkich placementów) — wcześniej
CutterMarksRenderer żył tylko w pipeline'ie PDF eksportu; canvas o nich nic nie wiedział. DrawMarksOverlay woła CutterMarkLayout.Compute i rysuje halo-+-core rectangles tak samo jak crop/registration
- Halo+core trick dla widoczności na każdym tle — wszystkie marki (Crop, Registration, OPOS) rysowane teraz dwoma penami: gruba biała otoczka (alpha 220, stroke 2.4/2.0) najpierw, czarny rdzeń na wierzchu. Wcześniej czarny stroke 0.5 px na
#0A0E13 (dark theme canvas-bg) był praktycznie niewidoczny — fragmenty marków padających poza papier znikały
- Min pixel size przy ekstremalnym zoom-out:
markLen ≥ 6 px, markOff ≥ 2 px, OPOS square ≥ 4 px. Bez clamp'u przy fit-zoom na rolce 320×2000mm (scale ≈ 0.05) krzyżyki cięcia miały sub-pikselową długość. Affekuje tylko podgląd na ekranie — eksport PDF używa surowych mm z MarkLengthMm
- Domyślne marki dla presetu rolkowego:
Crop=true, Registration=true, CutterMarks=None, ColorBars=false, FoldMarks=false. Wcześniej rolka miała tylko OPOS włączone — operator który chciał klasycznych marków widział "nic". Teraz crop ticks + paserki domyślnie, OPOS opt-in via checkbox
- Checkbox "Włącz markery Summa OPOS" w Edytorze szablonów (sekcja MARKERY PLOTERA). Toggle flipuje
CutterMarks między None ↔ SummaOPOS; gdy odznaczony, combobox typu + size + offset jest IsEnabled=false. Po zamknięciu Edytora MainWindow wymusza re-plan jeśli był aktywny job — bez tego zmiana w POCO MarksOptions nie propagowała się do canvasu (brak INotifyPropertyChanged i UseTemplate(sameRef) nie odpalał setter'a)
RollFed — centrowanie i sugestie
- Block items centrowany poziomo w canvasie rolki —
xOriginPts = marginPts + (availWidth - blockWidth) / 2. Wcześniej pakowane od lewego marginesu, leftover lecił na prawo (block off-center). Y zostaje top-anchored — to kierunek przewijania rolki, centrowanie wpajałoby pusty pasek przed każdym segmentem
- Sheet margin rolki 0 → 5 mm — bez tego znaczniki
MarkOffsetMm(3) + MarkLengthMm(5) = 8 mm wypadały poza stronę i były clipped przez PDF page bounds. Strata: w bardzo wąskich produktach (30 mm) 1 item per row mniej; zysk: marki rzeczywiście istnieją na wyjściu
- RollFed + 2-stronicowy PDF → duplex sugerowany automatycznie —
SuggestForContext dostała parametr sourcePageCount, adapter dla RollFed ustawia Duplex = sourcePageCount >= 2. Wcześniej rolka zawsze single-sided → user z 2-stronnym PDFem (front+back wizytówki) dostawał tylko front silently
Sugestie szablonu — naprawione dwa współbieżne bugi
- Karty w dialogu były niewidzialne w Avalonia 11.2 —
Application.Current.TryFindResource(key, out _) bez parametru ThemeVariant przestał znajdować zasoby z ResourceDictionary.ThemeDictionaries; Res() zwracało Brushes.Transparent dla każdego pędzla, więc Background, BorderBrush i Foreground kart były przezroczyste — karty były w drzewie wizualnym ale niewidoczne i nieklikalne (Avalonia hit-test pomija Border z przezroczystym tłem). Fix: TryFindResource(key, Application.Current.ActualThemeVariant, out _)
- Plan failed po zastosowaniu sugestii — adapter
AdaptToCurrentContext brał fit.NUpX/Y z optymalizera który próbuje także rotacji o 90° dla lepszego packing'u. Dla wizytówki 85×55 na SRA3 wybierał wariant rotowany 6×3 (18 slotów zamiast 16), ale Trim zostawiał w natywnej orientacji. Template.Validate() liczył NUpX × 91mm + gaps + margins ≈ 590 mm i odrzucał (450 mm szerokość SRA3). Fix: adapter liczy N-up bezpośrednio formułą walidatora w natywnej orientacji (strata 1-2 sloty w niektórych przypadkach, zysk: zero rozjazdu między NUp a Trim)
- Wizytówka jako saddle-stitch booklet — adapter dziedziczył
Binding z currentTemplate (workflow), a powinien ze source.Template.Binding (produkt). User w workflow A4 booklet wybierający "wizytówka standard" dostawał SaddleStitch który traktował 2 strony PDF jako rozkładówkę (1 wizytówka pośrodku zamiast 16). Nowa reguła: jeśli current = RollFed → keep RollFed (continuous-roll output to workflow override), inaczej → binding ze source preset (wizytówka jest Ganging z definicji)
- Dialog "Sugerowane szablony" Height 540 → 680 +
CanResize=True. Wcześniej content (3 matched + expander) nie mieścił się, footer z przyciskiem "Zastosuj" wymagał scrolla
Topbar, step rail, panele
- License badge w topbarze po prawej (przed Plan/Eksport) z warning-tintem gdy
DaysRemaining < 7. Wcześniej w centrum jako część StatusText — gubił się. Nowe pole LicenseBadgeText + LicenseExpiringSoon w VM, mutually-exclusive Classes.pill / Classes.pill-warning binding
- Step rail wyższy (44 → 50 px), aktywny krok dostaje
AccentSoft background (delikatny niebieski tint), step 4 (Eksport) gdy Preview.Sheets.Count > 0 pokazuje białe ▶ na kółku Accent zamiast cyfry "4" — CTA wizualne. Meta-text font-size 10.5 → 11 + Margin="0,3,0,0" dla oddechu. Foreground nieaktywnych kroków Ink3 → Ink2 (kontrast na granicy WCAG AA → AAA)
- Lewy panel — hover-actions na liście plików. Wiersz dostaje
Classes="file-row"; embedded StackPanel Classes="hover-actions" z 24×24 przyciskami ▲▼✕ z Opacity=0 domyślnie, fade-in na :pointerover rodzica. Stary Grid akcji ▲▼✕ pod listą wywalony, Info button stretched. Destrukcyjne "Anuluj operację" + "Resetuj wszystko" wyrzucone z dolnej części panelu (są w menu Plik). Sekcja "Plik wyjściowy" expander zwinięty domyślnie
- "Wczytaj zaznaczone" dynamic label: "Wczytaj N zaznaczone" +
IsEnabled bindowany na CheckedFileCount. VM tracking via SourceFiles.CollectionChanged + per-entry PropertyChanged na IsIncluded. File row selection indicator przeniesiony na lewą krawędź, 4 px szerokości, pełna wysokość wiersza, CornerRadius="2,0,0,2"
- Topbar — logo "iP" z subtelnym gradientem (LinearGradientBrush Accent → ciemny korpus) zamiast jednolitego
BadgeBg. Nagłówki sekcji w lewym panelu: font-size 10.5 → 11 + LetterSpacing=0.66 dla professional small-caps look. Dark-mode toggle w menu Widok → Przełącz motyw
- Statusbar pasek nakładał się na tekst przy wąskim oknie — Avalonia
StackPanel Orientation=Horizontal nie respektuje bounds rodzica, jego desired width to suma children. ClipToBounds=True na lewej kolumnie statusbara: status text przy wąskim oknie jest czysto przycinany zamiast nakładać się na progress bar
Drobne polish
- Mojibake
"Ă—" → "×" w 4 miejscach renderowanego tekstu (N-Up "2 × 1", statusbar sheet dims "450 × 320 mm", empty-state mockup) + 2 komentarze XAML. Avalonia 11.2 renderowała dosłownie podwójnie zakodowane bajty UTF-8
- Dialog Settings za małe (Width 460 Height 440 CanResize=False) — przycisk Zamknij nie mieścił się w pełni przy 3 sekcjach (Język + Jednostki + Motyw). Bump do 480×600 + MinWidth/MinHeight + resize ON
- Inner ImpositionCanvas
DrawEmptyState usunięty — XAML overlay zastępuje go w pełni. Wraz z nim nieużywany InfoForeground brush
Build: 0 warnings / 0 errors. Testy: 123/123 zielone (zaktualizowany StickerSize_GetsRollFedBindingWithCropMarksNoOposByDefault po zmianie defaultu CutterMarks).
Inteligentne sugestie z kontekstu, RollFed duplex, jednostki mm/cale, linijka podglądu
Sugestie szablonu świadome kontekstu
- Dwupoziomowy widok sugestii — gdy masz wczytany szablon, na górze dialogu pokazują się propozycje dopasowane do Twojego ustawienia: każdy preset re-anchorowany do aktualnego
Sheet + Binding + marginesów + marks + roll/overlay. Nagłówek "Dopasowane do Twojego ustawienia: {sheet} · {binding}" jasno mówi co i czemu. Oryginalna biblioteka (kanoniczne SRA3 / Roll 320) zwijana w sekcji "Inne formaty" — dla użytkownika który chce wyjść poza swój standard
- N-up przeliczany przez LayoutOptimizer dla każdej dopasowanej sugestii — gdy preset "wizytówka 85×55" trafia na Twój arkusz B2, dostajesz sloty obliczone dla B2, nie dla zaszytej SRA3
- FitWarning (amber bubble) na kartach gdzie optymalizator wylądował na 1×1 — natychmiastowy sygnał "ten format nie zgang-uje się dobrze na Twoim arkuszu". Nowa metoda
TemplateSuggestionEngine.SuggestForContext(width, height, currentTemplate) zwraca TemplateSuggestionSet { Matched, Library, ContextSheetName, ContextBinding }
RollFed + duplex — backs wreszcie istnieją
- Strategia honoruje
Template.Duplex: 2-stronicowy PDF (front design + back design) → wszystkie itemy na rolce dostają stronę 1 z przodu i stronę 2 z tyłu. 4-stronicowy PDF → itemy cyklują pary (1+2, 3+4, 1+2…). 1-stronicowy PDF degraduje grzecznie do single-sided (nie ma sensu drukować tej samej grafiki po obu stronach). Backs mają identyczną geometrię jak fronts
- Spread + toggle przód/tył działają dla RollFed duplex — wcześniej canvas wymuszał single-side dla każdego RollFed niezależnie od duplex. Teraz blokada zostaje tylko dla rolek bez backs (jednostronnych). Nowy helper
ForceSingleSide(vm) zastępuje binary IsRollFed check
- Spread dla extreme-aspect (rolki/banery) — pierwsza wersja wpychała oba arkusze w fit-both
sheetW*2+gap × sheetH, co dla rolki 320×8000mm dawało dwie 16-px strzpy. Teraz ComputeSpreadLayout rozpoznaje extreme-aspect i: wysokie rolki — side-by-side z fit do połowy szerokości okna każda, dosunięte do góry; szerokie banery — stacked top-bottom z fit do połowy wysokości każdy, dosunięte do lewej. Bez ręcznego zoomowania
Jednostki miary mm / cale
- Settings → "Jednostki miary" — combo Metryczne (mm) / Cale (in). Nowy enum
DisplayUnits + property AppSettings.Units + parser z fallback'iem. Przechowywanie wewnętrzne pozostaje w mm; to wyłącznie warstwa prezentacji
- Singleton
DisplayUnitsService z obserwowalnym eventem Changed — UI odświeża się od razu, bez restartu aplikacji. Helpery FromMm, Suffix ("mm" / "in"), BaseTickMm (10 mm dla metryki, 0.5 in = 12.7 mm dla cali)
Linijka podglądu
- Paski na górnej i lewej krawędzi canvas pokazują współrzędne arkusza w aktywnej jednostce. Origin = lewy-górny róg arkusza (jak we wszystkich design appach), rośnie w prawo i w dół. Etykiety obróconej osi Y czytasz wzdłuż linijki
- Tick spacing dobierany automatycznie z mnożników {1, 2, 5, 10, 20, 50, 100, 200, 500, 1000} × base step tak, żeby labelowane major ticki miały ≥60 px miejsca. Na overview labelujesz co 100 mm, na zoom-in co 1 mm — bez ręcznej konfiguracji
- Origin tick (niebieski, grubszy) wyraźnie zaznacza krawędź arkusza nawet przy paneę. Chip w narożniku pokazuje aktywny suffix ("mm" / "in") żeby od razu wiedzieć w jakiej jednostce czytasz
- Rysowana poza scene cache — zmiana jednostki / zoom / pan odświeża linijkę natychmiast, bez inwalidacji cached bitmap. Wyłączona w spread mode (dwa arkusze = niejednoznaczne origin) i przy rotacji widoku (tick math zakłada osie wyrównane do canvas)
Reset wszystkiego przywraca domyślny szablon
- Po Reset → ponowny Load tego samego pliku pojawia się podgląd. Wcześniej
ResetAll zerował CurrentTemplate=null, przez co kolejny LoadCheckedFilesAsync pomijał PlanCurrentJob ("if CurrentTemplate is not null") i zostawiał użytkownika z "Wczytano N stron z M plików" oraz pustym canvas. ResetAll woła teraz TryLoadDefaultTemplate() — wraca do stanu startowego aplikacji
Build: 0 warnings / 0 errors. Testy: 123/123 zielone (było 109, +14 nowych — context-aware suggestions, RollFed duplex pairing, display units). Jeden istniejący test MultipleSourcePages_CycledRoundRobin zaktualizowany o jawne Duplex=false (wcześniej polegał na ignorowanym Duplex w RollFed).
Smart preflight, template suggestions, layout optimizer + naprawy podglądu i imposycji
Preflight v2 — content-based bleed + narrative summary
- Content-based bleed detection — nowy
PdfContentExtentWalker skanuje per-stronę bounding box wszystkich obrazów + glyphów tekstu (PdfPig), porównuje z TrimBox/BleedBox. Dwa nowe issue codes: BLEED_CONTENT_UNUSED ("deklarowany spad bez treści w obszarze bleed — białe paski po cięciu") i BLEED_CONTENT_OVERFLOWS_BLEEDBOX ("content wychodzi poza BleedBox — RIP utnie")
- Smart preflight summary panel — nad listą issues w FileInfoDialog pojawia się kolorowy banner (4 mood themes: Passing / InfoOnly / WarningsOnly / Critical) z jednolinjowym headline'em i top-5 priorytetowymi akcjami imperatywnymi ("Spad zerowy na 4 stronach — w źródle ustaw bleed ≥ 3 mm"). Pure-function
PreflightSummaryGenerator + 22 nowe klucze HF.PV.Action.* w PL/EN
Template suggestions z wymiarów PDF
- Tools → "Sugeruj szablon z PDF…" —
TemplateSuggestionEngine z biblioteką 25 presetów (wizytówki, pocztówki, ulotki, plakaty, naklejki rolka z OPOS, hangtagi, CD/DVD, bilety). Euclidean dimensional matching z auto-rotacją, threshold 25mm. Dialog z selectable cards (confidence %, sheet + N-up summary), klik "Zastosuj" pcha gotowy Template do MainWindowViewModel
- Auto-rejestracja "Roll 320" paper preset — 320×1000mm dla naklejek/etykiet rolkowych.
EnsureAuxiliaryPaperPresets idempotentne, woła się raz w composition root
Layout optimizer (auto N-up)
- Przycisk "Optymalizuj N-up" w karcie Layout edytora szablonów.
LayoutOptimizer.Optimize próbuje obu orientacji item (0° i 90°), liczy max sloty przy aktualnych margin/gutter/bleed, tie-break na wyższą sheet utilization. Bez rotacji gdy remis (nie flipuje gratuicznie orientacji)
- Status banner po kliku: "Optymalny układ: 6 → 21 sztuk na arkuszu (3×7)" lub "Aktualny układ (12 sztuk) jest już optymalny". Hint o rotacji item jeśli optymalna orientacja wymaga obrotu — nie flipuje Trim w tle, żeby nie zaskoczyć operatora
Podgląd — Trim/Bleed guides + manual update check
- Checkbox "Trim/Bleed" w toolbarze podglądu — per-placement cyjan przerywany = TrimBox (linia cięcia), magenta kropkowany = BleedBox (do gdzie ma sięgać treść). Wizualne potwierdzenie content-bleed preflight checks. Domyślnie off (opt-in dla weryfikacji)
- Help → "Sprawdź aktualizacje…" — manual entry point obok cichego startup checka. Nowa
UpdateService.ManualCheckAsync zwraca tri-state result (UpdateAvailable / AlreadyLatest / Failed) — user zawsze dostaje explicit feedback dialog "Masz najnowszą wersję (1.2.3)" zamiast cichego nulla
Imposition — duplex pairing dla ganging
- GangingStrategy: 2-stronicowy PDF + 12-up + duplex → 1 arkusz z 12 frontami na stronie A i 12 tyłami na stronie B (było: 2 osobne arkusze jednostronne). 4-stronicowy PDF → 2 arkusze pairowane (1+2), (3+4). Nieparzysta liczba stron: ostatni arkusz ma front + pusty back.
Duplex=false zachowuje starą semantykę (jeden arkusz per strona). Grid offsets pre-computed raz — front i back dzielą identyczną siatkę
Podgląd — naprawy UX
- Licznik arkuszy 1-based — pokazuje "Arkusz 1/2" zamiast wprowadzającego w błąd "0/2". Nowy
CurrentSheetNumber => CurrentSheetIndex + 1 w PreviewViewModel
- Toggle przód/tył działa w spread view — wcześniej w trybie rozkładówki klik na "Tył" nie zmieniał nic wizualnie (oba boki widać równocześnie). Teraz auto-wyłącza spread i pokazuje stronę przeciwną
- Biały arkusz po odznaczeniu rozkładówki — gdy
ShowBackSide=true a BackPlacements puste (single-sided ganging), VM auto-wraca do front. Bez tego user wpadał na biały placeholder
- CMYK bars na środku górnej krawędzi arkusza — pojedynczy pasek wewnątrz papieru (było: per-placement powyżej arkusza, klipowane na małych sheetach). 40% szerokości arkusza, cap 160px, ~6px wysokości. Niezależny toggle "Paski CMYK" w toolbarze
- Overview placeholder threshold 0.5 → 0.25 — wcześniej jeden tick scrolla z 50% zoomu (0.5÷1.25 = 0.4) niespodziewanie wpadał w tryb "str. 1" placeholder. Teraz overview kicks in dopiero przy genuinie miniaturowym arkuszu
Build: 0 warnings / 0 errors. Testy: 109/109 zielone (było 66 przed sesją, +43 nowe — content-bleed, summary generator, suggestion engine, layout optimizer, ganging duplex).
Preview pipeline v3 — koniec eksplozji RAM na rolkach A0/A1, render proporcjonalny do ekranu (Fiery-style)
Eksplozja pamięci 3,5 GB → ~70 MB przy rolkach 1000+ slotów
- Memory-budget LRU zastępuje count-based —
PdfPreviewRenderer trzyma się teraz twardego budżetu 512 MB (settable przez MaxMemoryBytes) zamiast liczby wpisów (poprzednio 80). Pojedyncze duże bitmapy A0/A1 nie mogą już rozdąć cache do wielu GB. Eviction: snapshot + sort po LastAccessTick + drop do limitu
- Scale-clamping per bitmap (max 64 MB) — przed alokacją sprawdzamy naturalne wymiary strony (cheap probe Docnet, bez rasteryzacji) i rozwiązujemy s = √(cap / (w·h·4)) żeby cap'nąć efektywną skalę. A0 portrait nigdy nie zaalokuje 1.16 GB jak przy zoom 6×
- Display-pixel-aware rendering — root cause fix dla 3.5 GB. Nowy overload
RequestPageAsync(pdf, page, zoom, displayPixelWidth) liczy scale z rzeczywistego rozmiaru placementu na ekranie, nie z vm.Zoom. Dla 50mm naklejki przy 1600% zoom na 8.7m rolce: zamiast 1446×936 px bitmap (~5 MB) renderujemy 121×78 px (~38 KB) — ~130× redukcja przy zerowej utracie wizualnej. SharpnessMargin 2× zapewnia ostrość przy lekkim zoom in
- Niskie buckety w
ScaleBuckets — dodane 0.5 / 0.75 / 1.0 obok istniejących 1.5 / 2.0 / 3.0 / 4.5 / 6.0. Display-aware caller dostaje skale proporcjonalne do faktycznego demand'u
- Cancellation tokens per cache key —
_pendingCts zastępuje proste _pending. Nowy zoom na tej samej stronie cancel-uje wcześniejsze CTS prefix-sweep'em; render-task po WaitAsync(token) bail-outuje bez dotykania Docnet jeśli scale stała się stale. Eliminuje "render noise" przy szybkim zoomowaniu
Vector overview mode (Fiery Impose-style)
- Przy
vm.Zoom < 0.5 canvas pomija TryGetPageBitmap i rysuje vector placeholder z numerem strony zamiast rasteryzowanego PDF. Mirror tego co robi Fiery Impose / Acrobat na overview zoom — przy fit-to-window użytkownik sprawdza layout, nie content, więc rasteryzacja to czysty koszt bez informacji
- Zero background renderów w overview tier — żaden Docnet open, żaden cache slot. Ogromna oszczędność CPU/RAM przy przelatywaniu przez wielostronicowe joby
- Eyedropper wyłączony w overview (nie ma bitmapy do sample), tooltip hit-area zachowany. Centered numer strony zastępuje corner label przy małych rozmiarach
Roll-aware sheet layout — koniec 22px słupków
- Aspect ratio > 4:1 → fit po krótszym wymiarze. Rolka 320×8692mm pod fit-both dawała scale 0.069 → sheet rysował się jako 22px wąski słupek w 600px oknie. Teraz scale 2.06 → sheet wypełnia szerokość okna (~660px), długość przelewa się pionowo, user pan-uje/scroll-uje. Działa też dla horizontal rolek/banerów (fit po wysokości + align-left)
- Align-to-start zamiast center na długiej osi — pionowa rolka startuje u góry, pozioma od lewej. User widzi początek rolki, nie tiny chunk po środku
- Standardowe formaty (A4, A3, B1, kwadrat) niezmienione — fit-both + center jak dotąd. Threshold 4:1 jest gap'em między A-series (1.41:1) a rolkami (typowo 10:1+)
- Helper
ComputeSheetLayout zastępuje 3 zduplikowane bloki fit-scale + center calc w canvas
RollFed wymusza single-sheet (spread nie ma sensu dla rolki)
- "Rozkładówka" ignorowana dla RollFed binding — spread view (front+back obok siebie) to booklet concept. Dla ciągłej rolki dawałby już-wąski strip skompresowany jeszcze bardziej. Canvas wymusza
DrawSingleSheet niezależnie od vm.ShowSpread
- Scene cache działa dla RollFed nawet gdy spread toggle on —
effectiveSpread trafia do SceneSnapshot i cacheEligible check, więc no-op toggle nie inwaliduje cache
Architektura — refactor i porządki
GetOrProbePageBox — zunifikowany Docnet probe natywnych wymiarów strony z cache w _pageDimensions. Używany przez ClampScaleForMemory i ComputeDisplayScale (DRY)
StoreInCache serializowany przez _cacheLock — eliminuje race przy concurrent inserts (TryHitCache reads zostają lock-free). Throughput nie cierpi bo inserts są throttlowane przez MaxConcurrentRenders (2-4)
PreviewViewModel.TryGetPageBitmap ma nowy opcjonalny param displayPixelWidth = 0 — back-compat z istniejącymi callerami, nowa display-aware ścieżka aktywuje się przy > 0
- Build: 0 warnings / 0 errors, testy 66/66 zielone
Edytor szablonów — UX po pierwszych testach 1.2: walidacja, persistence, polskie komunikaty
Edytor szablonów — koniec utraty stanu i niejasnych błędów
- Stan edytora przeżywa zamknięcie dialogu —
TemplateEditorViewModel przeniesiony z Transient do Singleton w DI. Wpisane wartości pozostają między kolejnymi otwarciami menedżera szablonów w tej samej sesji aplikacji. Wcześniej każde otwarcie dawało świeży VM z domyślnymi wartościami — wszystko co wpisałeś przepadało jeśli dialog się zamknął
- Walidacja blokuje zamknięcie dialogu z niepoprawnym szablonem — kliknięcie Użyj szablonu najpierw waliduje. Gdy są błędy, dialog NIE zamyka się, banner z listą błędów pojawia się u góry edytora, użytkownik widzi co poprawić bez utraty żadnych wartości. Wcześniej dialog zamykał się cicho, a błąd wybuchał dopiero w MainWindow podczas planowania
- Czerwony banner z błędami nad nagłówkiem szablonu, każdy błąd na osobnej linii. Banner znika automatycznie po naprawieniu wszystkich błędów (kliknięcie OK rewaliduje), również po wczytaniu nowego szablonu z dysku lub presetu
- Komunikaty walidacji po polsku — wszystkie błędy w
Template.Validate() i RollFedStrategy przetłumaczone. Zamiast "Sheet dimensions must be positive" jest "Wymiary arkusza muszą być dodatnie"; "Roll usable width X cannot fit item Y" → "Użyteczna szerokość rolki Xmm nie mieści itemu Ymm"; itd.
- Auto-generowanie ID szablonu — gdy pole ID jest puste,
Validate() generuje GUID-based zamiast rzucać "Template Id is required". Pole dalej edytowalne — można nadpisać czytelną nazwą
- Edytor startuje z poprawnymi defaultami — VM inicjalizuje się
MakeBlankTemplate() (SRA3 landscape, A4 trim) zamiast pustym new Template(). Koniec kaskady błędów "Sheet/Trim must be positive" przy pierwszym otwarciu
- Mniej duplikatów w komunikatach — chained checki ("roll usable width -10mm cannot fit item 0mm") pomijane gdy bazowe wartości są zerowe. Wcześniej dostawałeś 3 echa tego samego problemu
Roll length — przełącznik split / continuous (jak Caldera, Onyx)
- Checkbox "Podziel na segmenty" + osobne pole długości segmentu zastąpiło anty-wzorzec "0 = bez limitu". UI dychotomia matches branżowy standard — Caldera ma "Continuous" toggle, Onyx ma panel-length mode w device profile, Flexi/Ergosoft to samo. Toggle off = jeden ciągły output PDF; toggle on = aktywny numeryk z domyślnym 1000mm
- Per-section enable toggles w sekcji Rolka i Nakładka / Logo — checkbox Włącz przy nagłówku, inputy są wyszarzone gdy wyłączone. Walidacja respektuje flagę: standardowy sheet-fit check pomijany gdy roll active, overlay walidowany tylko gdy enabled. Koniec konfliktów typu "RollFed binding wyklucza saddle stitch validation"
- Nowy preset: "Naklejki 50×50 — rolka 320mm" — RollFed binding, 1000 sztuk, 6 sztuk/rząd × 167 rzędów, gap 2mm, Summa OPOS markers (3mm, offset 5mm). Klikasz preset → masz gotowy szablon pod produkcję naklejek na rolce
UI — drobne poprawki
- Auto-fill szerokości i wysokości arkusza po wybraniu presetu (SRA3 → 450×320 itd.) — wcześniej trzeba było ręcznie wpisać. Pod spodem: zamiana referencji
Template.Sheet na nową instancję SheetSize żeby Avalonia odświeżyła nested bindings (mutacja in-place nie wystarczała, bo POCO nie ma INotifyPropertyChanged)
- Sekcja "Rozmiar arkusza" uproszczona — usunięto zduplikowany rząd ręcznej edycji W/H/Nazwa. Zostały: dropdown presetu + landscape, plus jedna linia Dodaj własny rozmiar z polami szerokości i wysokości (z opisami i normalną wielkością)
- Strony www (PL + EN) — index, help/pomoc, faq, privacy: wpis o roll-fed + Summa OPOS + overlay loga w hero/features, nowe pytanie FAQ "Czy obsługuje produkcję naklejek na rolce z plotterem Summa?", footer wersja 1.2.1
Architektura
RollOptions.Enabled i OverlayOptions.Enabled (default false) — bool flagi gate'ujące walidację per-sekcja niezależnie od Binding. JSON backward-compatible — stare szablony bez tych pól wczytują się z defaultami false
TemplateEditorViewModel.TryValidate() — niewybuchająca walidacja zwracająca true/false, populująca ValidationErrors kolekcję bindowaną do bannera
TemplateEditorViewModel.RollSplitIntoSegments — derived property mapująca checkbox split/continuous na MaxRollLengthMm (0 vs >0). Bez nowego pola w modelu — UI affordance nad istniejącym semantykiem
- Nowy test:
Validation_AutoGeneratesIdWhenMissing — pilnuje że pusty Id nie throw'uje. Pokrycie: 66/66 zielone
Roll-fed / print&cut — produkcja naklejek na rolce z markerami Summa OPOS
Nowa oprawa: RollFed (step-and-repeat na wstędze)
- Nowy typ oprawy
BindingType.RollFed — produkcja naklejek, etykiet i innych aplikacji rolkowych na ploterach lateksowych / solwentowych. Zamiast pojedynczego arkusza generuje segment wstęgi o szerokości rolki (Sheet.WidthMm) i wysokości obliczanej dynamicznie z liczby powtórzeń, gapów i wymiarów itemu
- Variable repeat — pole
RollOptions.RepeatCount mówi ile sztuk wyprodukować. Silnik automatycznie liczy ile mieści się w rzędzie (floor((width + gap) / (item + gap))), ile rzędów potrzeba i wypełnia ostatni rząd częściowo jeśli liczba nie dzieli się równo
- Multi-segment split — gdy
MaxRollLengthMm > 0 (np. ploter ma limit ramki / operator chce krótsze segmenty), wynik dzieli się na N osobnych SheetLayout-ów. Każdy segment ma sztywną wysokość = MaxRollLengthMm. Bez limitu = jeden segment z tight-fit do faktycznej zawartości
- Basic nesting (auto-rotation) — checkbox Pozwól obrócić w UI każe silnikowi porównać upakowanie 0° vs 90° i wybrać orientację która zmieści więcej itemów w rzędzie. Nie zaawansowany irregular nesting (to backlog), ale dla prostokątnych naklejek bardzo skuteczne
- Single-sided (front-only) — rolki nie duplexuje się;
BackPlacements zawsze pusty
Markery plotera Summa OPOS / OPOS-XY
- Nowy enum
CutterMarkType w MarksOptions: None, SummaOPOS, SummaOPOSXY. Cztery solid-black kwadraty (default 3mm) w narożnikach bounding-box-u wszystkich non-blank placementów, offset domyślnie 5mm od cut line — Summa wymaga min. 5–8mm clearance dla sensora optycznego
- Wariant OPOS-XY dorzuca mały label tekstowy "Sheet N" obok markera origin (BottomLeft) — sensor go ignoruje, operator widzi numer segmentu wzrokiem przy ładowaniu rolki na ploter
- Pure geometry helper
CutterMarkLayout w Imposition.Core/Marks/ — bez zależności od PdfSharp, w pełni testowalny w izolacji (10 testów jednostkowych pokrywających bbox, ignorowanie blank slotów, wybór offsetu, OPOS-XY)
- Renderer
CutterMarksRenderer wpięty w PdfComposer obok PrinterMarksRenderer. Markery rysowane raz na arkusz/segment (nie per-item) — to zgodne z workflow Summa, gdzie ploter kalibruje się do całej grupy
Overlay loga / nakładka per arkusz
- Nowy
OverlayOptions — stempluje plik PNG/JPG/PDF na każdym arkuszu wynikowym. 9 anchor pozycji (TopLeft … BottomRight), offset X/Y, max szerokość (aspect ratio zachowany), tryb Once per sheet (raz na arkusz) lub Once per item (raz na każdy placement)
- Wsparcie raster + vector — PNG/JPG przez
XImage, single-page PDF przez XPdfForm. Detekcja po rozszerzeniu pliku
- Pure geometry helper
LogoOverlayLayout — 12 testów jednostkowych dla wszystkich anchor permutacji, aspect preservation, blank ignoring, edge cases
- Renderer
LogoOverlayRenderer wpięty w PdfComposer. Brak loga = no-op (puste pole). Brak pliku na dysku = warning w logu, eksport jedzie dalej (defensywnie, żeby nie psuć batch jobów przy nieistniejącej ścieżce)
Edytor szablonów — nowe panele
- Sekcja "Rolka (RollFed)" — pola: liczba powtórzeń, odstęp X/Y, maks. długość segmentu, allow rotation
- Sekcja "Markery plotera (print&cut)" — combo typu markera, rozmiar, odsunięcie
- Sekcja "Nakładka / Logo" — file picker (PNG/JPG/PDF), combo anchor, max szerokość, offset X/Y, toggle raz na arkusz
- Combo box Typ oprawy automatycznie pokazuje nową pozycję
RollFed. Wszystkie nowe panele lokalizowane PL/EN. Pre-existing UI bez zmian
API i architektura
Template rozszerzony o trzy nowe property: Roll, Overlay (oraz pola w Marks: CutterMarks, CutterMarkSizeMm, CutterMarkOffsetMm). JSON serializacja kompatybilna wstecznie — stare szablony bez tych pól wczytują się z defaultami
Template.Validate() dla RollFed pomija standardowy check required sheet W×H ≥ N-up math (długość arkusza liczona dynamicznie). Zamiast tego sprawdza, czy item w ogóle mieści się szerokością rolki
PdfComposer przyjmuje teraz dodatkowo CutterMarksRenderer i LogoOverlayRenderer w konstruktorze (DI). Wywoływane razem z istniejącym PrinterMarksRenderer w RenderSheetSide. Zarejestrowane jako singletons w CompositionRoot
- Pokrycie testami: 65/65 zielone (29 istniejących + 14 RollFed + 10 CutterMarkLayout + 12 LogoOverlayLayout)
„Run as User” — koniec zapisu do Program Files, hardening UX hot folderów
Krytyczne: aplikacja nie pisze już do Program Files
- Wszystkie dane dynamiczne przeniesione do
%APPDATA% / %LOCALAPPDATA% — wcześniej licencje, szablony i niektóre cache zapisywały się do C:\Program Files\imPRESS Studio\, co dawało UnauthorizedAccessException u użytkowników bez admina, kolizje z UAC przy aktywacji licencji oraz utratę danych przy aktualizacji aplikacji. Aplikacja działa teraz poprawnie pod zwykłym kontem Windows bez podnoszonych uprawnień
- Nowy centralny helper
AppPaths — single source of truth dla wszystkich ścieżek. Roaming (%APPDATA%\imPRESS Studio\): settings.json, hotfolders.json, templates/, presets/, licenses/, icc/ (user-imported), export-presets/, localization/. Local-only (%LOCALAPPDATA%\imPRESS Studio\): logs/, state/hotfolder.db, cache/, temp/, recovery/, runtime/spool/, license.stamp. Bundled assety (read-only ICC, default template) zostają w {install}/icc/ i {install}/config/ i nigdy nie są zapisywane podczas runtime'u
- Migracja 1.0.x → 1.1.1 (idempotentna, jednorazowa) — przy pierwszym starcie kopiuje stary
Program Files\imPRESS Studio\config\license.json do %APPDATA%\imPRESS Studio\licenses\license.json, kopiuje stare szablony do %APPDATA%\imPRESS Studio\templates\, przenosi poprzednie %LocalAppData%\ImpositionApp\* (logi, state, cache) do %LocalAppData%\imPRESS Studio\*. Operator nie musi ręcznie nic przenosić — wszystko działa po update'cie
- Ujednolicone nazwy katalogów — usunięto inconsistency
ImpositionApp vs imPRESS Studio w kilku miejscach (logi, ledger, dialog "Otwórz logi"). Wszędzie teraz używana jest jedna nazwa: imPRESS Studio
- User-imported ICC profiles trafiają teraz do
%APPDATA%\imPRESS Studio\icc\. Bundled profile dostarczone z instalatorem dalej w {install}/icc/ (read-only), oba katalogi merge'owane w combobox eksportu z user-priority na konflikty nazw
Hot folder UX po realnych testach produkcyjnych
- Auto-default
.work/.archive/.error — pola Folder roboczy / archiwum / błędów w dialogu edycji nie są już wymagane. Gdy puste, runner sam tworzy .work, .archive, .error jako podkatalogi folderu wejściowego (z dropką, więc filewatcher i tak ich nie matchuje). Dialog pokazuje wyliczoną wartość pod każdym blank polem: "Domyślnie zostanie utworzony: D:\HF\input\.work" — operator widzi co się stanie, zanim kliknie Zapisz
- Realtime walidacja per-pole w dialogu Dodaj/Edytuj — czerwone gwiazdki
* przy wymaganych polach (Nazwa, Wejście, Wyjście, Szablon), pod każdym polem mała czerwona etykieta z konkretnym błędem. Walidacja na każdy keystroke; przycisk Zapisz jest disabled dopóki IsValid = false. Koniec ze zbiorczym banner-em po kliknięciu Zapisz — wiesz od razu które pole jest złe
- Banner statusu licencji w managerze — gdy licencja jest nieprawidłowa lub wygasła, czerwony banner ⚠ na górze okna z treścią błędu i przyciskiem Otwórz menedżer licencji, który otwiera dialog aktywacji bez wychodzenia z managera. Po pomyślnej aktywacji banner znika i Start staje się dostępny. Wcześniej operator widział tylko warning w logu i nie wiedział czemu Start nic nie robi
- Banner odzyskania zadań po crashu — po starcie aplikacji, jeżeli runner odzyskał osierocone zadania z poprzedniej sesji (proces padł w trakcie eksportu), pojawia się niebieski banner: "Odzyskano N przerwane zadanie/zadania hot folderów po poprzednim zamknięciu aplikacji."
- Start/Restart disabled przy nieprawidłowej licencji — komendy mają
CanExecute = HasSelection && LicenseValid, więc przyciski są wyszarzone. Wcześniej kliknięcie Start przy złej licencji zapisywało wyjątek tylko do loga, bez czytelnego sygnału w UI
Hardening backendu — fail fast zamiast cichych crashy
- Hard guard clauses na każdym I/O boundary —
HotFolderRunner.EnsureFolders, FileTransitions.MoveToWork/ApplyOnSuccess/ApplyOnFailure/ReturnToInput, HotFolderJobProcessor.LoadTemplateAsync, oba watcher sources (FileSystemWatcher + polling) walidują teraz: ArgumentException.ThrowIfNullOrWhiteSpace, Path.IsPathFullyQualified, brak invalid characters. Jeden z testów zlapal Directory.CreateDirectory("") mimo walidacji UI — backend nie ufa już upstream'owi i sam fail-fastuje z czytelnym komunikatem
- Walidator hot folderów rozluźniony dla dotted defaults — wcześniejsza zasada "work/archive/error nie mogą leżeć wewnątrz input" jest dalej egzekwowana, ale teraz akceptuje single-level subdir o nazwie
.work, .archive, .error jako runner-managed exception (i tak są wykluczone z FSW przez nazwę z kropką + explicit check w runner)
- Atomic write i rotacja uszkodzonych configów —
AppSettings.Save() używa teraz .tmp + File.Move, więc crash w trakcie zapisu nie zostawia półpustego pliku settings.json. AppSettings.Load() przy JsonException rotuje plik do .broken-yyyyMMdd-HHmmss i wraca z defaultami zamiast crashować. HotFolderConfigStore już to miał — teraz spójna polityka w całej aplikacji
- Startup summary log — pierwsza linia w logu pokazuje teraz wszystkie kluczowe ścieżki: roaming, local, logs, licenses, state, hotfolders config. Diagnostyka problemów u klienta jest natychmiastowa
- Mniej szumu w logu — komunikat "Hot folder config not found at ...; starting empty." loguje się teraz tylko raz per process. Wcześniej manager VM polluował logi tym wpisem co 1,5 sekundy (interval timera odświeżania). Reszta typowo śmieciowych komunikatów też przejrzana
Drobne
HotFolderStatusSnapshot rozszerzony o pole RecoveredOrphansAtStart — manager VM agreguje tę liczbę między runnerami żeby renderować banner odzyskania
HotFolderManagerViewModel bierze teraz LicenseValidator jako dependency, sprawdza licencję przy InitializeAsync i po zamknięciu ActivationDialog
- Wersja
1.1.0 → 1.1.1 (patch — runtime/UX hardening, brak nowych funkcji ani breaking changes)
Uwagi przy aktualizacji
- Operator nic nie musi robić — migracja licencji i szablonów odbywa się automatycznie przy pierwszym uruchomieniu 1.1.1. Po update obie ścieżki (stara i nowa) chwilowo współistnieją; nowa wygrywa, stara jest opcjonalnie usuwana (failure OK gdy brak admina). Po następnej deinstalacji 1.0.x zostawiona kopia w Program Files znika
- Istniejące hot foldery działają bez zmian — config
hotfolders.json przechowuje tylko ścieżki które były wpisane wcześniej; runner przy starcie wypełnia blank pola (.work/.archive/.error) defaultami. Konfiguracje sprzed 1.1.1 z explicit ścieżkami nie są dotykane
- Pliki w starych lokalizacjach (
%LocalAppData%\ImpositionApp\logs itd.) nie są kasowane — operator może je sprawdzić i ręcznie usunąć po zweryfikowaniu że nowa lokalizacja działa
„Hot Folders” — automatyczna impozycja w trybie produkcyjnym
Nowa funkcja flagowa: hot foldery
- Pełny system hot folderów dla drukarni produkcyjnych — wskazujesz folder wejściowy, aplikacja sama wykrywa wrzucone pliki PDF, nakłada wybrany szablon, eksportuje gotowy arkusz do folderu wyjściowego i archiwizuje oryginał. Wszystko w tle, bez interakcji użytkownika. Idealne pod workflow „operator wrzuca PDF z DTP, ripper bierze gotowy arkusz”
- Wiele hotfolderów jednocześnie — każdy z własnym szablonem (np. Saddle A4 → 4-up, Wizytówki gang-run, Broszura A5). Każdy runner jest izolowany — błąd na jednym folderze nie zatrzymuje pozostałych
- Wielowarstwowa detekcja zakończenia kopiowania (
FileStabilityProbe) — N kolejnych pomiarów rozmiaru + LastWriteTimeUtc + próba otwarcia z FileShare.None. Eliminuje race condition gdy kopiowanie 200 MB PDF przez SMB jeszcze trwa, a FileSystemWatcher już zgłosił Created. Tolerancja na Defendera trzymającego exclusive lock na 2-5 sekund po zakończeniu kopiowania
- Polling fallback dla SMB/DFS — gdy
FileSystemWatcher kłamie na share'ach sieciowych, drugi mechanizm robi snapshot diff folderu co N sekund. Oba źródła aktywne równolegle, deduplikator usuwa duplikaty
- Recovery po crashu — gdy aplikacja padnie w trakcie eksportu, ledger SQLite trzyma rekord
reserved; przy następnym starcie pliki w .work wracają do input i są przetwarzane od nowa. Gwarancja zero-loss
- Ledger SQLite w
%LocalAppData%\ImpositionApp\state\hotfolder.db z trybem WAL — historia każdego joba (kto, kiedy, ile prób, czy sukces, output path). Auto-prune wpisów starszych niż 30 dni
- Anty-duplikat oparty na fingerprincie — SHA-256 z pierwszego 1 MB pliku + rozmiar + mtime. Re-export tego samego pliku po edycji = inny fingerprint = nowy job. Ten sam plik wrzucony dwa razy bez zmian = pominięty
- Retry przez Polly v8 — exponential backoff z jitter, osobne polityki dla I/O (5×, 200ms base), eksportu (3×, 2s base) i ledgera (8×, 50ms — chroni przed
SQLITE_BUSY). Deterministyczne błędy preflight nie są retry'owane
- Globalny limit procesów Ghostscript (
GhostscriptThrottle z SemaphoreSlim) — bez tego N hotfolderów × M zadań × ~500 MB RAM gs zabijało maszynę. Domyślnie max 2 procesy gs jednocześnie, konfigurowalne
- Walidacja licencji per job + okresowa — host sprawdza licencję przy starcie i co 60 minut w tle. Każdy export waliduje licencję jeszcze raz tuż przed startem. Wygaśnięcie w trakcie 24/7 pracy zatrzyma runnery z czytelnym komunikatem
Interfejs zarządzania
- Nowa pozycja menu: Narzędzia → Hot foldery… (Tools → Hot Folders w EN). Świadomie nie dodajemy przycisku do głównego paska — to funkcja produkcyjna, nie codzienna akcja obok Eksportuj
- Okno managera z listą skonfigurowanych hot folderów: nazwa, status (Bezczynny / Uruchamianie / Działa / Zatrzymany / Błąd), folder wejściowy/wyjściowy, szablon, licznik OK/błędów/kolejki. Auto-refresh co 1,5 sekundy przez
DispatcherTimer
- Akcje na liście: Dodaj, Edytuj, Usuń, Start, Stop, Restart, Otwórz wejście, Otwórz wyjście, Otwórz logi (skrót do
%LocalAppData%\ImpositionApp\logs)
- Dialog edycji z folder/file pickerami dla wszystkich ścieżek (input / output / archive / error / work / template / Ghostscript). Sekcje: Podstawowe, Foldery, Szablon i filtry, Działanie, Eksport. Walidacja na Save z banner-em zawierającym listę bullet-błędów (puste pola, ścieżki nieabsolutne, nieistniejący szablon, foldery nakładające się, brak gs przy włączonym PDF/X)
- Banner ostatniego błędu — gdy zaznaczony hot folder ma
LastError, pojawia się czerwony pasek z treścią. Operator widzi co się stało bez nurkowania w logi
- Pełna lokalizacja PL/EN — wszystkie etykiety, statusy, komunikaty walidacji, opcje enum (Po sukcesie: Nic / Archiwizuj / Usuń) tłumaczone
CLI
- Komendy
hotfolder run/list/start/stop/reload — imPRESS Studio.exe hotfolder run uruchamia daemon w foreground (Ctrl+C zatrzymuje), gotowe pod uruchomienie jako Windows Service w przyszłej wersji. hotfolder list pokazuje status wszystkich folderów, start/stop przyjmują GUID hot folderu, reload wczytuje hotfolders.json ponownie i uzgadnia stan (start nowych, stop usuniętych, restart zmienionych)
Konfiguracja i przechowywanie
- Plik konfiguracji
%APPDATA%\imPRESS Studio\hotfolders.json — atomicznie zapisywany przez .tmp + File.Move. Edytowalny ręcznie, walidowany przy każdym wczytaniu. Złamana składnia rotuje plik do .broken-{timestamp} zamiast pożerać konfigurację
- Walidator wymusza absolutne ścieżki, niepustość pól wymaganych, istnienie szablonu na dysku i — krytyczne — odrzuca konfigurację gdzie
workPath/archivePath/errorPath/outputPath leży wewnątrz inputPath (klasyczny błąd początkujących powodujący nieskończoną pętlę: aplikacja przerabia własne wyjścia)
- Long path support — manifest aplikacji deklaruje
longPathAware=true i perMonitorV2 DPI awareness. Hot foldery na głębokich mapowanych dyskach nie są już ograniczone do 260 znaków
Architektura i zależności
- Nowy moduł
Imposition.HotFolder — Configuration / Watching / Queueing / State / Processing / Hosting / Diagnostics / DependencyInjection. Zero powiązań z UI, w pełni używalne z CLI, gotowe pod future REST API / Windows Service
- Dodane pakiety NuGet:
Microsoft.Data.Sqlite 8.0.10 (ledger), Polly + Polly.Core 8.4.2 (retry/backoff), Microsoft.Extensions.Hosting 8.0.0 (IHostedService dla cyklu życia hosta)
HotFolderHost implementuje IHostedService — gotowy pod hostowanie w generic host. Startowany z Program.Main przed Avalonią (GUI) lub jako foreground daemon (CLI). Drugi tryb jest fundamentem pod uruchomienie jako Windows Service w przyszłej wersji
- Wersja aplikacji
1.0.8 → 1.1.0 (minor bump zgodnie z SemVer — nowa, kompatybilna funkcjonalność)
Odporność produkcyjna
- Atomowa state machine plików:
input → .work/{jobId}__file.pdf → output + archive (lub error). File.Move na NTFS atomowy w obrębie woluminu; po przeniesieniu do .work plik jest niewidzialny dla FileSystemWatcher, co eliminuje duplikaty z innych instancji aplikacji
- Backoff exponential z jitter dla wszystkich operacji I/O — nie zalewamy NAS-a powtórzonymi requestami w czasie krótkiej awarii sieci
- Top-level try/catch w każdej pętli
Task.Run — żaden wyjątek z producenta/konsumenta/poller'a/recovery loopu nie wykończy procesu w ciszy
- Recreate watchera po
InternalBufferOverflowException + automatyczny full rescan folderu — bez tego po overflow gubilibyśmy eventy dla brakujących plików na zawsze. Dodatkowy auto-recovery loop po dowolnym FSW.Error z exponential backoff
- Channel<T> z bounded capacity i
FullMode=Wait dla kolejki jobów — jobów nie tracimy, ale producent czeka asynchronicznie gdy konsument utknie. Pod skrajnym DDoS-em (10000 plików nagle) nie wybuchamy z OOM
Uwagi przy aktualizacji
- Bez breaking changes — istniejący workflow (Eksportuj, CLI
impose, szablony, licencje) działa identycznie. Hot foldery to dodatek, włącza go się przez menu
- Hot foldery wymagają ważnej licencji — host nie wystartuje runnerów gdy licencja jest niepoprawna lub wygasła. To samo dotyczy
hotfolder run z CLI
- Pierwsze uruchomienie tworzy
%APPDATA%\imPRESS Studio\hotfolders.json oraz %LocalAppData%\ImpositionApp\state\hotfolder.db przy pierwszym save w UI — pliki nie powstają same z siebie przy update
„Color & Clock” — zarządzanie ICC + ochrona przed cofnięciem zegara
Nowe funkcje
- Pełne zarządzanie profilami ICC w oknie eksportu — pole tekstowe zastąpione listą rozwijaną z auto-skanowaniem folderu
icc/ w katalogu instalacji. Pozycja (brak) dla eksportu bez konwersji. Przycisk Wczytaj… otwiera systemowy file picker (filtr *.icc / *.icm), wybrany profil jest kopiowany do icc/ i automatycznie wybrany. Przycisk Folder otwiera katalog w Eksploratorze do ręcznych dodatków. Pod listą podpowiedź pokazuje liczbę dostępnych profili i ścieżkę
- Ochrona licencji przed cofnięciem zegara — nowy
LicenseClockGuard przy każdej udanej walidacji zapisuje HMAC-podpisany znacznik czasu w %LocalAppData%\imPRESS Studio\license.stamp. Klucz HMAC pochodzi z podpisu licencji (więc znacznik jest licencja-specific i nie da się go skopiować z innej maszyny). Przy następnej walidacji jeśli zegar systemowy cofnął się o więcej niż 2h przed zapisaną wartość — eksport zablokowany z komunikatem „Wykryto cofnięcie zegara systemowego”. Tolerancja 2h na driftu NTP / DST. Edycja pliku .stamp wykrywana przez weryfikację HMAC i traktowana jako tampering
Zmiany
- Email kontaktowy w oknie O programie zaktualizowany na
impress_studio@proton.me (poprzednio wojciech.bujacz@hotmail.com)
„License Hardening” — szczelny gate eksportu, nowy fingerprint i tolerancja sprzętowa
Krytyczne poprawki
- Eksport bez licencji — załatany — kliknięcie Eksportuj bez ważnej licencji generowało plik PDF mimo wszystko. Teraz
MainWindowViewModel.ExportAsync twardo waliduje licencję z dysku na każde wywołanie (nie tylko cached App.LicenseStatus z momentu startu) — zamyka okno, w którym ktoś usuwał plik mid-session albo licencja wygasała w trakcie pracy. Identyczny gate w trybie CLI (impose): exit code 2 + komunikat z hintem do license activate
Nowy fingerprint sprzętowy
- Hostname usunięty — nazwa komputera była nietrwałym identyfikatorem (zmiana 5-sekundowa, świetnie obchodzona). Już nie ma żadnego udziału w fingerprint
- 3 niezależne komponenty: SHA-256 z (a) MAC adresu pierwszego fizycznego NIC z filtrem na virtuals (VMware/Hyper-V/Bluetooth/loopback są pomijane), (b) numeru seryjnego dysku systemowego (
InterfaceType ≠ USB AND MediaType LIKE 'Fixed%' — pendrive się nie liczy), (c) UUID systemowego z SMBIOS (Win32_ComputerSystemProduct)
- Tolerancja 2 z 3 — licencja waliduje się gdy ≥ 2 z 3 komponentów się zgadza. Wymiana karty sieciowej, dysku albo czyszczenie BIOS-a — pojedyncza zmiana nie wywala licencji. Dwie zmiany jednocześnie (
1/3) → komunikat „licencja jest przypisana do innego komputera (1/3 elementow zgodnych — wymagana ponowna aktywacja)"
- Backward compat — stare licencje pre-1.0.7 z pojedynczym
MachineHash nadal walidują się normalnie przez fallback na composite. Nikt nie traci dostępu
Narzędzia wydawcy
Uwagi dla wydawcy
- Po pierwszym
license keygen wklej zawartość license_public.xml do LicenseValidator.PublicKeyXml i przebuduj. Klucz prywatny nigdy nie idzie z aplikacją
„Progressive Zoom” — natychmiastowy podgląd przy powiększaniu
Wydajność podglądu
- Progressive load (jak Google Maps) — gdy użytkownik powiększa stronę i nowa skala jest jeszcze rasteryzowana w tle, canvas natychmiast pokazuje najlepszy wcześniej zcache'owany bitmap (przeskalowany do nowego rozmiaru). Wynik jest chwilowo miękki, ale widoczny od razu — ostry render dochodzi po 0,5–2s zamiast pustego placeholdera
- Coarsene scale buckets — zamiast 19 poziomów rozdzielczości (skok co 0,25) tylko 5 dyskretnych poziomów:
1.5 / 2.0 / 3.0 / 4.5 / 6.0×. Wiele kroków zoomu wpada w ten sam bucket, znacznie redukując liczbę pełnych re-rasteryzacji PDF-a
- Cancel-na-zoom-spam — gdy użytkownik szybko zoomuje 1×→2×→3×→4×, stare requesty kończą się w tle ale nie odświeżają już canvasa. Bez tego każda kropla scrolla wywoływała pełny repaint na pośrednim, już nieaktualnym poziomie
- Filter cache po referencji bitmapy — cache filtra kanałów CMYK + overprint trzyma teraz klucz na referencji źródłowego bitmapu, nie indeksie strony. Eliminuje subtelny stale-bitmap bug przy zmianie skali z aktywnym filtrem
Uwagi techniczne
- PDFium/Docnet rasteryzuje per-stronę na CPU — to jest faktyczne wąskie gardło (przy A4 6× to ~18 megapikseli per strona). Hardware nie pomoże, dlatego optymalizacja wchodzi w warstwę pipeline'u rasteryzacji i schedulowania, nie renderingu Skii (która już używa GPU pod spodem). Plik 100 MB i tak będzie wolniejszy niż 11 MB — ale teraz nigdy nie zobaczysz pustego ekranu, tylko płynne dochodzenie do ostrości
„Ink Inspector” — separacja kanałów CMYK + próbnik koloru
Nowe funkcje
- Toggle kanałów CMYK — cztery checkboxy w pasku opcji podglądu (C / M / Y / K). Wyłączenie któregokolwiek zdejmuje wybrany ink z arkusza, pozwalając obejrzeć separację. Implementacja przez konwersję RGB→CMYK→RGB per pixel z zerowaniem wybranego kanału. Wynik cachowany per (strona, maska kanałów, overprint), więc przełączanie jest natychmiastowe
- Próbnik koloru (eyedropper) — pływający panel w prawym dolnym rogu canvasa pokazuje pod kursorem: kwadrat z kolorem, wartości
R G B (0-255) oraz C M Y K (0-100%). Pomiar bierze piksel z surowego renderu, niezależnie od aktywnego filtra kanałów
Zmiany
- Pasek opcji podglądu poszerzony o sekcję Kanały: z separatorem od dotychczasowych togglów (Spread / Marks / Creep / Overprint)
- Litery C/M/Y/K w checkboxach kolorowane zgodnie z kanałem (cyan/magenta/yellow/black) — wizualna mnemonika
Uwagi
- Symulacja, nie prawdziwa separacja — Docnet/PDFium daje composite RGB, nie ma sposobu odzyskać oryginalne plates bez ponownego przepuszczenia PDF-a przez Ghostscript z urządzeniem
tiffsep. Filtr per-pixel daje plausible „pokaż mi tylko cyjan" wystarczająco wiernie do proofingu wzrokowego — do akceptacji prepress użyj eksportu PDF/X i zewnętrznego RIP-a
„Adaptive Preview” — szybszy podgląd dużych PDF-ów
Nowe funkcje
- Równoległa rasteryzacja stron — silnik podglądu (
PdfPreviewRenderer) używa puli wątków ograniczonej do Math.Min(4, ProcessorCount-1) przez SemaphoreSlim. Wcześniej każda strona renderowała się sekwencyjnie; teraz na 4-rdzeniowym CPU 4 strony liczą się jednocześnie
- Pre-rendering sąsiednich arkuszy — przy zmianie aktualnego arkusza w tle ładują się strony arkuszy
−1, +1, +2. Nawigacja strzałkami / kliknięciem miniatury jest natychmiastowa zamiast czekania ~sekunda na każdy nowy arkusz
- Kwantyzacja zoomu (cache buckets) — skala renderu zaokrąglana do siatki 0,25× i ograniczana do max 6×. Zoom 1,01× → 1,02× nie wywołuje już ponownej rasteryzacji, bo trafia w ten sam bucket cache
- LRU cache z limitem 80 bitmap — przy przekroczeniu limitu pamięci cache wycina 10% najstarszych wpisów. Wcześniej cache rósł nieograniczenie i zjadał kilkaset MB przy długich sesjach
Zmiany
- Avalonia 11 / Skia już używa GPU (Direct3D 11 / OpenGL na Windows) — nie wprowadzono dodatkowej warstwy OpenGL, bo wąskim gardłem nie był rendering canvasa, lecz CPU-bound rasteryzacja PDF przez Docnet/PDFium. Optymalizacje skupione tam, gdzie liczy się czas
RenderAndCache nie blokuje już Task.Run wątku w nieskończoność — semafor gwarantuje, że szybki tryb prefetch nie zagłodzi UI
Poprawki
- Strict preflight + dialog raportu — gdy dostępny jest interaktywny dialog raportu (tryb UI),
StrictPreflight nie wyrzuca już wyjątku przed pokazaniem raportu. Użytkownik widzi listę 5 ostrzeżeń i sam decyduje. CLI bez callbacka nadal honoruje strict
- Race condition w PreflightReportDialog — dialog tworzony jest teraz przez
Dispatcher.UIThread.InvokeAsync (pipeline wywołuje callback z wątku roboczego)
- installer.iss — guard
#if !DirExists() z czytelnym komunikatem zamiast cryptycznego „No files found" gdy katalog publish/ nie istnieje
„Print-Ready” — PDF/X-1a, raport preflight i numeracja w podglądzie
Nowe funkcje
- Eksport PDF/X-1a:2001 — obok PDF/X-4 dostępny jest teraz starszy standard PDF/X-1a wymagany przez wiele drukarni offsetowych. PDF 1.4, tylko CMYK, bez przezroczystości. Wybór standardu z listy rozwijanej w oknie eksportu (Brak / X-1a / X-4)
- Raport preflight przed eksportem — gdy walidacja źródłowego PDF-u znajdzie ostrzeżenia (RGB-only zamiast CMYK, brakujący profil ICC, transparencja w trybie X-1a, zaszyfrowany plik, niezgodny rozmiar trim, PDF wyższej wersji niż docelowy standard), aplikacja pokazuje czytelny dialog z listą znalezisk pogrupowanych po wadze (błąd / ostrzeżenie / info). Użytkownik może kontynuować lub anulować
- Numerowanie arkuszy widoczne na podglądzie — wcześniej numer arkusza był stemplowany dopiero w eksportowanym PDF. Teraz nakładka pojawia się też na ImpositionCanvas w czasie rzeczywistym — gdy zmieniasz pozycję lub format w oknie eksportu, podgląd aktualizuje się natychmiast. Renderowanie w pełni wektorowe (FormattedText), bez wpływu na FPS przy zoomie
- Rozszerzona walidacja preflight — nowe reguły:
RGB_ONLY (źródło tylko RGB), NO_ICC (obrazy bez ICC), ENCRYPTED (PDF zaszyfrowany), X1A_TRANSPARENCY, X1A_OCG, X1A_VERSION, X4_VERSION
Zmiany
- Pole Konwertuj do PDF/X-4 w oknie eksportu zastąpione listą rozwijaną Standard PDF/X
ExportOptions.ConvertToPdfX4 zachowane jako shim dla kompatybilności — pod spodem ustawia PdfXMode
- Argumenty Ghostscript dobierane automatycznie pod docelowy standard (
CompatibilityLevel=1.4 dla X-1a, 1.6 dla X-4)
ExportPipeline.RunAsync przyjmuje opcjonalny callback confirmAfterPreflight — UI pokazuje raport, CLI pomija dialog
„Numbering & Persistence” — numerowanie arkuszy i zapamiętywanie opcji eksportu
Nowe funkcje
- Numerowanie arkuszy — opcja w oknie eksportu stempluje numer arkusza na każdym wyjściowym arkuszu. Konfigurowalne: pozycja (6 wariantów: rogi i środki góra/dół), format (np.
{0} / {1}, Arkusz {0}), domyślnie Prawy dolny
- Wybierak pliku Ghostscript — przycisk
... obok pola ścieżki otwiera systemowy dialog z filtrem na gswin64c.exe / gswin32c.exe
- Instalator Inno Setup — pełny kreator z wyborem katalogu instalacji, folderu w menu Start, opcjonalnym skrótem na pulpicie. Czysta deinstalacja przez Panel Sterowania
- Auto-aktualizacja przez GitHub Releases — przy starcie aplikacja sprawdza najnowszy tag na
dnblsr-lab/imPRESS-Studio i oferuje pobranie nowszego instalatora
Poprawki
- Trwałość opcji eksportu — ścieżka do Ghostscripta, profil ICC, ustawienia preflight i zakres arkuszy są teraz zapisywane w
%APPDATA%\imPRESS Studio\settings.json i przywracane przy następnym otwarciu okna eksportu (wcześniej każde otwarcie czyściło pola)
Zmiany
- Wersjonowanie zgodne z SemVer — z
1.01 na 1.0.2 (poprzednie 1.01 traktowane jako 1.0.1)
- Velopack zastąpiony przez Inno Setup — instalator daje pełną kontrolę użytkownikowi nad miejscem instalacji i skrótami
- Okno eksportu rozszerzone o sekcję Numerowanie stron + ScrollViewer dla wygody przy mniejszych rozdzielczościach
„Polish Pass” — menu, ustawienia i gang-run
Nowe funkcje
- Pasek menu aplikacji — Plik, Edycja, Widok, Narzędzia, Ustawienia, Pomoc ze skrótami klawiaturowymi widocznymi w pozycjach menu
- Okno ustawień aplikacji — wybór języka interfejsu (polski / angielski), konfiguracja zapisywana w
%APPDATA%\imPRESS Studio\settings.json
- Infrastruktura tłumaczeń (i18n) — słowniki PL/EN, markup
{loc:Loc Key} w XAML, serwis LocalizationService z powiadamianiem o zmianie języka
- Szablony gang-run 3+ — DL Ulotka 3-up (99×210, 3×1 na SRA3), Wizytówki 6-up (90×50, 3×2), Wizytówki 8-up (85×55, 4×2), Wizytówki 12-up (85×55, 4×3) z walidacją mieszczenia na arkuszu
Zmiany
- Przycisk „O programie” przeniesiony z nagłówka do menu Pomoc — czystszy layout paska tytułowego
- Wybór języka usunięty z okna „O programie” i przeniesiony do nowego okna Ustawienia
- Wersja aplikacji podniesiona z 1.00 na 1.01 (okno „O programie” oraz zasoby)
- Pełny przegląd tekstów w UI — uzupełnione polskie znaki diakrytyczne w komunikatach statusowych, tooltipach i oknach dialogowych
„First Impress” — pierwsza oficjalna wersja produkcyjna
Nowe funkcje
- System licencjonowania — aktywacja kluczem Base64 lub plikiem
.json, powiązanie z hashem sprzętu, obsługa edycji Trial / Standard / Professional, wygasanie z 14-dniowym ostrzeżeniem
- Okno aktywacji licencji — pokazuje identyfikator maszyny z przyciskiem kopiowania, pole na klucz aktywacyjny, opcja wczytania pliku licencji
- Ikona aplikacji — nowa ikona programu (
ikona.ico) i logo (logo.png) osadzone w exe i oknach dialogowych
- CLI licencyjne — komendy
license keygen, license fingerprint, license issue, license activate, license info
- Panel informacji o pliku PDF — dialog z ikoną „i”, pełne metadane (wymiary, trim, czcionki, kolory, przezroczystości, szyfrowanie, OCG, tagowanie)
- Rebranding — zmiana nazwy z „Imposition Studio” na „imPRESS Studio” we wszystkich oknach, pliku wykonywalnym i CLI
- Rozszerzony lewy panel — z 320 do 380 px dla lepszej czytelności kart i etykiet
Zmiany
- Plik wykonywalny przemianowany z
ImpositionApp.exe na imPRESS Studio.exe
- Wszystkie okna dialogowe otrzymały spójną ikonę w tytule
- Przeorganizowany układ okna „O programie” z nowym logo
Bezpieczeństwo
- Weryfikacja licencji podpisem RSA-2048 — klucz prywatny nigdy nie trafia do aplikacji
- Hash sprzętu SHA-256 z numeru seryjnego płyty głównej, dysku i nazwy komputera
„Release Candidate” — ostatnie testy przed wydaniem 1.0
Nowe funkcje
- Multi-file loader — obsługa wielu plików PDF jednocześnie z checkboxami do selektywnego wczytania
- Scalanie plików źródłowych — zaznaczenie kilku plików łączy je w jeden dokument przed impozycją
- Zmiana kolejności plików — strzałki ▲▼ do układania listy przed scaleniem
- Info o pliku — okno z pełnymi metadanymi wybranego PDF-a
- Reset all — przycisk czyszczący projekt do ustawień początkowych
Zmiany
- Przebudowany panel plików źródłowych — lista zastąpiła pojedynczy wybór
- Przycisk „Wczytaj zaznaczone” zamiast „Wczytaj plik”
Poprawki
- Naprawiono zawieszenie przy próbie wczytania zaszyfrowanego PDF-a
- Poprawiono wyświetlanie nazwy szablonu w pasku tytułu
„Polish & Stats” — dopracowanie UI i panel statystyk
Nowe funkcje
- Panel statystyk — powierzchnia papieru, wykorzystanie, odpad, szacowanie kosztów, waga
- NumericUpDown dla ceny za arkusz i gramatury papieru — kalkulacje w czasie rzeczywistym
- Progress bary dla wykorzystania papieru i odpadu
- Karta informacji o oprawie — typ, stron na sygnaturę, spad, rynienka
- Pasek miniatur arkuszy — szybka nawigacja na dole okna podglądu
Zmiany
- Przebudowane menu nagłówka — przyciski Szablon, Opcje eksportu, Pomoc, Licencja, O programie
- Wyraźne rozdzielenie trzech paneli kolorami i liniami
„Preview Master” — interaktywny podgląd arkuszy
Nowe funkcje
- Interaktywny podgląd na
ImpositionCanvas — rendering stron na arkuszu z pełną precyzją drukarską
- Zoom względem kursora — przybliżenie kółkiem myszy skupia się na wskazywanym miejscu
- Pan (przesuwanie) — przeciąganie myszą po arkuszu
- Obrót widoku o 90° (klawisz R)
- Tryb rozkładówki — przód i tył arkusza obok siebie
- Wizualizacja pełzania (creep) — pomarańczowe linie przerywane
- Symulacja nadruku — multiply blend dla ciemnienia CMYK
- Skróty klawiaturowe — Ctrl+P, Ctrl+E, Ctrl+O, Ctrl+0, F, R, ←/→
„Print Marks & Creep”
Nowe funkcje
- Znaczniki drukarskie — linie cięcia, pasery (registration marks), paski kolorów CMYK, znaczniki bigowania
- Kompensacja pełzania dla oprawy zeszytowej — z konfiguracją grubości papieru
- Opcje falcowania — Z-fold i harmonijka z konfigurowalną liczbą paneli
- Własne rozmiary papieru — dodawanie rozmiarów poza listą predefiniowaną
Zmiany
- Rozszerzona obsługa marginesów: spad, strefa bezpieczna, rynienka, grzbiet, margines arkusza
„PDF/X-4 & Ghostscript”
Nowe funkcje
- Konwersja do PDF/X-4 przez Ghostscript — standard ISO 15930-7
- Obsługa profili ICC — ISOcoated_v2_eci i inne dostarczane w folderze
icc/
- Ścisły preflight — ostrzeżenia przerywają eksport
- Zakres arkuszy w eksporcie —
1-5, 2,4,6, kombinacje
- Tryb CLI — komenda
impose do zadań wsadowych
„Template Manager”
Nowe funkcje
- Menedżer szablonów z pełną edycją parametrów
- Import/eksport szablonów JSON — wymiana między stanowiskami
- Gotowe szablony dla typowych publikacji (broszura A5, ulotka A4, wizytówki)
- Walidacja szablonu przed uruchomieniem impozycji
„Binding Types”
Nowe funkcje
- Oprawa klejona (perfect bound) z obsługą grzbietu
- Falcowanie — wstępna implementacja Z-fold
- Sygnatury — konfigurowalne 4/8/16 stron na składkę
„Saddle Stitch MVP”
Nowe funkcje
- Pierwsza działająca impozycja — oprawa zeszytowa z układem 2×1
- Eksport PDF przez PdfSharpCore
- Drag & drop plików PDF na okno aplikacji
- Pasek statusu z informacją o stanie operacji
„Genesis” — szkielet aplikacji
Nowe funkcje
- Podstawowa architektura — Avalonia 11 + .NET 8 + MVVM
- Podział na projekty:
Imposition.Core, Imposition.Pdf, Imposition.Export, Imposition.Ui, Imposition.Utils, Imposition.App
- Wczytywanie PDF-ów przez PdfPig — analiza stron, czcionek, metadanych
- Kontener DI oparty na Microsoft.Extensions.DependencyInjection
- Logowanie Serilog z plikowym i konsolowym sinkiem
Funkcje planowane w przyszłych wersjach
Na roadmapie
- Wersja Windows Service dla hot folderów — daemon poza kontekstem zalogowanego użytkownika, autostart przy boot, zarządzanie przez SCM. Obecnie hot folder host można uruchomić z CLI (
imPRESS Studio.exe hotfolder run) jako foreground proces — Windows Service wrapper to naturalne rozszerzenie
- REST API + webhooki dla hot folderów — POST
/jobs z PDF + JSON config, webhook on completion, integracja z MIS
- Integracja JDF/JMF — komunikacja z systemami MIS/ERP, parser job ticketów dla hot folderów
- Wersja macOS i Linux (Avalonia jest cross-platform)
- Silnik preview OpenGL dla szybszego renderu dużych arkuszy
- Kolejne języki UI — niemiecki i czeski (PL/EN już dostępne)
- Więcej szablonów gang-run — etykiety, naklejki, karty lojalnościowe
- Multi-template per hot folder z regex routingiem (np.
A4_*.pdf → 4-up, A3_*.pdf → 8-up)