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
2020-06-18 17:20:47 -0400
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
46d49e81db9fcd1ead890f7126463afbb0f75cd6
46d49e81
1 parent
b104bbbf
Allow MultiPage to relayout individual pages with support for flex
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
179 additions
and
33 deletions
pdf/CHANGELOG.md
pdf/lib/widgets/multi_page.dart
pdf/pubspec.yaml
pdf/test/widget_flex_test.dart
test/golden/orientation.pdf
test/golden/widgets-flex.pdf
pdf/CHANGELOG.md
View file @
46d49e8
# Changelog
## 1.9.0
-
Allow MultiPage to relayout individual pages with support for flex
## 1.8.1
-
Fix Wrap break condition
...
...
pdf/lib/widgets/multi_page.dart
View file @
46d49e8
...
...
@@ -50,15 +50,11 @@ class NewPage extends Widget {
class
_MultiPageWidget
{
const
_MultiPageWidget
({
@required
this
.
child
,
@required
this
.
x
,
@required
this
.
y
,
@required
this
.
constraints
,
@required
this
.
widgetContext
,
});
final
Widget
child
;
final
double
x
;
final
double
y
;
final
BoxConstraints
constraints
;
final
WidgetContext
widgetContext
;
}
...
...
@@ -80,18 +76,21 @@ class _MultiPageInstance {
}
class
MultiPage
extends
Page
{
MultiPage
(
{
PageTheme
pageTheme
,
PdfPageFormat
pageFormat
,
BuildListCallback
build
,
this
.
crossAxisAlignment
=
CrossAxisAlignment
.
start
,
this
.
header
,
this
.
footer
,
ThemeData
theme
,
this
.
maxPages
=
20
,
PageOrientation
orientation
,
EdgeInsets
margin
})
:
_buildList
=
build
,
MultiPage
({
PageTheme
pageTheme
,
PdfPageFormat
pageFormat
,
BuildListCallback
build
,
this
.
mainAxisAlignment
=
MainAxisAlignment
.
start
,
this
.
crossAxisAlignment
=
CrossAxisAlignment
.
start
,
this
.
header
,
this
.
footer
,
ThemeData
theme
,
this
.
maxPages
=
20
,
PageOrientation
orientation
,
EdgeInsets
margin
,
})
:
_buildList
=
build
,
assert
(
mainAxisAlignment
!=
null
),
assert
(
crossAxisAlignment
!=
null
),
assert
(
maxPages
!=
null
&&
maxPages
>
0
),
super
(
pageTheme:
pageTheme
,
...
...
@@ -108,6 +107,8 @@ class MultiPage extends Page {
final
BuildCallback
footer
;
final
MainAxisAlignment
mainAxisAlignment
;
final
List
<
_MultiPageInstance
>
_pages
=
<
_MultiPageInstance
>[];
final
int
maxPages
;
...
...
@@ -202,7 +203,7 @@ class MultiPage extends Page {
}());
offsetStart
=
pageHeight
-
(
_mustRotate
?
pageHeightMargin
-
margin
.
bottom
:
_margin
.
top
);
(
_mustRotate
?
pageHeightMargin
-
_
margin
.
bottom
:
_margin
.
top
);
offsetEnd
=
_mustRotate
?
pageHeightMargin
-
_margin
.
left
:
_margin
.
bottom
;
...
...
@@ -268,8 +269,6 @@ class MultiPage extends Page {
_pages
.
last
.
widgets
.
add
(
_MultiPageWidget
(
child:
child
,
x:
_margin
.
left
,
y:
offsetStart
-
child
.
box
.
height
,
constraints:
localConstraints
,
widgetContext:
widgetContext
?.
clone
(),
),
...
...
@@ -289,8 +288,6 @@ class MultiPage extends Page {
_pages
.
last
.
widgets
.
add
(
_MultiPageWidget
(
child:
child
,
x:
_margin
.
left
,
y:
offsetStart
-
child
.
box
.
height
,
constraints:
constraints
,
widgetContext:
child
is
SpanningWidget
&&
canSpan
?
child
.
saveContext
().
clone
()
...
...
@@ -307,8 +304,22 @@ class MultiPage extends Page {
@override
void
postProcess
(
Document
document
)
{
final
EdgeInsets
_margin
=
margin
;
final
bool
_mustRotate
=
mustRotate
;
final
double
pageHeight
=
_mustRotate
?
pageFormat
.
width
:
pageFormat
.
height
;
final
double
pageWidth
=
_mustRotate
?
pageFormat
.
height
:
pageFormat
.
width
;
final
double
pageHeightMargin
=
_mustRotate
?
_margin
.
horizontal
:
_margin
.
vertical
;
final
double
pageWidthMargin
=
_mustRotate
?
_margin
.
vertical
:
_margin
.
horizontal
;
final
double
availableWidth
=
pageWidth
-
pageWidthMargin
;
for
(
_MultiPageInstance
page
in
_pages
)
{
double
offsetStart
=
pageHeight
-
(
_mustRotate
?
pageHeightMargin
-
_margin
.
bottom
:
_margin
.
top
);
double
offsetEnd
=
_mustRotate
?
pageHeightMargin
-
_margin
.
left
:
_margin
.
bottom
;
if
(
pageTheme
.
buildBackground
!=
null
)
{
final
Widget
child
=
pageTheme
.
buildBackground
(
page
.
context
);
if
(
child
!=
null
)
{
...
...
@@ -320,16 +331,25 @@ class MultiPage extends Page {
}
}
int
totalFlex
=
0
;
double
allocatedSize
=
0
;
Widget
lastFlexChild
;
for
(
_MultiPageWidget
widget
in
page
.
widgets
)
{
final
Widget
child
=
widget
.
child
;
if
(
child
is
SpanningWidget
&&
child
.
canSpan
)
{
final
WidgetContext
context
=
child
.
saveContext
();
context
.
apply
(
widget
.
widgetContext
);
final
int
flex
=
child
is
Flexible
?
child
.
flex
:
0
;
if
(
flex
>
0
)
{
totalFlex
+=
flex
;
lastFlexChild
=
child
;
}
else
{
if
(
child
is
SpanningWidget
&&
child
.
canSpan
)
{
final
WidgetContext
context
=
child
.
saveContext
();
context
.
apply
(
widget
.
widgetContext
);
}
child
.
layout
(
page
.
context
,
widget
.
constraints
,
parentUsesSize:
false
);
assert
(
child
.
box
!=
null
);
allocatedSize
+=
child
.
box
.
height
;
}
child
.
layout
(
page
.
context
,
widget
.
constraints
,
parentUsesSize:
false
);
assert
(
child
.
box
!=
null
);
_paintChild
(
page
.
context
,
widget
.
child
,
widget
.
x
,
widget
.
y
,
pageFormat
.
height
);
}
if
(
header
!=
null
)
{
...
...
@@ -338,6 +358,7 @@ class MultiPage extends Page {
headerWidget
.
layout
(
page
.
context
,
page
.
constraints
,
parentUsesSize:
false
);
assert
(
headerWidget
.
box
!=
null
);
offsetStart
-=
headerWidget
.
box
.
height
;
_paintChild
(
page
.
context
,
headerWidget
,
_margin
.
left
,
page
.
offsetStart
-
headerWidget
.
box
.
height
,
pageFormat
.
height
);
}
...
...
@@ -349,11 +370,114 @@ class MultiPage extends Page {
footerWidget
.
layout
(
page
.
context
,
page
.
constraints
,
parentUsesSize:
false
);
assert
(
footerWidget
.
box
!=
null
);
offsetEnd
+=
footerWidget
.
box
.
height
;
_paintChild
(
page
.
context
,
footerWidget
,
_margin
.
left
,
_margin
.
bottom
,
pageFormat
.
height
);
}
}
final
double
freeSpace
=
math
.
max
(
0
,
offsetStart
-
offsetEnd
-
allocatedSize
);
final
double
spacePerFlex
=
totalFlex
>
0
?
(
freeSpace
/
totalFlex
)
:
double
.
nan
;
double
allocatedFlexSpace
=
0
;
double
leadingSpace
=
0
;
double
betweenSpace
=
0
;
if
(
totalFlex
==
0
)
{
final
int
totalChildren
=
page
.
widgets
.
length
;
switch
(
mainAxisAlignment
)
{
case
MainAxisAlignment
.
start
:
leadingSpace
=
0.0
;
betweenSpace
=
0.0
;
break
;
case
MainAxisAlignment
.
end
:
leadingSpace
=
freeSpace
;
betweenSpace
=
0.0
;
break
;
case
MainAxisAlignment
.
center
:
leadingSpace
=
freeSpace
/
2.0
;
betweenSpace
=
0.0
;
break
;
case
MainAxisAlignment
.
spaceBetween
:
leadingSpace
=
0.0
;
betweenSpace
=
totalChildren
>
1
?
freeSpace
/
(
totalChildren
-
1
)
:
0.0
;
break
;
case
MainAxisAlignment
.
spaceAround
:
betweenSpace
=
totalChildren
>
0
?
freeSpace
/
totalChildren
:
0.0
;
leadingSpace
=
betweenSpace
/
2.0
;
break
;
case
MainAxisAlignment
.
spaceEvenly
:
betweenSpace
=
totalChildren
>
0
?
freeSpace
/
(
totalChildren
+
1
)
:
0.0
;
leadingSpace
=
betweenSpace
;
break
;
}
}
for
(
_MultiPageWidget
widget
in
page
.
widgets
)
{
final
Widget
child
=
widget
.
child
;
final
int
flex
=
child
is
Flexible
?
child
.
flex
:
0
;
final
FlexFit
fit
=
child
is
Flexible
?
child
.
fit
:
FlexFit
.
loose
;
if
(
flex
>
0
)
{
assert
(
child
is
!
SpanningWidget
);
final
double
maxChildExtent
=
child
==
lastFlexChild
?
(
freeSpace
-
allocatedFlexSpace
)
:
spacePerFlex
*
flex
;
double
minChildExtent
;
switch
(
fit
)
{
case
FlexFit
.
tight
:
assert
(
maxChildExtent
<
double
.
infinity
);
minChildExtent
=
maxChildExtent
;
break
;
case
FlexFit
.
loose
:
minChildExtent
=
0.0
;
break
;
}
assert
(
minChildExtent
!=
null
);
final
BoxConstraints
innerConstraints
=
BoxConstraints
(
minWidth:
widget
.
constraints
.
maxWidth
,
maxWidth:
widget
.
constraints
.
maxWidth
,
minHeight:
minChildExtent
,
maxHeight:
maxChildExtent
);
child
.
layout
(
page
.
context
,
innerConstraints
,
parentUsesSize:
false
);
assert
(
child
.
box
!=
null
);
final
double
childSize
=
child
.
box
.
height
;
assert
(
childSize
<=
maxChildExtent
);
allocatedSize
+=
childSize
;
allocatedFlexSpace
+=
maxChildExtent
;
}
}
double
pos
=
offsetStart
-
leadingSpace
;
for
(
_MultiPageWidget
widget
in
page
.
widgets
)
{
pos
-=
widget
.
child
.
box
.
height
;
double
x
;
switch
(
crossAxisAlignment
)
{
case
CrossAxisAlignment
.
start
:
x
=
0
;
break
;
case
CrossAxisAlignment
.
end
:
x
=
availableWidth
-
widget
.
child
.
box
.
width
;
break
;
case
CrossAxisAlignment
.
center
:
x
=
availableWidth
/
2
-
widget
.
child
.
box
.
width
/
2
;
break
;
case
CrossAxisAlignment
.
stretch
:
x
=
0
;
break
;
}
_paintChild
(
page
.
context
,
widget
.
child
,
_margin
.
left
+
x
,
pos
,
pageFormat
.
height
);
pos
-=
betweenSpace
;
}
if
(
pageTheme
.
buildForeground
!=
null
)
{
final
Widget
child
=
pageTheme
.
buildForeground
(
page
.
context
);
if
(
child
!=
null
)
{
...
...
pdf/pubspec.yaml
View file @
46d49e8
...
...
@@ -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
:
1.
8.1
version
:
1.
9.0
environment
:
sdk
:
"
>=2.3.0
<3.0.0"
...
...
pdf/test/widget_flex_test.dart
View file @
46d49e8
...
...
@@ -93,6 +93,24 @@ void main() {
);
});
test
(
'MultiPage Spacer'
,
()
{
pdf
.
addPage
(
MultiPage
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
build:
(
Context
context
)
=>
<
Widget
>[
for
(
int
i
=
0
;
i
<
60
;
i
++)
Text
(
'Begin
$i
'
),
Spacer
(),
// Defaults to a flex of one.
Text
(
'Middle'
),
// Gives twice the space between Middle and End than Begin and Middle.
Spacer
(
flex:
2
),
// Expanded(flex: 2, child: SizedBox.shrink()),
Text
(
'End'
),
],
),
);
});
tearDownAll
(()
{
final
File
file
=
File
(
'widgets-flex.pdf'
);
file
.
writeAsBytesSync
(
pdf
.
save
());
...
...
test/golden/orientation.pdf
View file @
46d49e8
No preview for this file type
test/golden/widgets-flex.pdf
View file @
46d49e8
No preview for this file type
Please
register
or
login
to post a comment