Technisch artikel

RTF-bestanden naar PDF transformeren: een handleiding voor Delphi-ontwikkelaars

Het converteren van de bestanden in Rich Text Format (RTF) naar Portable Document Format (PDF) verplaatst de inhoud van een documentgerichte architectuur met omlooptekst, naar de vaste paginageometrie van PDF. Binnen het Delphi VCL-framework is de standaardoplossing vaak het laden van het RTF-bestand in de TRichEdit, en dit proberen af te drukken of te renderen via GDI (Graphic Device Interface). Deze methode loopt echter al snel spaak op tekstdoorloop, paginering en de omgang met ingesloten afbeeldingen en elementen

Degenen die een programmatische, batchgeoriënteerde of server-veilige conversie (die niet vereist is voor Win32/GUI-handlers) nodig hebben, wenden zich tot speciale PDF-componenten. In dit artikel wordt onderzocht hoe dit wordt bereikt door de VCL HotPDF-component te gebruiken voor rechtstreekse import in de PDF-documentstructuur

De tekortkomingen van TRichEdit-oplossingen in Delphi begrijpen

Van oudsher wordt het genereren van een PDF van de rich-tekst gepoogd door een virtuele printer te configureren via Delphi TPrinter, de inhoud van TRichEdit te sturen om te worden afgedrukt met het commando EM_FORMATRANGE, en het GDI-oppervlak op te vangen. Dit stuit onmiddellijk op drie fundamentele problemen:

  1. Paginering controleren: Het besturingssysteem regelt de line-breaks. Handmatige pogingen om randen te meten en doorlopende tekst te verwerken met VCL resulteren bijna altijd in afgesneden regels onderaan elke pagina. Het handhaven van het GDI-canvas in verhouding tot lettergrootte over OS-schaling is volatiel

  2. Achtergronduitvoering en Windows Handles: Een TRichEdit is een verpakking van de eigen Windows-bedieningselementen. Proberen RTF stilletjes te converteren in een multi-threaded of windowless backend, veroorzaakt direct een bottleneck als de window-handles falen. Een VCL TRichEdit zal niet goed renderen op de achtergrond en GDI-rendering zal instorten onder de laadparameters van de service

  3. Verlies van metagegevens en verhoudingen van afbeeldingen: RTF sluit afbeeldingen in, vaak in metafile (EMF/WMF) of verouderde binaire DIB-formaten, en gebruikt besturingsverhoudingen om de lay-out te dicteren. Het afdrukken vanuit TRichEdit leidt in veel gevallen tot ontbrekende afbeeldingen, afbeeldingen van slechte kwaliteit doordat pixels in de metafile worden afgedwongen, of vervormde verhoudingen

U wilt een transformatie direct van the RTF-bestandsstroom naar PDF-tekeningsobjecten, waarbij de interface- en afdrukservices van het besturingssysteem worden omzeild

Paginering afhandelen tijdens de RTF-naar-PDF-uitvoering

De kritische uitdaging is paginering: RTF bevat geen intrinsieke pagina's (er zijn alleen pagina-einden en conceptmarges). PDF accepteert alleen pagina's. Bij het direct toewijzen van de RTF in een lege PDF is de parser de motor van de berekening, die weet waar het is gebleven en vraagt om een nieuwe pagina aan te maken als de drempel wordt overschreden

Als u HotPDF gebruikt (wat een speciale engine gebruikt voor het ontleden van het Rich Text Format), moet u het RTF-document expliciet in uw PDF plaatsen, en een parameter is de omvang van uw paginagrenzen. De truc hierbij is het behandelen van overloop en het maken van daaropvolgende pagina's in the PDF totdat de parser meldt dat de tekst voltooid is

procedure ConvertRTFtoPDF(const InputFile, OutputFile: string);
var
  PdfDoc: THotPDF;
  TextLeft: Integer;
