Skip to content

Commit 276c808

Browse files
author
LokeshPalani
committed
Added missed files in the pdf
1 parent 5c1d4dc commit 276c808

File tree

5 files changed

+4407
-0
lines changed

5 files changed

+4407
-0
lines changed
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
import 'dart:convert';
2+
3+
import '../../interfaces/pdf_interface.dart';
4+
import '../io/pdf_constants.dart';
5+
import '../io/pdf_cross_table.dart';
6+
import '../pages/pdf_page.dart';
7+
import '../primitives/pdf_array.dart';
8+
import '../primitives/pdf_boolean.dart';
9+
import '../primitives/pdf_dictionary.dart';
10+
import '../primitives/pdf_name.dart';
11+
import '../primitives/pdf_number.dart';
12+
import '../primitives/pdf_reference_holder.dart';
13+
import '../primitives/pdf_stream.dart';
14+
import '../primitives/pdf_string.dart';
15+
16+
/// Internal class
17+
class FdfDocument {
18+
/// Internal Consturctor
19+
FdfDocument(this.dictionary, this.page);
20+
21+
/// Internal field
22+
late PdfDictionary dictionary;
23+
24+
/// Internal field
25+
late PdfPage page;
26+
27+
/// Internal field
28+
String _annotationID = '';
29+
30+
/// Internal method
31+
Map<String, dynamic> exportAnnotations(
32+
int currentID, List<String> annotID, int pageIndex, bool hasAppearance) {
33+
const String startObject =
34+
'${PdfOperators.whiteSpace}0${PdfOperators.whiteSpace}${PdfOperators.obj}${PdfOperators.newLine}';
35+
const String endObject =
36+
PdfOperators.newLine + PdfOperators.endobj + PdfOperators.newLine;
37+
PdfDictionary dictionary = this.dictionary;
38+
_annotationID = currentID.toString();
39+
final List<int> exportData = <int>[];
40+
exportData.addAll(utf8.encode('$currentID$startObject<<'));
41+
final Map<int, IPdfPrimitive> subDictionaries = <int, IPdfPrimitive>{};
42+
final List<int> streamReferences = <int>[];
43+
annotID.add(_annotationID);
44+
dictionary.items![PdfName('Page')] = PdfNumber(pageIndex);
45+
Map<String, dynamic> exportDataDictionary = _getEntriesInDictionary(
46+
subDictionaries,
47+
streamReferences,
48+
currentID,
49+
dictionary,
50+
hasAppearance);
51+
exportData.addAll(exportDataDictionary['exportData'] as List<int>);
52+
currentID = exportDataDictionary['currentID'] as int;
53+
dictionary.remove('Page');
54+
exportData.addAll(utf8.encode('>>$endObject'));
55+
while (subDictionaries.isNotEmpty) {
56+
final List<int> keys = subDictionaries.keys.toList();
57+
for (final int key in keys) {
58+
if (subDictionaries[key] is PdfDictionary) {
59+
dictionary = subDictionaries[key]! as PdfDictionary;
60+
if (dictionary.containsKey(PdfDictionaryProperties.type)) {
61+
final IPdfPrimitive? name =
62+
dictionary[PdfDictionaryProperties.type];
63+
if (name != null &&
64+
name is PdfName &&
65+
name.name == PdfDictionaryProperties.annot) {
66+
annotID.add(key.toString());
67+
dictionary.items![PdfName('Page')] = PdfNumber(pageIndex);
68+
}
69+
}
70+
exportData.addAll(utf8.encode('$key$startObject<<'));
71+
exportDataDictionary = _getEntriesInDictionary(subDictionaries,
72+
streamReferences, currentID, dictionary, hasAppearance);
73+
exportData.addAll(exportDataDictionary['exportData'] as List<int>);
74+
currentID = exportDataDictionary['currentID'] as int;
75+
if (dictionary.containsKey('Page')) {
76+
dictionary.remove('Page');
77+
}
78+
exportData.addAll(utf8.encode('>>'));
79+
if (streamReferences.contains(key)) {
80+
exportData.addAll(_appendStream(subDictionaries[key]!));
81+
}
82+
exportData.addAll(utf8.encode(endObject));
83+
} else if (subDictionaries[key] is PdfName) {
84+
final PdfName name = subDictionaries[key]! as PdfName;
85+
exportData.addAll(utf8.encode('$key$startObject$name$endObject'));
86+
} else if (subDictionaries[key] is PdfArray) {
87+
final PdfArray array = subDictionaries[key]! as PdfArray;
88+
exportData.addAll(utf8.encode('$key$startObject'));
89+
final Map<String, dynamic> result = _appendArrayElements(array,
90+
currentID, hasAppearance, subDictionaries, streamReferences);
91+
exportData.addAll(result['exportData'] as List<int>);
92+
currentID = result['currentID'] as int;
93+
exportData.addAll(utf8.encode(endObject));
94+
} else if (subDictionaries[key] is PdfBoolean) {
95+
final PdfBoolean boolean = subDictionaries[key]! as PdfBoolean;
96+
exportData.addAll(utf8.encode(
97+
'$key$startObject${boolean.value! ? 'true' : 'false'}$endObject'));
98+
} else if (subDictionaries[key] is PdfString) {
99+
final PdfString data = subDictionaries[key]! as PdfString;
100+
if (data.value != null) {
101+
exportData.addAll(utf8.encode(
102+
'$key$startObject(${_getFormattedStringFDF(data.value!)})$endObject'));
103+
}
104+
}
105+
subDictionaries.remove(key);
106+
}
107+
}
108+
currentID++;
109+
return <String, dynamic>{'exportData': exportData, 'currentID': currentID};
110+
}
111+
112+
/// Internal method
113+
List<int> _appendStream(IPdfPrimitive stream) {
114+
final List<int> streamData = <int>[];
115+
if (stream is PdfStream &&
116+
stream.dataStream != null &&
117+
stream.dataStream!.isNotEmpty) {
118+
streamData.addAll(utf8.encode('stream${PdfOperators.newLine}'));
119+
streamData.addAll(stream.dataStream!);
120+
streamData.addAll(utf8.encode('${PdfOperators.newLine}endstream'));
121+
}
122+
return streamData;
123+
}
124+
125+
Map<String, dynamic> _getEntriesInDictionary(
126+
Map<int, IPdfPrimitive> dictionaries,
127+
List<int> streamReferences,
128+
int currentID,
129+
PdfDictionary dictionary,
130+
bool hasAppearance) {
131+
final List<int> annotationData = <int>[];
132+
bool isStream = false;
133+
final List<PdfName?> keys = dictionary.items!.keys.toList();
134+
for (final PdfName? key in keys) {
135+
if (!hasAppearance && key!.name == PdfDictionaryProperties.ap) {
136+
continue;
137+
}
138+
if (key!.name != PdfDictionaryProperties.p) {
139+
annotationData.addAll(utf8.encode(key.toString()));
140+
}
141+
if (key.name == 'Sound' ||
142+
key.name == PdfDictionaryProperties.f ||
143+
hasAppearance) {
144+
isStream = true;
145+
}
146+
final IPdfPrimitive? primitive = dictionary[key];
147+
if (primitive is PdfString) {
148+
if (primitive.value != null) {
149+
annotationData.addAll(
150+
utf8.encode('(${_getFormattedStringFDF(primitive.value!)})'));
151+
}
152+
} else if (primitive is PdfName) {
153+
annotationData.addAll(utf8.encode(primitive.toString()));
154+
} else if (primitive is PdfArray) {
155+
final Map<String, dynamic> result = _appendArrayElements(
156+
primitive, currentID, isStream, dictionaries, streamReferences);
157+
annotationData.addAll(result['exportData'] as List<int>);
158+
currentID = result['currentID'] as int;
159+
} else if (primitive is PdfNumber) {
160+
annotationData.addAll(utf8.encode(' ${primitive.value!}'));
161+
} else if (primitive is PdfBoolean) {
162+
annotationData.addAll(utf8.encode(' ${primitive.value!}'));
163+
} else if (primitive is PdfDictionary) {
164+
annotationData.addAll(utf8.encode('<<'));
165+
final Map<String, dynamic> data = _getEntriesInDictionary(dictionaries,
166+
streamReferences, currentID, primitive, hasAppearance);
167+
annotationData.addAll(data['exportData'] as List<int>);
168+
currentID = data['currentID'] as int;
169+
annotationData.addAll(utf8.encode('>>'));
170+
} else if (primitive is PdfReferenceHolder) {
171+
if (PdfPageHelper.getHelper(page).document != null) {
172+
final int pageNumber =
173+
PdfPageHelper.getHelper(page).document!.pages.indexOf(page);
174+
if (key.name == PdfDictionaryProperties.parent) {
175+
annotationData.addAll(utf8.encode(' $_annotationID 0 R'));
176+
annotationData.addAll(utf8.encode('/Page $pageNumber'));
177+
} else if (key.name == PdfDictionaryProperties.irt) {
178+
if (primitive.object != null && primitive.object is PdfDictionary) {
179+
final IPdfPrimitive? inReplyTo = primitive.object;
180+
if (inReplyTo != null &&
181+
inReplyTo is PdfDictionary &&
182+
inReplyTo.containsKey('NM')) {
183+
final IPdfPrimitive? name =
184+
PdfCrossTable.dereference(inReplyTo['NM']);
185+
if (name != null && name is PdfString) {
186+
if (name.value != null) {
187+
annotationData.addAll(utf8
188+
.encode('(${_getFormattedStringFDF(name.value!)})'));
189+
}
190+
}
191+
}
192+
}
193+
} else if (key.name != PdfDictionaryProperties.p) {
194+
currentID++;
195+
annotationData.addAll(utf8.encode(' $currentID 0 R'));
196+
if (isStream) {
197+
streamReferences.add(currentID);
198+
}
199+
if (primitive.object != null) {
200+
dictionaries[currentID] = primitive.object!;
201+
}
202+
}
203+
}
204+
}
205+
isStream = false;
206+
}
207+
return <String, dynamic>{
208+
'exportData': annotationData,
209+
'currentID': currentID
210+
};
211+
}
212+
213+
String _getFormattedStringFDF(String value) {
214+
String result = '';
215+
for (int i = 0; i < value.length; i++) {
216+
final int c = value.codeUnitAt(i);
217+
if (c == 40 || c == 41) {
218+
result += r'\';
219+
}
220+
if (c == 13 || c == 10) {
221+
if (c == 13) {
222+
result += r'\r';
223+
}
224+
if (c == 10) {
225+
result += r'\n';
226+
}
227+
continue;
228+
}
229+
result += String.fromCharCode(c);
230+
}
231+
return result;
232+
}
233+
234+
Map<String, dynamic> _appendArrayElements(
235+
PdfArray array,
236+
int currentID,
237+
bool isStream,
238+
Map<int, IPdfPrimitive> dictionaries,
239+
List<int> streamReferences) {
240+
final List<int> arrayData = <int>[];
241+
arrayData.addAll(utf8.encode('['));
242+
if (array.elements.isNotEmpty) {
243+
final int count = array.elements.length;
244+
for (int i = 0; i < count; i++) {
245+
final IPdfPrimitive? element = array.elements[i];
246+
if (i != 0 &&
247+
element != null &&
248+
(element is PdfNumber ||
249+
element is PdfReferenceHolder ||
250+
element is PdfBoolean)) {
251+
arrayData.addAll(utf8.encode(' '));
252+
}
253+
final Map<String, dynamic> result = _appendElement(
254+
element!, currentID, isStream, dictionaries, streamReferences);
255+
arrayData.addAll(result['exportData'] as List<int>);
256+
currentID = result['currentID'] as int;
257+
}
258+
}
259+
arrayData.addAll(utf8.encode(']'));
260+
return <String, dynamic>{'exportData': arrayData, 'currentID': currentID};
261+
}
262+
263+
Map<String, dynamic> _appendElement(
264+
IPdfPrimitive element,
265+
int currentID,
266+
bool isStream,
267+
Map<int, IPdfPrimitive> dictionaries,
268+
List<int> streamReferences) {
269+
final List<int> exportData = <int>[];
270+
if (element is PdfNumber) {
271+
exportData.addAll(utf8.encode(element.value!.toString()));
272+
} else if (element is PdfName) {
273+
exportData.addAll(utf8.encode(element.toString()));
274+
} else if (element is PdfString) {
275+
if (element.value != null) {
276+
exportData
277+
.addAll(utf8.encode('(${_getFormattedStringFDF(element.value!)})'));
278+
}
279+
} else if (element is PdfBoolean) {
280+
exportData.addAll(utf8.encode(element.value!.toString()));
281+
} else if (element is PdfReferenceHolder) {
282+
currentID++;
283+
if (isStream) {
284+
streamReferences.add(currentID);
285+
}
286+
if (element.object != null) {
287+
dictionaries[currentID] = element.object!;
288+
}
289+
exportData.addAll(utf8.encode('$currentID 0 R'));
290+
} else if (element is PdfArray) {
291+
final Map<String, dynamic> result = _appendArrayElements(
292+
element, currentID, isStream, dictionaries, streamReferences);
293+
currentID = result['currentID'] as int;
294+
exportData.addAll(result['exportData'] as List<int>);
295+
} else if (element is PdfDictionary) {
296+
exportData.addAll(utf8.encode('<<'));
297+
final Map<String, dynamic> data = _getEntriesInDictionary(
298+
dictionaries, streamReferences, currentID, element, isStream);
299+
exportData.addAll(data['exportData'] as List<int>);
300+
currentID = data['currentID'] as int;
301+
exportData.addAll(utf8.encode('>>'));
302+
}
303+
return <String, dynamic>{'exportData': exportData, 'currentID': currentID};
304+
}
305+
}

0 commit comments

Comments
 (0)