Bài viết kỹ thuật

Định hình Văn bản Tiếng Ả Rập và RTL trong PDF bằng Delphi với HotPDF

Truyền cụm từ tiếng Ả Rập يوضح ملف PDF vào TextOut và mở kết quả. Các chữ cái chạy sai hướng, và mỗi chữ nằm ở dạng cô lập (isolated form) của nó với một khoảng trống hiện rõ trước ký tự tiếp theo, giống như có ai đó gõ tiếng Anh ngược và nhấn dấu cách giữa mỗi ký tự. Không có ngoại lệ (exception) nào kích hoạt. Không có cảnh báo nào in ra. Đầu ra đơn giản là sai, và nó sai bởi vì hai phép biến đổi độc lập mà tiếng Ả Rập phụ thuộc vào đã không bao giờ diễn ra. Biết được hai phép biến đổi đó là gì, và hàm gọi nào thực thi chúng, là phần lớn những gì cần giải quyết về kết xuất PDF ngôn ngữ kịch bản phức tạp (complex-script PDF output)

HotPDF là một thành phần VCL PDF gốc dành cho Delphi và C++Builder, và nó thực hiện công việc chuyển đổi từ phải sang trái (right-to-left) cho bạn thông qua một lệnh gọi khác biệt. Nó cũng dừng lại ở một vài khía cạnh cụ thể mà bạn muốn biết trước khi bạn cam kết hỗ trợ một ngôn ngữ (locale), vì vậy bài viết này liệt kê các khái niệm và các ranh giới thực tế; hướng dẫn thiết lập thực hành cho bản thân lệnh gọi đó nằm trong bài viết tham khảo về RtLTextOut

Tại sao một chuỗi ký tự chính xác vẫn in ra sai

