Tehnički članak

GoToR, ugrađene i Launch akcije u PDF-u

PDFlibPas programerima za Delphi i C++Builder pruža tri vrste akcija za navigaciju koja napušta trenutačnu stranicu: GoToR (Go To Remote) otvara određenu stranicu u drugoj PDF datoteci, GoToE (Go To Embedded) otvara PDF datoteku ugrađenu u trenutačni dokument, a Launch pokreće vanjski program ili otvara datoteku putem ljuske operacijskog sustava. Sve tri pripadaju odjeljku §12.6.4 standarda ISO 32000-1 o vrstama akcija, koji definira i uobičajenu akciju GoTo, a svaka krije vlastitu zamku za neoprezne: broj stranice čije značenje ovisi o pozivu koji je izgradio akciju, cilj koji je naziv, a ne putanja datoteke, te dva parametra niza koji izgledaju jednako, ali služe dvama različitim preglednicima

Ništa od toga nije hipotetsko. Paket tehničke dokumentacije — glavni priručnik, PDF sa specifikacijama koji distributer ažurira prema vlastitom rasporedu i alat za kalibraciju instaliran uz oba dokumenta — oslanja se upravo na takvo povezivanje između dokumenata: unakrsnu referencu koja mora stići na 5. stranicu datoteke sa specifikacijama, podatkovni list koji vrijedi isporučiti unutar priručnika umjesto pokraj njega i poveznicu koja izravno predaje rad kalibracijskom alatu. Ovaj je članak zrcalna suprotnost čitanju akcija knjižnih oznaka i bilježaka iz postojećeg PDF-a: taj članak obrađuje preuzimanje akcije GoToR, Launch ili GoToE koju je drugi proizvođač već zapisao u datoteku, a ovaj objašnjava izgradnju iste tri vrste akcija od nule, uključujući pravila na razini polja koja PDFlibPas provjerava prije nego što zapiše ijedan bajt

Tri načina na koja PDF akcija napušta trenutačnu stranicu

PDFlibPas odvaja lokalnu navigaciju od svega ostalog prema ključu akcije /S, a GoToR, GoToE i Launch tri su podvrste čiji se cilj nalazi izvan trenutačne stranice: GoToR prema odjeljku §12.6.4.3 standarda ISO 32000-1, GoToE prema §12.6.4.4, a Launch prema §12.6.4.5, sve unutar šireg odjeljka §12.6.4 o vrstama akcija koji definira i uobičajenu akciju GoTo. Odredište obične akcije GoTo imenuje objekt stranice koji već postoji u dokumentu, pa ga PDFlibPas može odmah provjeriti; GoToR i GoToE ne mogu se provjeriti na isti način jer vanjska datoteka možda uopće ne postoji na ovom računalu, a broj stranica ugrađene datoteke nije podatak koji matični dokument prati, pa obje nose nerazriješenu referencu umjesto čvrste poveznice — specifikaciju datoteke i odredište za GoToR, naziv ugrađene datoteke i ciljnu stranicu za GoToE — dok Launch potpuno izostavlja pojam odredišta i samo imenuje ono što operacijski sustav treba pokrenuti ili otvoriti. Ta se podjela na strani zapisivanja vidi kao dvije skupine poziva: visokorazinski jednokratni graditelji kao što su AddLinkToFile, AddLinkToFileEx, AddLinkToEmbeddedPDF i AddLinkToLocalFile zajedno stvaraju bilješku poveznice s aktivnim područjem na stranici i njezinu akciju, što pokriva većinu stvarnih rasporeda — redak teksta ili ikonu koju čitatelj pritisne — dok nižerazinski postavljači kao što su SetActionRemoteDestinationEx, SetActionLaunchOptions i njihovi parnjaci AddActionNext* pridružuju ili zamjenjuju akciju na objektu za koji već imate ručicu: postojećoj knjižnoj oznaci, okidaču polja obrasca ili događaju životnog ciklusa na razini dokumenta ili stranice. Obje skupine na kraju zapisuju iste oblike rječnika; razlika je u tome gdje se nalazite kada ih pozovete i, kao što objašnjava sljedeći odjeljak, što tada znači broj stranice

Kako izgraditi GoToR poveznicu koja otvara stranicu u drugoj PDF datoteci?

