David PHAM-VAN

Fix Text height with TrueType fonts

@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 - Add PageTheme.copyWith 10 - Add PageTheme.copyWith
11 - Add more font drawing options 11 - Add more font drawing options
12 - Add Opacity Widget 12 - Add Opacity Widget
  13 +- Fix Text height with TrueType fonts
13 14
14 ## 1.4.1 15 ## 1.4.1
15 16
@@ -191,8 +191,11 @@ class Table extends Widget implements SpanningWidget { @@ -191,8 +191,11 @@ class Table extends Widget implements SpanningWidget {
191 assert(defaultColumnWidth != null), 191 assert(defaultColumnWidth != null),
192 super(); 192 super();
193 193
194 - factory Table.fromTextArray(  
195 - {@required Context context, @required List<List<String>> data}) { 194 + factory Table.fromTextArray({
  195 + @required Context context,
  196 + @required List<List<String>> data,
  197 + EdgeInsets margin = const EdgeInsets.all(5),
  198 + }) {
196 final List<TableRow> rows = <TableRow>[]; 199 final List<TableRow> rows = <TableRow>[];
197 for (List<String> row in data) { 200 for (List<String> row in data) {
198 final List<Widget> tableRow = <Widget>[]; 201 final List<Widget> tableRow = <Widget>[];
@@ -200,13 +203,13 @@ class Table extends Widget implements SpanningWidget { @@ -200,13 +203,13 @@ class Table extends Widget implements SpanningWidget {
200 for (String cell in row) { 203 for (String cell in row) {
201 tableRow.add(Container( 204 tableRow.add(Container(
202 alignment: Alignment.center, 205 alignment: Alignment.center,
203 - margin: const EdgeInsets.all(5), 206 + margin: margin,
204 child: Text(cell, style: Theme.of(context).tableHeader))); 207 child: Text(cell, style: Theme.of(context).tableHeader)));
205 } 208 }
206 } else { 209 } else {
207 for (String cell in row) { 210 for (String cell in row) {
208 tableRow.add(Container( 211 tableRow.add(Container(
209 - margin: const EdgeInsets.all(5), 212 + margin: margin,
210 child: Text(cell, style: Theme.of(context).tableCell))); 213 child: Text(cell, style: Theme.of(context).tableCell)));
211 } 214 }
212 } 215 }
@@ -405,6 +405,7 @@ class RichText extends Widget { @@ -405,6 +405,7 @@ class RichText extends Widget {
405 {@required this.text, 405 {@required this.text,
406 this.textAlign = TextAlign.left, 406 this.textAlign = TextAlign.left,
407 this.softWrap = true, 407 this.softWrap = true,
  408 + this.tightBounds = false,
408 this.textScaleFactor = 1.0, 409 this.textScaleFactor = 1.0,
409 this.maxLines}) 410 this.maxLines})
410 : assert(text != null); 411 : assert(text != null);
@@ -419,6 +420,8 @@ class RichText extends Widget { @@ -419,6 +420,8 @@ class RichText extends Widget {
419 420
420 final bool softWrap; 421 final bool softWrap;
421 422
  423 + final bool tightBounds;
  424 +
422 final int maxLines; 425 final int maxLines;
423 426
424 final List<_Span> _spans = <_Span>[]; 427 final List<_Span> _spans = <_Span>[];
@@ -551,14 +554,10 @@ class RichText extends Widget { @@ -551,14 +554,10 @@ class RichText extends Widget {
551 } 554 }
552 555
553 final double baseline = span.baseline * textScaleFactor; 556 final double baseline = span.baseline * textScaleFactor;
554 - top = math.min(  
555 - top ?? metrics.top + baseline,  
556 - metrics.top + baseline,  
557 - );  
558 - bottom = math.max(  
559 - bottom ?? metrics.bottom + baseline,  
560 - metrics.bottom + baseline,  
561 - ); 557 + final double mt = tightBounds ? metrics.top : metrics.descent;
  558 + final double mb = tightBounds ? metrics.bottom : metrics.ascent;
  559 + top = math.min(top ?? mt + baseline, mt + baseline);
  560 + bottom = math.max(bottom ?? mb + baseline, mb + baseline);
562 561
563 final _Word wd = _Word( 562 final _Word wd = _Word(
564 word, 563 word,
@@ -785,6 +784,7 @@ class Text extends RichText { @@ -785,6 +784,7 @@ class Text extends RichText {
785 TextStyle style, 784 TextStyle style,
786 TextAlign textAlign = TextAlign.left, 785 TextAlign textAlign = TextAlign.left,
787 bool softWrap = true, 786 bool softWrap = true,
  787 + bool tightBounds = false,
788 double textScaleFactor = 1.0, 788 double textScaleFactor = 1.0,
789 int maxLines, 789 int maxLines,
790 }) : assert(text != null), 790 }) : assert(text != null),
@@ -792,6 +792,7 @@ class Text extends RichText { @@ -792,6 +792,7 @@ class Text extends RichText {
792 text: TextSpan(text: text, style: style), 792 text: TextSpan(text: text, style: style),
793 textAlign: textAlign, 793 textAlign: textAlign,
794 softWrap: softWrap, 794 softWrap: softWrap,
  795 + tightBounds: tightBounds,
795 textScaleFactor: textScaleFactor, 796 textScaleFactor: textScaleFactor,
796 maxLines: maxLines); 797 maxLines: maxLines);
797 } 798 }
@@ -56,85 +56,116 @@ void main() { @@ -56,85 +56,116 @@ void main() {
56 margin: const EdgeInsets.all(10), 56 margin: const EdgeInsets.all(10),
57 build: (Context context) => Column(children: <Widget>[ 57 build: (Context context) => Column(children: <Widget>[
58 Container( 58 Container(
59 - padding: const EdgeInsets.all(5),  
60 - margin: const EdgeInsets.only(bottom: 10),  
61 - decoration: const BoxDecoration(  
62 - color: PdfColors.amber,  
63 - border: BoxBorder(  
64 - top: true,  
65 - bottom: true,  
66 - left: true,  
67 - right: true,  
68 - width: 2)),  
69 - child: Text('Hello World',  
70 - textScaleFactor: 2, textAlign: TextAlign.center)), 59 + padding: const EdgeInsets.all(5),
  60 + margin: const EdgeInsets.only(bottom: 10),
  61 + decoration: const BoxDecoration(
  62 + color: PdfColors.amber,
  63 + border: BoxBorder(
  64 + top: true,
  65 + bottom: true,
  66 + left: true,
  67 + right: true,
  68 + width: 2)),
  69 + child: Text(
  70 + 'Hello World',
  71 + textScaleFactor: 2,
  72 + textAlign: TextAlign.center,
  73 + ),
  74 + ),
71 Align( 75 Align(
72 - alignment: Alignment.topLeft,  
73 - child: Link(  
74 - destination: 'anchor',  
75 - child: Text(  
76 - 'Internal link',  
77 - style: const TextStyle(  
78 - color: PdfColors.blue,  
79 - decoration: TextDecoration.underline,  
80 - ),  
81 - ))), 76 + alignment: Alignment.topLeft,
  77 + child: Link(
  78 + destination: 'anchor',
  79 + child: Text(
  80 + 'Internal link',
  81 + style: const TextStyle(
  82 + color: PdfColors.blue,
  83 + decoration: TextDecoration.underline,
  84 + ),
  85 + ),
  86 + ),
  87 + ),
82 Padding(padding: const EdgeInsets.all(5)), 88 Padding(padding: const EdgeInsets.all(5)),
83 Row( 89 Row(
84 - mainAxisAlignment: MainAxisAlignment.spaceEvenly,  
85 - children: <Widget>[  
86 - Image(im),  
87 - PdfLogo(),  
88 - Column(children: <Widget>[ 90 + mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  91 + children: <Widget>[
  92 + Image(im),
  93 + PdfLogo(),
  94 + Column(
  95 + children: <Widget>[
89 Text('(', style: symbol), 96 Text('(', style: symbol),
90 Text('4', style: symbol), 97 Text('4', style: symbol),
91 - ]),  
92 - ]), 98 + ],
  99 + ),
  100 + ],
  101 + ),
93 Padding( 102 Padding(
94 - padding: const EdgeInsets.only(left: 30, top: 20),  
95 - child: Lorem(textAlign: TextAlign.justify)), 103 + padding: const EdgeInsets.only(left: 30, top: 20),
  104 + child: Lorem(textAlign: TextAlign.justify),
  105 + ),
96 Expanded( 106 Expanded(
97 child: FittedBox( 107 child: FittedBox(
98 child: Transform.rotateBox( 108 child: Transform.rotateBox(
99 angle: 0.2, 109 angle: 0.2,
100 - child: Text('Expanded'), 110 + child: Text(
  111 + 'Expanded',
  112 + tightBounds: true,
  113 + ),
101 ), 114 ),
102 ), 115 ),
103 ), 116 ),
104 Container( 117 Container(
105 - padding: const EdgeInsets.only(top: 5),  
106 - decoration: const BoxDecoration(  
107 - border: BoxBorder(top: true, width: 1)),  
108 - child: Text("That's all Folks!",  
109 - textAlign: TextAlign.center,  
110 - style: Theme.of(context)  
111 - .defaultTextStyle  
112 - .copyWith(font: Font.timesBoldItalic()),  
113 - textScaleFactor: 3)), 118 + decoration:
  119 + const BoxDecoration(border: BoxBorder(top: true, width: 1)),
  120 + child: Text(
  121 + "That's all Folks!",
  122 + tightBounds: true,
  123 + textAlign: TextAlign.center,
  124 + style: Theme.of(context).defaultTextStyle.copyWith(
  125 + font: Font.timesBoldItalic(),
  126 + ),
  127 + textScaleFactor: 3,
  128 + ),
  129 + ),
114 ]))); 130 ])));
115 }); 131 });
116 132
117 test('Pdf Widgets page 2', () { 133 test('Pdf Widgets page 2', () {
118 - pdf.addPage(Page( 134 + pdf.addPage(
  135 + Page(
119 pageFormat: const PdfPageFormat(400, 400), 136 pageFormat: const PdfPageFormat(400, 400),
120 margin: const EdgeInsets.all(10), 137 margin: const EdgeInsets.all(10),
121 build: (Context context) => Center( 138 build: (Context context) => Center(
122 - child: GridView(  
123 - crossAxisCount: 3,  
124 - direction: Axis.vertical,  
125 - crossAxisSpacing: 10,  
126 - mainAxisSpacing: 10,  
127 - padding: const EdgeInsets.all(10),  
128 - children: List<Widget>.generate(  
129 - 9, (int n) => FittedBox(child: Text('${n + 1}'))))))); 139 + child: GridView(
  140 + crossAxisCount: 3,
  141 + direction: Axis.vertical,
  142 + crossAxisSpacing: 10,
  143 + mainAxisSpacing: 10,
  144 + padding: const EdgeInsets.all(10),
  145 + children: List<Widget>.generate(
  146 + 9,
  147 + (int n) => FittedBox(
  148 + child: Text('${n + 1}', tightBounds: true),
  149 + ),
  150 + ),
  151 + ),
  152 + ),
  153 + ),
  154 + );
130 }); 155 });
131 156
132 - test('Pdf Widgets page 3', () {  
133 - pdf.addPage(MultiPage(  
134 - pageFormat: const PdfPageFormat(400, 200),  
135 - margin: const EdgeInsets.all(10),  
136 - build: (Context context) => <Widget>[  
137 - Table.fromTextArray(context: context, data: <List<String>>[ 157 + test(
  158 + 'Pdf Widgets page 3',
  159 + () {
  160 + pdf.addPage(
  161 + MultiPage(
  162 + pageFormat: const PdfPageFormat(400, 200),
  163 + margin: const EdgeInsets.all(10),
  164 + build: (Context context) => <Widget>[
  165 + Table.fromTextArray(
  166 + context: context,
  167 + margin: const EdgeInsets.all(3),
  168 + data: <List<String>>[
138 <String>['Company', 'Contact', 'Country'], 169 <String>['Company', 'Contact', 'Country'],
139 <String>['Alfreds Futterkiste', 'Maria Anders', 'Germany'], 170 <String>['Alfreds Futterkiste', 'Maria Anders', 'Germany'],
140 <String>[ 171 <String>[
@@ -165,82 +196,96 @@ void main() { @@ -165,82 +196,96 @@ void main() {
165 <String>['Dynatronics Accessories', "Cong Ch'en", 'China'], 196 <String>['Dynatronics Accessories', "Cong Ch'en", 'China'],
166 <String>['York Steak House', 'Outi Vuorinen', 'Finland'], 197 <String>['York Steak House', 'Outi Vuorinen', 'Finland'],
167 <String>['Weathervane', 'Else Jeremiassen', 'Iceland'], 198 <String>['Weathervane', 'Else Jeremiassen', 'Iceland'],
168 - ]),  
169 - Anchor(name: 'anchor', child: Text('Anchor')),  
170 - ]));  
171 - }); 199 + ],
  200 + ),
  201 + Anchor(name: 'anchor', child: Text('Anchor')),
  202 + ],
  203 + ),
  204 + );
  205 + },
  206 + );
172 207
173 - test('Pdf Widgets page 4', () {  
174 - pdf.addPage(Page(  
175 - pageFormat: const PdfPageFormat(400, 200),  
176 - margin: const EdgeInsets.all(10),  
177 - build: (Context context) => Stack(overflow: Overflow.visible,  
178 - // fit: StackFit.expand,  
179 - // alignment: Alignment.bottomRight,  
180 - children: <Widget>[  
181 - Positioned(  
182 - right: 10,  
183 - top: 10,  
184 - child: CustomPaint(  
185 - size: const PdfPoint(50, 50),  
186 - painter: (PdfGraphics canvas, PdfPoint size) {  
187 - canvas  
188 - ..setColor(PdfColors.indigo)  
189 - ..drawRRect(0, 0, size.x, size.y, 10, 10)  
190 - ..fillPath();  
191 - })),  
192 - Positioned(  
193 - left: 10,  
194 - bottom: 10,  
195 - child: RichText(  
196 - text: TextSpan(  
197 - text: 'Hello ',  
198 - style: Theme.of(context).defaultTextStyle,  
199 - children: <TextSpan>[  
200 - TextSpan(  
201 - text: 'bold',  
202 - style: TextStyle(  
203 - fontWeight: FontWeight.bold,  
204 - fontSize: 20,  
205 - color: PdfColors.blue)),  
206 - const TextSpan(  
207 - text: ' world!',  
208 - ),  
209 - ], 208 + test(
  209 + 'Pdf Widgets page 4',
  210 + () {
  211 + pdf.addPage(
  212 + Page(
  213 + pageFormat: const PdfPageFormat(400, 200),
  214 + margin: const EdgeInsets.all(10),
  215 + build: (Context context) => Stack(
  216 + overflow: Overflow.visible,
  217 + // fit: StackFit.expand,
  218 + // alignment: Alignment.bottomRight,
  219 + children: <Widget>[
  220 + Positioned(
  221 + right: 10,
  222 + top: 10,
  223 + child: CustomPaint(
  224 + size: const PdfPoint(50, 50),
  225 + painter: (PdfGraphics canvas, PdfPoint size) {
  226 + canvas
  227 + ..setColor(PdfColors.indigo)
  228 + ..drawRRect(0, 0, size.x, size.y, 10, 10)
  229 + ..fillPath();
  230 + })),
  231 + Positioned(
  232 + left: 10,
  233 + bottom: 10,
  234 + child: RichText(
  235 + text: TextSpan(
  236 + text: 'Hello ',
  237 + style: Theme.of(context).defaultTextStyle,
  238 + children: <TextSpan>[
  239 + TextSpan(
  240 + text: 'bold',
  241 + style: TextStyle(
  242 + fontWeight: FontWeight.bold,
  243 + fontSize: 20,
  244 + color: PdfColors.blue)),
  245 + const TextSpan(
  246 + text: ' world!',
210 ), 247 ),
211 - )),  
212 - Positioned(  
213 - right: 10,  
214 - bottom: 10,  
215 - child: UrlLink(  
216 - child: Text(  
217 - 'https://github.com/DavBfr/dart_pdf/',  
218 - style: const TextStyle(  
219 - color: PdfColors.grey,  
220 - fontSize: 8,  
221 - decoration: TextDecoration.underline,  
222 - ),  
223 - ),  
224 - destination: 'https://github.com/DavBfr/dart_pdf/')),  
225 - Positioned(  
226 - left: 10,  
227 - top: 10,  
228 - child: Container(  
229 - width: 100,  
230 - height: 100,  
231 - child: Stack(  
232 - alignment: Alignment.center,  
233 - fit: StackFit.expand,  
234 - children: <Widget>[  
235 - Center(  
236 - child: Text('30%', textScaleFactor: 1.5)),  
237 - CircularProgressIndicator(  
238 - value: .3,  
239 - backgroundColor: PdfColors.grey300,  
240 - strokeWidth: 15),  
241 - ])))  
242 - ])));  
243 - }); 248 + ],
  249 + ),
  250 + )),
  251 + Positioned(
  252 + right: 10,
  253 + bottom: 10,
  254 + child: UrlLink(
  255 + child: Text(
  256 + 'https://github.com/DavBfr/dart_pdf/',
  257 + style: const TextStyle(
  258 + color: PdfColors.grey,
  259 + fontSize: 8,
  260 + decoration: TextDecoration.underline,
  261 + ),
  262 + ),
  263 + destination: 'https://github.com/DavBfr/dart_pdf/')),
  264 + Positioned(
  265 + left: 10,
  266 + top: 10,
  267 + child: Container(
  268 + width: 100,
  269 + height: 100,
  270 + child: Stack(
  271 + alignment: Alignment.center,
  272 + fit: StackFit.expand,
  273 + children: <Widget>[
  274 + Center(child: Text('30%', textScaleFactor: 1.5)),
  275 + CircularProgressIndicator(
  276 + value: .3,
  277 + backgroundColor: PdfColors.grey300,
  278 + strokeWidth: 15),
  279 + ],
  280 + ),
  281 + ),
  282 + ),
  283 + ],
  284 + ),
  285 + ),
  286 + );
  287 + },
  288 + );
244 289
245 tearDownAll(() { 290 tearDownAll(() {
246 final File file = File('widgets.pdf'); 291 final File file = File('widgets.pdf');
No preview for this file type