Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
dart_pdf
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
David PHAM-VAN
2021-04-16 16:52:18 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
b4879e61f06c83351ad31690d6283ae75114997b
b4879e61
1 parent
42af351b
Implement SpanningWidget on RichText
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
153 additions
and
29 deletions
pdf/CHANGELOG.md
pdf/lib/src/widgets/text.dart
pdf/test/widget_text_test.dart
test/golden/widgets-text.pdf
pdf/CHANGELOG.md
View file @
b4879e6
...
...
@@ -9,6 +9,7 @@
-
Use covariant on SpanningWidget
-
ImageProvider.resolve returns non-null object
-
Fix textScalingFactor with lineSpacing
-
Implement SpanningWidget on RichText
## 3.2.0
...
...
pdf/lib/src/widgets/text.dart
View file @
b4879e6
...
...
@@ -22,6 +22,7 @@ import 'package:pdf/pdf.dart';
import
'annotations.dart'
;
import
'document.dart'
;
import
'geometry.dart'
;
import
'multi_page.dart'
;
import
'text_style.dart'
;
import
'theme.dart'
;
import
'widget.dart'
;
...
...
@@ -30,6 +31,15 @@ enum TextAlign { left, right, center, justify }
enum
TextDirection
{
ltr
,
rtl
}
/// How overflowing text should be handled.
enum
TextOverflow
{
/// Span to the next page when possible.
span
,
/// Render overflowing text outside of its container.
visible
,
}
abstract
class
_Span
{
_Span
(
this
.
style
);
...
...
@@ -81,6 +91,7 @@ class _TextDecoration {
if
(
_box
!=
null
)
{
return
_box
;
}
final
x1
=
spans
[
startSpan
].
offset
.
x
+
spans
[
startSpan
].
left
;
final
x2
=
spans
[
endSpan
].
offset
.
x
+
spans
[
endSpan
].
left
+
spans
[
endSpan
].
width
;
...
...
@@ -475,6 +486,7 @@ class _Line {
final
int
firstSpan
;
final
int
countSpan
;
int
get
lastSpan
=>
firstSpan
+
countSpan
;
TextAlign
get
textAlign
=>
parent
.
_textAlign
;
...
...
@@ -484,12 +496,17 @@ class _Line {
final
TextDirection
textDirection
;
double
get
height
=>
parent
.
_spans
.
sublist
(
firstSpan
,
lastSpan
)
.
reduce
((
a
,
b
)
=>
a
.
height
>
b
.
height
?
a
:
b
)
.
height
;
@override
String
toString
()
=>
'
$runtimeType
$firstSpan
-
$
{firstSpan + countSpan}
baseline:
$baseline
width:
$wordsWidth
'
;
'
$runtimeType
$firstSpan
-
$
lastSpan
baseline:
$baseline
width:
$wordsWidth
'
;
void
realign
(
double
totalWidth
,
bool
isLast
)
{
final
spans
=
parent
.
_spans
.
sublist
(
firstSpan
,
firstSpan
+
coun
tSpan
);
final
spans
=
parent
.
_spans
.
sublist
(
firstSpan
,
las
tSpan
);
var
delta
=
0.0
;
switch
(
textAlign
)
{
...
...
@@ -534,7 +551,31 @@ class _Line {
}
}
class
RichText
extends
Widget
{
class
_RichTextContext
extends
WidgetContext
{
var
startOffset
=
0.0
;
var
endOffset
=
0.0
;
var
spanStart
=
0
;
var
spanEnd
=
0
;
@override
void
apply
(
_RichTextContext
other
)
{
startOffset
=
other
.
startOffset
;
endOffset
=
other
.
endOffset
;
spanStart
=
other
.
spanStart
;
spanEnd
=
other
.
spanEnd
;
}
@override
WidgetContext
clone
()
{
return
_RichTextContext
()..
apply
(
this
);
}
@override
String
toString
()
=>
'
$runtimeType
Offset:
$startOffset
->
$endOffset
Span:
$spanStart
->
$spanEnd
'
;
}
class
RichText
extends
Widget
implements
SpanningWidget
{
RichText
({
required
this
.
text
,
this
.
textAlign
,
...
...
@@ -543,6 +584,7 @@ class RichText extends Widget {
this
.
tightBounds
=
false
,
this
.
textScaleFactor
=
1.0
,
this
.
maxLines
,
this
.
overflow
=
TextOverflow
.
visible
,
});
static
bool
debug
=
false
;
...
...
@@ -567,6 +609,10 @@ class RichText extends Widget {
final
List
<
_TextDecoration
>
_decorations
=
<
_TextDecoration
>[];
final
_context
=
_RichTextContext
();
final
TextOverflow
overflow
;
void
_appendDecoration
(
bool
append
,
_TextDecoration
td
)
{
if
(
append
&&
_decorations
.
isNotEmpty
)
{
final
last
=
_decorations
.
last
;
...
...
@@ -601,7 +647,7 @@ class RichText extends Widget {
:
constraints
.
constrainHeight
();
var
offsetX
=
0.0
;
var
offsetY
=
0.0
;
var
offsetY
=
_context
.
startOffset
;
var
top
=
0.0
;
var
bottom
=
0.0
;
...
...
@@ -664,19 +710,20 @@ class RichText extends Widget {
spanStart
+=
spanCount
;
spanCount
=
0
;
if
(
_maxLines
!=
null
&&
lines
.
length
>=
_maxLines
)
{
return
false
;
}
offsetX
=
0.0
;
offsetY
+=
bottom
-
top
+
style
.
lineSpacing
!
*
textScaleFactor
;
offsetY
+=
bottom
-
top
;
top
=
0
;
bottom
=
0
;
if
(
_maxLines
!=
null
&&
lines
.
length
>=
_maxLines
)
{
return
false
;
}
if
(
offsetY
>
constraintHeight
)
{
return
false
;
}
offsetY
+=
style
.
lineSpacing
!
*
textScaleFactor
;
}
else
{
// One word Overflow, try to split it.
final
pos
=
_splitWord
(
word
,
font
,
style
,
constraintWidth
);
...
...
@@ -733,26 +780,25 @@ class RichText extends Widget {
spanStart
+=
spanCount
;
if
(
_maxLines
!=
null
&&
lines
.
length
>=
_maxLines
)
{
spanCount
=
0
;
return
false
;
}
offsetX
=
0.0
;
if
(
spanCount
>
0
)
{
offsetY
+=
bottom
-
top
+
style
.
lineSpacing
!
*
textScaleFactor
;
offsetY
+=
bottom
-
top
;
}
else
{
offsetY
+=
space
.
ascent
+
space
.
descent
+
style
.
lineSpacing
!
*
textScaleFactor
;
offsetY
+=
space
.
ascent
+
space
.
descent
;
}
top
=
0
;
bottom
=
0
;
spanCount
=
0
;
if
(
_maxLines
!=
null
&&
lines
.
length
>=
_maxLines
)
{
return
false
;
}
if
(
offsetY
>
constraintHeight
)
{
return
false
;
}
offsetY
+=
style
.
lineSpacing
!
*
textScaleFactor
;
}
}
...
...
@@ -789,13 +835,15 @@ class RichText extends Widget {
}
offsetX
=
0.0
;
offsetY
+=
bottom
-
top
+
style
.
lineSpacing
!
*
textScaleFactor
;
offsetY
+=
bottom
-
top
;
top
=
0
;
bottom
=
0
;
if
(
offsetY
>
constraintHeight
)
{
return
false
;
}
offsetY
+=
style
.
lineSpacing
!
*
textScaleFactor
;
}
final
baseline
=
span
.
baseline
!
*
textScaleFactor
;
...
...
@@ -834,6 +882,7 @@ class RichText extends Widget {
offsetX
,
_textDirection
,
));
offsetY
+=
bottom
-
top
;
}
assert
(!
overflow
||
constraintWidth
.
isFinite
);
...
...
@@ -855,7 +904,29 @@ class RichText extends Widget {
}
box
=
PdfRect
(
0
,
0
,
constraints
.
constrainWidth
(
width
),
constraints
.
constrainHeight
(
offsetY
+
bottom
-
top
));
constraints
.
constrainHeight
(
offsetY
));
_context
..
endOffset
=
offsetY
-
_context
.
startOffset
..
spanEnd
=
_spans
.
length
;
if
(
this
.
overflow
!=
TextOverflow
.
span
)
{
return
;
}
if
(
offsetY
>
constraintHeight
+
0.0001
)
{
_context
.
spanEnd
-=
lines
.
last
.
countSpan
;
_context
.
endOffset
-=
lines
.
last
.
height
;
}
for
(
var
index
=
0
;
index
<
_decorations
.
length
;
index
++)
{
final
decoration
=
_decorations
[
index
];
if
(
decoration
.
startSpan
>=
_context
.
spanEnd
||
decoration
.
endSpan
<
_context
.
spanStart
)
{
_decorations
.
removeAt
(
index
);
index
--;
}
}
}
@override
...
...
@@ -894,7 +965,7 @@ class RichText extends Widget {
);
}
for
(
var
span
in
_spans
)
{
for
(
var
span
in
_spans
.
sublist
(
_context
.
spanStart
,
_context
.
spanEnd
)
)
{
assert
(()
{
if
(
Document
.
debug
&&
RichText
.
debug
)
{
span
.
debugPaint
(
context
,
textScaleFactor
,
box
);
...
...
@@ -950,6 +1021,23 @@ class RichText extends Widget {
return
pos
;
}
@override
bool
get
canSpan
=>
overflow
==
TextOverflow
.
span
;
@override
bool
get
hasMoreWidgets
=>
overflow
==
TextOverflow
.
span
;
@override
void
restoreContext
(
_RichTextContext
context
)
{
_context
.
spanStart
=
context
.
spanEnd
;
_context
.
startOffset
=
-
context
.
endOffset
;
}
@override
WidgetContext
saveContext
()
{
return
_context
;
}
}
class
Text
extends
RichText
{
...
...
@@ -962,12 +1050,15 @@ class Text extends RichText {
bool
tightBounds
=
false
,
double
textScaleFactor
=
1.0
,
int
?
maxLines
,
TextOverflow
overflow
=
TextOverflow
.
visible
,
})
:
super
(
text:
TextSpan
(
text:
text
,
style:
style
),
textAlign:
textAlign
,
softWrap:
softWrap
,
tightBounds:
tightBounds
,
textDirection:
textDirection
,
textScaleFactor:
textScaleFactor
,
maxLines:
maxLines
);
text:
TextSpan
(
text:
text
,
style:
style
),
textAlign:
textAlign
,
softWrap:
softWrap
,
tightBounds:
tightBounds
,
textDirection:
textDirection
,
textScaleFactor:
textScaleFactor
,
maxLines:
maxLines
,
overflow:
overflow
,
);
}
...
...
pdf/test/widget_text_test.dart
View file @
b4879e6
...
...
@@ -290,6 +290,38 @@ void main() {
);
});
test
(
'Text Widgets RichText overflow.span'
,
()
{
final
rnd
=
math
.
Random
(
42
);
final
para
=
LoremText
(
random:
rnd
).
paragraph
(
100
);
pdf
.
addPage
(
MultiPage
(
pageFormat:
const
PdfPageFormat
(
600
,
200
,
marginAll:
10
),
build:
(
Context
context
)
=>
[
SizedBox
(
height:
90
,
width:
20
),
RichText
(
overflow:
TextOverflow
.
span
,
textAlign:
TextAlign
.
justify
,
text:
TextSpan
(
text:
para
,
children:
[
const
TextSpan
(
text:
' '
),
const
TextSpan
(
text:
'Underline'
,
style:
TextStyle
(
decoration:
TextDecoration
.
underline
),
),
const
TextSpan
(
text:
'. '
),
TextSpan
(
text:
para
),
TextSpan
(
text:
para
),
TextSpan
(
text:
para
),
],
),
),
],
),
);
});
tearDownAll
(()
async
{
final
file
=
File
(
'widgets-text.pdf'
);
await
file
.
writeAsBytes
(
await
pdf
.
save
());
...
...
test/golden/widgets-text.pdf
View file @
b4879e6
No preview for this file type
Please
register
or
login
to post a comment