I have an issue with generating a PDF with PdfDocument on Android. I've tried to generate the most generic PDF:
val pdfFile = File({filePathToPdfFile})
val pdfDocument = PdfDocument()
val pageInfo = PdfDocument
.PageInfo
.Builder(
PainterPdf.pageWidth,
PainterPdf.pageHeight,
1,
)
.create()
val page = pdfDocument.startPage(pageInfo)
val canvas = page.canvas
canvas.drawText(
"Hello World!",
100f,
200f,
Paint(),
)
pdfDocument.finishPage(page)
pdfDocument.writeTo(FileOutputStream(pdfFile))
pdfDocument.close()
This generates a PDF which weight 179,5 KB which is very heavy. I've try some libraries (iText and pdfBox) but... iText is EOL for free version (and there are some vulnerabilities), and pdfBox has some vulnerabilities with android portage (the java version doesn't work).
Is there a way to reduce the weight of the generated PDF file with PdfDocument. It's seems very strange that it weight that much!
Thanks
I can reproduce the problem on Android 13 but not on Android 9 which produces a 14.3Kb file.
The difference between the 2 PDF's seems to be in the size of the embedded font file.
Android 13 uses "AAAAAA+RobotoStatic-Regular"
Android 9 uses "Roboto-Regular"
On Android 9 it embeds a subset of the font, just enough of the font for the letters used (8 characters). As you add more different characters the font data size gets larger.
On Android 13 it embeds all the characters of the font
I don't think you can change this behaviour, while this might make the pdfs larger for examples with limited set of characters, in real world pdfs then the differences will get smaller because more characters are used.
Having the full font embedded is much better if the PDF is edited later because as new characters are used then the editing program will have the correct font available and won't have to use a different font it it does not have the correct font available.
If you want to make is smaller then try a different Typeface like
Typeface.MONOSPACEas it is smaller (probably because it does not have the bold and or italic versions of the font)Update
As Pdfdocument just uses the Skia PDF backend as Skia is the graphics Library Android uses, I don't think behaviour can be changed at runtime.
I would raise a bug with google about the change in behaviour, especial as it's not mentioned in the documentation. (Font Subsetting feature should be made runtime configurable in Android)
As a work around have you tried drawing everything to a bitmap and then drawing the bitmap to the PDF canvas.
e.g. change the drawing part to:-
As bitmaps are compressed, depending on your content it might meet your size requirements, in this example the PDF ends up at 3.5KB
Note the Text won't be selectable and the quality might be too low for you.
It might be possible to fix the quality and keep inside your size requirement by generating a higher resolution bitmap (say twice the pdf point size) and then when drawing the bitmap to the PDF scale it back to half the size
e.g.
Update 2
May be you could manually optimize the fonts, do you need more than the first 128 (Basic Latin) characters? as the default fonts contains 3000+ characters. e.g. generate your fonts with less characters in them.
The process used to use a tools called "sfntly" and you might be able to use this to dynamically subset your fonts to the characters actually used.
Note
Not all fonts allow you to modify them, thus you could be breaking the fonts license if you subset them, this might be why Google have generically disabled font subsetting in PDFs.