PDF/A, PDF/X, và PDF/UA là ba tiêu chuẩn khác nhau giải quyết ba vấn đề khác nhau: lưu trữ dài hạn, trao đổi in ấn, và khả năng tiếp cận. Chúng không phải là ba ô chọn trên một biểu mẫu tuân thủ duy nhất, và lỗi phổ biến nhất là coi chúng như thể chúng là vậy. Một tệp có thể hoàn hảo về PDF/A nhưng vô dụng đối với một xưởng in; một bản in gốc hoàn hảo có thể không đọc được đối với một trình đọc màn hình. Tệ hơn, cả ba đều là ràng buộc trên cấu trúc nội bộ của tệp, không phải trên hình thức hiển thị của nó. Một tài liệu mở gọn gàng trong mọi trình xem bạn có vẫn có thể thất bại khi kiểm định ngay lần thử đầu tiên, và thường là như vậy
HotPDF, thư viện PDF VCL gốc của losLab, coi sự tuân thủ là thứ bạn khai báo trước khi trang đầu tiên tồn tại. Bạn đặt một thuộc tính tuân thủ, gắn các cấu trúc mà tiêu chuẩn yêu cầu, và thư viện từ chối các cấu hình mâu thuẫn với hồ sơ tại thời điểm lưu. Đó là một mô hình tốt hơn so với việc tạo ra một tệp rồi hy vọng một trình hậu xử lý có thể trang bị lại nó, vì phần lớn những gì các tiêu chuẩn này yêu cầu không thể thêm vào sau khi sự việc đã xảy ra
Ba tiêu chuẩn ISO, ba lời hứa khác nhau
PDF/A (ISO 19005) nói về thời gian. Nó hứa hẹn một tệp sẽ vẫn hiển thị giống hệt hàng thập kỷ sau, nên nó đòi hỏi sự tự chứa hoàn toàn: mọi phông chữ được nhúng, mọi màu sắc được gán ý nghĩa độc lập với thiết bị thông qua một OutputIntent, siêu dữ liệu XMP đầy đủ, và một lệnh cấm đối với bất cứ thứ gì mà hành vi của nó phụ thuộc vào môi trường. Mã hóa và JavaScript đều bị loại trừ, vì không ai có thể đảm bảo bộ giải mã hoặc engine script sẽ còn tồn tại vào năm 2050
PDF/X (ISO 15930) nói về màu sắc trên giấy. Nó tồn tại để một nhà thiết kế có thể đưa một tệp cho một xưởng in mà cả hai bên không cần phải bàn bạc thêm, điều này có nghĩa là các điều kiện in đặc trưng hóa, một khóa /Trapped bắt buộc, hình học cắt xén và tràn lề được xác định rõ, và trong biến thể X-1a, không có tính trong suốt sống (live transparency) để bộ RIP phải đoán mò. PDF/UA (ISO 14289) nói về ai có thể đọc được kết quả. Công nghệ hỗ trợ cần một cây thẻ (tag tree) hoàn chỉnh, một thứ tự đọc hợp lý, một ngôn ngữ tài liệu được khai báo, và các văn bản thay thế cho bất cứ thứ gì không phải là văn bản
Vì ba tiêu chuẩn này kéo theo các hướng khác nhau, hãy chọn tiêu chuẩn chi phối theo từng kênh đầu ra thay vì cố đuổi theo một tệp duy nhất thỏa mãn cả ba. Một bản in gốc chỉ-CMYK chính xác là thứ sai để đưa cho một người dùng trình đọc màn hình chưa bao giờ thấy màu sắc, và việc khóa cứng hành vi động của hồ sơ lưu trữ va chạm với bất cứ thứ gì có tính tương tác. Hãy tạo ra theo từng kênh từ cùng một nguồn dữ liệu và bạn sẽ né được toàn bộ xung đột đó
PDF/A: OutputIntent là phần mà ai cũng quên
Nếu một tệp PDF/A thất bại khi kiểm định, OutputIntent là điều đầu tiên cần kiểm tra. Đây là cấu trúc mà các bộ tạo tài liệu bỏ sót thường xuyên nhất, chính vì không có gì nhìn thấy được phụ thuộc vào nó. ISO 19005 yêu cầu một cấu trúc như vậy: một hồ sơ ICC được nhúng ghim chặt ý nghĩa thực sự của các màu thiết bị của tài liệu. HotPDF biến hồ sơ đó thành một đầu vào tường minh thay vì một việc nghĩ đến sau:
var
Pdf: THotPDF;
ICC: TFileStream;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'invoice-archival.pdf';
Pdf.PDFACompliance := 'B'; // mức B: trung thực về mặt hình ảnh
Pdf.Lang := 'en-US';
Pdf.StandardFontEmulation := False; // nhúng phông chữ thực, không giả lập Base-14
ICC := TFileStream.Create('sRGB.icc', fmOpenRead);
try
Pdf.AddPDFAOutputIntent('sRGB IEC61966-2.1', '', ICC, 3, 'DeviceRGB');
finally
ICC.Free;
end;
Pdf.BeginDoc;
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(50, 760, 0, 'Archival invoice body');
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Một vài chi tiết quyết định đạt hay trượt ở đây. StandardFontEmulation phải tắt: các phông chữ Base-14 giả lập không được nhúng, và việc nhúng là không thể thương lượng theo ISO 19005. Mã hóa phải luôn bị vô hiệu hóa, nên đừng bao giờ kết hợp PDFACompliance với ActivateProtection; một tệp lưu trữ được mã hóa là một mâu thuẫn mà trình xác thực bắt được ngay lập tức. Số lượng thành phần trong AddPDFAOutputIntent phải khớp với hồ sơ, là 3 đối với một hồ sơ RGB như sRGB IEC61966-2.1 và 4 đối với CMYK. HotPDF theo dõi việc sử dụng DeviceRGB và DeviceCMYK dựa trên ý định đã khai báo trong khi nó ghi, nên một lần tô CMYK lạc lối trong một tài liệu ý định-RGB sẽ trở thành một vấn đề được báo cáo thay vì một vấn đề âm thầm
Có một điều đáng nói về hồ sơ ICC: hãy coi nó như một tài sản triển khai có phiên bản, không phải một tệp ai đó từng thả vào máy chủ build một lần. Các byte của nó được nhúng vào mỗi tài liệu bạn tạo ra, nên một hồ sơ bị cắt cụt hoặc hỏng sẽ âm thầm đầu độc cả một lô, và bạn chỉ phát hiện ra tại thời điểm kiểm định. Hãy phát hành nó cùng trình cài đặt của bạn, ghi lại checksum của nó trong nhật ký chạy, và tải nó thông qua mẫu TFileStream được trình bày ở trên để một tệp bị thiếu thất bại ồn ào trong quá trình tạo thay vì âm thầm tại cổng lưu trữ
PDF/X cho in ấn: Trapped, CMYK, và hồ sơ máy in
Các bản in gốc đảo ngược câu chuyện màu sắc. Máy in muốn CMYK đặc trưng hóa, và tiêu chuẩn buộc bạn phải nêu rõ liệu việc trapping đã được áp dụng hay chưa ngay cả khi câu trả lời trung thực là bạn không có ý tưởng gì. Khóa /Trapped là bắt buộc bất kể thế nào:
Pdf.PDFXCompliance := 'X-1a';
Pdf.Trapped := 'Unknown'; // khóa bắt buộc theo ISO 15930
ICC := TFileStream.Create('FOGRA39.icc', fmOpenRead);
try
Pdf.AddPDFXOutputIntent('FOGRA39 (ISO 12647-2:2004)', '', ICC, 4, 'DeviceCMYK');
finally
ICC.Free;
end;
Pdf.BeginDoc;
// vẽ với màu an toàn cho CMYK, không trong suốt, không mã hóa
Pdf.EndDoc;
Số lượng thành phần giờ là 4 đối với hồ sơ máy in CMYK. X-1a cũng cấm tính trong suốt sống, nên hãy kiểm toán bất kỳ đoạn mã vẽ nào xếp lớp các phần tử trong mờ; bất cứ thứ gì một trình xem hợp thành trên màn hình chính là thứ mà một bộ RIP sẽ từ chối diễn giải. Khi xưởng in của bạn gửi một đặc trưng hóa khác, hãy hoán đổi các byte hồ sơ và chuỗi định danh nhưng để nguyên cấu trúc xung quanh
PDF/UA: cấu trúc được tạo ra, không bao giờ được trang bị lại
Khả năng tiếp cận là tiêu chuẩn mà các nhóm thường cố gắn thêm vào cuối cùng, và nó trừng phạt cách tiếp cận đó nặng nề hơn hai tiêu chuẩn kia. Cây thẻ phải phản chiếu thứ tự mà nội dung đã được tạo ra một cách logic, đây là thông tin mà bạn đơn giản là không còn có nữa một khi tệp đã được ghi ra. Đặt PDFUACompliance sẽ bật đầu ra có gắn thẻ, và API cấu trúc gắn mỗi lệnh gọi vẽ với vai trò ngữ nghĩa của nó khi bạn tiến hành:
Pdf.PDFUACompliance := True; // tự động bật tagged PDF
Pdf.Lang := 'en-US'; // đặt tường minh; để trống sẽ quay về 'en'
Pdf.BeginDoc;
Root := Pdf.AddStructureElement(sstDocument, nil);
H1 := Pdf.EmitTaggedHeading(1, Root, 50, 700, 'Quarterly Report');
Para := Pdf.BeginTaggedContent('P', Root);
Pdf.CurrentPage.TextOut(50, 650, 0, 'Revenue grew in all regions.');
Pdf.EndTaggedContent;
Pdf.EndDoc;
Lỗi cần đề phòng là văn bản được vẽ bên ngoài bất kỳ cặp BeginTaggedContent/EndTaggedContent nào. Nó hiển thị hoàn hảo và vẫn vô hình đối với một trình đọc màn hình, nên không có người kiểm thử sáng mắt nào từng phát hiện ra nó; lỗi này được phát hành và chỉ lộ ra khi một người dùng công nghệ hỗ trợ thực sự gặp phải khoảng trống đó. Khi các mẫu của bạn mang các tên vai trò cấu trúc tùy chỉnh, hãy ánh xạ chúng vào tập chuẩn bằng AddStructRoleMap('MyHead', 'H1') để các trình đọc tuân thủ biết chúng có nghĩa là gì. ISO 14289 cũng yêu cầu một ngôn ngữ được khai báo. HotPDF quay về 'en' khi Lang để trống, nhưng đó là một lưới an toàn, không phải một lý do để bỏ ngỏ ngôn ngữ tài liệu thực sự
Xác minh: tin trình xác thực, không tin trình xem
Một trình xem mở được tệp của bạn không chứng minh được điều gì về sự tuân thủ, nên việc xác minh thuộc về đường phát hành với các công cụ kiểm tra cấu trúc chứ không phải hiển thị. Đối với PDF/A và PDF/UA, veraPDF là trình xác thực mã nguồn mở chuẩn tham chiếu; nó báo cáo các lỗi theo điều khoản ISO, điều này ánh xạ thẳng trở lại cấu hình ở trên. Đối với PDF/X, các hồ sơ Preflight của Adobe Acrobat vẫn là phép kiểm tra thực tế, vì sự tuân thủ máy in cũng liên quan nhiều đến ý định màu sắc như cú pháp
Bộ tạo tài liệu tự làm phần việc của riêng nó trong chuyện này. Tại thời điểm lưu, HotPDF đối chiếu các cờ tính năng với phiên bản PDF đã cấu hình, âm thầm hạ cấp những gì phiên bản đó không thể diễn đạt, chẳng hạn như AES-256 hạ xuống AES-128 dưới PDF 1.7. Các cổng tuân thủ trong EndDoc đi xa hơn và báo lỗi thẳng thừng trên các mâu thuẫn cứng, như yêu cầu PDFACompliance cùng với mã hóa. Không cái nào trong hai cái này thay thế trình xác thực bên ngoài. Chúng chỉ ngăn các cấu hình bất khả thi không bao giờ đến được đó
Một thói quen mang lại lợi ích lặp đi lặp lại: quản lý phiên bản toàn bộ thiết lập tuân thủ như một đơn vị. Bản phát hành HotPDF, phiên bản mẫu, checksum hồ sơ ICC, bản build trình xác thực đã ký duyệt. Sự tuân thủ trôi dạt ngay khi bất kỳ cái nào trong số đó thay đổi so với những cái khác, và những cuộc kiểm toán xấu xí nhất là những cuộc mà không ai có thể tái tạo lại tổ hợp nào đã tạo ra một tệp lưu trữ năm năm tuổi. Một bản ghi cấu hình duy nhất cho mỗi lô giải quyết điều đó vĩnh viễn
Cuối cùng, hãy chạy trình xác thực trên đầu ra sản xuất thực tế, không bao giờ trên một mẫu được xây dựng tay gọn gàng. Những lỗi cắn người thường đến từ dữ liệu mà không ai lường trước: một logo khách hàng đến dưới dạng CMYK trong khi ý định lại nói RGB, một chỉnh sửa mẫu vô tình để lọt một phông chữ chưa nhúng, một đường mã mới vẽ văn bản bên ngoài cây thẻ. Hãy giữ lại một tệp đã biết-là-lỗi từ mỗi sự cố trong quá khứ như một đầu vào hồi quy và cổng tuân thủ sẽ duy trì tính trung thực theo thời gian. Đối với khía cạnh hiển thị của các pipeline này, xem bài viết của chúng tôi về đầu ra báo cáo, phông chữ, và hình ảnh với HotPDF; để nối các trình xác thực vào một bản build, có một bài viết đồng hành về tự động hóa kiểm tra preflight PDF
Các thuộc tính tuân thủ, output intent, và API gắn thẻ được dùng trong các ví dụ này đi kèm với HotPDF Delphi Component cho Delphi và C++Builder; trang sản phẩm liên kết đến tài liệu tham khảo đầy đủ cho mọi lệnh gọi được trình bày ở đây