HotPDF se kompajlira i izvodi pod Free Pascalom 3.2.2 s Lazarusom, i pošten sažetak tog prijenosa su dvije rečenice. Stvaranje dokumenata, učitavanje, spremanje, kompresija, dekompresija, šifriranje i dešifriranje sve rade na isključivo Pascal pozadinama, pa Lazarus aplikacija može proizvoditi i trošiti stvarni PDF bez ikakve C ovisnosti. Neobavezni izvorni kodeci slika ne rade, jer prethodno izgrađeni Win64 objekti koriste COFF varijantu koju nijedan Free Pascal povezivač ne može konzumirati, pa na tom alatnom lancu ulazne točke prelaze u začepčene verzije koje zaključavaju greškom
Doći od "kompajlira se" do "radi" uzelo je određen skup ispravaka, i svaki od njih je zamka koja će naći svaku drugu Delphi bazu kôda koja se premješta na Free Pascal. Vrijedi ih zapisati u redoslijedu u kojem su boljele
Zašto jedinica koja se kompajlira ne dokazuje ništa?
Zato što Pascal jedinica može referencirati simbol koji nikad neće učiniti ništa korisno i i dalje zadovoljiti kompajler. U trenutku kada su se svih 113 knjižičnih jedinica izgradilo čisto pod Free Pascalom, rukovatelji arhivskih spremnika stvarno su radili, provjereno probnim testom koji je otvorio CBZ i pretvorio ga u PDF. Ravnanje XFA obrazaca uopće nije radilo, jer ravnanje mora napuhati komprimirani tok paketa /XFA a ulazna točka deflatea bila je još začepčena verzija. Ništa u izlazu izgradnje nije razlikovalo ta dva slučaja
Pravilo koje je iz toga izašlo kratko je. Prije nego napišete u napomeni o izdanju da značajka radi na novom alatnom lancu, napišite probu u vremenu izvođenja koja značajku vježba od početka do kraja na tom alatnom lancu. Pokrivenost kompajliranjem preduvjet je, nikad dokaz. Šira slika onoga što prijenos pokriva je u napomenama o Win64 podršci za Free Pascal i Lazarus
Iznimka unutar cdecl začepčene verzije ne dospijeva do pozivatelja
Ovo zaslužuje vlastito poglavlje jer je simptom tako varljiv. Jedinice začepčenih verzija izlažu C ulazne točke onako kako bi to učinila statička biblioteka, pa začepčena verzija izgleda ovako
// Izgleda razumno. Nije.
function inflate(Strm: Pointer; Flush: Integer): PtrUInt; cdecl;
public name 'inflate';
begin
raise ENotSupportedException.Create('codec unavailable');
end;
Na Free Pascalu za Win64 ta se iznimka ne širi do pozivatelja. Nema rukovatelja try..except koji je vidi, jer odmotavanje preko cdecl granice deklarirane ovako ne nosi Pascalov okvir iznimke; proces završava s izlaznim kôdom 217. Sa strane aplikacije nema pogreške, nema poruke i nema retka u dnevniku, samo program koji nestane. To je strogo gore od pogrešnog odgovora, jer se pogrešan odgovor može obraditi
Primamljiv ispravak je učiniti da začepčena verzija vrati kôd kvara, i za inflate to je ispravno jer zlib ima dobro definiran povrat pogreške. Općenito je pogrešno: začepčena verzija za jpeg_read_header koja vraća nulu govori pozivatelju da nastavi sa strukturom koju nitko nije inicijalizirao. Trajni ispravak jest ograničiti na Pascal ulaznoj točki umjesto unutar začepčene verzije u obliku C, koristeći onu konvenciju kvara koju taj API već ima
function TryDecodeJPEG(const Data: TBytes; out Bitmap: TBitmap): Boolean;
begin
{$IFDEF FPC}
// Odbijte prije nego se uopće dođe do začepčene verzije, s vlastitom
// konvencijom kvara ovog API-ja umjesto iznimkom preko cdecl
Bitmap := nil;
Result := False;
Exit;
{$ENDIF}
Result := DecodeJPEGNative(Data, Bitmap);
end;
paszlib nije zlib, a razlika su dvije klase dokumenata
Pascal implementacija deflatea dostupna na Free Pascalu rukuje s dva uokvirenja: zlib omotom i sirovim deflateom. Ne rukuje gzip uokvirenjem, koje zlib bira kroz vrijednosti windowBits od 16 do 31, i ne rukuje načinom automatske detekcije koji biraju vrijednosti 32 do 47. HotPDF treba oboje. Sigurni put SVG uvoza traži 31, a učitavač ima ljestvicu povratka koja traži 47 kada je uokvirenje toka dvosmisleno. Preskočite bilo koje i cijela obitelj dokumenata prestaje se otvarati, s dekodirajućom pogreškom koja upućuje na tok, a ne na nedostajuće uokvirenje
Postoji druga, oštrija nespojivost. Zapis z_stream koji deklarira paszlib nema isti memorijski raspored kao C-ov: njegovo polje msg kratak je niz umjesto pokazivača, a total_in i total_out su 64-bitni gdje C ABI ima strojne riječi. Pozivni zapis dakle ne može se prosljediti ravno. Radni aranžman jest držati stanje paszliba iza pokazivača state koji javni zapis već rezervira, i kopirati javna polja unutra i van oko svakog poziva. Gzip CRC i osmobajtni završetak duljine obračunaju se u tom istom shim sloju, koji je prirodno mjesto za njih budući da on već posjeduje odluku o uokvirenju
Prosljeđivanje dinamičkog polja netipiziranom var parametru
Ovo je greška koja najvjerojatnije upravo sjedi u vašem kôdu. Kada dinamičko polje prosljedite netipiziranom var parametru, ono što primatelj dobije jest adresa varijable polja, a to je adresa pokazivača, ne adresa korisnog tereta. Čitanje u nju dakle prepisuje samu varijablu i sve što sjedi uz nju
var
FBuffer: TBytes;
begin
SetLength(FBuffer, 65536);
// Pogrešno: predaje adresu varijable FBuffer
FStream.Read(FBuffer, Length(FBuffer));
// Ispravno: predaje adresu prvog bajta korisnog tereta
FStream.Read(FBuffer[0], Length(FBuffer));
end;
Na Delphiju pogrešan oblik često se čini da radi, jer ono što oštećuje jest susjedni stogovni utor koji poslije ništa ne čita. Na Free Pascalu isti redak na prvoj uporabi izaziva segmentacijsku pogrešku. Ono što to čini tako teškim za uočiti okom jest to da statička polja nemaju takav problem, jer je statička varijabla polja vlastiti korisni teret, pa su oba pravopisa ispravna u istoj datoteci ovisno o deklaraciji nekoliko stotina redaka dalje
ZIP spremnici bez System.Zip
Free Pascal nema ekvivalent RTL zip jedinice, a dostupna alternativa ima i drugačiju API površinu i bez podrške za starije šifriranje koje stariji formati spremnika i dalje koriste, pa se mali čitač unutar knjižnice pokazao kraćim od prilagođavanja njoj. Dvije pojedinosti formata koštale su vremena i lako ih je pogriješiti
Prva je bajt provjere zaglavlja šifriranja. Njegov dvanaesti bajt uobičajeno je gornji bajt CRC-a, ali kada je postavljena zastavica bita 3 opće namjene, što znači da veličine žive u pratećem opisniku podataka i da CRC još nije poznat, bajt provjere dolazi iz gornjeg bajta vremena izmjene umjesto toga. Implementirajte samo CRC oblik i svaki arhiv napisan u načinu strujanja odbit će ispravnu lozinku. Druga je dodatno polje ZIP64: njegova tri 64-bitna polja pojavljuju se u fiksnom redoslijedu ali se pišu samo kada je odgovarajuće 32-bitno polje zasićeno, pa ih čitanje po fiksnim pomacima radi na arhivima koje ste testirali i pada na sljedećem. Raščlanite ih pozicijski u odnosu na to koja su 32-bitna polja zasićena
Jedna pogodnost vrijedna znanja: Free Pascal tok dekompresije uzima drugi argument konstruktora koji preskače zlib zaglavlje, što je točno ono što ZIP unosi trebaju jer spremaju sirovi deflate. Taj put uopće ne dira knjižični zlib shim, pa na njega ne utječe nedostajuća C pozadina
Prozirnost znakova u boji pod LCL-om
Čitanje alfa kanala rasteriziranog znaka u boji jedina je grafička pojedinost bez izravne pretvorbe. LCL PNG klasa nema pristupnika scanlinea koji izlaže alfu, a dodjeljivanje PNG-a bitmapa odbacuje je, pa znak emocije u boji stiže potpuno neproziran i kompozitira s crnim okvirom iza sebe. Radni put jest sučeljska slika: stvorite je iz PNG-a, zatim čitajte piksele kroz pristupnik boje, pazeći da su njegove komponente 16-bitne i da trebaju pomak dolje za osam da postanu bajtovi. Ta površina također koristi prirodni redoslijed redaka od vrha prema dolje, pa inverzija Height - 1 - Y koju VCL scanline kôd treba mora se ukloniti, a ne portirati
Dvije napomene o sustavu izgradnje prije prijave greške
Potpuna ponovna izgradnja povremeno ne uspijeva s nedefiniranim simbolom čije ime završava sufiksom $crc i heksadecimalnom vrijednošću. Taj se sufiks računa iz tipova parametara, i ne uspijeva se podudariti kada jedna izgradnja kompajlira jedinicu u odnosu na dvije različite verzije sučelja u istom prolazu. Ponovno pokretanje izgradnje to čisti; potpis nije pogrešan
Drugo, Free Pascal 3.2.2 nema anonimne metode, pa gdje god je knjižnica koristila zatvorenje za povezivanje paralelnog cjevovoda Free Pascal izgradnja uzima deterministički serijski povratak umjesto toga. Izlaz je identičan, propusnost nije; ako ovisite o paralelnom prikazivanju stranica, to je razlog da za sada ostanete na Delphiju, a dizajn cjevovoda opisan je u članku o paralelnom cjevovodu prikazivanja. Stanje kodeka slika drugo je mjesto gdje izbor alatnog lanca mijenja mogućnosti, a ne samo brzinu, pa Lazarus raspoređivanje treba planirati formate slika u skladu s tim; trenutna matrica po alatnom lancu je na stranici proizvoda HotPDF Delphi PDF component