Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting text size using Android PDFDocument based on PDF document/canvas size

I am trying to convert a LinearLayout to PDF using the Android PDFDocument class. I inflate the layout into a ViewGroup, scale the view to the canvas, and draw onto the canvas. I am having success making the PDF, but the font size is drawn based on the device resolution/density and not the PDF size. Basically, the font ends up being huge on the actual PDF. I believe this is due to the View being drawn with regards to the dimensions and density of the device screen and then translated to the canvas.

I have experimented setting the dimensions in px and pt, but I can't seem to get it right. The font appears about the correct size when the dimensions are set very small (1-2dp or px), but I know that when running this across different devices I will have problems.

What is the best way to scale the text and View dimensions so they appear the appropriate size on the final PDF (approx. 12pt font at 300 dpi)? Would I need to pull some sort of dimensions from the device screen and then resize all Views based on a ratio between the device and the PDF canvas??

My head is sore from beating it off the wall.

Thanks, Andy

//Sets print options
PrintAttributes printAttrs = new PrintAttributes.Builder().
setColorMode(PrintAttributes.COLOR_MODE_COLOR).
setMediaSize(PrintAttributes.MediaSize.NA_LETTER).
setResolution(new PrintAttributes.Resolution("res1", PRINT_SERVICE, 300, 300)).
setMinMargins(PrintAttributes.Margins.NO_MARGINS).build();

//create PDF Document
PdfDocument document = new PrintedPdfDocument(context, printAttrs);
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, 1).create();


//Inflate an XML template into a view with a LinearLayout root
LinearLayout container = new LinearLayout(context);
LayoutInflater inflater = LayoutInflater.from(context);
View view = new View(context);
view = inflater.inflate(R.layout.layout_pdf_meal_template, container, true);

//Pull data/strings from SQLite
//My codes goes through and populates the data gathered from the database to the LinearLayout's subviews

//create page
PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();

//Draw view on the page
int measureWidth = View.MeasureSpec.makeMeasureSpec(canvas.getWidth(), View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(canvas.getHeight(), View.MeasureSpec.EXACTLY);
container.measure(measureWidth, measuredHeight);
container.layout(0, 0, canvas.getWidth(), canvas.getHeight());


container.draw(canvas);
document.finishPage(page);
like image 755
aterbo Avatar asked Dec 14 '15 00:12

aterbo


2 Answers

Try canvas.setDensity(72) as it is working for Bitmaps? See here.

Or use 72 for the PrintAttributes.Resolution?

like image 117
user1712200 Avatar answered Nov 15 '22 20:11

user1712200


Apologies for any problems as this is my first post on SO! I solved this problem (albeit using the PdfDocument supplied by PrintDocumentAdapter) by scaling the canvas as follows, where hdpi and vdpi are the horizontal and vertical resolution of the PdfDocument (in your case both are 300, but perhaps you want more for better results?):

....

PrintAttributes.MediaSize pageSize = printAttributes.getMediaSize();
PrintAttributes.Resolution resolution = printAttributes.getResolution();
int hdpi = resolution.getHorizontalDpi();
int vdpi = resolution.getVerticalDpi();
int availableWidth = pageSize.getWidthMils() * hdpi / 1000;

....
content.setLayoutParams(new ConstraintLayout.LayoutParams(availableWidth, ConstraintLayout.LayoutParams.WRAP_CONTENT));

int measureWidth = View.MeasureSpec.makeMeasureSpec(availableWidth, View.MeasureSpec.EXACTLY);
content.measure(measureWidth, View.MeasureSpec.UNSPECIFIED);

content.layout(0, 0, content.getMeasuredWidth(), content.getMeasuredHeight());
canvas.scale(72f / hdpi, 72f / vdpi);
content.draw(canvas);

....

In the above content is the ConstraintLayout I want to print, containing several TextViews. The WRAP_CONTENT and UNSPECIFIED allow the view to take on the correct height and print correctly, in my case anyway.

like image 25
Bill Beastall Avatar answered Nov 15 '22 20:11

Bill Beastall