Unicode giữ văn bản theo trật tự logic (logical order), tức là thứ tự mà bạn gõ và đọc to nó lên. Trình kết xuất (renderer) thì phải đặt các hình tượng (glyphs) xuống theo thứ tự trực quan (visual order). Đối với các kịch bản viết từ trái sang phải, các thứ tự đó trùng khớp với nhau và không ai phải suy nghĩ về nó. Đối với tiếng Ả Rập và tiếng Do Thái, chúng không giống nhau, và khi một dòng đơn lẻ trộn lẫn nhiều hướng đi, chẳng hạn như một câu tiếng Ả Rập mang theo một mã (token) Latinh là "PDF" hoặc một giá tiền viết bằng số, Thuật toán Đa hướng Unicode (Unicode Bidirectional Algorithm - UAX #9) quyết định một cách chính xác cách các đoạn từ-trái-sang-phải lồng ghép bên trong một dòng từ-phải-sang-trái. Đó chính là phép biến đổi đầu tiên, tức là sự sắp xếp lại trật tự (reordering), và bỏ qua nó là nguyên nhân lật ngược dòng văn bản

Phép biến đổi thứ hai là định hình theo ngữ cảnh (contextual shaping). Một chữ cái tiếng Ả Rập được vẽ khác nhau tùy thuộc vào vị trí của nó trong một từ: ở đầu (initial), ở giữa (medial), ở cuối (final), hoặc đứng một mình (standing alone). Mã điểm (codepoint) vẫn không thay đổi trong suốt quá trình; chỉ có hình tượng (glyph) là thay đổi. Một luồng xử lý (pipeline) chuyển thẳng từng mã điểm thành hình tượng mặc định của nó tạo ra chính xác kết quả bị ngắt kết nối, dưới dạng cô lập như ví dụ ở đoạn mở đầu. Tiếng Do Thái bỏ qua bước này, bởi vì các chữ cái của nó không nối với nhau, nhưng nó vẫn cần sự sắp xếp lại. Tiếng Ả Rập cần cả hai, và đó là lý do vì sao tiếng Ả Rập, chứ không phải tiếng Do Thái, mới là chuỗi văn bản bạn dùng để kiểm thử

Trên máy tính để bàn, chẳng có gì ở đây là vấn đề của bạn cả. Khi một biểu mẫu VCL (VCL form) vẽ tiếng Ả Rập vào trong TEdit, ngăn xếp văn bản của hệ điều hành sẽ âm thầm sắp xếp lại và định hình nó, đó cũng chính là lý do vì sao chuỗi văn bản trông có vẻ hoàn hảo trên màn hình lại đi ra một cách hỏng hóc trong một tệp PDF đơn giản (naive PDF). Một luồng nội dung (content stream) không lưu trữ dạng văn bản có thể chỉnh sửa. Nó lưu trữ những hình tượng (glyphs) đã định vị, vì thế bất kể ai phát xuất luồng dữ liệu đều kế thừa lấy công việc định hình (shaping) mà hệ điều hành từng xử lý. RtLTextOut là hàm gọi lấy lại chức năng đó

Những gì RtLTextOut sẽ định hình cho bạn

HotPDF giữ cho luồng chạy (path) tiếng Latin và luồng ngôn ngữ phức tạp (complex-script path) thành hai phương thức khác biệt. TextOut in ra những gì bạn cấp cho nó theo đúng thứ tự bạn đưa vào. RtLTextOut thực hiện cả hai phép biến đổi trước — xếp đặt lại đa hướng (bidirectional reordering) chạy dọc qua toàn bộ một dòng, phân tích ngữ cảnh (contextual analysis) dành cho các nét kịch bản nối chữ — và sau đó mới in ra. Các quy tắc định hình của hệ kịch bản nào được áp dụng sẽ được đưa vào (travels in) thông qua bộ mã ký tự của phông chữ (font's charset) thay vì thông qua chính lệnh gọi đó, vì vậy hướng chạy là một lựa chọn minh bạch (explicit) ở mọi điểm gọi hàm thay vì là một sự suy diễn bắt nguồn từ chính các ký tự đó. Các bước thiết lập từ tham số này đến tham số khác, những giá trị cho bảng charset, các bước đăng ký font chữ, và cả một ví dụ khả biên dịch toàn vẹn đều có trong bài viết tham khảo RtLTextOut; phần này chỉ đi liền vào ý nghĩa của những biến đổi đó là gì, chúng ngừng lại ở đâu, và cách chứng minh chúng đã vận hành

Có một quy tắc sử dụng mang tầm quan trọng kể cả ở tầm cao tổng quát thế này: dữ liệu đầu vào bắt buộc phải theo trình tự logic, bởi vì RtLTextOut sẽ tự thực thi việc hoán đảo, và một chuỗi bạn đã lật lại bằng tay rồi sẽ bị biến thành đảo nghịch kép (double-reversed) — bài viết tham chiếu đã dẫn dắt qua cái bẫy này lẫn công tác sửa lỗi nó. Điều mang lại sự quan tâm về lỗi ngầm này ngay tại đây nằm ở lý do tại sao nó vẫn qua lọt công đoạn testing. Một dòng tiếng Ả Rập thuần túy bị đảo nghịch kép (double-reversed pure-Arabic) có thể trông hoàn toàn chuẩn xác, và nó chỉ gãy vỡ (falls apart) lúc một dòng có chứa một từ tiếng Latinh hoặc một chữ số, bởi vì những chuỗi đi vào được nhúng đó không còn khớp nhau theo cách mà tiêu chuẩn UAX #9 chỉ thị nữa. Lỗi bug không nằm bên trong khâu kết xuất render; nó nằm ở việc nạp (feeding) thứ văn bản (text) đã được xử lý đi một nửa vào cỗ thuật toán đó

Chính sự phản ứng hướng hỗn hợp (mixed-direction behavior) tương tự này lại khiến cho người duyệt xem văn bản dễ bị bối rối hơn cả mã code bị lầm lẫn. Nằm trong một dòng chạy từ phải qua trái, thì những con số và chữ tiếng Latin nằm lồng vào vẫn chạy đọc từ trái sang phải. Sẽ có người vốn chưa làm việc với các khối cấu hình bố cục bidi đa hướng (bidirectional layout) khi nhìn vào tờ hóa đơn đã lên kết xuất sẽ thấy số tài khoản bị quay sang "sai" đầu (the "wrong" way) nếu đặt tương chiếu với khối từ tiếng Ả Rập ở bên cạnh nó, thế rồi liền viết báo cáo nó như là một lỗi. Đó hoàn toàn là kết quả đúng chuẩn spec. Một dòng ghi chú ngắn gọn thuộc bộ tiêu chuẩn nghiệm thu, được viết trước mốc thời gian kiểm thử chéo của một độc giả ngôn ngữ bản xứ (native-speaker pass), sẽ tiết kiệm được rất nhiều thời gian cãi qua cãi lại đấy

Khi nào định hình nối chữ và đảo hướng là đủ, và khi nào không

Đối với văn bản thông dụng đang chạy nối tiếp bằng tiếng Ả Rập và Hebrew — từ các báo cáo, các hóa đơn, hợp đồng cho đến các bức thư từ — đảo hướng (reordering) đi cùng nối dính khối ngữ cảnh (contextual joining) là toàn bộ khối lượng công việc rồi, và RtLTextOut hoàn toàn đáp ứng trọn vẹn được một mình nó. Khúc giao điểm sẽ hiện ra ngay khi các cấu trúc typo vươn khỏi phần nối chữ (joining). Câu trả lời của HotPDF khi xét về hệ tiếng Ả Rập đó là một cỗ định hình phía xuất lệnh do mình tự quyết (opt-in producer-side shaper): cài đặt AutoShapeArabic := True và cả thư viện này sẽ đi chép lại đoạn nội dung thứ tự-logic ban đầu dồn sang thành cấu hình hiển thị Unicode (Unicode Presentation Forms) diễn ra ngay phía trước phần chạy luồng hai chiều (bidirectional pass), nên vì thế các dạng khối nối chữ mới được đo tính trực tiếp đè lên các chữ hàng xóm sát bên (logical neighbors) rồi phần gấp gập chữ nối đè (ligature folds) cứ vậy được in thẳng xuống thành những đoạn mã codepoints mà tệp định dạng PDF sẽ thật sự chứa (carries), thay vì phó thác cho trình xem PDF (viewer) tự biên tính ra. Nút lật này mặc định đóng (off) và đường ra đầu ra giữ ổn định cấp byte (byte-stable) khi nó được giữ yên, vậy nên kích mở nó là một quyết định cân nhắc dành riêng trên từng tuyến văn bản đầu cuối (per document pipeline), không phải là công tắc nâng cấp toàn cầu (global upgrade). Đồ hình thiết kế tự quyết (opt-in model) đó cũng được nối dài đến tất cả ngôn ngữ nối chữ (joining right-to-left scripts) khác mà HotPDF định hình: Syriac, N'Ko, Adlam, và Hanifi Rohingya trong từng loại cũng đều đang mang sẵn cờ (flag) kiểu auto-shape của riêng nó và bắt chước y hệt tiếng Ả Rập

Những tính năng OpenType mang tính chất cấu hình là một bộ phận máy móc khác hoàn toàn. Chuỗi chữ dính liền tạo dáng tùy ý (Discretionary ligatures) cùng những khả năng tính năng thay ký tự đơn điểm (single-substitution features) tương tự sẽ chuyển lướt qua bộ GetSingleSubstituteGlyph(GID, 'liga'), nó tự phân rã lần lượt một bản chuyển đổi thay thế (substitution) ở mỗi lượt — lấy ID của ký tự hình nhập vào ở hàng trước nhất, mã ghim thẻ đặc trưng (feature tag) đưa vào thứ nhì — rồi đáp trả nguyên một bản chưa biên đổi của glyph đó mỗi khi cái feature ấy không phù hợp chức năng. Công việc đó vốn đã quá đủ dùng khi muốn kéo lái một bảng danh mục gập ligatures khả hữu (finite) đã biết được tự tay giữ. Nó không phải toàn bộ hệ máy GSUB hoàn chỉnh (full GSUB engine), và điểm cách biệt đó cũng đúng vừa vặn tại vị trí nơi những mưu cầu tích hợp một ngôn ngữ địa phương hoài bão nhất gánh lỗi rẽ lối đi sai: một cấu hình xử lý đường truyền định dạng nối nối tiếng Ả Rập không tì vết thật ra đã chỉ cho thấy xong khâu định lại bidi (reordering) và phần gập khối dính nét (joining) thôi, không hơn đâu

Phạm vi phủ sóng qua các kịch bản chữ

Tiếng Ả Rập kiểm chứng (exercises) được cả hai phương án biến đổi, đó chính là lý giải do đâu mà nó là hệ chuỗi dành cho mục đích bài test rà lỗi, và do đâu việc thả trót lọt một khung chuỗi Ả Rập (Arabic pass) là mảnh bằng chứng chắc chắn nhất làm tin hệ pipeline này chạy ổn. Ngôn ngữ Hebrew cần khâu đổi xoay (reordering) nhưng lại chẳng màng gì tới sự cấu dính (joining), bởi lẽ các mẫu chữ của nó đứng đơn độc (stand alone); giả như Hebrew được render nét căng mà Arabic lên bản in toàn trôi dạt cắt ngang rời rạc, thì tức là nửa cấu hình đôi bidi (bidirectional half) cực tốt còn cái vế nối nét dính liền định dạng context (contextual half) còn chưa thèm khởi chạy bao giờ

Tiếng Thái (Thai) lại ngự ở đằng sau phòng tuyến khác biệt toàn diện. Nó chạy chữ từ trái xuyên ngang tới bên phải, nên hoàn toàn không dính dáng bất cứ thứ thao tác phân chiều (bidirectional) nào, mà con chữ của nó cũng đâu dính nối, vậy nên nó khỏi phải tính điểm ngữ cảnh bối cảnh (contextual analysis) luôn; bộ chuỗi (strings) hệ Thai cứ thế rẽ vào luồng thông thường của TextOut hệt như hệ Latinh. Thứ tiếng Thái đang nắm giữ ở đây chính là các nhóm dấu ký đè ngầm định dồn chồng (stacked marks) — những thẻ thanh điệu lẫn thanh âm (vowels) vắt ngang cả chóp đầu hoặc treo phần chân (above and below) các chữ phụ âm căn bản (base consonant) — cùng việc định đoạt coi chúng ở chỗ đó được ổn định chưa lại phụ thuộc vào cái gốc phông chữ kia định hướng tích dựng bộ gộp ký tự dồn dấu kết hợp (combining marks) sao cho ăn khít với kiểu nén lớp (stack) lại mà không mượn đến engine shaping phân tích hỗ trợ. Vài mẫu phông chữ Thái chuẩn mực đa phần thường sẽ được việc. Hãy chạy test ngay cùng bộ chữ cụ thể bạn nhắm đem cài đặt nhúng, thay vì cái đồ tương đương giả

Hệ chữ Devanagari và tất thảy phần dư lại từ gia đình gốc ngôn ngữ Ấn (Indic) đều chắc nịch một cách chướng ngại thành thật khó qua (honest hard stop). Mấy kí hiệu thanh mẫu (vowel signs) xoay quanh bấu vào rải khắp trên mọi cụm chùm phụ âm (consonant clusters) cùng chuỗi phức liên phụ âm dính cục (conjuncts) thành lập trải trên những dây xích hoán ứng nối thay thế bám vào hoàn cảnh, đấy toàn quy về phận đất thuộc riêng của nền GSUB hoàn thiện trọn gói, vượt khỏi cái vỏ bọc xếp ngược chuyển hướng và dồn nối chữ (joining). Kể ra nếu tính đến chuyện để tiếng Ấn bản ngữ (Indic) dọn lối trong lộ trình (roadmap) cho dự án, thì bạn hẵng cho chạy một mẻ thí điểm thật lòng với những dòng chữ khách hàng (customer strings) thực chất đã, sớm hơn việc buột miệng lên mặt hứa — việc xử Ả Rập làm ngon trơn chẳng cấu thành cơ sở cho ra Devanagari êm ru đâu. Các chuỗi (strings) hệ CJK (Trung/Nhật/Hàn), tiếng Việt mang kèm bộ thanh dấu vắt đè nhau (stacked diacritics), cộng thêm thứ ngôn ngữ châu Âu trộn hỗn độn đều nắm theo lối luồng mòn thông lệ và không ngó nghiêng gì bộ phận phân tách dòng đa chiều (bidirectional analysis), và rất bõ công (pays) hòng mà phân rẽ rạch ròi giữ cả đôi đường nhánh đó tác biệt vật lý với nhau khỏi đoạn xử lý làm nội dung kết xuất (report code), thả bên đoạn trích xử (routine) dùng đối nội với lượt chạy RTL (RTL runs) và dành trích kia lo toan mọi thứ còn thừa lại, thế nên lý do luận cứ thuộc locale cứ trực diện tại ngay trên khung gọi trích hàm thay vì núp sau cờ hiệu gán lỏng lúc có kẻ quên ghim

Phạm vi che lấp hình tự Glyph được phán quyết trước cả định dạng shaping

Phần Shaping bốc các khối hình (glyphs) lấy từ bên trong cái mâm chứa là phông chữ (font). Gặp đúng phông này chả bao nạp giữ chúng, thì chẳng thà chẳng có cái rỗng gì cả mà nhúp lấy, vốn là một nguyên do kinh điển chôn vùi vụ làm phân phối ứng dụng (deployment failure) — ở phía bên dàn của nhà lập trình mọi việc rất lung linh, vậy mà kéo theo mảng hộp khuyết trống rỗng trơn về đầu server của khách khi vụ thế chấp phông (font substitution) không một tiếng nói kéo theo — chính là hệ lụy không bao hàm tới được mặt chữ (coverage problem), hoàn toàn không phải lỗi khâu cấu kết định dạng hình thái (shaping problem). Đường lối sửa bài thuốc theo hiện trường, xin phép đăng kí nguyên khối phông (font) nhét cùng app chuyên chở thay vì phó thác mọi sự phụ trợ nơi cỗ thiết bị có sẵn (machine has installed), đang được chỉ đi chi tiết từng li tại trang nội dung bản tham chiếu. Gốc điểm cốt túy tư duy (conceptual point) là mặt bao chữ (coverage) thà phải khai thông minh định rõ chuẩn trước tất tật bao nhiêu nghi vấn kiểu dáng shaping ngớ ngẩn (meaningful), và rằng nó được đoan chắc lên khối mã trình (programmatically) thay vì phải tự căng nhãn quan săm soi dòm liếc mặt ảnh ngõ ra

// Sau hàm RegisterUnicodeTTF, hãy đánh giá (audit) độ phủ cho
// dải mã điểm (codepoints) mà dữ liệu của bạn thực tế sử dụng
GID := Pdf.GetUnicodeGlyphForCodepoint($0628);  // U+0628 ARABIC LETTER BEH (Chữ Ả Rập BEH)
LogGlyphAudit($0628, GID);

Bản thân tiến trình cấu kết làm ghi danh cũng đã đeo hai hòn neo hạn định — nền PDF 1.5 làm phần đỡ bắt bược để ứng công tác lồng nhúng dải Unicode (embedded Unicode) cùng phân định bit cho giấy cấp nhúng của mẫu phông (font's embedding-permission bits) — kể thảy cũng mang điểm tại chung lối dẫn đính cặp với đoạn trình ở bài tham chiếu về lệnh RtLTextOut. Điều hợp lối thuộc vào chỗ này chính là cung cách thanh tra (audit habit): lệnh GetUnicodeGlyphForCodepoint là chiếc hệ còi phát cảnh giới ban sớm (early-warning system) của bạn. Mở đường dò tìm qua chùm danh bạ độ trải codepoint mà dòng dữ kiện của bản gốc thực bụng xài ngay lúc phần việc dịch vụ cất bước leo trớn khởi hành (starts up) và log chép mảng IDs của hình khối (glyph IDs) gửi đền về. Lúc đó 1 vết lõm bám hụt chữ phủ (coverage gap) sẽ lột mặt ra thành một hàng viết nằm vạ lên đường lưu hệ log khởi đà xuyên vào mốc tiến lăn (rollout), thay cho dáng dấp làm những chữ tự chạy mất dạng nhởn nhơ nơi cuống phiếu hóa đơn (invoice) cái mà vốn xui thay mò mẫm chạm ngõ tới một khách khứa mất rồi

Trình tự lối đọc vốn thuộc quy chế cho Văn Bản, đâu phải quy về hình chữ Glyph

Vuốt được từng con mảnh glyph khớp trơn tru vẫn chừa cho lại một thứ dang dở trơ gọng. Quy chuẩn ISO 32000-1 §12.2 ấn định cho 1 kiểu sắp xếp (viewer preference) sở hữu định danh /Direction làm vai ấn định thông báo trật tự duyệt ngắm theo toàn vẹn tổng quát của khung văn (document's overall reading order). Nó chẳng thèm sờ vào mảnh ghép glyph nào sất. Công đoạn của nó làm hòng rao báo cỗ thiết bị trình xem (viewer) bằng cách thức làm sao bố cục mảng kẹp hai mặt nối tiếp (two-up spreads), bề nách phía bìa nào thiết kế trải mặt-đối-mặt (facing-page layout) lẽ phải mở ra khai cuộc từ đó, và hướng mặt nào giao diện điều phối thao tác duyệt bài (reading UI) nên đánh ngả đầu tới. Phẳng lì mọi yếu tố trên vốn không bày tỏ hình bóng bản thân tại diện một tờ mặt đơn lẻ (single page), đây là lý do xác tín vì tại làm sao cái kia hay gánh chịu tình trạng rơi vào dĩ vãng quên lãng

// Chỉ định trật tự đọc từ phải qua trái ở cấp độ toàn bộ tài liệu (document level)
Pdf.Direction := RightToLeft;  // bổ sung vpDirection vào mục ViewerPreferences

Lên khung điều phối tham số Direction đọng thâu trọn công vụ rồi: phần gài thuộc tính (property setter) sẽ cấy thông số vpDirection chèn ngập sâu thuộc tính ViewerPreferences (Tùy Chọn Khung Nhìn Trình Xem) thuộc về cấu kết trang văn, như thế có duy nhất một đường chuỗi rinh lôi tùy lựa lấn vô ruột file đó thôi. Xảy như chùm dải chữ nọ dồn ra phía ngoài xuôi qua cổng của RtLTextOut bạn ẵm ngay thứ kia làm phí (free), bởi lẽ tiếng gọi lệnh (the call) tung lật (flips) mảng điều hướng trang giấy dội trả cho 1 tác nhân phụ hệ văng trượt theo lề (side effect) — bài tham chiến đối chứng đã bao khoanh chốt định cái thời điểm 1 phần file hỗn hợp vần vũ đoái mong một thao tác cởi dỡ trói (undone) đấy. Mảnh sự vụ nơi ngài bệ hạ bắt buộc phải chính tay khai dựng nó đó là 1 tài liệu bản pdf đánh tráo đầu về dạng từ-phải-qua-trái (right-to-left document) làm từ cấu thành mọi loại phương thế luân phiên nào khác nưã, cụ tỷ để nói ví dụ gạt bắt trích xuất ra từ ngõ thâu vào do người điều chỉnh định khối uốn (pre-shaped) ở khúc thượng nguồn trút (upstream) rồi đổ màu vẽ len vào lối đi (ordinary path) truyền cựu xưa. Ném xó buông lửng nó phơi ra kia thì dải tờ nguyên cọc in ra phác vạch mẫu chứng thực 1 mặt (single-page proof) nơi ngài mải dán mi mục chăm dòm chõ nom lốt thấu đồng dạng tựa in vào bất kì một dáng kiểu nào trót lướt qua; rồi thời điểm đó lúc một tay ất ơ tống bản sao cho máy phun lệnh 2 mặt (duplex) mảng cuốn sổ in ghép (booklet), những cái chạc xoè 2 đôi trang mặt đâm húc phơi phảng dạng hình hắt mặt tráng gương (mirrored), và mầm sự cố gây chuyện đích thực khởi xướng nên từ sự bưng trốn rơi sót (missing) của cỗ đoạn dòng (one-liner) mốc nối duy nhất vốn trôi tuột của tuần tự cũ rích thủa ròng rã nào cơ

Chế độ thẩm tra giám định phần ra khung hình định dạng

Nghiệm định dò la giáp gốc tận nguồn (Verify end to end), với vì một vách trang PDF hoàn toàn ngắm nghía cho qua được là đủ khuôn ngay thẳng rồi vậy nhưng y nguyên bốc thành rác bỏ vô vụn phế thải so với mọi thể loại quy về hạ nguồn (downstream). Ba mốc lượt xét nghiệm xộc ra tìm kiếm bắt sóng đặng khối vụn khuyết lớn phập phồng (problems). Quẹt gánh (Copy) cuộn văn (text) kéo tuột ngược đánh tống (back out) giũ khỏi bộ Acrobat rồi làm nhịp cân đo (compare) chùm mảnh chữ con kí (codepoints) nhắm bắn đối hạch vào bộ xâu chữ nhập nguyên thủy (source string). Nhét bấm trồi chế độ làm search tìm hạch sách chữ ở trong file (in-document search) ở bản khung đọc máy (viewer's) để ngắm định một dãy chữ mà nơi này ngươi ngó trông rõ (can see) tại cõi giấy. Xong mở toang cửa ốp bộ tống kết ra (output) giội nơi cỗ máy vắng vẻ tiệt phông chữ nền đồ (development fonts) của người sở hữu đính sẵn, đồ vọc mà nó là dòng thiết bị mang độ bắt thóp dễ dính (most likely) lộ diện vụ đánh bù hoán chuyển thay phông (substitution). Sạch chẳng mấy đồ gỡ lại gánh trọn đỡ việc lật mở giùm cho mặt giám khảo xem ngôn chuẩn thuần địa (native reader) mắt ghim chặt soi mói ở đích một tài liệu chuẩn thật đúng gốc rễ (one real document), thứ lột tẩy thó túm rặt mấy cái dằm cọc màng thứ bộ tập rác ráp máy móc phỉnh lừa (synthetic corpus) sẽ nhè bỏ tuốt. Chiếm được nhịp rà soát (review) điểm danh ấy kẹp lên khung đặt của lịch làm việc rành rành từ thủa trước khi bộ đồ format đánh chuông đóng sập đậy xuất thuyền đi

Trích ngắt có điểm tính các cụm văn thử nghiệm (test strings) đúng bề chủ tâm rắp đặt (on purpose) thay chỗ chuyện gom bốc dùng nhặt vòng (recycling) hễ bất kỳ dòng chữ mớ nào tay phụ dịch thuật (translator) dồn ném đền từ hạn mùa cả năm (last year) nọ. Mức bệ thấp biên an định cho đủ rành một mảng ngôn bản địa (workable minimum per locale): một câu thuần chất dạng hệ script yêng bản, lại đi với đôi đoạn văn chữ gá lẫn cả danh bạ từ Latin đóng dãn thương hiệu hãng mác, với dải dọc rải bới gồm mấy con nét số liệu pha dòng giá loại tiền cước, kèm bộ định danh gánh luôn bộ trích thanh chìm diacritics hay vướng mắc gộp marks bấu nhằng nhịt. Tên hiệu chủ định dòng khách ruột bản xịn bẻ răng cấu thủng cái sự lập định mặc định tin phó (assumptions) rằng nấy chùm đám văn bịt trám (filler text) rỗi hơi dọn chỗ lấp ló vẹn rành nguyên chưa động thủ tới (untouched), thành thế hẵng đành mở nới mảng cọc rào kiểm tụ lùi (regression set) ấp cơi lên theo cấp bệ độ lùi thêm một đoạn chữ string mỗi bận độ 1 sự vụ ốp lên ngả support mọc đẩy ra (turns up) thứ định khối mẫu dạng chưa màng dòm thấu ngó đến

Lên đăng thông danh phông (Font registration), việc tỉa chia tách chữ rút ngắn (subsetting), với toàn bộ hàm api vọc văn vẽ lệnh API kéo ngày diễn ra (everyday text-drawing API) bọc gộp sẵn nơi mục văn bản đầu thông bản tài báo, kho phông, cùng dạng bộ ảnh mảng nhúng (images with HotPDF). Nếu cả thứ mẫu bản thư tệp kia đồng phần bị ghép bắt đo hạch vọc gỡ cấu hình điều chế mặt khả cập tương tiếp thông dạng accessibility profiles (accessibility profiles), các bước quy nạp trói thẻ ngôn dải từ (language tagging) đi kèm mấy chế luật định khung hình tại trang luận án báo hạch chuẩn định hóa cho mảng PDF/A cùng PDF/UA validation bám sấn đứng đĩnh đạc bọc choại bên phía mặt nổi chóp rũ (sit on top of) lên cái ngả chế vụ nhồi vọc shaping tại ranh giới đây

Những kho giao dịch APIs lo ngả phải qua phía trái cùng kho Unicode phông cất rải vạch trên xuất thân bám đẩy luân chuyển gá cùng Thành phần HotPDF (HotPDF Component) ứng dựng trên sàn Delphi và gã C++Builder; mục link trang chứa sản phẩm gắn dính cọc cả mảng trích xuất thông đáp text-output reference toàn bộ luôn