Akcija GoToR treba dvije stvari — specifikaciju datoteke i odredište unutar te datoteke — a PDFlibPas izlaže dva različita poziva za zadavanje drugog dijela, svaki s vlastitim pravilom numeriranja stranica. AddLinkToFile i AddLinkToFileEx, visokorazinski graditelji aktivnih područja na stranici, provjeravaju da je njihov argument Page ili DestPage veći od nule, prema istom numeriranju od 1 koje PDFlibPas koristi svugdje drugdje, uključujući SelectPage. SetActionRemoteDestinationEx, nižerazinski postavljač za pridruživanje ili zamjenu akcije GoToR na objektu za koji već imate ručicu, umjesto toga provjerava da je DestPage veći ili jednak nuli i zapisuje ga izravno u polje eksplicitnog odredišta akcije bez prilagodbe: očekuje izvorni indeks stranice ciljnog dokumenta koji počinje od nule, prema numeriranju koje ISO 32000-1 propisuje za udaljeno eksplicitno odredište. Ako nižerazinskom postavljaču predate isti broj koji biste dali visokorazinskom graditelju, poveznica će otvoriti stranicu prerano

var
  Lib: TPDFlib;
  ActionID: Integer;
begin
  Lib := TPDFlib.Create;
  try
    if Lib.LoadFromFile('manual.pdf', '') = 1 then
    begin
      Lib.SelectPage(12);
      // Page is 1-based here, same as SelectPage above: this opens
      // the fifth page of specs.pdf.
      Lib.AddLinkToFile(72, 700, 200, 16, 'specs.pdf', 5, 0, 0, 0);

      // A later maintenance pass repoints the same link at a
      // reorganized file. SetActionRemoteDestinationEx edits the
      // action directly, and DestPage here is the zero-based index
      // PDF itself uses for a remote explicit destination -- "the
      // fifth page" is now 4, not 5.
      ActionID := Lib.GetAnnotActionID(1);
      Lib.SetActionRemoteDestinationEx(ActionID, 'specs-2026.pdf',
        4, Ord(dkFit), 0, 0, 0, 0, 0, 0, -1);
    end;
  finally
    Lib.Free;
  end;
end;

Preostali argumenti funkcije SetActionRemoteDestinationEx jednako su doslovni. ValueMask je skup bitova — 1 za lijevo, 2 za vrh, 4 za desno, 8 za dno i 16 za zumiranje — a PDFlibPas ga provjerava prema DestType prije bilo kakvog zapisivanja: odredište dkFitR mora zadati točno 15 (sva četiri ruba, bez zumiranja), dkFit i dkFitB moraju zadati 0, a dkFitH/dkFitV prihvaćaju samo svoju relevantnu koordinatu. Bitovi koje ostavite nepostavljenima unutar inače valjane maske ne izostavljaju se iz polja; zapisuju se kao eksplicitni PDF null, što ISO 32000-1 za tu koordinatu tumači kao zadržavanje vrijednosti koju preglednik već ima — legitiman način da kažete „skoči na ovu stranicu, ostavi zumiranje nepromijenjenim“, a ne propust. Samo zumiranje pohranjuje se kao razlomak predane vrijednosti, pa poziv koji traži 150 posto u polje predaje pohranjenu vrijednost 1.5, a valjani ulazni raspon je od 0 do 6400

Kako povezati PDF ugrađen u vlastiti dokument?

AddLinkToEmbeddedPDF izgrađuje akciju GoToE, a njegov ciljni argument EmbeddedFileName jest naziv, a ne putanja: mora odgovarati nizu Title koji je već predan funkciji EmbedFile pri dodavanju privitka, jer je taj naslov doslovni ključ koji PDFlibPas pohranjuje u stablu naziva dokumenta /EmbeddedFiles, a GoToE razrješava cilj traženjem tog naziva, bez ponovnog pristupa datotečnom sustavu. Funkcija provjerava samo da EmbeddedFileName nije prazan i da je TargetPage najmanje 1 — ako predate naziv koji nikada nije stvarno ugrađen, poziv će i dalje vratiti uspjeh, akcija će i dalje biti zapisana, a poveznica se jednostavno neće razriješiti ni jednom čitatelju koji je pritisne

var
  Lib: TPDFlib;
