Skip to content

Add Android rendering logic for PDF reports#3774

Open
andreia-ferreira wants to merge 22 commits into
masterfrom
andreia/3739/pdf-report-layout
Open

Add Android rendering logic for PDF reports#3774
andreia-ferreira wants to merge 22 commits into
masterfrom
andreia/3739/pdf-report-layout

Conversation

@andreia-ferreira

@andreia-ferreira andreia-ferreira commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Towards #3715

This PR adds the specific Android implementations for rendering PDF files.

Main changes:

  • New helpers:
    • PdfCursor to keep track of the current position within a page and its reserved spaces
    • PdfPageController to keep track of page counts and their lifecycles
  • Android implementations of the previously introduced interfaces as well as platform specific helpers PdfWriter, PdfCanvas, PdfTextPaints and DocumentPdfCanvas in order to draw the layout

There are no functionality changes yet. The full flow will be implemented in a final follow up PR. For reference, the current layout will generate the following document structure:
Screenshot From 2026-06-10 14-25-22

@shobhitagarwal1612 PTAL?

@andreia-ferreira andreia-ferreira changed the title Andreia/3739/pdf report layout Add components to render the PDF layout Jun 9, 2026
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.52239% with 82 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.97%. Comparing base (c167392) to head (25ffb1f).

Files with missing lines Patch % Lines
...undplatform/feature/pdf/AndroidPdfImageProvider.kt 52.77% 24 Missing and 10 partials ⚠️
...ndplatform/feature/pdf/AndroidPdfReportLauncher.kt 0.00% 19 Missing ⚠️
...g/groundplatform/feature/pdf/AndroidPdfRenderer.kt 0.00% 17 Missing ⚠️
...ndplatform/feature/pdf/render/DocumentPdfCanvas.kt 55.55% 6 Missing and 2 partials ⚠️
...org/groundplatform/feature/pdf/render/PdfWriter.kt 98.03% 1 Missing and 2 partials ⚠️
...ndplatform/feature/pdf/AndroidPdfOutputProvider.kt 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3774      +/-   ##
============================================
+ Coverage     66.60%   66.97%   +0.37%     
- Complexity     1684     1771      +87     
============================================
  Files           392      402      +10     
  Lines         10145    10480     +335     
  Branches       1295     1333      +38     
============================================
+ Hits           6757     7019     +262     
- Misses         2711     2769      +58     
- Partials        677      692      +15     
Files with missing lines Coverage Δ
...org/groundplatform/feature/pdf/render/PdfCanvas.kt 100.00% <100.00%> (ø)
...groundplatform/feature/pdf/render/PdfTextPaints.kt 100.00% <100.00%> (ø)
...org/groundplatform/feature/pdf/render/PdfCursor.kt 100.00% <100.00%> (ø)
...ndplatform/feature/pdf/render/PdfPageController.kt 100.00% <100.00%> (ø)
...ndplatform/feature/pdf/AndroidPdfOutputProvider.kt 88.88% <88.88%> (ø)
...org/groundplatform/feature/pdf/render/PdfWriter.kt 98.03% <98.03%> (ø)
...ndplatform/feature/pdf/render/DocumentPdfCanvas.kt 55.55% <55.55%> (ø)
...g/groundplatform/feature/pdf/AndroidPdfRenderer.kt 0.00% <0.00%> (ø)
...ndplatform/feature/pdf/AndroidPdfReportLauncher.kt 0.00% <0.00%> (ø)
...undplatform/feature/pdf/AndroidPdfImageProvider.kt 52.77% <52.77%> (ø)

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@andreia-ferreira andreia-ferreira force-pushed the andreia/3739/pdf-report-layout branch from 0c304e7 to d7bd17c Compare June 9, 2026 15:26

@shobhitagarwal1612 shobhitagarwal1612 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add screenshots to the description?

@andreia-ferreira

Copy link
Copy Markdown
Collaborator Author

@shobhitagarwal1612 there is no UI entry point in this PR to show the direct output. But I've added a screenshot of how the doc will look like once the feature is completed in the next PR, hope it helps

@shobhitagarwal1612 shobhitagarwal1612 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sending the PR. I've left a few comments for you to review. On a high level, the PR looks reasonable but due to the large diff, it's hard to throughly review the code. Would you mind breaking it up into small 2-3 PRs?

Comment on lines +45 to +47
writer(document, images, DocumentPdfCanvas(pdf), totalPages = totalPages)
.drawDocument(document)
File(outputPath).outputStream().use { pdf.writeTo(it) }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is file operation, should it be wrapped in IO dispatchers block? Or will this be handled at the caller?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it should! Updated this to run with a IO dispatcher

Comment on lines +70 to +77
photoFilenames
.filter { it.isNotEmpty() }
.forEach { filename ->
loadPhotoBitmap(filename)?.let { bitmap ->
bitmapsToRelease += bitmap
images[PdfImageSet.ImageRef.Photo(filename)] = PdfImage(bitmap)
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use async / awaitAll to decode the images concurrently?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call, implemented 👍

private val photoMaxWidthPx = pointsToRenderPixels(PdfConfig.TABLE_ANSWER_TEXT_WIDTH.toFloat())
private val photoMaxHeightPx = pointsToRenderPixels(PdfConfig.PHOTO_MAX_HEIGHT.toFloat())

override suspend fun load(qrContent: String?, photoFilenames: Set<String>): PdfImageSet {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to previous question, are we planning to wrap the caller with io dispatcher? If not, should we do it here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked into it, but in this case I believe it's best to run on a Default dispatcher since most of the work here consists on CPU intensive things, with image decoding, scaling etc. And that dispatcher is provided by the call site, PdfExportService

@andreia-ferreira andreia-ferreira changed the title Add components to render the PDF layout Add Android rendering logic for PDF reports Jun 10, 2026
@andreia-ferreira

Copy link
Copy Markdown
Collaborator Author

extracted 2 PRs out of this one:

This way, this PR becomes focused on the Android implementation of the interfaces needed to generate the PDF report. Since his depends on the PRs above, I'll mark this as draft for the time being

@andreia-ferreira andreia-ferreira marked this pull request as draft June 10, 2026 16:16
# Conflicts:
#	core/ui/src/commonMain/kotlin/org/groundplatform/ui/components/qrcode/GroundQrCode.kt
#	core/ui/src/commonMain/kotlin/org/groundplatform/ui/components/qrcode/QrCodeGenerator.kt
#	feature/pdf/src/commonMain/kotlin/org/groundplatform/feature/pdf/render/PdfConfig.kt
@andreia-ferreira andreia-ferreira marked this pull request as ready for review June 11, 2026 15:51
@andreia-ferreira

Copy link
Copy Markdown
Collaborator Author

updated this PR after merging the previous ones and applied the suggestions, ready for another review 👀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants