Import Form XObject z SVG

THotPDF.ImportSVGFormXObject parsuje SVG raz i rejestruje jeden wielokrotnego użytku PDF Form XObject, a THPDFPage.DrawSVGFormXObject umieszcza go w dowolnym rozmiarze i opcjonalnie tworzy adnotacje linków strony

Deklaracja

function ImportSVGFormXObject(const Input: TBytes): AnsiString; overload;
function ImportSVGFormXObject(
  const Input: TBytes;
  out Statistics: THPDFSVGImportStatistics
): AnsiString; overload;

procedure DrawSVGFormXObject(
  const FormName: AnsiString;
  X, Y, W, H: Single;
  AddLinks: Boolean = True
);

Profil wektorowy

Granice tekstu i malowania

Tekst obsługuje jednolite wypełnienie, warianty bold i italic, rozmiar fontu, transformacje, kotwiczenie, nieprzezroczystość i przycinanie geometryczne; malowanie tekstu gradientem kończy się błędem fail-closed, a każdy węzeł text lub tspan pozostaje niezależnie pozycjonowanym przebiegiem, a nie kompletnym silnikiem layoutu przepływu tekstu SVG

Tekst importowanego dokumentu zachowuje wybrany krój bold i italic dzięki sprawdzeniom glifów świadomym stylu i layoutowi zapasowemu, zachowuje zmierzone granice tuszu i odrzuca rzeczywiście nierozstrzygnięte glify

Tekst UTF-8 oraz szesnastkowe lub dziesiętne referencje znaków XML zachowują te same skalary Unicode na Delphi i FPC, łącznie ze skalarami uzupełniającymi reprezentowanymi przez pary zastępcze UTF-16

Samodzielne przeciążenie HPDFBuildSVGFormData bez buildera tekstu używa zmierzonych posunięć rodzin Base 14 Helvetica, Times i Courier oraz odrzuca znaki poza WinAnsi zamiast podstawiać znaki zapytania; przeciążenie z THPDFSVGTextRunBuilder przyjmuje dostarczone przez wywołującego osadzone formy tekstu i metryki

Gradienty zachowują ograniczoną aproksymację wektorowych pasm; zasoby przezroczyste wymagają PDF 1.4 i są odrzucane przez ścisły profil PDF/A-1

Style stroke

stroke-dasharray, stroke-dashoffset i stroke-miterlimit działają przez atrybuty prezentacji, osadzony CSS, style inline i dziedziczenie, łącznie z grupami i instancjami use tylko do fragmentów

Tablice dash przyjmują liczby rozdzielone przecinkami lub białymi znakami oraz obsługiwane długości; procenty używają znormalizowanej przekątnej viewportu, liczonej jako sqrt((viewWidth * viewWidth + viewHeight * viewHeight) / 2)

Tablice o nieparzystej długości powtarzają się, tworząc wzorzec o parzystej długości, każdy podpath restartuje wzorzec, a dodatnie lub ujemne offsety zawijają się wokół pełnego wzorca; none i tablice pełne zer dają stroke jednolite

Malowane dash o zerowej długości zachowują znaczniki zakończeń round lub square; zwykłe stroke jednolite, wzorce stroke gradientowego, clipy, maski i izolowane grupy nieprzezroczystości współdzielą wybrane ustawienia stroke

Domyślny limit miter to 4; wartości SVG 2 z zakresu od 0 do 1 są akceptowane i używają łączeń bevel tam, gdzie miter przekroczyłby limit, podczas gdy granice zasobów gradientu i przezroczystości zachowują ostre łączenia w ramach wybranego limitu

Renderowanie natywne używa ograniczonej geometrii dash, by zachować offsety, długości ułamkowe i tablice dłuższe niż limit pióra GDI, z adaptacyjnym spłaszczaniem krzywych i ciągłymi malowanymi łączeniami przez granice segmentów

Kalibracja dash przez pathLength pozostaje poza tym profilem; kształty łączące nietrywialną tablicę dash z pathLength kończą się błędem fail-closed, zamiast po cichu użyć nieskalibrowanych długości

Semantyka stroke podąża za modelem stroke SVG 2 w ramach opisanych poniżej budżetów parsera i renderera

Konfiguracja shapingu tekstu

Osadzony tekst SVG używa ustawień ShapingFeatures, AutoShapeArabic, AutoShapeSyriac, AutoShapeNko, AutoShapeAdlam i AutoShapeHanifiRohingya dokumentu importującego, wraz z jego wyborami skryptu i języka GSUB oraz łańcuchami zapasowymi fontów

Ustawienia te działają zarówno przy mierzeniu posunięć, jak i przy generowaniu wyglądów tekstu, bez zmieniania konfiguracji wywołującego; shaping pozostaje opt-in i wymaga fontu dostarczającego żądane glify i tabele OpenType

Każdy wygenerowany wygląd tekstu przyjmuje najwyżej 256 różnych wyborów fontów shapingu i 64 MiB skumulowanych surowych danych fontów; nieobsługiwane dane fontu albo przekroczenie limitu atomowo kończy import błędem

Nieprzezroczystość obiektu i grupy

opacity działa raz na kompletny zamalowany wynik swojego węzła i nie jest dziedziczona przez potomków; fill-opacity i stroke-opacity zachowują swoje osobne, dziedziczone wartości malowania

Dwa nakładające się nieprzezroczyste czerwone prostokąty wewnątrz <g opacity="0.5"> pozostają równomiernie półprzezroczyste w miejscu nakładania, podczas gdy dwa niezależnie półprzezroczyste prostokąty stają się ciemniejsze tam, gdzie się nakładają