begin
  Lib := TPDFlib.Create;
  try
    Lib.NewDocument;
    Lib.NewPage;
    // The Title argument becomes the key PDFlibPas stores in the
    // document's EmbeddedFiles name tree -- that string, not
    // "datasheet.pdf", is the target GoToE resolves against.
    if Lib.EmbedFile('Datasheet', 'datasheet.pdf', 'application/pdf') = 1 then
      Lib.AddLinkToEmbeddedPDF(72, 700, 200, 16, 'Datasheet', 3, 0, 0);
    Lib.SaveToFile('manual.pdf');
  finally
    Lib.Free;
  end;
end;

Ovdje se zbrajaju dvije donje granice verzije, a ne jedna. EmbedFile treba PDF 1.4 za stablo naziva /EmbeddedFiles, a AddLinkToEmbeddedPDF zasebno podiže donju granicu na PDF 1.6 zbog same vrste akcije GoToE, pa je učinkoviti minimum za svaki dokument koji koristi tu mogućnost 1.6, a ne 1.4. Primijetite i da je TargetPage ovdje numeriran od 1, prema uobičajenoj konvenciji PDFlibPasa — namjerno suprotno indeksu DestPage koji počinje od nule i upravo je obrađen u prethodnom odjeljku, što podsjeća da primjenjivo numeriranje stranica ovisi o vrsti akcije i konkretnom pozivu, a ne o jednom općem pravilu. Ciljni rječnik akcije može sadržavati i unos /R s vrijednošću C za dijete ili P za roditelja, čime podržava lanac od dva skoka u ugrađenu datoteku ili natrag u spremnik, iako AddLinkToEmbeddedPDF izgrađuje samo smjer prema djetetu, jer jedino on ima smisla iz dokumenta koji ugrađuje drugi dokument, a ne iz onoga koji je ugrađen

Launch akcije: jedan FileName, dva ciljna niza koja nisu zamjenjiva

SetActionLaunchOptions zapisuje ciljnu datoteku Launch akcije u dva različita ključa iz jednog argumenta FileName, a ta dva ključa sadrže dvije različite vrste niza. Ključ najviše razine /F dobiva rječnik specifikacije datoteke, izgrađen istom pretvorbom putanje koju PDFlibPas koristi za GoToR, odnosno prenosivim oblikom koji ISO 32000-1 definira u §7.11.3 za rječnik specifikacije datoteke. Podrječnik /Win, kada ga PDFlibPas zapisuje, dobiva vlastiti ključ /F postavljen na sirovu vrijednost FileName točno onako kako je predana, bez ikakve pretvorbe, jer je /Win /F u ISO 32000-1 §12.6.4.5 dokumentiran kao običan niz s putanjom sustava Windows namijenjen samo čitanju u pregledniku za Windows. Ako predate prenosivu, već pretvorenu putanju očekujući da će oba ključa biti jednaka, kopija /Win sadržavat će upravo ono što ste predali funkciji, nepromijenjeno

var
  Lib: TPDFlib;
  ActionID: Integer;
begin
  Lib := TPDFlib.Create;
  try
    if Lib.LoadFromFile('manual.pdf', '') = 1 then
    begin
      Lib.SelectPage(1);
      Lib.AddLinkToLocalFile(72, 660, 220, 16, 'calibrate.exe', 0);
      ActionID := Lib.GetAnnotActionID(1);
      // Operation 0 leaves this as a normal open -- pass 1 to ask a
      // Windows viewer to print instead. Parameters and
      // DefaultDirectory only ever reach /Win /P and /Win /D, never
      // the top-level /F.
      Lib.SetActionLaunchOptions(ActionID, 'calibrate.exe',
        '/silent /profile:default', 'C:\Tools\Calibration', 0, -1);
    end;
  finally
    Lib.Free;
  end;
end;

Launch tretirajte kao najzahtjevniju od tri akcije jer je njezina cijela svrha pokretanje programa ili otvaranje datoteke izvan PDF sandboxa, a svaki uobičajeni preglednik tome pristupa u skladu s tim. Poboljšana sigurnost programa Adobe Acrobat prema zadanim postavkama blokira ili traži potvrdu za Launch akcije, osim kada se cilj nalazi na izričito pouzdanoj lokaciji, a većina poslovnih instalacija Acrobata tu zaštitu ostavlja uključenom. Launch akcija u dokumentu namijenjenom javnosti stoga nije pouzdan okidač: računajte na to da će je preglednik koji otvara datoteku blokirati, zatražiti potvrdu ili tiho zanemariti, te je čuvajte za zatvorena okruženja u kojima nadzirete i postavke pouzdanosti preglednika — interni kiosk, kontrolirano uvođenje u tvrtki ili dokument koji nikada ne napušta računalo kojim upravljate

