Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
dart_pdf
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
David PHAM-VAN
2021-04-04 16:38:27 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
ebc78a8ab33d4d8a6cdc451c7854df4497925c0e
ebc78a8a
1 parent
87e5eab9
Implement Compressed XREF
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
150 additions
and
18 deletions
pdf/CHANGELOG.md
pdf/lib/src/pdf/catalog.dart
pdf/lib/src/pdf/data_types.dart
pdf/lib/src/pdf/document.dart
pdf/lib/src/pdf/document_parser.dart
pdf/lib/src/pdf/output.dart
pdf/lib/src/pdf/xref.dart
pdf/lib/src/widgets/document.dart
pdf/pubspec.yaml
pdf/CHANGELOG.md
View file @
ebc78a8
# Changelog
## 3.
1.1
## 3.
2.0
-
Fix documentation
-
Add Positioned.fill()
-
Improve GraphicState
-
Add SVG Color filter
-
Implement Compressed XREF
## 3.1.0
...
...
pdf/lib/src/pdf/catalog.dart
View file @
ebc78a8
...
...
@@ -57,7 +57,7 @@ class PdfCatalog extends PdfObjectDict {
super
.
prepare
();
/// the PDF specification version, overrides the header version starting from 1.4
params
[
'/Version'
]
=
PdfName
(
'/
${pdfDocument.version}
'
);
params
[
'/Version'
]
=
PdfName
(
'/
${pdfDocument.version
String
}
'
);
params
[
'/Pages'
]
=
pdfPageList
.
ref
();
...
...
pdf/lib/src/pdf/data_types.dart
View file @
ebc78a8
...
...
@@ -600,6 +600,7 @@ class PdfDictStream extends PdfDict<PdfDataType> {
Map
<
String
,
PdfDataType
>
values
=
const
<
String
,
PdfDataType
>{},
required
this
.
data
,
this
.
isBinary
=
false
,
this
.
encrypt
=
true
,
})
:
super
.
values
(
values
);
final
Uint8List
data
;
...
...
@@ -608,6 +609,8 @@ class PdfDictStream extends PdfDict<PdfDataType> {
final
bool
isBinary
;
final
bool
encrypt
;
@override
void
output
(
PdfStream
s
)
{
final
_values
=
PdfDict
(
values
);
...
...
@@ -638,7 +641,7 @@ class PdfDictStream extends PdfDict<PdfDataType> {
}
}
if
(
object
.
pdfDocument
.
encryption
!=
null
)
{
if
(
encrypt
&&
object
.
pdfDocument
.
encryption
!=
null
)
{
_data
=
object
.
pdfDocument
.
encryption
!.
encrypt
(
_data
,
object
);
}
...
...
pdf/lib/src/pdf/document.dart
View file @
ebc78a8
...
...
@@ -35,6 +35,15 @@ import 'page_list.dart';
import
'signature.dart'
;
import
'stream.dart'
;
/// PDF version to generate
enum
PdfVersion
{
/// PDF 1.4
pdf_1_4
,
/// PDF 1.5 to 1.7
pdf_1_5
,
}
/// Display hint for the PDF viewer
enum
PdfPageMode
{
/// This page mode indicates that the document
...
...
@@ -69,6 +78,7 @@ class PdfDocument {
PdfPageMode
pageMode
=
PdfPageMode
.
none
,
DeflateCallback
?
deflate
,
bool
compress
=
true
,
this
.
version
=
PdfVersion
.
pdf_1_4
,
})
:
deflate
=
compress
?
(
deflate
??
defaultDeflate
)
:
null
,
prev
=
null
,
_objser
=
1
{
...
...
@@ -84,7 +94,8 @@ class PdfDocument {
DeflateCallback
?
deflate
,
bool
compress
=
true
,
})
:
deflate
=
compress
?
(
deflate
??
defaultDeflate
)
:
null
,
_objser
=
prev
!.
size
{
_objser
=
prev
!.
size
,
version
=
prev
.
version
{
// Now create some standard objects
pdfPageList
=
PdfPageList
(
this
);
pdfNames
=
PdfNames
(
this
);
...
...
@@ -107,6 +118,9 @@ class PdfDocument {
/// This is the Catalog object, which is required by each Pdf Document
late
PdfCatalog
catalog
;
/// PDF version to generate
final
PdfVersion
version
;
/// This is the info object. Although this is an optional object, we
/// include it.
PdfInfo
?
info
;
...
...
@@ -139,7 +153,7 @@ class PdfDocument {
PdfGraphicStates
?
_graphicStates
;
/// The PDF specification version
final
String
version
=
'1.7'
;
final
String
version
String
=
'1.7'
;
/// This holds the current fonts
final
Set
<
PdfFont
>
fonts
=
<
PdfFont
>{};
...
...
@@ -188,7 +202,7 @@ class PdfDocument {
/// This writes the document to an OutputStream.
Future
<
void
>
_write
(
PdfStream
os
)
async
{
final
pos
=
PdfOutput
(
os
);
final
pos
=
PdfOutput
(
os
,
version
);
// Write each object to the [PdfStream]. We call via the output
// as that builds the xref table
...
...
pdf/lib/src/pdf/document_parser.dart
View file @
ebc78a8
...
...
@@ -32,6 +32,8 @@ abstract class PdfDocumentParserBase {
/// The offset of the previous cross reference table
int
get
xrefOffset
;
PdfVersion
get
version
=>
PdfVersion
.
pdf_1_4
;
/// Import the existing objects into the new PDF document
void
mergeDocument
(
PdfDocument
pdfDocument
);
}
...
...
pdf/lib/src/pdf/output.dart
View file @
ebc78a8
...
...
@@ -16,6 +16,7 @@
import
'catalog.dart'
;
import
'data_types.dart'
;
import
'document.dart'
;
import
'encryption.dart'
;
import
'info.dart'
;
import
'object.dart'
;
...
...
@@ -26,11 +27,24 @@ import 'xref.dart';
/// PDF document writer
class
PdfOutput
{
/// This creates a Pdf [PdfStream]
PdfOutput
(
this
.
os
)
{
os
.
putString
(
'%PDF-1.4
\n
'
);
PdfOutput
(
this
.
os
,
this
.
version
)
{
String
v
;
switch
(
version
)
{
case
PdfVersion
.
pdf_1_4
:
v
=
'1.4'
;
break
;
case
PdfVersion
.
pdf_1_5
:
v
=
'1.5'
;
break
;
}
os
.
putString
(
'%PDF-
$v
\n
'
);
os
.
putBytes
(
const
<
int
>[
0x25
,
0xC2
,
0xA5
,
0xC2
,
0xB1
,
0xC3
,
0xAB
,
0x0A
]);
}
/// Pdf version to output
final
PdfVersion
version
;
/// This is the actual [PdfStream] used to write to.
final
PdfStream
os
;
...
...
@@ -49,6 +63,9 @@ class PdfOutput {
/// This is used to track the /Sign object (signature)
PdfSignature
?
signatureID
;
/// Generate a compressed cross reference table
bool
get
isCompressed
=>
version
.
index
>
PdfVersion
.
pdf_1_4
.
index
;
/// This method writes a [PdfObject] to the stream.
void
write
(
PdfObject
ob
)
{
// Check the object to see if it's one that is needed later
...
...
@@ -73,12 +90,6 @@ class PdfOutput {
throw
Exception
(
'Root object is not present in document'
);
}
final
_xref
=
os
.
offset
;
xref
.
output
(
os
);
// now the trailer object
os
.
putString
(
'trailer
\n
'
);
final
params
=
PdfDict
();
// the number of entries (REQUIRED)
...
...
@@ -104,9 +115,22 @@ class PdfOutput {
params
[
'/Prev'
]
=
PdfNum
(
rootID
!.
pdfDocument
.
prev
!.
xrefOffset
);
}
// end the trailer object
params
.
output
(
os
);
os
.
putString
(
'
\n
startxref
\n
$_xref
\n
%%EOF
\n
'
);
final
_xref
=
os
.
offset
;
if
(
isCompressed
)
{
xref
.
outputCompressed
(
rootID
!,
os
,
params
);
}
else
{
xref
.
output
(
os
);
}
if
(!
isCompressed
)
{
// the trailer object
os
.
putString
(
'trailer
\n
'
);
params
.
output
(
os
);
os
.
putByte
(
0x0a
);
}
// the reference to the xref object
os
.
putString
(
'startxref
\n
$_xref
\n
%%EOF
\n
'
);
if
(
signatureID
!=
null
)
{
await
signatureID
!.
writeSignature
(
os
);
...
...
pdf/lib/src/pdf/xref.dart
View file @
ebc78a8
...
...
@@ -14,6 +14,8 @@
* limitations under the License.
*/
import
'dart:typed_data'
;
import
'package:pdf/src/pdf/stream.dart'
;
import
'data_types.dart'
;
...
...
@@ -45,6 +47,24 @@ class PdfXref {
return
rs
+
' n '
;
}
/// The xref in the format of the compressed xref section in the Pdf file
int
cref
(
ByteData
o
,
int
ofs
,
List
<
int
>
w
)
{
assert
(
w
.
length
>=
3
);
void
setVal
(
int
l
,
int
v
)
{
for
(
var
n
=
0
;
n
<
l
;
n
++)
{
o
.
setUint8
(
ofs
,
(
v
>>
(
l
-
n
-
1
)
*
8
)
&
0xff
);
ofs
++;
}
}
setVal
(
w
[
0
],
1
);
setVal
(
w
[
1
],
offset
);
setVal
(
w
[
2
],
generation
);
return
ofs
;
}
@override
bool
operator
==(
Object
other
)
{
if
(
other
is
PdfXref
)
{
...
...
@@ -113,4 +133,70 @@ class PdfXrefTable extends PdfDataType {
// now write the last block
_writeblock
(
s
,
firstid
,
block
);
}
/// Output a compressed cross-reference table
void
outputCompressed
(
PdfObject
object
,
PdfStream
s
,
PdfDict
params
)
{
// Write this object too
final
id
=
offsets
.
last
.
id
+
1
;
final
offset
=
s
.
offset
;
offsets
.
add
(
PdfXref
(
id
,
offset
));
// Sort all references
offsets
.
sort
((
a
,
b
)
=>
a
.
id
.
compareTo
(
b
.
id
));
s
.
putString
(
'
$id
0 obj
\n
'
);
params
[
'/Type'
]
=
const
PdfName
(
'/XRef'
);
params
[
'/Size'
]
=
PdfNum
(
id
+
1
);
var
firstid
=
0
;
// First id in block
var
lastid
=
0
;
// The last id used
final
blocks
=
<
int
>[];
// xrefs in this block first, count
// We need block 0 to exist
blocks
.
add
(
firstid
);
for
(
var
x
in
offsets
)
{
// check to see if block is in range
if
(
x
.
id
!=
(
lastid
+
1
))
{
// no, so store this block, and reset
blocks
.
add
(
lastid
-
firstid
+
1
);
firstid
=
x
.
id
;
blocks
.
add
(
firstid
);
}
lastid
=
x
.
id
;
}
blocks
.
add
(
lastid
-
firstid
+
1
);
if
(!(
blocks
.
length
==
2
&&
blocks
[
0
]
==
0
&&
blocks
[
1
]
==
id
+
1
))
{
params
[
'/Index'
]
=
PdfArray
.
fromNum
(
blocks
);
}
var
bytes
=
2
;
// A pdf less than 256 bytes is unlikely
while
(
1
<<
(
bytes
*
8
)
<
offset
)
{
bytes
++;
}
final
w
=
[
1
,
bytes
,
1
];
params
[
'/W'
]
=
PdfArray
.
fromNum
(
w
);
final
wl
=
w
.
reduce
((
a
,
b
)
=>
a
+
b
);
final
o
=
ByteData
((
offsets
.
length
+
2
)
*
wl
);
var
ofs
=
0
;
// Write offset zero, all zeros
ofs
+=
wl
;
for
(
var
x
in
offsets
)
{
ofs
=
x
.
cref
(
o
,
ofs
,
w
);
}
// Write the object
PdfDictStream
(
object:
object
,
data:
o
.
buffer
.
asUint8List
(),
isBinary:
true
,
encrypt:
false
,
values:
params
.
values
,
).
output
(
s
);
}
}
...
...
pdf/lib/src/widgets/document.dart
View file @
ebc78a8
...
...
@@ -26,6 +26,7 @@ class Document {
PdfPageMode
pageMode
=
PdfPageMode
.
none
,
DeflateCallback
?
deflate
,
bool
compress
=
true
,
PdfVersion
version
=
PdfVersion
.
pdf_1_4
,
this
.
theme
,
String
?
title
,
String
?
author
,
...
...
@@ -37,6 +38,7 @@ class Document {
pageMode:
pageMode
,
deflate:
deflate
,
compress:
compress
,
version:
version
,
)
{
if
(
title
!=
null
||
author
!=
null
||
...
...
pdf/pubspec.yaml
View file @
ebc78a8
...
...
@@ -4,7 +4,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl
homepage
:
https://github.com/DavBfr/dart_pdf/tree/master/pdf
repository
:
https://github.com/DavBfr/dart_pdf
issue_tracker
:
https://github.com/DavBfr/dart_pdf/issues
version
:
3.
1.1
version
:
3.
2.0
environment
:
sdk
:
"
>=2.12.0-0
<3.0.0"
...
...
Please
register
or
login
to post a comment