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
2023-07-24 08:45:49 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
9d3ca6a45129882bce5802f734414fd2a6f65a7b
9d3ca6a4
1 parent
4f6ec254
RTL Fixes and changelog
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
580 additions
and
280 deletions
pdf/CHANGELOG.md
pdf/lib/src/pdf/rect.dart
pdf/lib/src/widgets/basic.dart
pdf/lib/src/widgets/border_radius.dart
pdf/lib/src/widgets/decoration.dart
pdf/lib/src/widgets/flex.dart
pdf/lib/src/widgets/geometry.dart
pdf/lib/src/widgets/grid_paper.dart
pdf/lib/src/widgets/grid_view.dart
pdf/lib/src/widgets/multi_page.dart
pdf/lib/src/widgets/page.dart
pdf/lib/src/widgets/page_theme.dart
pdf/lib/src/widgets/stack.dart
pdf/lib/src/widgets/table_helper.dart
pdf/lib/src/widgets/text.dart
pdf/test/rtl_layout_test.dart
test/golden/rtl-layout.pdf
test/golden/widgets-text.pdf
pdf/CHANGELOG.md
View file @
9d3ca6a
...
...
@@ -4,6 +4,7 @@
-
Improve TTF writer with multi-compound characters
-
Partially revert underline on spans changes
-
Add RTL support
[
Milad-Akarie
]
## 3.10.4
...
...
pdf/lib/src/pdf/rect.dart
View file @
9d3ca6a
...
...
@@ -22,7 +22,8 @@ import 'point.dart';
class
PdfRect
{
const
PdfRect
(
this
.
x
,
this
.
y
,
this
.
width
,
this
.
height
);
factory
PdfRect
.
fromLTRB
(
double
left
,
double
top
,
double
right
,
double
bottom
)
{
factory
PdfRect
.
fromLTRB
(
double
left
,
double
top
,
double
right
,
double
bottom
)
{
return
PdfRect
(
left
,
top
,
right
-
left
,
bottom
-
top
);
}
...
...
@@ -70,7 +71,8 @@ class PdfRect {
/// Returns a new rectangle with edges moved outwards by the given delta.
PdfRect
inflate
(
double
delta
)
{
return
PdfRect
.
fromLTRB
(
left
-
delta
,
top
-
delta
,
right
+
delta
,
bottom
+
delta
);
return
PdfRect
.
fromLTRB
(
left
-
delta
,
top
-
delta
,
right
+
delta
,
bottom
+
delta
);
}
/// Returns a new rectangle with edges moved inwards by the given delta.
...
...
pdf/lib/src/widgets/basic.dart
View file @
9d3ca6a
...
...
@@ -39,16 +39,22 @@ class LimitedBox extends SingleChildWidget {
BoxConstraints
_limitConstraints
(
BoxConstraints
constraints
)
{
return
BoxConstraints
(
minWidth:
constraints
.
minWidth
,
maxWidth:
constraints
.
hasBoundedWidth
?
constraints
.
maxWidth
:
constraints
.
constrainWidth
(
maxWidth
),
maxWidth:
constraints
.
hasBoundedWidth
?
constraints
.
maxWidth
:
constraints
.
constrainWidth
(
maxWidth
),
minHeight:
constraints
.
minHeight
,
maxHeight:
constraints
.
hasBoundedHeight
?
constraints
.
maxHeight
:
constraints
.
constrainHeight
(
maxHeight
));
maxHeight:
constraints
.
hasBoundedHeight
?
constraints
.
maxHeight
:
constraints
.
constrainHeight
(
maxHeight
));
}
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
PdfPoint
size
;
if
(
child
!=
null
)
{
child
!.
layout
(
context
,
_limitConstraints
(
constraints
),
parentUsesSize:
true
);
child
!.
layout
(
context
,
_limitConstraints
(
constraints
),
parentUsesSize:
true
);
assert
(
child
!.
box
!=
null
);
size
=
constraints
.
constrain
(
child
!.
box
!.
size
);
}
else
{
...
...
@@ -73,16 +79,19 @@ class Padding extends SingleChildWidget {
final
EdgeInsetsGeometry
padding
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
final
resolvedPadding
=
padding
.
resolve
(
Directionality
.
of
(
context
));
if
(
child
!=
null
)
{
final
childConstraints
=
constraints
.
deflate
(
resolvedPadding
);
child
!.
layout
(
context
,
childConstraints
,
parentUsesSize:
parentUsesSize
);
assert
(
child
!.
box
!=
null
);
box
=
constraints
.
constrainRect
(
width:
child
!.
box
!.
width
+
resolvedPadding
.
horizontal
,
height:
child
!.
box
!.
height
+
resolvedPadding
.
vertical
);
width:
child
!.
box
!.
width
+
resolvedPadding
.
horizontal
,
height:
child
!.
box
!.
height
+
resolvedPadding
.
vertical
);
}
else
{
box
=
constraints
.
constrainRect
(
width:
resolvedPadding
.
horizontal
,
height:
resolvedPadding
.
vertical
);
box
=
constraints
.
constrainRect
(
width:
resolvedPadding
.
horizontal
,
height:
resolvedPadding
.
vertical
);
}
}
...
...
@@ -97,8 +106,10 @@ class Padding extends SingleChildWidget {
..
lineTo
(
box
!.
x
,
box
!.
top
)
..
moveTo
(
box
!.
x
+
resolvedPadding
.
left
,
box
!.
y
+
resolvedPadding
.
bottom
)
..
lineTo
(
box
!.
x
+
resolvedPadding
.
left
,
box
!.
top
-
resolvedPadding
.
top
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
top
-
resolvedPadding
.
top
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
y
+
resolvedPadding
.
bottom
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
top
-
resolvedPadding
.
top
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
y
+
resolvedPadding
.
bottom
)
..
fillPath
();
}
...
...
@@ -108,7 +119,8 @@ class Padding extends SingleChildWidget {
final
resolvedPadding
=
padding
.
resolve
(
Directionality
.
of
(
context
));
if
(
child
!=
null
)
{
final
mat
=
Matrix4
.
identity
();
mat
.
translate
(
box
!.
x
+
resolvedPadding
.
left
,
box
!.
y
+
resolvedPadding
.
bottom
);
mat
.
translate
(
box
!.
x
+
resolvedPadding
.
left
,
box
!.
y
+
resolvedPadding
.
bottom
);
context
.
canvas
..
saveContext
()
..
setTransform
(
mat
);
...
...
@@ -210,7 +222,8 @@ class Transform extends SingleChildWidget {
}
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
if
(!
adjustLayout
)
{
return
super
.
layout
(
context
,
constraints
,
parentUsesSize:
parentUsesSize
);
}
...
...
@@ -239,14 +252,20 @@ class Transform extends SingleChildWidget {
0
,
]);
final
dx
=
-
math
.
min
(
math
.
min
(
math
.
min
(
values
[
0
],
values
[
3
]),
values
[
6
]),
values
[
9
]);
final
dy
=
-
math
.
min
(
math
.
min
(
math
.
min
(
values
[
1
],
values
[
4
]),
values
[
7
]),
values
[
10
]);
final
dx
=
-
math
.
min
(
math
.
min
(
math
.
min
(
values
[
0
],
values
[
3
]),
values
[
6
]),
values
[
9
]);
final
dy
=
-
math
.
min
(
math
.
min
(
math
.
min
(
values
[
1
],
values
[
4
]),
values
[
7
]),
values
[
10
]);
box
=
PdfRect
.
fromLTRB
(
0
,
0
,
math
.
max
(
math
.
max
(
math
.
max
(
values
[
0
],
values
[
3
]),
values
[
6
]),
values
[
9
])
+
dx
,
math
.
max
(
math
.
max
(
math
.
max
(
values
[
1
],
values
[
4
]),
values
[
7
]),
values
[
10
])
+
dy
,
math
.
max
(
math
.
max
(
math
.
max
(
values
[
0
],
values
[
3
]),
values
[
6
]),
values
[
9
])
+
dx
,
math
.
max
(
math
.
max
(
math
.
max
(
values
[
1
],
values
[
4
]),
values
[
7
]),
values
[
10
])
+
dy
,
);
transform
.
leftTranslate
(
dx
,
dy
);
...
...
@@ -273,7 +292,11 @@ class Transform extends SingleChildWidget {
/// A widget that aligns its child within itself and optionally sizes itself
/// based on the child's size.
class
Align
extends
SingleChildWidget
{
Align
({
this
.
alignment
=
Alignment
.
center
,
this
.
widthFactor
,
this
.
heightFactor
,
Widget
?
child
})
Align
(
{
this
.
alignment
=
Alignment
.
center
,
this
.
widthFactor
,
this
.
heightFactor
,
Widget
?
child
})
:
assert
(
widthFactor
==
null
||
widthFactor
>=
0.0
),
assert
(
heightFactor
==
null
||
heightFactor
>=
0.0
),
super
(
child:
child
);
...
...
@@ -288,22 +311,30 @@ class Align extends SingleChildWidget {
final
double
?
heightFactor
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
final
shrinkWrapWidth
=
widthFactor
!=
null
||
constraints
.
maxWidth
==
double
.
infinity
;
final
shrinkWrapHeight
=
heightFactor
!=
null
||
constraints
.
maxHeight
==
double
.
infinity
;
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
final
shrinkWrapWidth
=
widthFactor
!=
null
||
constraints
.
maxWidth
==
double
.
infinity
;
final
shrinkWrapHeight
=
heightFactor
!=
null
||
constraints
.
maxHeight
==
double
.
infinity
;
if
(
child
!=
null
)
{
child
!.
layout
(
context
,
constraints
.
loosen
(),
parentUsesSize:
true
);
assert
(
child
!.
box
!=
null
);
box
=
constraints
.
constrainRect
(
width:
shrinkWrapWidth
?
child
!.
box
!.
width
*
(
widthFactor
??
1.0
)
:
double
.
infinity
,
height:
shrinkWrapHeight
?
child
!.
box
!.
height
*
(
heightFactor
??
1.0
)
:
double
.
infinity
);
width:
shrinkWrapWidth
?
child
!.
box
!.
width
*
(
widthFactor
??
1.0
)
:
double
.
infinity
,
height:
shrinkWrapHeight
?
child
!.
box
!.
height
*
(
heightFactor
??
1.0
)
:
double
.
infinity
);
final
resolvedAlignment
=
alignment
.
resolve
(
Directionality
.
of
(
context
));
child
!.
box
=
resolvedAlignment
.
inscribe
(
child
!.
box
!.
size
,
box
!);
}
else
{
box
=
constraints
.
constrainRect
(
width:
shrinkWrapWidth
?
0.0
:
double
.
infinity
,
height:
shrinkWrapHeight
?
0.0
:
double
.
infinity
);
width:
shrinkWrapWidth
?
0.0
:
double
.
infinity
,
height:
shrinkWrapHeight
?
0.0
:
double
.
infinity
);
}
}
...
...
@@ -326,40 +357,58 @@ class Align extends SingleChildWidget {
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
,
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
bottom
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
bottom
-
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
bottom
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
bottom
-
headSize
);
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
bottom
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
bottom
-
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
bottom
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
bottom
-
headSize
);
}
if
(
box
!.
bottom
+
child
!.
box
!.
top
<
box
!.
top
)
{
final
headSize
=
math
.
min
((
box
!.
top
-
child
!.
box
!.
top
-
box
!.
bottom
)
*
0.2
,
10
);
final
headSize
=
math
.
min
((
box
!.
top
-
child
!.
box
!.
top
-
box
!.
bottom
)
*
0.2
,
10
);
context
.
canvas
..
moveTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
top
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
top
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
top
+
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
top
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
top
+
headSize
);
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
top
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
top
+
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
,
box
!.
bottom
+
child
!.
box
!.
top
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
horizontalCenter
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
top
+
headSize
);
}
if
(
child
!.
box
!.
left
>
0
)
{
final
headSize
=
math
.
min
(
child
!.
box
!.
left
*
0.2
,
10
);
context
.
canvas
..
moveTo
(
box
!.
left
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
left
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
left
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
-
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
left
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
left
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
+
headSize
);
..
lineTo
(
box
!.
left
+
child
!.
box
!.
left
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
left
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
-
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
left
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
left
-
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
+
headSize
);
}
if
(
box
!.
left
+
child
!.
box
!.
right
<
box
!.
right
)
{
final
headSize
=
math
.
min
((
box
!.
right
-
child
!.
box
!.
right
-
box
!.
left
)
*
0.2
,
10
);
final
headSize
=
math
.
min
((
box
!.
right
-
child
!.
box
!.
right
-
box
!.
left
)
*
0.2
,
10
);
context
.
canvas
..
moveTo
(
box
!.
right
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
right
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
right
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
-
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
right
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
right
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
+
headSize
);
..
lineTo
(
box
!.
left
+
child
!.
box
!.
right
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
right
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
-
headSize
)
..
moveTo
(
box
!.
left
+
child
!.
box
!.
right
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
)
..
lineTo
(
box
!.
left
+
child
!.
box
!.
right
+
headSize
,
box
!.
bottom
+
child
!.
box
!.
verticalCenter
+
headSize
);
}
context
.
canvas
.
strokePath
();
...
...
@@ -374,19 +423,23 @@ class Align extends SingleChildWidget {
/// A widget that imposes additional constraints on its child.
class
ConstrainedBox
extends
SingleChildWidget
{
ConstrainedBox
({
required
this
.
constraints
,
Widget
?
child
})
:
super
(
child:
child
);
ConstrainedBox
({
required
this
.
constraints
,
Widget
?
child
})
:
super
(
child:
child
);
/// The additional constraints to impose on the child.
final
BoxConstraints
constraints
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
if
(
child
!=
null
)
{
child
!.
layout
(
context
,
this
.
constraints
.
enforce
(
constraints
),
parentUsesSize:
true
);
child
!.
layout
(
context
,
this
.
constraints
.
enforce
(
constraints
),
parentUsesSize:
true
);
assert
(
child
!.
box
!=
null
);
box
=
child
!.
box
;
}
else
{
box
=
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
this
.
constraints
.
enforce
(
constraints
).
smallest
);
box
=
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
this
.
constraints
.
enforce
(
constraints
).
smallest
);
}
}
...
...
@@ -399,7 +452,8 @@ class ConstrainedBox extends SingleChildWidget {
class
Center
extends
Align
{
Center
({
double
?
widthFactor
,
double
?
heightFactor
,
Widget
?
child
})
:
super
(
widthFactor:
widthFactor
,
heightFactor:
heightFactor
,
child:
child
);
:
super
(
widthFactor:
widthFactor
,
heightFactor:
heightFactor
,
child:
child
);
}
/// Scales and positions its child within itself according to [fit].
...
...
@@ -417,12 +471,14 @@ class FittedBox extends SingleChildWidget {
final
AlignmentGeometry
alignment
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
PdfPoint
size
;
if
(
child
!=
null
)
{
child
!.
layout
(
context
,
const
BoxConstraints
(),
parentUsesSize:
true
);
assert
(
child
!.
box
!=
null
);
size
=
constraints
.
constrainSizeAndAttemptToPreserveAspectRatio
(
child
!.
box
!.
size
);
size
=
constraints
.
constrainSizeAndAttemptToPreserveAspectRatio
(
child
!.
box
!.
size
);
}
else
{
size
=
constraints
.
smallest
;
}
...
...
@@ -439,12 +495,15 @@ class FittedBox extends SingleChildWidget {
final
sizes
=
applyBoxFit
(
fit
,
childSize
,
box
!.
size
);
final
scaleX
=
sizes
.
destination
!.
x
/
sizes
.
source
!.
x
;
final
scaleY
=
sizes
.
destination
!.
y
/
sizes
.
source
!.
y
;
final
sourceRect
=
resolvedAlignment
.
inscribe
(
sizes
.
source
!,
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
childSize
));
final
destinationRect
=
resolvedAlignment
.
inscribe
(
sizes
.
destination
!,
box
!);
final
sourceRect
=
resolvedAlignment
.
inscribe
(
sizes
.
source
!,
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
childSize
));
final
destinationRect
=
resolvedAlignment
.
inscribe
(
sizes
.
destination
!,
box
!);
final
mat
=
Matrix4
.
translationValues
(
destinationRect
.
x
,
destinationRect
.
y
,
0
)
..
scale
(
scaleX
,
scaleY
,
1
)
..
translate
(-
sourceRect
.
x
,
-
sourceRect
.
y
);
final
mat
=
Matrix4
.
translationValues
(
destinationRect
.
x
,
destinationRect
.
y
,
0
)
..
scale
(
scaleX
,
scaleY
,
1
)
..
translate
(-
sourceRect
.
x
,
-
sourceRect
.
y
);
context
.
canvas
..
saveContext
()
...
...
@@ -502,10 +561,12 @@ class AspectRatio extends SingleChildWidget {
}
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
box
=
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
_applyAspectRatio
(
constraints
));
if
(
child
!=
null
)
{
child
!.
layout
(
context
,
BoxConstraints
.
tightFor
(
width:
box
!.
width
,
height:
box
!.
height
));
child
!.
layout
(
context
,
BoxConstraints
.
tightFor
(
width:
box
!.
width
,
height:
box
!.
height
));
}
assert
(
child
!.
box
!=
null
);
}
...
...
@@ -532,7 +593,8 @@ class CustomPaint extends SingleChildWidget {
final
PdfPoint
size
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
if
(
child
!=
null
)
{
child
!.
layout
(
context
,
constraints
,
parentUsesSize:
parentUsesSize
);
assert
(
child
!.
box
!=
null
);
...
...
@@ -599,7 +661,9 @@ class SizedBox extends StatelessWidget {
@override
Widget
build
(
Context
context
)
{
return
ConstrainedBox
(
child:
child
,
constraints:
BoxConstraints
.
tightFor
(
width:
width
,
height:
height
));
return
ConstrainedBox
(
child:
child
,
constraints:
BoxConstraints
.
tightFor
(
width:
width
,
height:
height
));
}
}
...
...
@@ -622,7 +686,8 @@ class Builder extends StatelessWidget {
}
/// The signature of the [LayoutBuilder] builder function.
typedef
LayoutWidgetBuilder
=
Widget
Function
(
Context
context
,
BoxConstraints
?
constraints
);
typedef
LayoutWidgetBuilder
=
Widget
Function
(
Context
context
,
BoxConstraints
?
constraints
);
/// Builds a widget tree that can depend on the parent widget's size.
class
LayoutBuilder
extends
StatelessWidget
{
...
...
@@ -637,7 +702,8 @@ class LayoutBuilder extends StatelessWidget {
BoxConstraints
?
_constraints
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
_constraints
=
constraints
;
super
.
layout
(
context
,
constraints
);
}
...
...
@@ -684,7 +750,8 @@ class FullPage extends SingleChildWidget {
}
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
final
constraints
=
_getConstraints
(
context
);
if
(
child
!=
null
)
{
...
...
@@ -904,11 +971,13 @@ class OverflowBox extends SingleChildWidget {
}
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
box
=
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
constraints
.
smallest
);
if
(
child
!=
null
)
{
child
!.
layout
(
context
,
_getInnerConstraints
(
constraints
),
parentUsesSize:
true
);
child
!.
layout
(
context
,
_getInnerConstraints
(
constraints
),
parentUsesSize:
true
);
assert
(
child
!.
box
!=
null
);
final
resolvedAlignment
=
alignment
.
resolve
(
Directionality
.
of
(
context
));
child
!.
box
=
resolvedAlignment
.
inscribe
(
child
!.
box
!.
size
,
box
!);
...
...
pdf/lib/src/widgets/border_radius.dart
View file @
9d3ca6a
...
...
@@ -85,7 +85,9 @@ abstract class BorderRadiusGeometry {
@override
String
toString
()
{
String
?
visual
,
logical
;
if
(
_topLeft
==
_topRight
&&
_topRight
==
_bottomLeft
&&
_bottomLeft
==
_bottomRight
)
{
if
(
_topLeft
==
_topRight
&&
_topRight
==
_bottomLeft
&&
_bottomLeft
==
_bottomRight
)
{
if
(
_topLeft
!=
Radius
.
zero
)
{
if
(
_topLeft
.
x
==
_topLeft
.
y
)
{
visual
=
'BorderRadius.circular(
${_topLeft.x.toStringAsFixed(1)}
)'
;
...
...
@@ -125,10 +127,13 @@ abstract class BorderRadiusGeometry {
result
.
write
(
')'
);
visual
=
result
.
toString
();
}
if
(
_topStart
==
_topEnd
&&
_topEnd
==
_bottomEnd
&&
_bottomEnd
==
_bottomStart
)
{
if
(
_topStart
==
_topEnd
&&
_topEnd
==
_bottomEnd
&&
_bottomEnd
==
_bottomStart
)
{
if
(
_topStart
!=
Radius
.
zero
)
{
if
(
_topStart
.
x
==
_topStart
.
y
)
{
logical
=
'BorderRadiusDirectional.circular(
${_topStart.x.toStringAsFixed(1)}
)'
;
logical
=
'BorderRadiusDirectional.circular(
${_topStart.x.toStringAsFixed(1)}
)'
;
}
else
{
logical
=
'BorderRadiusDirectional.all(
$_topStart
)'
;
}
...
...
@@ -228,8 +233,6 @@ class BorderRadius extends BorderRadiusGeometry {
this
.
bottomRight
=
Radius
.
zero
,
});
/// A border radius with all zero radii.
static
const
BorderRadius
zero
=
BorderRadius
.
all
(
Radius
.
zero
);
...
...
@@ -245,14 +248,13 @@ class BorderRadius extends BorderRadiusGeometry {
/// The bottom-right [Radius].
final
Radius
bottomRight
;
@override
bool
get
isUniform
=>
topLeft
==
topRight
&&
topLeft
==
bottomLeft
&&
topLeft
==
bottomRight
;
bool
get
isUniform
=>
topLeft
==
topRight
&&
topLeft
==
bottomLeft
&&
topLeft
==
bottomRight
;
@override
Radius
get
uniform
=>
isUniform
?
topLeft
:
Radius
.
zero
;
void
paint
(
Context
context
,
PdfRect
box
)
{
// Ellipse 4-spline magic number
const
_m4
=
0.551784
;
...
...
@@ -261,13 +263,23 @@ class BorderRadius extends BorderRadiusGeometry {
// Start
..
moveTo
(
box
.
x
,
box
.
y
+
bottomLeft
.
y
)
// bottomLeft
..
curveTo
(
box
.
x
,
box
.
y
-
_m4
*
bottomLeft
.
y
+
bottomLeft
.
y
,
box
.
x
-
_m4
*
bottomLeft
.
x
+
bottomLeft
.
x
,
box
.
y
,
box
.
x
+
bottomLeft
.
x
,
box
.
y
)
..
curveTo
(
box
.
x
,
box
.
y
-
_m4
*
bottomLeft
.
y
+
bottomLeft
.
y
,
box
.
x
-
_m4
*
bottomLeft
.
x
+
bottomLeft
.
x
,
box
.
y
,
box
.
x
+
bottomLeft
.
x
,
box
.
y
)
// bottom
..
lineTo
(
box
.
x
+
box
.
width
-
bottomRight
.
x
,
box
.
y
)
// bottomRight
..
curveTo
(
box
.
x
+
_m4
*
bottomRight
.
x
+
box
.
width
-
bottomRight
.
x
,
box
.
y
,
box
.
x
+
box
.
width
,
box
.
y
-
_m4
*
bottomRight
.
y
+
bottomRight
.
y
,
box
.
x
+
box
.
width
,
box
.
y
+
bottomRight
.
y
)
..
curveTo
(
box
.
x
+
_m4
*
bottomRight
.
x
+
box
.
width
-
bottomRight
.
x
,
box
.
y
,
box
.
x
+
box
.
width
,
box
.
y
-
_m4
*
bottomRight
.
y
+
bottomRight
.
y
,
box
.
x
+
box
.
width
,
box
.
y
+
bottomRight
.
y
)
// right
..
lineTo
(
box
.
x
+
box
.
width
,
box
.
y
+
box
.
height
-
topRight
.
y
)
// topRight
...
...
@@ -281,8 +293,13 @@ class BorderRadius extends BorderRadiusGeometry {
// top
..
lineTo
(
box
.
x
+
topLeft
.
x
,
box
.
y
+
box
.
height
)
// topLeft
..
curveTo
(
box
.
x
-
_m4
*
topLeft
.
x
+
topLeft
.
x
,
box
.
y
+
box
.
height
,
box
.
x
,
box
.
y
+
_m4
*
topLeft
.
y
+
box
.
height
-
topLeft
.
y
,
box
.
x
,
box
.
y
+
box
.
height
-
topLeft
.
y
)
..
curveTo
(
box
.
x
-
_m4
*
topLeft
.
x
+
topLeft
.
x
,
box
.
y
+
box
.
height
,
box
.
x
,
box
.
y
+
_m4
*
topLeft
.
y
+
box
.
height
-
topLeft
.
y
,
box
.
x
,
box
.
y
+
box
.
height
-
topLeft
.
y
)
// left
..
lineTo
(
box
.
x
,
box
.
y
+
bottomLeft
.
y
);
}
...
...
@@ -329,17 +346,19 @@ class BorderRadius extends BorderRadiusGeometry {
/// `topRight` instead of `topStart` and `topEnd`).
class
BorderRadiusDirectional
extends
BorderRadiusGeometry
{
/// Creates a border radius where all radii are [radius].
const
BorderRadiusDirectional
.
all
(
Radius
radius
)
:
this
.
only
(
topStart:
radius
,
topEnd:
radius
,
bottomStart:
radius
,
bottomEnd:
radius
,
);
const
BorderRadiusDirectional
.
all
(
Radius
radius
)
:
this
.
only
(
topStart:
radius
,
topEnd:
radius
,
bottomStart:
radius
,
bottomEnd:
radius
,
);
/// Creates a border radius where all radii are [Radius.circular(radius)].
BorderRadiusDirectional
.
circular
(
double
radius
)
:
this
.
all
(
Radius
.
circular
(
radius
),
);
BorderRadiusDirectional
.
circular
(
double
radius
)
:
this
.
all
(
Radius
.
circular
(
radius
),
);
/// Creates a vertically symmetric border radius where the top and bottom
/// sides of the rectangle have the same radii.
...
...
@@ -347,11 +366,11 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
Radius
top
=
Radius
.
zero
,
Radius
bottom
=
Radius
.
zero
,
})
:
this
.
only
(
topStart:
top
,
topEnd:
top
,
bottomStart:
bottom
,
bottomEnd:
bottom
,
);
topStart:
top
,
topEnd:
top
,
bottomStart:
bottom
,
bottomEnd:
bottom
,
);
/// Creates a horizontally symmetrical border radius where the start and end
/// sides of the rectangle have the same radii.
...
...
@@ -359,11 +378,11 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
Radius
start
=
Radius
.
zero
,
Radius
end
=
Radius
.
zero
,
})
:
this
.
only
(
topStart:
start
,
topEnd:
end
,
bottomStart:
start
,
bottomEnd:
end
,
);
topStart:
start
,
topEnd:
end
,
bottomStart:
start
,
bottomEnd:
end
,
);
/// Creates a border radius with only the given non-zero values. The other
/// corners will be right angles.
...
...
@@ -378,7 +397,8 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
///
/// Consider using [BorderRadius.zero] instead, since that object has the same
/// effect, but will be cheaper to [resolve].
static
const
BorderRadiusDirectional
zero
=
BorderRadiusDirectional
.
all
(
Radius
.
zero
);
static
const
BorderRadiusDirectional
zero
=
BorderRadiusDirectional
.
all
(
Radius
.
zero
);
/// The top-start [Radius].
final
Radius
topStart
;
...
...
@@ -417,7 +437,8 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
Radius
get
_bottomRight
=>
Radius
.
zero
;
@override
bool
get
isUniform
=>
topStart
==
topEnd
&&
topStart
==
bottomStart
&&
topStart
==
bottomEnd
;
bool
get
isUniform
=>
topStart
==
topEnd
&&
topStart
==
bottomStart
&&
topStart
==
bottomEnd
;
@override
Radius
get
uniform
=>
isUniform
?
topStart
:
Radius
.
zero
;
...
...
@@ -442,4 +463,4 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
);
}
}
}
\ No newline at end of file
}
...
...
pdf/lib/src/widgets/decoration.dart
View file @
9d3ca6a
...
...
@@ -207,7 +207,7 @@ class RadialGradient extends Gradient {
final
_focal
=
focal
??
center
;
final
_radius
=
math
.
min
(
box
.
width
,
box
.
height
);
final
textDirection
=
Directionality
.
of
(
context
);
final
textDirection
=
Directionality
.
of
(
context
);
context
.
canvas
..
saveContext
()
..
clipPath
()
...
...
@@ -277,7 +277,8 @@ class BoxDecoration {
PdfRect
box
,
[
PaintPhase
phase
=
PaintPhase
.
all
,
])
{
final
resolvedBorderRadius
=
borderRadius
?.
resolve
(
Directionality
.
of
(
context
));
final
resolvedBorderRadius
=
borderRadius
?.
resolve
(
Directionality
.
of
(
context
));
if
(
phase
==
PaintPhase
.
all
||
phase
==
PaintPhase
.
background
)
{
if
(
color
!=
null
)
{
switch
(
shape
)
{
...
...
@@ -363,7 +364,7 @@ class BoxDecoration {
break
;
case
BoxShape
.
rectangle
:
if
(
resolvedBorderRadius
!=
null
)
{
if
(
resolvedBorderRadius
!=
null
)
{
resolvedBorderRadius
.
paint
(
context
,
box
);
context
.
canvas
.
clipPath
();
}
...
...
pdf/lib/src/widgets/flex.dart
View file @
9d3ca6a
...
...
@@ -394,8 +394,9 @@ class Flex extends MultiChildWidget with SpanningWidget {
double
?
leadingSpace
;
late
double
betweenSpace
;
final
textDirection
=
Directionality
.
of
(
context
)
;
final
flipMainAxis
=
!(
_startIsTopLeft
(
direction
,
textDirection
,
verticalDirection
)
??
true
);
final
textDirection
=
Directionality
.
of
(
context
);
final
flipMainAxis
=
!(
_startIsTopLeft
(
direction
,
textDirection
,
verticalDirection
)
??
true
);
switch
(
mainAxisAlignment
)
{
case
MainAxisAlignment
.
start
:
...
...
@@ -436,8 +437,9 @@ class Flex extends MultiChildWidget with SpanningWidget {
switch
(
crossAxisAlignment
)
{
case
CrossAxisAlignment
.
start
:
case
CrossAxisAlignment
.
end
:
childCrossPosition
=
_startIsTopLeft
(
flipAxis
(
direction
),
textDirection
,
verticalDirection
)
==
(
crossAxisAlignment
==
CrossAxisAlignment
.
start
)
childCrossPosition
=
_startIsTopLeft
(
flipAxis
(
direction
),
textDirection
,
verticalDirection
)
==
(
crossAxisAlignment
==
CrossAxisAlignment
.
start
)
?
0.0
:
crossSize
-
_getCrossSize
(
child
);
break
;
...
...
@@ -479,7 +481,8 @@ class Flex extends MultiChildWidget with SpanningWidget {
}
}
bool
?
_startIsTopLeft
(
Axis
direction
,
TextDirection
?
textDirection
,
VerticalDirection
?
verticalDirection
)
{
bool
?
_startIsTopLeft
(
Axis
direction
,
TextDirection
?
textDirection
,
VerticalDirection
?
verticalDirection
)
{
// If the relevant value of textDirection or verticalDirection is null, this returns null too.
switch
(
direction
)
{
case
Axis
.
horizontal
:
...
...
pdf/lib/src/widgets/geometry.dart
View file @
9d3ca6a
...
...
@@ -26,7 +26,10 @@ import '../../widgets.dart';
class
BoxConstraints
{
/// Creates box constraints with the given constraints.
const
BoxConstraints
(
{
this
.
minWidth
=
0.0
,
this
.
maxWidth
=
double
.
infinity
,
this
.
minHeight
=
0.0
,
this
.
maxHeight
=
double
.
infinity
});
{
this
.
minWidth
=
0.0
,
this
.
maxWidth
=
double
.
infinity
,
this
.
minHeight
=
0.0
,
this
.
maxHeight
=
double
.
infinity
});
/// Creates box constraints that require the given width or height.
const
BoxConstraints
.
tightFor
({
double
?
width
,
double
?
height
})
...
...
@@ -101,7 +104,8 @@ class BoxConstraints {
return
result
;
}
PdfRect
constrainRect
({
double
width
=
double
.
infinity
,
double
height
=
double
.
infinity
})
{
PdfRect
constrainRect
(
{
double
width
=
double
.
infinity
,
double
height
=
double
.
infinity
})
{
final
result
=
PdfPoint
(
constrainWidth
(
width
),
constrainHeight
(
height
));
return
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
result
);
}
...
...
@@ -158,8 +162,10 @@ class BoxConstraints {
return
BoxConstraints
(
minWidth:
width
==
null
?
minWidth
:
width
.
clamp
(
minWidth
,
maxWidth
),
maxWidth:
width
==
null
?
maxWidth
:
width
.
clamp
(
minWidth
,
maxWidth
),
minHeight:
height
==
null
?
minHeight
:
height
.
clamp
(
minHeight
,
maxHeight
),
maxHeight:
height
==
null
?
maxHeight
:
height
.
clamp
(
minHeight
,
maxHeight
));
minHeight:
height
==
null
?
minHeight
:
height
.
clamp
(
minHeight
,
maxHeight
),
maxHeight:
height
==
null
?
maxHeight
:
height
.
clamp
(
minHeight
,
maxHeight
));
}
/// Returns new box constraints that are smaller by the given edge dimensions.
...
...
@@ -191,11 +197,17 @@ class BoxConstraints {
return
BoxConstraints
(
minWidth:
minWidth
.
clamp
(
constraints
.
minWidth
,
constraints
.
maxWidth
),
maxWidth:
maxWidth
.
clamp
(
constraints
.
minWidth
,
constraints
.
maxWidth
),
minHeight:
minHeight
.
clamp
(
constraints
.
minHeight
,
constraints
.
maxHeight
),
maxHeight:
maxHeight
.
clamp
(
constraints
.
minHeight
,
constraints
.
maxHeight
));
minHeight:
minHeight
.
clamp
(
constraints
.
minHeight
,
constraints
.
maxHeight
),
maxHeight:
maxHeight
.
clamp
(
constraints
.
minHeight
,
constraints
.
maxHeight
));
}
BoxConstraints
copyWith
({
double
?
minWidth
,
double
?
maxWidth
,
double
?
minHeight
,
double
?
maxHeight
})
{
BoxConstraints
copyWith
(
{
double
?
minWidth
,
double
?
maxWidth
,
double
?
minHeight
,
double
?
maxHeight
})
{
return
BoxConstraints
(
minWidth:
minWidth
??
this
.
minWidth
,
maxWidth:
maxWidth
??
this
.
maxWidth
,
...
...
@@ -308,7 +320,8 @@ class EdgeInsets extends EdgeInsetsGeometry {
right
=
value
,
bottom
=
value
;
const
EdgeInsets
.
only
({
this
.
left
=
0.0
,
this
.
top
=
0.0
,
this
.
right
=
0.0
,
this
.
bottom
=
0.0
});
const
EdgeInsets
.
only
(
{
this
.
left
=
0.0
,
this
.
top
=
0.0
,
this
.
right
=
0.0
,
this
.
bottom
=
0.0
});
const
EdgeInsets
.
symmetric
({
double
vertical
=
0.0
,
double
horizontal
=
0.0
})
:
left
=
horizontal
,
...
...
@@ -385,7 +398,8 @@ class EdgeInsets extends EdgeInsetsGeometry {
}
class
_MixedEdgeInsets
extends
EdgeInsetsGeometry
{
const
_MixedEdgeInsets
.
fromLRSETB
(
this
.
_left
,
this
.
_right
,
this
.
_start
,
this
.
_end
,
this
.
_top
,
this
.
_bottom
);
const
_MixedEdgeInsets
.
fromLRSETB
(
this
.
_left
,
this
.
_right
,
this
.
_start
,
this
.
_end
,
this
.
_top
,
this
.
_bottom
);
@override
final
double
_left
;
...
...
@@ -410,9 +424,11 @@ class _MixedEdgeInsets extends EdgeInsetsGeometry {
assert
(
direction
!=
null
);
switch
(
direction
!)
{
case
TextDirection
.
rtl
:
return
EdgeInsets
.
fromLTRB
(
_end
+
_left
,
_top
,
_start
+
_right
,
_bottom
);
return
EdgeInsets
.
fromLTRB
(
_end
+
_left
,
_top
,
_start
+
_right
,
_bottom
);
case
TextDirection
.
ltr
:
return
EdgeInsets
.
fromLTRB
(
_start
+
_left
,
_top
,
_end
+
_right
,
_bottom
);
return
EdgeInsets
.
fromLTRB
(
_start
+
_left
,
_top
,
_end
+
_right
,
_bottom
);
}
}
}
...
...
@@ -430,7 +446,8 @@ class _MixedEdgeInsets extends EdgeInsetsGeometry {
/// of start and end).
class
EdgeInsetsDirectional
extends
EdgeInsetsGeometry
{
/// Creates insets from offsets from the start, top, end, and bottom.
const
EdgeInsetsDirectional
.
fromSTEB
(
this
.
start
,
this
.
top
,
this
.
end
,
this
.
bottom
);
const
EdgeInsetsDirectional
.
fromSTEB
(
this
.
start
,
this
.
top
,
this
.
end
,
this
.
bottom
);
/// Creates insets with only the given values non-zero.
///
...
...
@@ -580,7 +597,6 @@ abstract class AlignmentGeometry {
/// const constructors so that they can be used in const expressions.
const
AlignmentGeometry
();
/// Convert this instance into an [Alignment], which uses literal
/// coordinates (the `x` coordinate being explicitly a distance from the
/// left).
...
...
@@ -591,7 +607,6 @@ abstract class AlignmentGeometry {
/// * [AlignmentDirectional], which flips the horizontal direction
/// based on the `direction` argument.
Alignment
resolve
(
TextDirection
?
direction
);
}
class
Alignment
extends
AlignmentGeometry
{
...
...
@@ -753,7 +768,8 @@ class AlignmentDirectional extends AlignmentGeometry {
static
const
AlignmentDirectional
topEnd
=
AlignmentDirectional
(
1.0
,
-
1.0
);
/// The center point along the "start" edge.
static
const
AlignmentDirectional
centerStart
=
AlignmentDirectional
(-
1.0
,
0.0
);
static
const
AlignmentDirectional
centerStart
=
AlignmentDirectional
(-
1.0
,
0.0
);
/// The center point, both horizontally and vertically.
///
...
...
@@ -765,13 +781,15 @@ class AlignmentDirectional extends AlignmentGeometry {
static
const
AlignmentDirectional
centerEnd
=
AlignmentDirectional
(
1.0
,
0.0
);
/// The bottom corner on the "start" side.
static
const
AlignmentDirectional
bottomStart
=
AlignmentDirectional
(-
1.0
,
1.0
);
static
const
AlignmentDirectional
bottomStart
=
AlignmentDirectional
(-
1.0
,
1.0
);
/// The center point along the bottom edge.
///
/// Consider using [Alignment.bottomCenter] instead, as it does not
/// need to be [resolve]d to be used.
static
const
AlignmentDirectional
bottomCenter
=
AlignmentDirectional
(
0.0
,
1.0
);
static
const
AlignmentDirectional
bottomCenter
=
AlignmentDirectional
(
0.0
,
1.0
);
/// The bottom corner on the "end" side.
static
const
AlignmentDirectional
bottomEnd
=
AlignmentDirectional
(
1.0
,
1.0
);
...
...
@@ -813,7 +831,8 @@ class AlignmentDirectional extends AlignmentGeometry {
@override
Alignment
resolve
(
TextDirection
?
direction
)
{
assert
(
direction
!=
null
,
'Cannot resolve
$runtimeType
without a TextDirection.'
);
assert
(
direction
!=
null
,
'Cannot resolve
$runtimeType
without a TextDirection.'
);
switch
(
direction
!)
{
case
TextDirection
.
rtl
:
return
Alignment
(-
start
,
y
);
...
...
@@ -823,7 +842,6 @@ class AlignmentDirectional extends AlignmentGeometry {
}
}
/// An offset that's expressed as a fraction of a [PdfPoint].
@immutable
class
FractionalOffset
extends
Alignment
{
...
...
@@ -844,7 +862,10 @@ class FittedSizes {
}
FittedSizes
applyBoxFit
(
BoxFit
fit
,
PdfPoint
inputSize
,
PdfPoint
outputSize
)
{
if
(
inputSize
.
y
<=
0.0
||
inputSize
.
x
<=
0.0
||
outputSize
.
y
<=
0.0
||
outputSize
.
x
<=
0.0
)
{
if
(
inputSize
.
y
<=
0.0
||
inputSize
.
x
<=
0.0
||
outputSize
.
y
<=
0.0
||
outputSize
.
x
<=
0.0
)
{
return
const
FittedSizes
(
PdfPoint
.
zero
,
PdfPoint
.
zero
);
}
...
...
@@ -857,29 +878,38 @@ FittedSizes applyBoxFit(BoxFit fit, PdfPoint inputSize, PdfPoint outputSize) {
case
BoxFit
.
contain
:
sourceSize
=
inputSize
;
if
(
outputSize
.
x
/
outputSize
.
y
>
sourceSize
.
x
/
sourceSize
.
y
)
{
destinationSize
=
PdfPoint
(
sourceSize
.
x
*
outputSize
.
y
/
sourceSize
.
y
,
outputSize
.
y
);
destinationSize
=
PdfPoint
(
sourceSize
.
x
*
outputSize
.
y
/
sourceSize
.
y
,
outputSize
.
y
);
}
else
{
destinationSize
=
PdfPoint
(
outputSize
.
x
,
sourceSize
.
y
*
outputSize
.
x
/
sourceSize
.
x
);
destinationSize
=
PdfPoint
(
outputSize
.
x
,
sourceSize
.
y
*
outputSize
.
x
/
sourceSize
.
x
);
}
break
;
case
BoxFit
.
cover
:
if
(
outputSize
.
x
/
outputSize
.
y
>
inputSize
.
x
/
inputSize
.
y
)
{
sourceSize
=
PdfPoint
(
inputSize
.
x
,
inputSize
.
x
*
outputSize
.
y
/
outputSize
.
x
);
sourceSize
=
PdfPoint
(
inputSize
.
x
,
inputSize
.
x
*
outputSize
.
y
/
outputSize
.
x
);
}
else
{
sourceSize
=
PdfPoint
(
inputSize
.
y
*
outputSize
.
x
/
outputSize
.
y
,
inputSize
.
y
);
sourceSize
=
PdfPoint
(
inputSize
.
y
*
outputSize
.
x
/
outputSize
.
y
,
inputSize
.
y
);
}
destinationSize
=
outputSize
;
break
;
case
BoxFit
.
fitWidth
:
sourceSize
=
PdfPoint
(
inputSize
.
x
,
inputSize
.
x
*
outputSize
.
y
/
outputSize
.
x
);
destinationSize
=
PdfPoint
(
outputSize
.
x
,
sourceSize
.
y
*
outputSize
.
x
/
sourceSize
.
x
);
sourceSize
=
PdfPoint
(
inputSize
.
x
,
inputSize
.
x
*
outputSize
.
y
/
outputSize
.
x
);
destinationSize
=
PdfPoint
(
outputSize
.
x
,
sourceSize
.
y
*
outputSize
.
x
/
sourceSize
.
x
);
break
;
case
BoxFit
.
fitHeight
:
sourceSize
=
PdfPoint
(
inputSize
.
y
*
outputSize
.
x
/
outputSize
.
y
,
inputSize
.
y
);
destinationSize
=
PdfPoint
(
sourceSize
.
x
*
outputSize
.
y
/
sourceSize
.
y
,
outputSize
.
y
);
sourceSize
=
PdfPoint
(
inputSize
.
y
*
outputSize
.
x
/
outputSize
.
y
,
inputSize
.
y
);
destinationSize
=
PdfPoint
(
sourceSize
.
x
*
outputSize
.
y
/
sourceSize
.
y
,
outputSize
.
y
);
break
;
case
BoxFit
.
none
:
sourceSize
=
PdfPoint
(
math
.
min
(
inputSize
.
x
,
outputSize
.
x
),
math
.
min
(
inputSize
.
y
,
outputSize
.
y
));
sourceSize
=
PdfPoint
(
math
.
min
(
inputSize
.
x
,
outputSize
.
x
),
math
.
min
(
inputSize
.
y
,
outputSize
.
y
));
destinationSize
=
sourceSize
;
break
;
case
BoxFit
.
scaleDown
:
...
...
pdf/lib/src/widgets/grid_paper.dart
View file @
9d3ca6a
...
...
@@ -200,7 +200,6 @@ class GridPaper extends SingleChildWidget {
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
final
resolvedMargin
=
margin
.
resolve
(
Directionality
.
of
(
context
));
box
=
PdfRect
.
fromPoints
(
PdfPoint
.
zero
,
constraints
.
biggest
);
if
(
child
!=
null
)
{
...
...
@@ -216,7 +215,8 @@ class GridPaper extends SingleChildWidget {
assert
(
child
!.
box
!=
null
);
child
!.
box
=
PdfRect
.
fromPoints
(
PdfPoint
(
resolvedMargin
.
left
,
box
!.
top
-
resolvedMargin
.
top
-
child
!.
box
!.
height
),
PdfPoint
(
resolvedMargin
.
left
,
box
!.
top
-
resolvedMargin
.
top
-
child
!.
box
!.
height
),
child
!.
box
!.
size
);
}
}
...
...
@@ -273,8 +273,8 @@ class GridPaper extends SingleChildWidget {
context
.
canvas
..
setStrokeColor
(
border
.
left
.
color
)
..
setLineWidth
(
border
.
left
.
width
)
..
drawLine
(
box
!.
left
+
resolvedMargin
.
left
,
box
!.
top
,
box
!.
left
+
resolvedMargin
.
left
,
box
!.
bottom
)
..
drawLine
(
box
!.
left
+
resolvedMargin
.
left
,
box
!.
top
,
box
!.
left
+
resolvedMargin
.
left
,
box
!.
bottom
)
..
strokePath
();
border
.
left
.
style
.
unsetStyle
(
context
);
}
...
...
@@ -293,8 +293,8 @@ class GridPaper extends SingleChildWidget {
context
.
canvas
..
setStrokeColor
(
border
.
top
.
color
)
..
setLineWidth
(
border
.
top
.
width
)
..
drawLine
(
box
!.
left
,
box
!.
top
-
resolvedMargin
.
top
,
box
!.
right
,
box
!.
top
-
resolvedMargin
.
top
)
..
drawLine
(
box
!.
left
,
box
!.
top
-
resolvedMargin
.
top
,
box
!.
right
,
box
!.
top
-
resolvedMargin
.
top
)
..
strokePath
();
border
.
top
.
style
.
unsetStyle
(
context
);
}
...
...
pdf/lib/src/widgets/grid_view.dart
View file @
9d3ca6a
...
...
@@ -47,7 +47,8 @@ class GridViewContext extends WidgetContext {
}
@override
String
toString
()
=>
'
$runtimeType
first:
$firstChild
last:
$lastChild
size:
${childCrossAxis}
x
$childMainAxis
'
;
String
toString
()
=>
'
$runtimeType
first:
$firstChild
last:
$lastChild
size:
${childCrossAxis}
x
$childMainAxis
'
;
}
class
GridView
extends
MultiChildWidget
with
SpanningWidget
{
...
...
@@ -73,7 +74,8 @@ class GridView extends MultiChildWidget with SpanningWidget {
int
?
_mainAxisCount
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
if
(
children
.
isEmpty
)
{
box
=
PdfRect
.
zero
;
return
;
...
...
@@ -81,7 +83,8 @@ class GridView extends MultiChildWidget with SpanningWidget {
assert
(()
{
if
(
constraints
.
maxHeight
.
isInfinite
&&
childAspectRatio
.
isInfinite
)
{
print
(
'Unable to calculate the GridView dimensions. Please set the height constraints or childAspectRatio.'
);
print
(
'Unable to calculate the GridView dimensions. Please set the height constraints or childAspectRatio.'
);
return
false
;
}
return
true
;
...
...
@@ -102,19 +105,25 @@ class GridView extends MultiChildWidget with SpanningWidget {
}
if
(
constraints
.
maxHeight
.
isInfinite
||
_mainAxisCount
==
null
)
{
_mainAxisCount
=
((
children
.
length
-
_context
.
firstChild
)
/
crossAxisCount
).
ceil
();
_mainAxisCount
=
((
children
.
length
-
_context
.
firstChild
)
/
crossAxisCount
).
ceil
();
_context
.
childCrossAxis
=
crossAxisExtent
/
crossAxisCount
-
(
crossAxisSpacing
*
(
crossAxisCount
-
1
)
/
crossAxisCount
);
_context
.
childCrossAxis
=
crossAxisExtent
/
crossAxisCount
-
(
crossAxisSpacing
*
(
crossAxisCount
-
1
)
/
crossAxisCount
);
_context
.
childMainAxis
=
math
.
min
(
_context
.
childCrossAxis
!
*
childAspectRatio
,
mainAxisExtent
/
_mainAxisCount
!
-
(
mainAxisSpacing
*
(
_mainAxisCount
!
-
1
)
/
_mainAxisCount
!));
_context
.
childMainAxis
=
math
.
min
(
_context
.
childCrossAxis
!
*
childAspectRatio
,
mainAxisExtent
/
_mainAxisCount
!
-
(
mainAxisSpacing
*
(
_mainAxisCount
!
-
1
)
/
_mainAxisCount
!));
if
(
_context
.
childCrossAxis
!.
isInfinite
)
{
throw
Exception
(
'Unable to calculate child height as the height constraint is infinite.'
);
throw
Exception
(
'Unable to calculate child height as the height constraint is infinite.'
);
}
}
else
{
_mainAxisCount
=
((
mainAxisExtent
+
mainAxisSpacing
)
/
(
mainAxisSpacing
+
_context
.
childMainAxis
!)).
floor
();
_mainAxisCount
=
((
mainAxisExtent
+
mainAxisSpacing
)
/
(
mainAxisSpacing
+
_context
.
childMainAxis
!))
.
floor
();
if
(
_mainAxisCount
!
<
0
)
{
// Not enough space to put one line, try to ask for more space.
...
...
@@ -122,8 +131,12 @@ class GridView extends MultiChildWidget with SpanningWidget {
}
}
final
totalMain
=
(
_context
.
childMainAxis
!
+
mainAxisSpacing
)
*
_mainAxisCount
!
-
mainAxisSpacing
;
final
totalCross
=
(
_context
.
childCrossAxis
!
+
crossAxisSpacing
)
*
crossAxisCount
-
crossAxisSpacing
;
final
totalMain
=
(
_context
.
childMainAxis
!
+
mainAxisSpacing
)
*
_mainAxisCount
!
-
mainAxisSpacing
;
final
totalCross
=
(
_context
.
childCrossAxis
!
+
crossAxisSpacing
)
*
crossAxisCount
-
crossAxisSpacing
;
final
startX
=
resolvedPadding
.
left
;
const
startY
=
0.0
;
...
...
@@ -132,12 +145,14 @@ class GridView extends MultiChildWidget with SpanningWidget {
BoxConstraints
?
innerConstraints
;
switch
(
direction
)
{
case
Axis
.
vertical
:
innerConstraints
=
BoxConstraints
.
tightFor
(
width:
_context
.
childCrossAxis
,
height:
_context
.
childMainAxis
);
innerConstraints
=
BoxConstraints
.
tightFor
(
width:
_context
.
childCrossAxis
,
height:
_context
.
childMainAxis
);
crossAxis
=
startX
;
mainAxis
=
startY
;
break
;
case
Axis
.
horizontal
:
innerConstraints
=
BoxConstraints
.
tightFor
(
width:
_context
.
childMainAxis
,
height:
_context
.
childCrossAxis
);
innerConstraints
=
BoxConstraints
.
tightFor
(
width:
_context
.
childMainAxis
,
height:
_context
.
childCrossAxis
);
mainAxis
=
startX
;
crossAxis
=
startY
;
break
;
...
...
@@ -148,7 +163,9 @@ class GridView extends MultiChildWidget with SpanningWidget {
final
isRtl
=
textDirection
==
TextDirection
.
rtl
;
for
(
final
child
in
children
.
sublist
(
_context
.
firstChild
,
math
.
min
(
children
.
length
,
_context
.
firstChild
+
crossAxisCount
*
_mainAxisCount
!)))
{
_context
.
firstChild
,
math
.
min
(
children
.
length
,
_context
.
firstChild
+
crossAxisCount
*
_mainAxisCount
!)))
{
child
.
layout
(
context
,
innerConstraints
);
assert
(
child
.
box
!=
null
);
...
...
@@ -158,7 +175,8 @@ class GridView extends MultiChildWidget with SpanningWidget {
PdfPoint
(
isRtl
?
(
_context
.
childCrossAxis
!
+
child
.
box
!.
width
-
crossAxis
)
:
(
_context
.
childCrossAxis
!
-
child
.
box
!.
width
)
/
2.0
+
crossAxis
,
:
(
_context
.
childCrossAxis
!
-
child
.
box
!.
width
)
/
2.0
+
crossAxis
,
totalMain
+
resolvedPadding
.
bottom
-
(
_context
.
childMainAxis
!
-
child
.
box
!.
height
)
/
2.0
-
...
...
@@ -172,8 +190,9 @@ class GridView extends MultiChildWidget with SpanningWidget {
child
.
box
=
PdfRect
.
fromPoints
(
PdfPoint
(
isRtl
?
totalMain
-
(
child
.
box
!.
width
+
mainAxis
)
:
(
_context
.
childMainAxis
!
-
child
.
box
!.
width
)
/
2.0
+
mainAxis
,
?
totalMain
-
(
child
.
box
!.
width
+
mainAxis
)
:
(
_context
.
childMainAxis
!
-
child
.
box
!.
width
)
/
2.0
+
mainAxis
,
totalCross
+
resolvedPadding
.
bottom
-
(
_context
.
childCrossAxis
!
-
child
.
box
!.
height
)
/
2.0
-
...
...
@@ -208,10 +227,14 @@ class GridView extends MultiChildWidget with SpanningWidget {
switch
(
direction
)
{
case
Axis
.
vertical
:
box
=
constraints
.
constrainRect
(
width:
totalCross
+
padding
.
horizontal
,
height:
totalMain
+
padding
.
vertical
);
box
=
constraints
.
constrainRect
(
width:
totalCross
+
padding
.
horizontal
,
height:
totalMain
+
padding
.
vertical
);
break
;
case
Axis
.
horizontal
:
box
=
constraints
.
constrainRect
(
width:
totalMain
+
padding
.
horizontal
,
height:
totalCross
+
padding
.
vertical
);
box
=
constraints
.
constrainRect
(
width:
totalMain
+
padding
.
horizontal
,
height:
totalCross
+
padding
.
vertical
);
break
;
}
}
...
...
@@ -231,25 +254,37 @@ class GridView extends MultiChildWidget with SpanningWidget {
..
lineTo
(
box
!.
right
,
box
!.
bottom
)
..
lineTo
(
box
!.
right
,
box
!.
top
)
..
lineTo
(
box
!.
left
,
box
!.
top
)
..
moveTo
(
box
!.
left
+
resolvedPadding
.
left
,
box
!.
bottom
+
resolvedPadding
.
bottom
)
..
moveTo
(
box
!.
left
+
resolvedPadding
.
left
,
box
!.
bottom
+
resolvedPadding
.
bottom
)
..
lineTo
(
box
!.
left
+
resolvedPadding
.
left
,
box
!.
top
-
resolvedPadding
.
top
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
top
-
resolvedPadding
.
top
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
bottom
+
resolvedPadding
.
bottom
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
top
-
resolvedPadding
.
top
)
..
lineTo
(
box
!.
right
-
resolvedPadding
.
right
,
box
!.
bottom
+
resolvedPadding
.
bottom
)
..
fillPath
();
for
(
var
c
=
1
;
c
<
crossAxisCount
;
c
++)
{
switch
(
direction
)
{
case
Axis
.
vertical
:
context
.
canvas
..
drawRect
(
box
!.
left
+
resolvedPadding
.
left
+
(
_context
.
childCrossAxis
!
+
crossAxisSpacing
)
*
c
-
crossAxisSpacing
,
box
!.
bottom
+
resolvedPadding
.
bottom
,
math
.
max
(
crossAxisSpacing
,
1
),
box
!.
height
-
resolvedPadding
.
vertical
)
..
drawRect
(
box
!.
left
+
resolvedPadding
.
left
+
(
_context
.
childCrossAxis
!
+
crossAxisSpacing
)
*
c
-
crossAxisSpacing
,
box
!.
bottom
+
resolvedPadding
.
bottom
,
math
.
max
(
crossAxisSpacing
,
1
),
box
!.
height
-
resolvedPadding
.
vertical
)
..
fillPath
();
break
;
case
Axis
.
horizontal
:
context
.
canvas
..
drawRect
(
box
!.
left
+
resolvedPadding
.
left
,
box
!.
bottom
+
resolvedPadding
.
bottom
+
(
_context
.
childCrossAxis
!
+
crossAxisSpacing
)
*
c
-
crossAxisSpacing
,
box
!.
bottom
+
resolvedPadding
.
bottom
+
(
_context
.
childCrossAxis
!
+
crossAxisSpacing
)
*
c
-
crossAxisSpacing
,
box
!.
width
-
resolvedPadding
.
horizontal
,
math
.
max
(
crossAxisSpacing
,
1
))
..
fillPath
();
...
...
@@ -263,15 +298,24 @@ class GridView extends MultiChildWidget with SpanningWidget {
context
.
canvas
..
drawRect
(
box
!.
left
+
resolvedPadding
.
left
,
box
!.
bottom
+
resolvedPadding
.
bottom
+
(
_context
.
childMainAxis
!
+
mainAxisSpacing
)
*
c
-
mainAxisSpacing
,
box
!.
bottom
+
resolvedPadding
.
bottom
+
(
_context
.
childMainAxis
!
+
mainAxisSpacing
)
*
c
-
mainAxisSpacing
,
box
!.
width
-
resolvedPadding
.
horizontal
,
math
.
max
(
mainAxisSpacing
,
1
))
..
fillPath
();
break
;
case
Axis
.
horizontal
:
context
.
canvas
..
drawRect
(
box
!.
left
+
resolvedPadding
.
left
+
(
_context
.
childMainAxis
!
+
mainAxisSpacing
)
*
c
-
mainAxisSpacing
,
box
!.
bottom
+
resolvedPadding
.
bottom
,
math
.
max
(
mainAxisSpacing
,
1
),
box
!.
height
-
resolvedPadding
.
vertical
)
..
drawRect
(
box
!.
left
+
resolvedPadding
.
left
+
(
_context
.
childMainAxis
!
+
mainAxisSpacing
)
*
c
-
mainAxisSpacing
,
box
!.
bottom
+
resolvedPadding
.
bottom
,
math
.
max
(
mainAxisSpacing
,
1
),
box
!.
height
-
resolvedPadding
.
vertical
)
..
fillPath
();
break
;
}
...
...
@@ -288,7 +332,8 @@ class GridView extends MultiChildWidget with SpanningWidget {
..
saveContext
()
..
setTransform
(
mat
);
for
(
var
child
in
children
.
sublist
(
_context
.
firstChild
,
_context
.
lastChild
))
{
for
(
var
child
in
children
.
sublist
(
_context
.
firstChild
,
_context
.
lastChild
))
{
child
.
paint
(
context
);
}
context
.
canvas
.
restoreContext
();
...
...
pdf/lib/src/widgets/multi_page.dart
View file @
9d3ca6a
...
...
@@ -61,12 +61,14 @@ mixin SpanningWidget on Widget {
/// Called before relayout to restore the saved state and
/// restart the layout in the same conditions
@protected
void
applyContext
(
covariant
WidgetContext
context
)
=>
saveContext
().
apply
(
context
);
void
applyContext
(
covariant
WidgetContext
context
)
=>
saveContext
().
apply
(
context
);
}
class
NewPage
extends
Widget
{
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
box
=
PdfRect
.
zero
;
}
}
...
...
@@ -183,7 +185,8 @@ class MultiPage extends Page {
/// This is not checked with a Release build.
final
int
maxPages
;
void
_paintChild
(
Context
context
,
Widget
child
,
double
x
,
double
y
,
double
pageHeight
)
{
void
_paintChild
(
Context
context
,
Widget
child
,
double
x
,
double
y
,
double
pageHeight
)
{
if
(
mustRotate
)
{
final
_margin
=
resolvedMargin
!;
context
.
canvas
...
...
@@ -212,23 +215,30 @@ class MultiPage extends Page {
final
_margin
=
resolvedMargin
!;
final
_mustRotate
=
mustRotate
;
final
pageHeight
=
_mustRotate
?
pageFormat
.
width
:
pageFormat
.
height
;
final
pageHeightMargin
=
_mustRotate
?
_margin
.
horizontal
:
_margin
.
vertical
;
final
pageHeightMargin
=
_mustRotate
?
_margin
.
horizontal
:
_margin
.
vertical
;
final
constraints
=
BoxConstraints
(
maxWidth:
_mustRotate
?
(
pageFormat
.
height
-
_margin
.
vertical
)
:
(
pageFormat
.
width
-
_margin
.
horizontal
));
maxWidth:
_mustRotate
?
(
pageFormat
.
height
-
_margin
.
vertical
)
:
(
pageFormat
.
width
-
_margin
.
horizontal
));
final
fullConstraints
=
mustRotate
?
BoxConstraints
(
maxWidth:
pageFormat
.
height
-
_margin
.
vertical
,
maxHeight:
pageFormat
.
width
-
_margin
.
horizontal
)
maxWidth:
pageFormat
.
height
-
_margin
.
vertical
,
maxHeight:
pageFormat
.
width
-
_margin
.
horizontal
)
:
BoxConstraints
(
maxWidth:
pageFormat
.
width
-
_margin
.
horizontal
,
maxHeight:
pageFormat
.
height
-
_margin
.
vertical
);
maxWidth:
pageFormat
.
width
-
_margin
.
horizontal
,
maxHeight:
pageFormat
.
height
-
_margin
.
vertical
);
final
calculatedTheme
=
theme
??
document
.
theme
??
ThemeData
.
base
();
Context
?
context
;
late
double
offsetEnd
;
double
?
offsetStart
;
var
_index
=
0
;
var
sameCount
=
0
;
final
baseContext
=
Context
(
document:
document
.
document
).
inheritFromAll
(<
Inherited
>[
final
baseContext
=
Context
(
document:
document
.
document
).
inheritFromAll
(<
Inherited
>[
calculatedTheme
,
if
(
pageTheme
.
textDirection
!=
null
)
InheritedDirectionality
(
pageTheme
.
textDirection
),
if
(
pageTheme
.
textDirection
!=
null
)
InheritedDirectionality
(
pageTheme
.
textDirection
),
]);
final
children
=
_buildList
(
baseContext
);
WidgetContext
?
widgetContext
;
...
...
@@ -263,8 +273,10 @@ class MultiPage extends Page {
return
true
;
}());
offsetStart
=
pageHeight
-
(
_mustRotate
?
pageHeightMargin
-
_margin
.
bottom
:
_margin
.
top
);
offsetEnd
=
_mustRotate
?
pageHeightMargin
-
_margin
.
left
:
_margin
.
bottom
;
offsetStart
=
pageHeight
-
(
_mustRotate
?
pageHeightMargin
-
_margin
.
bottom
:
_margin
.
top
);
offsetEnd
=
_mustRotate
?
pageHeightMargin
-
_margin
.
left
:
_margin
.
bottom
;
_pages
.
add
(
_MultiPageInstance
(
context:
context
,
...
...
@@ -316,7 +328,8 @@ class MultiPage extends Page {
// Else we crash if the widget is too big and cannot be separated
if
(!
canSpan
)
{
throw
Exception
(
'Widget won
\'
t fit into the page as its height (
${child.box!.height}
) '
throw
Exception
(
'Widget won
\'
t fit into the page as its height (
${child.box!.height}
) '
'exceed a page height (
${pageHeight - pageHeightMargin}
). '
'You probably need a SpanningWidget or use a single page layout'
);
}
...
...
@@ -328,7 +341,8 @@ class MultiPage extends Page {
span
.
applyContext
(
savedContext
);
}
final
localConstraints
=
constraints
.
copyWith
(
maxHeight:
offsetStart
-
offsetEnd
);
final
localConstraints
=
constraints
.
copyWith
(
maxHeight:
offsetStart
-
offsetEnd
);
span
.
layout
(
context
,
localConstraints
,
parentUsesSize:
false
);
assert
(
span
.
box
!=
null
);
widgetContext
=
span
.
saveContext
();
...
...
@@ -355,7 +369,8 @@ class MultiPage extends Page {
_MultiPageWidget
(
child:
child
,
constraints:
constraints
,
widgetContext:
child
is
SpanningWidget
&&
canSpan
?
child
.
cloneContext
()
:
null
,
widgetContext:
child
is
SpanningWidget
&&
canSpan
?
child
.
cloneContext
()
:
null
,
),
);
...
...
@@ -371,21 +386,27 @@ class MultiPage extends Page {
final
_mustRotate
=
mustRotate
;
final
pageHeight
=
_mustRotate
?
pageFormat
.
width
:
pageFormat
.
height
;
final
pageWidth
=
_mustRotate
?
pageFormat
.
height
:
pageFormat
.
width
;
final
pageHeightMargin
=
_mustRotate
?
_margin
.
horizontal
:
_margin
.
vertical
;
final
pageHeightMargin
=
_mustRotate
?
_margin
.
horizontal
:
_margin
.
vertical
;
final
pageWidthMargin
=
_mustRotate
?
_margin
.
vertical
:
_margin
.
horizontal
;
final
availableWidth
=
pageWidth
-
pageWidthMargin
;
final
isRTL
=
pageTheme
.
textDirection
==
TextDirection
.
rtl
;
for
(
final
page
in
_pages
)
{
var
offsetStart
=
pageHeight
-
(
_mustRotate
?
pageHeightMargin
-
_margin
.
bottom
:
_margin
.
top
);
var
offsetEnd
=
_mustRotate
?
pageHeightMargin
-
_margin
.
left
:
_margin
.
bottom
;
var
offsetStart
=
pageHeight
-
(
_mustRotate
?
pageHeightMargin
-
_margin
.
bottom
:
_margin
.
top
);
var
offsetEnd
=
_mustRotate
?
pageHeightMargin
-
_margin
.
left
:
_margin
.
bottom
;
if
(
pageTheme
.
buildBackground
!=
null
)
{
final
child
=
pageTheme
.
buildBackground
!(
page
.
context
);
child
.
layout
(
page
.
context
,
page
.
fullConstraints
,
parentUsesSize:
false
);
assert
(
child
.
box
!=
null
);
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
child
.
box
!.
width
)
:
_margin
.
left
;
_paintChild
(
page
.
context
,
child
,
xPos
,
_margin
.
bottom
,
pageFormat
.
height
);
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
child
.
box
!.
width
)
:
_margin
.
left
;
_paintChild
(
page
.
context
,
child
,
xPos
,
_margin
.
bottom
,
pageFormat
.
height
);
}
var
totalFlex
=
0
;
...
...
@@ -410,20 +431,28 @@ class MultiPage extends Page {
if
(
header
!=
null
)
{
final
headerWidget
=
header
!(
page
.
context
);
headerWidget
.
layout
(
page
.
context
,
page
.
constraints
,
parentUsesSize:
false
);
headerWidget
.
layout
(
page
.
context
,
page
.
constraints
,
parentUsesSize:
false
);
assert
(
headerWidget
.
box
!=
null
);
offsetStart
-=
headerWidget
.
box
!.
height
;
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
headerWidget
.
box
!.
width
)
:
_margin
.
left
;
_paintChild
(
page
.
context
,
headerWidget
,
xPos
,
page
.
offsetStart
!
-
headerWidget
.
box
!.
height
,
pageFormat
.
height
);
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
headerWidget
.
box
!.
width
)
:
_margin
.
left
;
_paintChild
(
page
.
context
,
headerWidget
,
xPos
,
page
.
offsetStart
!
-
headerWidget
.
box
!.
height
,
pageFormat
.
height
);
}
if
(
footer
!=
null
)
{
final
footerWidget
=
footer
!(
page
.
context
);
footerWidget
.
layout
(
page
.
context
,
page
.
constraints
,
parentUsesSize:
false
);
footerWidget
.
layout
(
page
.
context
,
page
.
constraints
,
parentUsesSize:
false
);
assert
(
footerWidget
.
box
!=
null
);
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
footerWidget
.
box
!.
width
)
:
_margin
.
left
;
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
footerWidget
.
box
!.
width
)
:
_margin
.
left
;
offsetEnd
+=
footerWidget
.
box
!.
height
;
_paintChild
(
page
.
context
,
footerWidget
,
xPos
,
_margin
.
bottom
,
pageFormat
.
height
);
_paintChild
(
page
.
context
,
footerWidget
,
xPos
,
_margin
.
bottom
,
pageFormat
.
height
);
}
final
freeSpace
=
math
.
max
(
0.0
,
offsetStart
-
offsetEnd
-
allocatedSize
);
...
...
@@ -452,14 +481,16 @@ class MultiPage extends Page {
break
;
case
MainAxisAlignment
.
spaceBetween
:
leadingSpace
=
0.0
;
betweenSpace
=
totalChildren
>
1
?
freeSpace
/
(
totalChildren
-
1
)
:
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
;
betweenSpace
=
totalChildren
>
0
?
freeSpace
/
(
totalChildren
+
1
)
:
0.0
;
leadingSpace
=
betweenSpace
;
break
;
}
...
...
@@ -471,8 +502,11 @@ class MultiPage extends Page {
final
flex
=
child
is
Flexible
?
child
.
flex
:
0
;
final
fit
=
child
is
Flexible
?
child
.
fit
:
FlexFit
.
loose
;
if
(
flex
>
0
)
{
assert
(
child
is
!
SpanningWidget
||
child
.
canSpan
==
false
,
'Cannot have a spanning widget flexible'
);
final
maxChildExtent
=
child
==
lastFlexChild
?
(
freeSpace
-
allocatedFlexSpace
)
:
spacePerFlex
*
flex
;
assert
(
child
is
!
SpanningWidget
||
child
.
canSpan
==
false
,
'Cannot have a spanning widget flexible'
);
final
maxChildExtent
=
child
==
lastFlexChild
?
(
freeSpace
-
allocatedFlexSpace
)
:
spacePerFlex
*
flex
;
late
double
minChildExtent
;
switch
(
fit
)
{
case
FlexFit
.
tight
:
...
...
@@ -526,7 +560,8 @@ class MultiPage extends Page {
if
(
child
is
SpanningWidget
&&
child
.
canSpan
)
{
child
.
applyContext
(
widget
.
widgetContext
!);
}
_paintChild
(
page
.
context
,
widget
.
child
,
_margin
.
left
+
x
,
pos
,
pageFormat
.
height
);
_paintChild
(
page
.
context
,
widget
.
child
,
_margin
.
left
+
x
,
pos
,
pageFormat
.
height
);
pos
-=
betweenSpace
;
}
...
...
@@ -535,8 +570,11 @@ class MultiPage extends Page {
child
.
layout
(
page
.
context
,
page
.
fullConstraints
,
parentUsesSize:
false
);
assert
(
child
.
box
!=
null
);
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
child
.
box
!.
width
)
:
_margin
.
left
;
_paintChild
(
page
.
context
,
child
,
xPos
,
_margin
.
bottom
,
pageFormat
.
height
);
final
xPos
=
isRTL
?
_margin
.
left
+
(
availableWidth
-
child
.
box
!.
width
)
:
_margin
.
left
;
_paintChild
(
page
.
context
,
child
,
xPos
,
_margin
.
bottom
,
pageFormat
.
height
);
}
}
}
...
...
pdf/lib/src/widgets/page.dart
View file @
9d3ca6a
...
...
@@ -93,7 +93,8 @@ class Page {
..
lineTo
(
0
,
pageFormat
.
height
)
..
moveTo
(
_margin
.
left
,
_margin
.
bottom
)
..
lineTo
(
_margin
.
left
,
pageFormat
.
height
-
_margin
.
top
)
..
lineTo
(
pageFormat
.
width
-
_margin
.
right
,
pageFormat
.
height
-
_margin
.
top
)
..
lineTo
(
pageFormat
.
width
-
_margin
.
right
,
pageFormat
.
height
-
_margin
.
top
)
..
lineTo
(
pageFormat
.
width
-
_margin
.
right
,
_margin
.
bottom
)
..
fillPath
();
}
...
...
@@ -101,7 +102,8 @@ class Page {
void
generate
(
Document
document
,
{
bool
insert
=
true
,
int
?
index
})
{
if
(
index
!=
null
)
{
if
(
insert
)
{
_pdfPage
=
PdfPage
(
document
.
document
,
pageFormat:
pageFormat
,
index:
index
);
_pdfPage
=
PdfPage
(
document
.
document
,
pageFormat:
pageFormat
,
index:
index
);
}
else
{
_pdfPage
=
document
.
document
.
page
(
index
);
}
...
...
@@ -116,9 +118,11 @@ class Page {
final
_margin
=
resolvedMargin
;
var
constraints
=
mustRotate
?
BoxConstraints
(
maxWidth:
pageFormat
.
height
-
_margin
!.
vertical
,
maxHeight:
pageFormat
.
width
-
_margin
.
horizontal
)
maxWidth:
pageFormat
.
height
-
_margin
!.
vertical
,
maxHeight:
pageFormat
.
width
-
_margin
.
horizontal
)
:
BoxConstraints
(
maxWidth:
pageFormat
.
width
-
_margin
!.
horizontal
,
maxHeight:
pageFormat
.
height
-
_margin
.
vertical
);
maxWidth:
pageFormat
.
width
-
_margin
!.
horizontal
,
maxHeight:
pageFormat
.
height
-
_margin
.
vertical
);
final
calculatedTheme
=
theme
??
document
.
theme
??
ThemeData
.
base
();
final
context
=
Context
(
...
...
@@ -127,7 +131,8 @@ class Page {
canvas:
canvas
,
).
inheritFromAll
(<
Inherited
>[
calculatedTheme
,
if
(
pageTheme
.
textDirection
!=
null
)
InheritedDirectionality
(
pageTheme
.
textDirection
),
if
(
pageTheme
.
textDirection
!=
null
)
InheritedDirectionality
(
pageTheme
.
textDirection
),
]);
Widget
?
background
;
...
...
@@ -139,7 +144,8 @@ class Page {
final
size
=
layout
(
content
,
context
,
constraints
);
if
(
_pdfPage
!.
pageFormat
.
height
==
double
.
infinity
)
{
_pdfPage
!.
pageFormat
=
_pdfPage
!.
pageFormat
.
copyWith
(
width:
size
.
x
,
height:
size
.
y
);
_pdfPage
!.
pageFormat
=
_pdfPage
!.
pageFormat
.
copyWith
(
width:
size
.
x
,
height:
size
.
y
);
constraints
=
mustRotate
?
BoxConstraints
(
maxWidth:
_pdfPage
!.
pageFormat
.
height
-
_margin
.
vertical
,
...
...
@@ -178,18 +184,22 @@ class Page {
}
@protected
PdfPoint
layout
(
Widget
child
,
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
PdfPoint
layout
(
Widget
child
,
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
final
_margin
=
resolvedMargin
!;
child
.
layout
(
context
,
constraints
,
parentUsesSize:
parentUsesSize
);
assert
(
child
.
box
!=
null
);
final
width
=
pageFormat
.
width
==
double
.
infinity
?
child
.
box
!.
width
+
_margin
.
left
+
_margin
.
right
:
pageFormat
.
width
;
final
width
=
pageFormat
.
width
==
double
.
infinity
?
child
.
box
!.
width
+
_margin
.
left
+
_margin
.
right
:
pageFormat
.
width
;
final
height
=
pageFormat
.
height
==
double
.
infinity
?
child
.
box
!.
height
+
_margin
.
top
+
_margin
.
bottom
:
pageFormat
.
height
;
final
height
=
pageFormat
.
height
==
double
.
infinity
?
child
.
box
!.
height
+
_margin
.
top
+
_margin
.
bottom
:
pageFormat
.
height
;
child
.
box
=
PdfRect
(
_margin
.
left
,
height
-
child
.
box
!.
height
-
_margin
.
top
,
child
.
box
!.
width
,
child
.
box
!.
height
);
child
.
box
=
PdfRect
(
_margin
.
left
,
height
-
child
.
box
!.
height
-
_margin
.
top
,
child
.
box
!.
width
,
child
.
box
!.
height
);
return
PdfPoint
(
width
,
height
);
}
...
...
@@ -212,7 +222,8 @@ class Page {
if
(
pageTheme
.
textDirection
==
TextDirection
.
rtl
)
{
child
.
box
=
PdfRect
(
((
mustRotate
?
box
.
height
:
box
.
width
)
-
child
.
box
!.
width
)
+
child
.
box
!.
x
,
((
mustRotate
?
box
.
height
:
box
.
width
)
-
child
.
box
!.
width
)
+
child
.
box
!.
x
,
child
.
box
!.
y
,
child
.
box
!.
width
,
child
.
box
!.
height
,
...
...
pdf/lib/src/widgets/page_theme.dart
View file @
9d3ca6a
...
...
@@ -54,8 +54,10 @@ class PageTheme {
final
TextDirection
?
textDirection
;
bool
get
mustRotate
=>
(
orientation
==
PageOrientation
.
landscape
&&
pageFormat
.
height
>
pageFormat
.
width
)
||
(
orientation
==
PageOrientation
.
portrait
&&
pageFormat
.
width
>
pageFormat
.
height
);
(
orientation
==
PageOrientation
.
landscape
&&
pageFormat
.
height
>
pageFormat
.
width
)
||
(
orientation
==
PageOrientation
.
portrait
&&
pageFormat
.
width
>
pageFormat
.
height
);
EdgeInsetsGeometry
?
get
margin
{
if
(
_margin
!=
null
)
{
...
...
@@ -73,11 +75,11 @@ class PageTheme {
}
if
(
mustRotate
)
{
return
EdgeInsets
.
fromLTRB
(
pageFormat
.
marginBottom
,
pageFormat
.
marginLeft
,
pageFormat
.
marginTop
,
pageFormat
.
marginRight
);
return
EdgeInsets
.
fromLTRB
(
pageFormat
.
marginBottom
,
pageFormat
.
marginLeft
,
pageFormat
.
marginTop
,
pageFormat
.
marginRight
);
}
else
{
return
EdgeInsets
.
fromLTRB
(
pageFormat
.
marginLeft
,
pageFormat
.
marginTop
,
pageFormat
.
marginRight
,
pageFormat
.
marginBottom
);
return
EdgeInsets
.
fromLTRB
(
pageFormat
.
marginLeft
,
pageFormat
.
marginTop
,
pageFormat
.
marginRight
,
pageFormat
.
marginBottom
);
}
}
...
...
pdf/lib/src/widgets/stack.dart
View file @
9d3ca6a
...
...
@@ -146,7 +146,8 @@ class PositionedDirectional extends Positioned {
final
double
?
end
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
super
.
layout
(
context
,
constraints
,
parentUsesSize:
parentUsesSize
);
switch
(
Directionality
.
of
(
context
))
{
case
TextDirection
.
rtl
:
...
...
@@ -181,7 +182,8 @@ class Stack extends MultiChildWidget {
final
Overflow
overflow
;
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
final
childCount
=
children
.
length
;
var
hasNonPositionedChildren
=
false
;
...
...
@@ -230,22 +232,27 @@ class Stack extends MultiChildWidget {
final
resolvedAlignment
=
alignment
.
resolve
(
Directionality
.
of
(
context
));
for
(
final
child
in
children
)
{
if
(
child
is
!
Positioned
)
{
child
.
box
=
PdfRect
.
fromPoints
(
resolvedAlignment
.
inscribe
(
child
.
box
!.
size
,
box
!).
offset
,
child
.
box
!.
size
);
child
.
box
=
PdfRect
.
fromPoints
(
resolvedAlignment
.
inscribe
(
child
.
box
!.
size
,
box
!).
offset
,
child
.
box
!.
size
);
}
else
{
final
positioned
=
child
;
var
childConstraints
=
const
BoxConstraints
();
if
(
positioned
.
left
!=
null
&&
positioned
.
right
!=
null
)
{
childConstraints
=
childConstraints
.
tighten
(
width:
box
!.
width
-
positioned
.
right
!
-
positioned
.
left
!);
childConstraints
=
childConstraints
.
tighten
(
width:
box
!.
width
-
positioned
.
right
!
-
positioned
.
left
!);
}
else
if
(
positioned
.
width
!=
null
)
{
childConstraints
=
childConstraints
.
tighten
(
width:
positioned
.
width
);
}
if
(
positioned
.
top
!=
null
&&
positioned
.
bottom
!=
null
)
{
childConstraints
=
childConstraints
.
tighten
(
height:
box
!.
height
-
positioned
.
bottom
!
-
positioned
.
top
!);
childConstraints
=
childConstraints
.
tighten
(
height:
box
!.
height
-
positioned
.
bottom
!
-
positioned
.
top
!);
}
else
if
(
positioned
.
height
!=
null
)
{
childConstraints
=
childConstraints
.
tighten
(
height:
positioned
.
height
);
childConstraints
=
childConstraints
.
tighten
(
height:
positioned
.
height
);
}
positioned
.
layout
(
context
,
childConstraints
,
parentUsesSize:
true
);
...
...
@@ -269,7 +276,8 @@ class Stack extends MultiChildWidget {
y
=
resolvedAlignment
.
inscribe
(
positioned
.
box
!.
size
,
box
!).
y
;
}
positioned
.
box
=
PdfRect
.
fromPoints
(
PdfPoint
(
x
!,
y
!),
positioned
.
box
!.
size
);
positioned
.
box
=
PdfRect
.
fromPoints
(
PdfPoint
(
x
!,
y
!),
positioned
.
box
!.
size
);
}
}
}
...
...
pdf/lib/src/widgets/table_helper.dart
View file @
9d3ca6a
...
...
@@ -120,7 +120,8 @@ mixin TableHelper {
rowNum
++;
}
final
textDirection
=
context
==
null
?
TextDirection
.
ltr
:
Directionality
.
of
(
context
);
final
textDirection
=
context
==
null
?
TextDirection
.
ltr
:
Directionality
.
of
(
context
);
for
(
final
row
in
data
)
{
final
tableRow
=
<
Widget
>[];
final
isOdd
=
(
rowNum
-
headerCount
)
%
2
!=
0
;
...
...
pdf/lib/src/widgets/text.dart
View file @
9d3ca6a
...
...
@@ -83,7 +83,8 @@ abstract class _Span {
}
class
_TextDecoration
{
_TextDecoration
(
this
.
style
,
this
.
annotation
,
this
.
startSpan
,
this
.
endSpan
)
:
assert
(
startSpan
<=
endSpan
);
_TextDecoration
(
this
.
style
,
this
.
annotation
,
this
.
startSpan
,
this
.
endSpan
)
:
assert
(
startSpan
<=
endSpan
);
static
const
double
_space
=
-
0.15
;
...
...
@@ -103,7 +104,8 @@ class _TextDecoration {
}
final
x1
=
spans
[
startSpan
].
offset
.
x
+
spans
[
startSpan
].
left
;
final
x2
=
spans
[
endSpan
].
offset
.
x
+
spans
[
endSpan
].
left
+
spans
[
endSpan
].
width
;
final
x2
=
spans
[
endSpan
].
offset
.
x
+
spans
[
endSpan
].
left
+
spans
[
endSpan
].
width
;
var
y1
=
spans
[
startSpan
].
offset
.
y
+
spans
[
startSpan
].
top
;
var
y2
=
y1
+
spans
[
startSpan
].
height
;
...
...
@@ -118,7 +120,8 @@ class _TextDecoration {
return
_box
;
}
_TextDecoration
copyWith
({
int
?
endSpan
})
=>
_TextDecoration
(
style
,
annotation
,
startSpan
,
endSpan
??
this
.
endSpan
);
_TextDecoration
copyWith
({
int
?
endSpan
})
=>
_TextDecoration
(
style
,
annotation
,
startSpan
,
endSpan
??
this
.
endSpan
);
void
backgroundPaint
(
Context
context
,
...
...
@@ -163,11 +166,15 @@ class _TextDecoration {
final
box
=
_getBox
(
spans
);
final
font
=
style
.
font
!.
getFont
(
context
);
final
space
=
_space
*
style
.
fontSize
!
*
textScaleFactor
*
style
.
decorationThickness
!;
final
space
=
_space
*
style
.
fontSize
!
*
textScaleFactor
*
style
.
decorationThickness
!;
context
.
canvas
..
setStrokeColor
(
style
.
decorationColor
??
style
.
color
)
..
setLineWidth
(
style
.
decorationThickness
!
*
style
.
fontSize
!
*
textScaleFactor
*
0.05
);
..
setLineWidth
(
style
.
decorationThickness
!
*
style
.
fontSize
!
*
textScaleFactor
*
0.05
);
if
(
style
.
decoration
!.
contains
(
TextDecoration
.
underline
))
{
final
base
=
-
font
.
descent
*
style
.
fontSize
!
*
textScaleFactor
/
2
;
...
...
@@ -240,7 +247,8 @@ class _TextDecoration {
context
.
canvas
..
setLineWidth
(.
5
)
..
drawRect
(
globalBox
.
x
+
box
.
x
,
globalBox
.
top
+
box
.
y
,
box
.
width
,
box
.
height
)
..
drawRect
(
globalBox
.
x
+
box
.
x
,
globalBox
.
top
+
box
.
y
,
box
.
width
,
box
.
height
)
..
setStrokeColor
(
PdfColors
.
yellow
)
..
strokePath
();
}
...
...
@@ -302,11 +310,14 @@ class _Word extends _Span {
context
.
canvas
..
setLineWidth
(.
5
)
..
drawRect
(
globalBox
!.
x
+
offset
.
x
+
metrics
.
left
,
globalBox
.
top
+
offset
.
y
+
metrics
.
top
,
metrics
.
width
,
metrics
.
height
)
..
drawRect
(
globalBox
!.
x
+
offset
.
x
+
metrics
.
left
,
globalBox
.
top
+
offset
.
y
+
metrics
.
top
,
metrics
.
width
,
metrics
.
height
)
..
setStrokeColor
(
PdfColors
.
orange
)
..
strokePath
()
..
drawLine
(
globalBox
.
x
+
offset
.
x
-
deb
,
globalBox
.
top
+
offset
.
y
,
globalBox
.
x
+
offset
.
x
+
metrics
.
right
+
deb
,
..
drawLine
(
globalBox
.
x
+
offset
.
x
-
deb
,
globalBox
.
top
+
offset
.
y
,
globalBox
.
x
+
offset
.
x
+
metrics
.
right
+
deb
,
globalBox
.
top
+
offset
.
y
)
..
setStrokeColor
(
PdfColors
.
deepPurple
)
..
strokePath
();
...
...
@@ -352,8 +363,10 @@ class _WidgetSpan extends _Span {
double
textScaleFactor
,
PdfPoint
point
,
)
{
widget
.
box
=
PdfRect
.
fromPoints
(
PdfPoint
(
point
.
x
+
widget
.
box
!.
offset
.
x
,
point
.
y
+
widget
.
box
!.
offset
.
y
),
widget
.
box
!.
size
);
widget
.
box
=
PdfRect
.
fromPoints
(
PdfPoint
(
point
.
x
+
widget
.
box
!.
offset
.
x
,
point
.
y
+
widget
.
box
!.
offset
.
y
),
widget
.
box
!.
size
);
widget
.
paint
(
context
);
}
...
...
@@ -367,7 +380,8 @@ class _WidgetSpan extends _Span {
context
.
canvas
..
setLineWidth
(.
5
)
..
drawRect
(
globalBox
!.
x
+
offset
.
x
,
globalBox
.
top
+
offset
.
y
,
width
,
height
)
..
drawRect
(
globalBox
!.
x
+
offset
.
x
,
globalBox
.
top
+
offset
.
y
,
width
,
height
)
..
setStrokeColor
(
PdfColors
.
orange
)
..
strokePath
()
..
drawLine
(
...
...
@@ -550,11 +564,14 @@ class _Line {
double
get
height
{
final
list
=
parent
.
_spans
.
sublist
(
firstSpan
,
lastSpan
);
return
list
.
isEmpty
?
0
:
list
.
reduce
((
a
,
b
)
=>
a
.
height
>
b
.
height
?
a
:
b
).
height
;
return
list
.
isEmpty
?
0
:
list
.
reduce
((
a
,
b
)
=>
a
.
height
>
b
.
height
?
a
:
b
).
height
;
}
@override
String
toString
()
=>
'
$runtimeType
$firstSpan
-
$lastSpan
baseline:
$baseline
width:
$wordsWidth
'
;
String
toString
()
=>
'
$runtimeType
$firstSpan
-
$lastSpan
baseline:
$baseline
width:
$wordsWidth
'
;
void
realign
(
double
totalWidth
)
{
final
spans
=
parent
.
_spans
.
sublist
(
firstSpan
,
lastSpan
);
...
...
@@ -566,7 +583,7 @@ class _Line {
delta
=
isRTL
?
wordsWidth
:
0
;
break
;
case
TextAlign
.
right
:
delta
=
isRTL
?
totalWidth:
totalWidth
-
wordsWidth
;
delta
=
isRTL
?
totalWidth
:
totalWidth
-
wordsWidth
;
break
;
case
TextAlign
.
start
:
delta
=
isRTL
?
totalWidth
:
0
;
...
...
@@ -576,7 +593,7 @@ class _Line {
break
;
case
TextAlign
.
center
:
delta
=
(
totalWidth
-
wordsWidth
)
/
2.0
;
if
(
isRTL
)
{
if
(
isRTL
)
{
delta
+=
wordsWidth
;
}
break
;
...
...
@@ -590,7 +607,9 @@ class _Line {
var
x
=
0.0
;
for
(
final
span
in
spans
)
{
span
.
offset
=
PdfPoint
(
isRTL
?
delta
-
x
-
(
span
.
offset
.
x
+
span
.
width
)
:
span
.
offset
.
x
+
x
,
isRTL
?
delta
-
x
-
(
span
.
offset
.
x
+
span
.
width
)
:
span
.
offset
.
x
+
x
,
span
.
offset
.
y
-
baseline
,
);
x
+=
gap
;
...
...
@@ -635,7 +654,8 @@ class RichTextContext extends WidgetContext {
}
@override
String
toString
()
=>
'
$runtimeType
Offset:
$startOffset
->
$endOffset
Span:
$spanStart
->
$spanEnd
'
;
String
toString
()
=>
'
$runtimeType
Offset:
$startOffset
->
$endOffset
Span:
$spanStart
->
$spanEnd
'
;
}
class
RichText
extends
Widget
with
SpanningWidget
{
...
...
@@ -684,7 +704,8 @@ class RichText extends Widget with SpanningWidget {
if
(
append
&&
_decorations
.
isNotEmpty
)
{
final
last
=
_decorations
.
last
;
if
(
last
.
style
==
td
.
style
&&
last
.
annotation
==
td
.
annotation
)
{
_decorations
[
_decorations
.
length
-
1
]
=
last
.
copyWith
(
endSpan:
td
.
endSpan
);
_decorations
[
_decorations
.
length
-
1
]
=
last
.
copyWith
(
endSpan:
td
.
endSpan
);
return
;
}
}
...
...
@@ -854,7 +875,8 @@ class RichText extends Widget with SpanningWidget {
}
@override
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
void
layout
(
Context
context
,
BoxConstraints
constraints
,
{
bool
parentUsesSize
=
false
})
{
_spans
.
clear
();
_decorations
.
clear
();
...
...
@@ -866,8 +888,12 @@ class RichText extends Widget with SpanningWidget {
final
_overflow
=
this
.
overflow
??
theme
.
overflow
;
final
constraintWidth
=
constraints
.
hasBoundedWidth
?
constraints
.
maxWidth
:
constraints
.
constrainWidth
();
final
constraintHeight
=
constraints
.
hasBoundedHeight
?
constraints
.
maxHeight
:
constraints
.
constrainHeight
();
final
constraintWidth
=
constraints
.
hasBoundedWidth
?
constraints
.
maxWidth
:
constraints
.
constrainWidth
();
final
constraintHeight
=
constraints
.
hasBoundedHeight
?
constraints
.
maxHeight
:
constraints
.
constrainHeight
();
var
offsetX
=
0.0
;
var
offsetY
=
_context
.
startOffset
;
...
...
@@ -894,10 +920,13 @@ class RichText extends Widget with SpanningWidget {
final
font
=
style
!.
font
!.
getFont
(
context
);
final
space
=
font
.
stringMetrics
(
' '
)
*
(
style
.
fontSize
!
*
textScaleFactor
);
final
space
=
font
.
stringMetrics
(
' '
)
*
(
style
.
fontSize
!
*
textScaleFactor
);
final
spanLines
=
(
_textDirection
==
TextDirection
.
rtl
?
bidi
.
logicalToVisual
(
span
.
text
!)
:
span
.
text
)!.
split
(
'
\n
'
);
final
spanLines
=
(
_textDirection
==
TextDirection
.
rtl
?
bidi
.
logicalToVisual
(
span
.
text
!)
:
span
.
text
)!
.
split
(
'
\n
'
);
for
(
var
line
=
0
;
line
<
spanLines
.
length
;
line
++)
{
final
words
=
spanLines
[
line
].
split
(
RegExp
(
r'\s'
));
...
...
@@ -905,15 +934,18 @@ class RichText extends Widget with SpanningWidget {
final
word
=
words
[
index
];
if
(
word
.
isEmpty
)
{
offsetX
+=
space
.
advanceWidth
*
style
.
wordSpacing
!
+
style
.
letterSpacing
!;
offsetX
+=
space
.
advanceWidth
*
style
.
wordSpacing
!
+
style
.
letterSpacing
!;
continue
;
}
final
metrics
=
font
.
stringMetrics
(
word
,
letterSpacing:
style
.
letterSpacing
!
/
(
style
.
fontSize
!
*
textScaleFactor
))
*
(
style
.
fontSize
!
*
textScaleFactor
);
final
metrics
=
font
.
stringMetrics
(
word
,
letterSpacing:
style
.
letterSpacing
!
/
(
style
.
fontSize
!
*
textScaleFactor
))
*
(
style
.
fontSize
!
*
textScaleFactor
);
if
(
_softWrap
&&
offsetX
+
metrics
.
width
>
constraintWidth
+
0.00001
)
{
if
(
_softWrap
&&
offsetX
+
metrics
.
width
>
constraintWidth
+
0.00001
)
{
if
(
spanCount
>
0
&&
metrics
.
width
<=
constraintWidth
)
{
overflow
=
true
;
lines
.
add
(
_Line
(
...
...
@@ -921,7 +953,9 @@ class RichText extends Widget with SpanningWidget {
spanStart
,
spanCount
,
bottom
,
offsetX
-
space
.
advanceWidth
*
style
.
wordSpacing
!
-
style
.
letterSpacing
!,
offsetX
-
space
.
advanceWidth
*
style
.
wordSpacing
!
-
style
.
letterSpacing
!,
_textDirection
,
true
,
));
...
...
@@ -983,7 +1017,9 @@ class RichText extends Widget with SpanningWidget {
),
);
offsetX
+=
metrics
.
advanceWidth
+
space
.
advanceWidth
*
style
.
wordSpacing
!
+
style
.
letterSpacing
!;
offsetX
+=
metrics
.
advanceWidth
+
space
.
advanceWidth
*
style
.
wordSpacing
!
+
style
.
letterSpacing
!;
}
if
(
line
<
spanLines
.
length
-
1
)
{
...
...
@@ -992,7 +1028,9 @@ class RichText extends Widget with SpanningWidget {
spanStart
,
spanCount
,
bottom
,
offsetX
-
space
.
advanceWidth
*
style
.
wordSpacing
!
-
style
.
letterSpacing
!,
offsetX
-
space
.
advanceWidth
*
style
.
wordSpacing
!
-
style
.
letterSpacing
!,
_textDirection
,
false
,
));
...
...
@@ -1021,7 +1059,8 @@ class RichText extends Widget with SpanningWidget {
}
}
offsetX
-=
space
.
advanceWidth
*
style
.
wordSpacing
!
-
style
.
letterSpacing
!;
offsetX
-=
space
.
advanceWidth
*
style
.
wordSpacing
!
-
style
.
letterSpacing
!;
}
else
if
(
span
is
WidgetSpan
)
{
span
.
child
.
layout
(
context
,
...
...
@@ -1124,7 +1163,8 @@ class RichText extends Widget with SpanningWidget {
}
}
box
=
PdfRect
(
0
,
0
,
constraints
.
constrainWidth
(
width
),
constraints
.
constrainHeight
(
offsetY
));
box
=
PdfRect
(
0
,
0
,
constraints
.
constrainWidth
(
width
),
constraints
.
constrainHeight
(
offsetY
));
_context
..
endOffset
=
offsetY
-
_context
.
startOffset
...
...
@@ -1144,7 +1184,8 @@ class RichText extends Widget with SpanningWidget {
for
(
var
index
=
0
;
index
<
_decorations
.
length
;
index
++)
{
final
decoration
=
_decorations
[
index
];
if
(
decoration
.
startSpan
>=
_context
.
spanEnd
||
decoration
.
endSpan
<
_context
.
spanStart
)
{
if
(
decoration
.
startSpan
>=
_context
.
spanEnd
||
decoration
.
endSpan
<
_context
.
spanStart
)
{
_decorations
.
removeAt
(
index
);
index
--;
}
...
...
@@ -1239,7 +1280,8 @@ class RichText extends Widget with SpanningWidget {
while
(
low
+
1
<
high
)
{
final
metrics
=
font
.
stringMetrics
(
word
.
substring
(
0
,
pos
),
letterSpacing:
style
.
letterSpacing
!
/
(
style
.
fontSize
!
*
textScaleFactor
))
*
letterSpacing:
style
.
letterSpacing
!
/
(
style
.
fontSize
!
*
textScaleFactor
))
*
(
style
.
fontSize
!
*
textScaleFactor
);
if
(
metrics
.
width
>
maxWidth
)
{
...
...
pdf/test/rtl_layout_test.dart
View file @
9d3ca6a
...
...
@@ -46,8 +46,6 @@ void main() {
pdf
=
Document
();
});
test
(
'RTL Text'
,
()
{
pdf
.
addPage
(
Page
(
...
...
@@ -134,7 +132,9 @@ void main() {
);
});
test
(
'Should render a blue box followed by a red box ordered RTL aligned right'
,
()
{
test
(
'Should render a blue box followed by a red box ordered RTL aligned right'
,
()
{
pdf
.
addPage
(
Page
(
textDirection:
TextDirection
.
rtl
,
...
...
@@ -149,7 +149,9 @@ void main() {
);
});
test
(
'Should render a blue box followed by a red box ordered RTL with aligned center'
,
()
{
test
(
'Should render a blue box followed by a red box ordered RTL with aligned center'
,
()
{
pdf
.
addPage
(
Page
(
textDirection:
TextDirection
.
rtl
,
...
...
@@ -165,7 +167,9 @@ void main() {
);
});
test
(
'Should render a blue box followed by a red box ordered RTL with CrossAxisAlignment.end aligned right'
,
()
{
test
(
'Should render a blue box followed by a red box ordered RTL with CrossAxisAlignment.end aligned right'
,
()
{
pdf
.
addPage
(
Page
(
pageFormat:
const
PdfPageFormat
(
150
,
100
),
...
...
@@ -184,7 +188,9 @@ void main() {
),
);
});
test
(
'Should render a blue box followed by a red box ordered LTR aligned left'
,
()
{
test
(
'Should render a blue box followed by a red box ordered LTR aligned left'
,
()
{
pdf
.
addPage
(
Page
(
pageFormat:
const
PdfPageFormat
(
150
,
50
),
...
...
@@ -197,7 +203,9 @@ void main() {
),
);
});
test
(
'Should render a blue box followed by a red box ordered TTB aligned right'
,
()
{
test
(
'Should render a blue box followed by a red box ordered TTB aligned right'
,
()
{
pdf
.
addPage
(
Page
(
textDirection:
TextDirection
.
rtl
,
...
...
@@ -216,7 +224,9 @@ void main() {
),
);
});
test
(
'Should render a blue box followed by a red box ordered TTB aligned left'
,
()
{
test
(
'Should render a blue box followed by a red box ordered TTB aligned left'
,
()
{
pdf
.
addPage
(
Page
(
textDirection:
TextDirection
.
ltr
,
...
...
@@ -569,7 +579,11 @@ void main() {
children:
[
for
(
int
i
=
0
;
i
<
7
;
i
++)
Container
(
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
),
],
),
...
...
@@ -594,7 +608,11 @@ void main() {
children:
[
for
(
int
i
=
0
;
i
<
7
;
i
++)
Container
(
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
),
],
),
...
...
@@ -618,7 +636,11 @@ void main() {
children:
[
for
(
int
i
=
0
;
i
<
7
;
i
++)
Container
(
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
),
],
),
...
...
@@ -643,7 +665,11 @@ void main() {
children:
[
for
(
int
i
=
0
;
i
<
7
;
i
++)
Container
(
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
color:
[
PdfColors
.
blue
,
PdfColors
.
red
,
PdfColors
.
yellow
][
i
%
3
],
),
],
),
...
...
test/golden/rtl-layout.pdf
0 → 100644
View file @
9d3ca6a
No preview for this file type
test/golden/widgets-text.pdf
View file @
9d3ca6a
No preview for this file type
Please
register
or
login
to post a comment