begin
  PdfDoc := THotPDF.Create(nil);
  try
    // Optional: Setup document properties like creator and title
    PdfDoc.DocInfo.Creator := 'Delphi Automation';
    PdfDoc.DocInfo.Title := 'RTF Conversion';

    // Add the initial blank page to our PDF Document
    PdfDoc.AddPage;

    // Call DrawRichText. 
    // This function returns the remaining text length after drawing to the specified page bounds.
    // If the return is greater than zero, the RTF text overflowed the designated area.
    TextLeft := PdfDoc.CurrentPage.DrawRichText(InputFile, 50, 50, 500, 750);

    // Enter a loop to add new pages as long as there is text remaining
    while TextLeft > 0 do
    begin
      PdfDoc.AddPage; // Advance the document to a new page
      TextLeft := PdfDoc.CurrentPage.DrawRichText('', 50, 50, 500, 750);
    end;

    // Save and finalize
    PdfDoc.SaveToFile(OutputFile);

  finally
    PdfDoc.Free;
  end;
end;

In dit patroon specificeert the aanroep van DrawRichText het InputFile-pad in de beginfase en een leeg bestandspad ('') in opeenvolgende iteraties. De interne buffer van HotPDF onthoudt de parse-status, met respect voor de stilzwijgende status tussen PDF-pagina's

Lettertypestijlen, hyperlinks en tekstverankering afhandelen

Omdat RTF geen PDF is, vertrouwt het zwaar op de lettertypen van de clientmachine. Een RTF die is gemarkeerd voor Courier New 14pt-vet, veronderstelt dat dit aanwezig is bij het opzetten van het formaat. PDF-vereisten schrijven voor dat de specifieke lettertypefamilies behouden blijven (en, om visuele verplaatsing in the document te voorkomen, dat het PDF-document ze idealiter onmiddellijk opneemt en insluit)

Wanneer the conversie in HotPDF plaatsvindt, zoekt de RTF-parser binnen het Delphi-systeem naar de bijbehorende tekststijlen uit het RTF-record, vertaalt RTF-tekenopmaak (zoals vet, cursief, kleuren) naar PDF GState en PDF-tekstuitlijning, en verwerkt onmiddellijk inbedding. U hoeft in principe niet door GDI of LogFont te waden, omdat dit programmatisch is overbrugd

Als u te maken heeft met bestanden die geen Engelse lettertypen bevatten, zullen tekstuitlijning en tekensets voor problemen zorgen als ze met slechte RTF-implementaties zijn vastgelegd. De engine van de component probeert the \ansicpg in de RTF-header of eventuele Unicode-stuurwoorden (\u) die van invloed zijn op de tekst te interpreteren en zet deze om naar veilige the Unicode (UTF-16) tekenstrings van de Delphi-applicatie, voordat the strings veilig in PDF worden opgemaakt

RTF-afbeeldingen correct in de PDF weergeven

RTF-documenten sluiten binaire afbeeldingsdata vaak in het hexadecimale (\pict) formaat in, en geven WMF/EMF of rasterafbeeldingen in the tekst op die meebewegen met regeleinden of worden verankerd aan specifieke locaties

Proberen dit op de GDI-printergebaseerde manier in PDF te krijgen dwingt the Windows Spooler om de binaire inhoud van de afbeelding opnieuw te verwerken, wat er vaak toe leidt dat afbeeldingen op mysterieuze wijze onscherp of verkeerd geschaald in uw definitieve PDF verschijnen

Doordat DrawRichText the RTF-stroom handmatig verwerkt, zal the methodiek intern de binaire data detecteren die de afbeeldingen markeren in de RTF, de data ontleden, en zonder omweg converteren via TImage of GDI in PDF In-Line Image of PDF XObject Formaten. Het resultaat hiervan in PDF-termen is dat RTF-documenten inclusief grafieken of schermopnamen in het uiteindelijke PDF exact met dezelfde resolutie behouden blijven en zich perfect en accuraat in de documentstroom zullen verankeren op the plaatsen die the RTF-afbeeldingsbesturingsverhoudingen sturen

Conversie optimaliseren in bulkbewerkingen

Omdat het afdrukken van documenten zware GDI-bronnen vergt in Delphi, maakt deze directe architectuur in RTF the creatie van backend web-servers of geautomatiseerde batchdiensten voor the transformatie naar PDF mogelijk, met aanzienlijke snelheid. In systemen waar een dagelijkse run van duizenden in-house of in-app gemaakte RTF-briefsjablonen direct naar the klanten verzonden moet worden as niet-aanpasbare the documenten, the resource-belasting is marginaal

De methoden en concepten die hier worden geschetst, maken deel uit van de HotPDF VCL Component, de primaire bibliotheek van losLab Software voor het programmeren en genereren van documenten