PDF/A ograničenje: zašto pozivi GoToR i Launch mogu vratiti nulu

SetActionRemoteDestinationEx i SetActionLaunchOptions u potpunosti odbijaju rad kada je ciljni dokument u bilo kojem načinu usklađenosti s PDF/A: oba najprije provjeravaju PDF/A način rada dokumenta i izlaze s rezultatom 0 prije diranja akcije, bez podizanja iznimke. To je namjerno. Ograničenja PDF/A za interaktivne akcije posebno isključuju Launch, jer je mogućnost da arhivska datoteka pokrene proizvoljan program upravo vrsta ponašanja ovisnog o okruženju koju formati za dugoročno arhiviranje nastoje spriječiti, a PDFlibPas isto konzervativno ograničenje primjenjuje na postavljač udaljenog skoka u istom putu koda. Praktičnu posljedicu lako je previdjeti tijekom razvoja: isti poziv koji radi na običnom PDF-u prevest će se, izvršiti i tiho neće učiniti ništa na dokumentu učitanom s postavljenom razinom usklađenosti s PDF/A, pa provjerite povratnu vrijednost umjesto da pretpostavite uspjeh — 0 ovdje nije pogreška neispravnog ulaza, nego odbijanje zahtjeva koji je u sukobu s vlastitom tvrdnjom dokumenta o usklađenosti

Kako se GoToR, GoToE i Launch uklapaju u veći tijek rada PDFlibPasa?

Tri vrste akcija iz ovog članka ne dosežu sva ista mjesta. Popratni članak o okidačima životnog ciklusa dokumenta i stranice obrađuje SetDocumentAction i SetPageAction, koji akciju GoToR ili Launch mogu pridružiti okidaču poput WillClose kroz zajedničke konstante PDF_ACTION_BUILDER_REMOTE_DESTINATION i PDF_ACTION_BUILDER_LAUNCH — isti graditelj pokriva i obični URI ili JavaScript okidač. GoToE nema takvu konstantu ni ikakav put u taj opći graditelj; AddLinkToEmbeddedPDF jedini je način na koji ga PDFlibPas izgrađuje, zbog čega je strogo akcija aktivnog područja na stranici, a nikada okidač na razini dokumenta ili stranice. Ondje gdje GoToR i Launch dosežu opći graditelj, kompromis je kontrola: on izgrađuje GoToR koji pokazuje samo na imenovano udaljeno odredište i Launch akciju sa samo nazivom datoteke i parametrima, dok se eksplicitno adresiranje stranice i vrste uklapanja te mogućnosti pokretanja specifične za Windows iz ovog članka dosežu samo izravnim pozivima SetActionRemoteDestinationEx i SetActionLaunchOptions

Prije izgradnje alata za održavanje oko ovih postavljača vrijedi znati jedno sigurnosno svojstvo. SetActionRemoteDestinationEx i SetActionLaunchOptions najprije izgrađuju cijelu zamjensku akciju u pomoćnom rječniku, a ključeve /F, /D ili /Win te /NewWindow brišu i kopiraju na aktivnu akciju tek nakon provjere te pomoćne kopije — zato poziv koji ne prođe provjeru, bilo zbog vrijednosti ValueMask izvan raspona ili praznog FileName, ostavlja izvornu akciju i svaki lanac /Next koji već visi s nje potpuno netaknutima, umjesto da ih napola prepiše. To je važno jer akcije GoToR i Launch mogu obje biti unutar lanca /Next izgrađenog pomoću AddActionNextRemoteDestinationEx, AddActionNextLaunchEx ili općenitijeg AddActionNextEx, pa jedan okidač može redom pokrenuti JavaScript zapis i zatim udaljeni skok. Izgradnja akcija GoToR, GoToE i Launch opisana ovdje dio je komponente PDFlibPas, izvorne PDF biblioteke za Delphi i C++Builder

Autorska prava 2026 losLab Software

Početna · Pretraži · losLab.com