saveDrawing method

Future<void> saveDrawing({
  1. required File pdfFile,
  2. required int totalPages,
  3. required BuildContext context,
  4. required DrawingController drawingController,
  5. required ImageController imageController,
  6. required TextBoxController textBoxController,
  7. required HighlightController highlightController,
  8. required UnderlineController underlineController,
  9. required Function refresh,
})

Saves the current edits (drawings, images, annotations, and text boxes) to a new PDF file with memory optimization.

Implementation

Future<void> saveDrawing({
  required File pdfFile,
  required int totalPages,
  required BuildContext context,
  required DrawingController drawingController,
  required ImageController imageController,
  required TextBoxController textBoxController,
  required HighlightController highlightController,
  required UnderlineController underlineController,
  required Function refresh,
}) async {
  if (isSaving) return;

  isSaving = true;
  PdfDocument? pdfDoc;

  try {
    // Early exit if nothing to save
    if (!(drawingController.hasAnyContent() ||
        imageController.hasAnyContent() ||
        textBoxController.hasAnyContent() ||
        highlightController.hasAnyContent() ||
        underlineController.hasAnyContent())) {
      return Navigator.pop(context, pdfFile);
    }

    final output = await getTemporaryDirectory();
    final String originalName = pdfFile.path.split('/').last.split('.').first;
    final String timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    final String savedPath = '${output.path}/${originalName}_$timestamp.pdf';
    final file = File(savedPath);

    // Copy the original file as base
    await pdfFile.copy(savedPath);

    const int batchSize = 5;

    for (
      int batchStart = 0;
      batchStart < totalPages;
      batchStart += batchSize
    ) {
      // final fileBytes = await readFileInChunks(file);
      pdfDoc ??= await Isolate.run(() async {
        return await processPdfDocViaUt(file);
      });

      final int batchEnd =
          (batchStart + batchSize > totalPages)
              ? totalPages
              : batchStart + batchSize;

      dev.log('Processing batch: pages ${batchStart + 1} to $batchEnd');

      /// ✅ Only proceed if something changed
      final bool batchModified = await _processPageBatch(
        pdfDoc!,
        batchStart,
        batchEnd,
        context,
        drawingController,
        imageController,
        textBoxController,
        highlightController,
        underlineController,
      );

      if (batchModified) {
        // Save only if something was added/changed
        await Isolate.run(() async {
          await savePdfDocToFile(pdfDoc!, file);
        });
        pdfDoc.dispose();
        pdfDoc = null;
        dev.log("Batch ${batchStart + 1}–$batchEnd saved");
      } else {
        dev.log("Batch ${batchStart + 1}–$batchEnd skipped (no changes)");
      }
      // Allow UI to refresh
      await Future.delayed(const Duration(milliseconds: 50));
    }
    if (pdfDoc != null) {
      await Isolate.run(() async {
        await savePdfDocToFile(pdfDoc!, file);
      });
    }
    dev.log('All pages processed, PDF saved at $savedPath');
    Navigator.pop(context, file);
  } catch (e) {
    debugPrint('Error while saving drawing and text: $e');
    rethrow;
  } finally {
    pdfDoc?.dispose();
    pdfDoc = null;
    isSaving = false;
  }
}