Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2ba264e
started work on new assetCacheAll - cache which holds assets all the …
QubaB Sep 27, 2025
ce14a04
implemented pdfDocument in asset cache so it is accessible from all p…
QubaB Sep 27, 2025
0b452e0
Implemented image provider for png.
QubaB Sep 28, 2025
5171d15
asset cache provides imageProvider as Notifier, so when more images s…
QubaB Sep 28, 2025
8023cf9
added comment about new cache approach
QubaB Sep 28, 2025
c0e6886
updated cache properties and description of problems of current cache
QubaB Sep 28, 2025
9b67b1d
added copyFile to FileManager - used to copy assets
QubaB Sep 28, 2025
efc1155
implemented saving of note using new assetCacheAll cache
QubaB Sep 28, 2025
1f3f983
FileManager - reworked copyFile to add correct base directory
QubaB Sep 28, 2025
0b5407b
implemented PdfInfoExtractor which extracts from pdf information. It …
QubaB Oct 5, 2025
7befb10
assetcacheAll - frmoved all non File cache items. cache now works
QubaB Oct 6, 2025
7b6876c
set correct asset id during saving
QubaB Oct 6, 2025
d4b5aaa
fileManager - skip copy file to itself (it created 0B file)
QubaB Oct 6, 2025
69127c2
removed assetsCache and implemented only new cache
QubaB Oct 6, 2025
08d9920
assetcache addUse a removeUse - used on delete image and undo/redo
QubaB Oct 6, 2025
13d4111
svgImage is rewriten to use only File not String
QubaB Oct 6, 2025
1b2b781
pdfImage fixed test of assetIndex
QubaB Oct 6, 2025
a133e53
Editor - fixed delete, undo/redo to increment and decrement asset use.
QubaB Oct 6, 2025
be0b92a
removed unused import
QubaB Oct 6, 2025
764753b
implemented renumbering of assets. implemented replacement of image p…
QubaB Oct 7, 2025
5774b1f
assets are copied (renamed) to correct file names in renumberBeforeSa…
QubaB Oct 8, 2025
4cd3793
importing pdf increase asset use counter for each page
QubaB Oct 8, 2025
a8c1e14
in json is stored also fileInfo, previewHash, Hash, fileSize to incre…
QubaB Oct 8, 2025
2095e5b
getPdfNotifier implemented to notify pdfs about its pdfDocument rend…
QubaB Oct 8, 2025
eea7dbb
fixed file extension to contain '.'
QubaB Oct 8, 2025
7311b80
assetCache - added AssetType for better recognition of asset in cache
QubaB Oct 8, 2025
6db2918
pdfrx version 2.1.16 or greater do not work on Windows and Saber cras…
QubaB Oct 12, 2025
c361877
added fixFileNameDelimiters and getTmpAssetDir
QubaB Oct 13, 2025
f8b6781
all temporary assets are stored to .tmpAssets directory in Document f…
QubaB Oct 13, 2025
b9c1586
rewriten importPdfFromFilePath it does not use Printing.raster to de…
QubaB Oct 15, 2025
2280d07
fixed saving assets (correct renaming of assets if some is deleted). …
QubaB Oct 15, 2025
e2f5a0f
addSync uses also assetIndex from Json to keep order of assets (backg…
QubaB Oct 15, 2025
8d404a2
use of the newest pdrfx 2.2.1
QubaB Oct 15, 2025
aa9c410
removed test of isolate
QubaB Oct 15, 2025
cba200e
fileManager: removed supportDirectory. It is not used and blocks to u…
QubaB Oct 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,235 changes: 1,149 additions & 86 deletions lib/components/canvas/_asset_cache.dart

Large diffs are not rendered by default.

12 changes: 2 additions & 10 deletions lib/components/canvas/canvas_image_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class _CanvasImageDialogState extends State<CanvasImageDialog> {
switch (widget.image) {
case PdfEditorImage image:
if (!image.loadedIn) await image.loadIn();
bytes = image.pdfBytes!;
bytes = await image.assetCacheAll.getBytes(image.assetId);
case SvgEditorImage image:
bytes = switch (image.svgLoader) {
(SvgStringLoader loader) =>
Expand All @@ -80,15 +80,7 @@ class _CanvasImageDialogState extends State<CanvasImageDialog> {
image.svgLoader, 'svgLoader', 'Unknown SVG loader type'),
};
case PngEditorImage image:
if (image.imageProvider is MemoryImage) {
bytes = (image.imageProvider as MemoryImage).bytes;
} else if (image.imageProvider is FileImage) {
bytes =
await (image.imageProvider as FileImage).file.readAsBytes();
} else {
throw ArgumentError.value(image.imageProvider, 'imageProvider',
'Unknown image provider type');
}
bytes = await image.assetCacheAll.getBytes(image.assetId);
}
if (!context.mounted) return;
FileManager.exportFile(imageFileName, bytes,
Expand Down
15 changes: 7 additions & 8 deletions lib/components/canvas/image/editor_image.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
Expand Down Expand Up @@ -33,7 +32,7 @@ sealed class EditorImage extends ChangeNotifier {
/// This is used when "downloading" the image to the user's photo gallery.
final String extension;

final AssetCache assetCache;
final AssetCacheAll assetCacheAll;

bool _isThumbnail = false;
bool get isThumbnail => _isThumbnail;
Expand Down Expand Up @@ -88,7 +87,7 @@ sealed class EditorImage extends ChangeNotifier {
@protected
EditorImage({
required this.id,
required this.assetCache,
required this.assetCacheAll,
required this.extension,
required this.pageIndex,
required this.pageSize,
Expand All @@ -112,7 +111,7 @@ sealed class EditorImage extends ChangeNotifier {
required List<Uint8List>? inlineAssets,
bool isThumbnail = false,
required String sbnPath,
required AssetCache assetCache,
required AssetCacheAll assetCacheAll,
}) {
String? extension = json['e'];
if (extension == '.svg') {
Expand All @@ -121,30 +120,30 @@ sealed class EditorImage extends ChangeNotifier {
inlineAssets: inlineAssets,
isThumbnail: isThumbnail,
sbnPath: sbnPath,
assetCache: assetCache,
assetCacheAll: assetCacheAll,
);
} else if (extension == '.pdf') {
return PdfEditorImage.fromJson(
json,
inlineAssets: inlineAssets,
isThumbnail: isThumbnail,
sbnPath: sbnPath,
assetCache: assetCache,
assetCacheAll: assetCacheAll,
);
} else {
return PngEditorImage.fromJson(
json,
inlineAssets: inlineAssets,
isThumbnail: isThumbnail,
sbnPath: sbnPath,
assetCache: assetCache,
assetCacheAll: assetCacheAll,
);
}
}

@mustBeOverridden
@mustCallSuper
Map<String, dynamic> toJson(OrderedAssetCache assets) => {
Map<String, dynamic> toJson() => {
'id': id,
'e': extension,
'i': pageIndex,
Expand Down
97 changes: 58 additions & 39 deletions lib/components/canvas/image/pdf_editor_image.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
part of 'editor_image.dart';

class PdfEditorImage extends EditorImage {
Uint8List? pdfBytes;
/// index of asset assigned to this pdf file
int assetId;

final int pdfPage;

/// If the pdf needs to be loaded from disk, this is the File
/// that the pdf will be loaded from.
final File? pdfFile;

final _pdfDocument = ValueNotifier<PdfDocument?>(null);
// final _pdfDocument = ValueNotifier<PdfDocument?>(null);

static final log = Logger('PdfEditorImage');

PdfEditorImage({
required super.id,
required super.assetCache,
required this.pdfBytes,
required super.assetCacheAll,
required this.assetId,
required this.pdfFile,
required this.pdfPage,
required super.pageIndex,
Expand All @@ -32,8 +34,8 @@ class PdfEditorImage extends EditorImage {
super.isThumbnail,
}) : assert(
!naturalSize.isEmpty, 'naturalSize must be set for PdfEditorImage'),
assert(pdfBytes != null || pdfFile != null,
'pdfFile must be set if pdfBytes is null'),
assert(pdfFile != null,
'pdfFile must be set'),
super(
extension: '.pdf',
srcRect: Rect.zero,
Expand All @@ -44,34 +46,58 @@ class PdfEditorImage extends EditorImage {
required List<Uint8List>? inlineAssets,
bool isThumbnail = false,
required String sbnPath,
required AssetCache assetCache,
required AssetCacheAll assetCacheAll,
}) {
String? extension = json['e'] as String?;
assert(extension == null || extension == '.pdf');

final assetIndex = json['a'] as int?;
final assetIndexJson = json['a'] as int?;

final Uint8List? pdfBytes;
int? assetIndex;
File? pdfFile;
if (assetIndex != null) {
if (assetIndexJson != null) {
if (inlineAssets == null) {
pdfFile =
FileManager.getFile('$sbnPath${Editor.extension}.$assetIndex');
pdfBytes = assetCache.get(pdfFile);
FileManager.getFile('$sbnPath${Editor.extension}.$assetIndexJson');
assetIndex = assetCacheAll.addSync(
pdfFile,'.pdf',assetIndexJson,
json.containsKey('ainf') ? json['ainf'] : null,
json.containsKey('aph') ? json['aph'].toInt() : null,
json.containsKey('afs') ? json['afs'] : null,
json.containsKey('ah') ? json['ah'].toInt() : null,
);
} else {
pdfBytes = inlineAssets[assetIndex];
pdfBytes = inlineAssets[assetIndexJson];
final tempFile=assetCacheAll.createRuntimeFile('.pdf',pdfBytes); // store to file
assetIndex = assetCacheAll.addSync(
tempFile,'.pdf',assetIndexJson,
json.containsKey('ainf') ? json['ainf'] : null,
json.containsKey('aph') ? json['aph'].toInt() : null,
json.containsKey('afs') ? json['afs'] : null,
json.containsKey('ah') ? json['ah'].toInt() : null,
);
}
} else {
if (kDebugMode) {
throw Exception('PdfEditorImage.fromJson: pdf bytes not found');
}
pdfBytes = Uint8List(0);
assetIndex=-1;
}

assert(assetIndex >=0,
'Either pdfBytes or pdfFile must be non-null');

// add to asset cache
if (assetIndex<0){
throw Exception('EditorImage.fromJson: pdf image not in assets');
}

return PdfEditorImage(
id: json['id'] ??
-1, // -1 will be replaced by EditorCoreInfo._handleEmptyImageIds()
assetCache: assetCache,
pdfBytes: pdfBytes,
assetCacheAll: assetCacheAll,
assetId: assetIndex,
pdfFile: pdfFile,
pdfPage: json['pdfi'],
pageIndex: json['i'] ?? 0,
Expand Down Expand Up @@ -99,18 +125,22 @@ class PdfEditorImage extends EditorImage {
}

@override
Map<String, dynamic> toJson(OrderedAssetCache assets) {
final json = super.toJson(
assets,
);
Map<String, dynamic> toJson() {
final json = super.toJson();

// remove non-pdf fields
json.remove('t'); // thumbnail bytes
assert(!json.containsKey('a'));
assert(!json.containsKey('b'));

json['a'] = assets.add(pdfFile ?? pdfBytes!);
json['a'] = assetCacheAll.getAssetIdOnSave(assetId); // assets can be reordered during saving
json['pdfi'] = pdfPage;
json['aph'] = assetCacheAll.getAssetPreviewHash(assetId); // assets prewiewHash
json['afs'] = assetCacheAll.getAssetFileSize(assetId); // assets can be reordered during saving
if (assetCacheAll.getAssetFileInfo(assetId) != '')
json['ainf'] = assetCacheAll.getAssetFileInfo(assetId); // asset file info
if (assetCacheAll.getAssetHash(assetId) != null)
json['ah'] = assetCacheAll.getAssetHash(assetId); // assets can be reordered during saving

return json;
}
Expand All @@ -127,9 +157,10 @@ class PdfEditorImage extends EditorImage {
dstRect = dstRect.topLeft & dstSize;
}

_pdfDocument.value ??= pdfFile != null
? await PdfDocument.openFile(pdfFile!.path)
: await PdfDocument.openData(pdfBytes!);
// _pdfDocument.value ??= await assetCacheAll.getPdfDocument(assetId);
// _pdfDocument.value ??= pdfFile != null
// ? await PdfDocument.openFile(pdfFile!.path)
// : await PdfDocument.openData(pdfBytes!);
}

@override
Expand All @@ -140,19 +171,6 @@ class PdfEditorImage extends EditorImage {

@override
Future<void> precache(BuildContext context) async {
if (_pdfDocument.value != null) return;

final completer = Completer<void>();

void onDocumentSet() {
if (_pdfDocument.value == null) return;
if (completer.isCompleted) return;
completer.complete();
_pdfDocument.removeListener(onDocumentSet);
}

_pdfDocument.addListener(onDocumentSet);
return completer.future;
}

@override
Expand All @@ -162,8 +180,9 @@ class PdfEditorImage extends EditorImage {
required bool isBackground,
required bool invert,
}) {
final pdfNotifier = assetCacheAll.getPdfNotifier(assetId); // value of pdfDocument
return ValueListenableBuilder(
valueListenable: _pdfDocument,
valueListenable: pdfNotifier,
builder: (context, pdfDocument, child) {
if (pdfDocument == null) {
return SizedBox.fromSize(size: srcRect.size);
Expand All @@ -183,8 +202,8 @@ class PdfEditorImage extends EditorImage {
@override
PdfEditorImage copy() => PdfEditorImage(
id: id,
assetCache: assetCache,
pdfBytes: pdfBytes,
assetCacheAll: assetCacheAll,
assetId: assetId,
pdfPage: pdfPage,
pdfFile: pdfFile,
pageIndex: pageIndex,
Expand Down
Loading
Loading