PDF yang header-nya membawa latar belakang gradasi gaya Word atau Excel, ketika dirender menjadi gambar, biasanya menghasilkan persegi panjang putih kosong di tempat di mana perpaduan warna seharusnya berada. Renderer halaman HotPDF sekarang mematuhi operator sh (shading) PDF untuk gradasi aksial Tipe 2 dan radial Tipe 3: ia mengevaluasi fungsi shading di sepanjang poros gradasi dan melukis perpaduan warna tersebut, di mana versi sebelumnya secara diam-diam mengabaikan operator tersebut dan membiarkan wilayah itu seputih kertas. Dua jenis shading yang mencakup hampir semua gradasi dokumen kantor telah didukung; sedangkan jenis mesh belum, dan artikel ini menjelaskan dengan jujur di mana batas tersebut berada
Mengapa gradasi PDF dirender sebagai kotak putih?
Gradasi PDF adalah konstruksi vektor, bukan bitmap yang dapat disalin (blit) oleh renderer. Kamus shading (ISO 32000-1 §8.7.4.5) menjelaskan geometri — poros atau sepasang lingkaran dalam array Coords — ditambah fungsi warna, dan operator sh melukis shading tersebut di seluruh wilayah klip saat ini, model grafis yang sama dengan yang diekspos HotPDF saat Anda menggambar jalur dan pengisian pada kanvas halaman. Renderer halaman HotPDF menelusuri stream konten operator demi operator, dan operator apa pun yang tidak memiliki jalur kode akan dilewati sehingga sisa halaman tetap dirender. Sebelum versi 2.335.0, sh berada dalam kumpulan yang dilewati tersebut: gradasi header atau halaman penuh tidak memberikan kontribusi apa pun pada output, sehingga latar belakang tampak berwarna putih. File tersebut tidak pernah rusak. Renderer hanya tidak memiliki handler untuk operator satu itu, dan kotak putih adalah tampilan visual dari handler yang hilang
Rantai evaluasi fungsi di balik shading
Shading tidak dapat dilukis hingga fungsinya dievaluasi, sehingga mekanisme tersebut harus ada terlebih dahulu. Shading aksial Tipe 2 dan radial Tipe 3 keduanya membawa /Function yang memetakan posisi parametrik di sepanjang gradasi menjadi warna (ISO 32000-1 §7.10), dan evaluator fungsi HotPDF menyelesaikan FunctionType dan mengirimkannya. Interpolasi eksponensial Tipe 2 (§7.10.3) menghitung C0 + t^N * (C1 - C0) dengan penjepitan Domain dan Range; fungsi sampel Tipe 0 (§7.10.2) membaca kisi-kisi sampel 8-, 16-, atau 32-bit dan memilih yang terdekat melalui peta Encode, kasus yang dibahas mendalam dalam panduan kami tentang pencarian warna sampel Tipe 0; fungsi penjahitan (stitching) Tipe 3 (§7.10.4) memilih sub-fungsi berdasarkan array Bounds dan melakukan rekursi ke dalamnya. Fungsi kalkulator PostScript Tipe 4 (§7.10.5) tidak dievaluasi — mereka diturunkan kualitasnya secara halus menjadi evaluasi yang gagal daripada warna yang salah, sesuai dengan kebijakan konservatif yang diambil HotPDF di seluruh jalur render. Evaluator ini dirilis pada versi 2.334.0, satu rilis sebelum operator itu sendiri, karena pelukis shading hanya sebagus fungsi di bawahnya
Bagaimana HotPDF mengubah gradasi kontinu menjadi piksel?
HotPDF memperkirakan perpaduan kontinu dengan sejumlah pita warna solid yang terbatas. Pelukis shading menelusuri poros gradasi, membaginya hingga 64 pita — lebih sedikit ketika poros tersebut pendek dalam piksel perangkat — mengevaluasi fungsi pada posisi parametrik setiap pita, dan mengisi persegi panjang yang tegak lurus dengan poros menggunakan brush solid. Komprominya adalah jumlah pita terhadap kehalusan: lebih banyak pita mengikuti perpaduan secara lebih dekat tetapi membutuhkan lebih banyak pengisian, dan 64 adalah batas atas yang disengaja. Karena jumlahnya juga berskala dengan panjang poros dalam piksel perangkat, resolusi sangat penting. Merender halaman yang sama pada DPI yang lebih tinggi memperpanjang poros, sehingga gradasi yang pendek memperoleh lebih banyak pita dan garis-garisnya menjadi lebih halus hingga batas atas tercapai
// The shading discretizer uses up to 64 color bands along the gradient
// axis, but never more than the axis is long in device pixels. Rendering
// the same page at a higher DPI lengthens that axis, so a short gradient
// gains bands and the banding softens until the 64-band ceiling is hit.
Thumb := Pdf.RenderLoadedPageToBitmap(PageIndex, 96); // coarser bands
Proof := Pdf.RenderLoadedPageToBitmap(PageIndex, 300); // up to 64 bands
Merender halaman berbayang ke bitmap
Titik masuk publik tidak berubah: RenderLoadedPageToBitmap menerima indeks halaman berbasis nol dan nilai DPI, mengembalikan bitmap 24-bit milik pemanggil, dan mengembalikan nil pada kegagalan alih-alih memunculkan pengecualian, sehingga dukungan shading transparan terhadap kode yang sudah Anda miliki. Halaman yang dulu merender header gradasinya dengan kosong sekarang mengembalikan bitmap yang sama dengan perpaduan warna yang dilukis di dalamnya, dan tidak diperlukan perubahan API untuk mendapatkannya. Satu hal yang patut diingat adalah kepemilikan: pemanggil membebaskan bitmap yang dikembalikan. Seluruh pipa rendering — interpretasi stream konten, glyph tersemat, dan caching halaman — dibahas dalam panduan merender halaman PDF ke bitmap di Delphi
var
Pdf: THotPDF;
Bmp: TBitmap;
begin
Pdf := THotPDF.Create(nil);
try
if Pdf.LoadFromFile('quarterly-report.pdf') > 0 then
begin
// Page 1 (zero-based) at 150 DPI. A gradient-filled header that
// used to come back blank now carries its color blend.
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
Bmp.SaveToFile('page1.bmp');
finally
Bmp.Free;
end;
end;
finally
Pdf.Free;
end;
end;
Perlindungan regresi yang sederhana diperoleh dari panggilan yang sama. Render halaman, sampel piksel di mana pita gradasi berada, dan pastikan ia bukan lagi warna putih kertas seperti yang biasa dilakukan oleh renderer sebelumnya — pemeriksaan satu baris yang menangkap kembalinya perilaku no-op yang lama secara diam-diam
Bmp := Pdf.RenderLoadedPageToBitmap(0, 150);
if Assigned(Bmp) then
try
// True when the sh operator painted; False if the region fell back to white.
HeaderPainted := Bmp.Canvas.Pixels[Bmp.Width div 2, 8] <> clWhite;
finally
Bmp.Free;
end;
Apa yang tidak dilukis HotPDF: mesh shading dan tepi klip
Empat jenis mesh shading berada di luar cakupan, dan sebuah dokumen harus mengetahuinya sejak awal. Free-form Gouraud triangle meshes (Tipe 4), lattice-form Gouraud meshes (Tipe 5), Coons patch meshes (Tipe 6), dan tensor-product patch meshes (Tipe 7), yang ditentukan di ISO 32000-1 §8.7.4.5.5 hingga §8.7.4.5.8, tidak dirender; halaman yang menggunakan salah satu dari mereka tetap dirender, hanya saja wilayah tersebut dibiarkan apa adanya. Dua batasan lebih lanjut layak untuk dinyatakan secara jelas. Persegi panjang pita mencakup garis shading daripada dipotong tepat ke jalur klip saat ini, sehingga gradasi yang dimasker menjadi bentuk bulat atau tidak beraturan akan melukis sebagai garis batasnya hingga pemotongan wilayah yang tepat hadir di putaran berikutnya. HotPDF juga mengasumsikan output fungsi adalah RGB or grayscale, so a shading authored in CMYK or an exotic color space is approximated rather than color-managed. Untuk dokumen yang sebenarnya diproses oleh sebagian besar tim Delphi dan C++Builder — laporan, faktur, pernyataan, dan salinan slide yang diekspor ke PDF — aksial dan radial mencakup hampir setiap gradasi yang akan Anda temui, dan bukti desain yang sarat mesh adalah kasus yang harus diperlakukan sebagai pratinjau dan bukan sebagai bukti hasil akhir
Renderer halaman HotPDF, dukungan operator sh yang dijelaskan di sini, dan evaluator fungsi Tipe 0/2/3 di bawahnya didistribusikan sebagai bagian dari HotPDF Component untuk Delphi dan C++Builder — pustaka VCL asli tanpa dependensi DLL eksternal, yang mencakup pembuatan, pengeditan, ekstraksi teks, dan rendering halaman PDF dalam satu paket