Zagnieżdżone grupy komponują się w kolejności: dwie otaczające nieprzezroczystości 0.5 dają efektywne 0.25 nad nieprzezroczystym potomkiem, a jawna nieprzezroczystość 1 potomka nie nadpisuje jego grupy otaczającej

Korzeń SVG, kontenery, linki, referencje do fragmentów, tekst, obrazy i kształty używają tej samej ścieżki nieprzezroczystości obiektu; referencje use tylko do fragmentów zachowują style zarówno instancji, jak i referencjonowanego węzła

Alpha fill i stroke pozostają niezależne, także w miejscu nakładania wewnątrz półprzezroczystego obiektu, a alpha stopni gradientu łączy się z alphą odpowiedniego malowania przed komponowaniem obiektu

Efekty clip i maski należą do swojego węzła, zamiast dziedziczyć się jako ustawienia malowania potomków; geometria linków pozostaje świadoma rozmieszczenia, a izolowane granice Form zachowują konserwatywnie przekształcone stroke i zakończenia

Importer zachowuje operatory wektorowe, osadzone Formy tekstu, zasoby obrazów, wzorce i maski wewnątrz izolowanych grup; nie spłaszcza całego SVG do bitmapy

Obsługiwane zachowanie podąża za modelem nieprzezroczystości obiektu i grupy SVG; pozostałe ograniczenia tekstu, gradientów i geometrii na tej stronie nadal obowiązują

Bezpieczeństwo i budżety

Importer przyjmuje SVG zwykłe lub kompresowane gzip do 8 MiB i ogranicza wejście rozwinięte do 32 MiB, łączne operatory main, pattern, mask i group do 16 MiB, węzły do 4 096, zagnieżdżenie do 64 poziomów, reguły CSS do 256, a wartości ścieżek do 100 000

Osadzone obrazy przyjmują wyłącznie ścisłe ładunki Base64 data:image/png;base64, i data:image/jpeg;base64, — najwyżej 128 obrazów, 16 384 pikseli na wymiar i 16 777 216 zdekodowanych pikseli na wszystkich obrazach łącznie; wymiary są sprawdzane przed natywnym dekodowaniem

Tekst jest ograniczony do 128 przebiegów i 65 536 jednostek UTF-16 na przebieg, a wzorce stroke gradientowego, maski i izolowane grupy nieprzezroczystości — do 128 zasobów każde; rekurencyjne referencje masek kończą się błędem fail-closed

Tablice dash zawierają najwyżej 64 wpisy źródłowe przed rozwinięciem tablic nieparzystych; dodatnie wpisy muszą mieć co najmniej 0,000001 jednostki użytkownika, pojedyncze długości i znormalizowany cykl nie mogą przekraczać 1 000 000 000, bezwzględne offsety nie mogą przekraczać 1 000 000 000, a limity miter muszą pozostać między 0 a 1 000 000

Rzeczywiste zagnieżdżone efekty przezroczystości są ograniczone do ośmiu poziomów, zgodnie z natywnym rendererem, niezależnie od limitu głębokości drzewa SVG; zwykłe zagnieżdżone kontenery bez efektów przezroczystości nie zużywają tego przydziału

Granice efektów przezroczystości muszą być skończone, a każda współrzędna musi pozostać w wartości bezwzględnej 1 000 000 000; importy poza tym ograniczonym profilem współrzędnych kończą się błędem przed rejestracją grupy lub maski

Nieudane importy wycofują wygenerowane obiekty, osadzone Formy tekstu, wpisy rejestru oraz stan wersji i kolorów urządzenia, więc wywołujący mogą ponownie użyć tego samego dokumentu i zachować otaczającą transakcję grafu

Skrypty, handlery zdarzeń, DTD, foreignObject, nieobsługiwane typy mediów danych, URL-e JavaScript i zewnętrzne URL-e malowania lub zasobów obrazów kończą się błędem fail-closed

Referencje do fragmentów, takie jak url(#gradient), url(#clip) i href="#symbol", pozostają wewnątrz sparsowanego dokumentu i nigdy nie wyzwalają dostępu do plików ani sieci

Statystyki

THPDFSVGImportStatistics raportuje węzły, reguły CSS, gradienty, stroke gradientowe, maski, obrazy, linki, przebiegi tekstu, izolowane grupy nieprzezroczystości przez GroupCount oraz łączne bajty wygenerowanych operatorów main, pattern, mask i group

HPDFBuildSVGFormData wystawia ograniczony parser osobno przez THPDFSVGFormData i THPDFSVGLinkInfo dla wywołujących, którzy przed rejestracją potrzebują treści Form, wymiarów własnych, zasobów nieprzezroczystości, ładunków obrazów, strumieni pattern i mask, nazw zasobów tekstu albo metadanych linków; Groups dostarcza strumienie operatorów izolowanych grup i konserwatywne granice Form

Przykład

Document.BeginDoc;
FormName := Document.ImportSVGFormXObject(SVGBytes, Statistics);
if FormName = '' then
  raise Exception.Create('SVG import failed');

Document.CurrentPage.DrawSVGFormXObject(
  FormName,
  36,
  72,
  240,
  120,
  True
);

Document.CurrentPage.DrawSVGFormXObject(
  FormName,
  320,
  72,
  120,
  60,
  False
);

Zobacz też: THotPDF.ImportSVGFormXObject, THPDFPage.DrawSVGFormXObject, Import HTML5 paginowanych mediów