Committed by
David PHAM-VAN
Fix Arabic TextAlign.justify issues
Set default text align based on text direction
Showing
6 changed files
with
52 additions
and
10 deletions
@@ -56,8 +56,11 @@ abstract class _Span { | @@ -56,8 +56,11 @@ abstract class _Span { | ||
56 | var offset = PdfPoint.zero; | 56 | var offset = PdfPoint.zero; |
57 | 57 | ||
58 | double get left; | 58 | double get left; |
59 | + | ||
59 | double get top; | 60 | double get top; |
61 | + | ||
60 | double get width; | 62 | double get width; |
63 | + | ||
61 | double get height; | 64 | double get height; |
62 | 65 | ||
63 | @override | 66 | @override |
@@ -544,6 +547,7 @@ class _Line { | @@ -544,6 +547,7 @@ class _Line { | ||
544 | 547 | ||
545 | final int firstSpan; | 548 | final int firstSpan; |
546 | final int countSpan; | 549 | final int countSpan; |
550 | + | ||
547 | int get lastSpan => firstSpan + countSpan; | 551 | int get lastSpan => firstSpan + countSpan; |
548 | 552 | ||
549 | TextAlign get textAlign => parent._textAlign; | 553 | TextAlign get textAlign => parent._textAlign; |
@@ -569,39 +573,46 @@ class _Line { | @@ -569,39 +573,46 @@ class _Line { | ||
569 | 573 | ||
570 | void realign(double totalWidth) { | 574 | void realign(double totalWidth) { |
571 | final spans = parent._spans.sublist(firstSpan, lastSpan); | 575 | final spans = parent._spans.sublist(firstSpan, lastSpan); |
576 | + final isRTL = textDirection == TextDirection.rtl; | ||
572 | 577 | ||
573 | var delta = 0.0; | 578 | var delta = 0.0; |
574 | switch (textAlign) { | 579 | switch (textAlign) { |
575 | case TextAlign.left: | 580 | case TextAlign.left: |
581 | + delta = isRTL ? totalWidth - wordsWidth : 0; | ||
576 | break; | 582 | break; |
577 | case TextAlign.right: | 583 | case TextAlign.right: |
578 | - delta = totalWidth - wordsWidth; | 584 | + delta = isRTL ? 0 : totalWidth - wordsWidth; |
579 | break; | 585 | break; |
580 | case TextAlign.center: | 586 | case TextAlign.center: |
581 | delta = (totalWidth - wordsWidth) / 2.0; | 587 | delta = (totalWidth - wordsWidth) / 2.0; |
582 | break; | 588 | break; |
583 | case TextAlign.justify: | 589 | case TextAlign.justify: |
584 | if (!justify) { | 590 | if (!justify) { |
585 | - totalWidth = wordsWidth; | ||
586 | break; | 591 | break; |
587 | } | 592 | } |
593 | + | ||
588 | delta = (totalWidth - wordsWidth) / (spans.length - 1); | 594 | delta = (totalWidth - wordsWidth) / (spans.length - 1); |
589 | var x = 0.0; | 595 | var x = 0.0; |
590 | for (final span in spans) { | 596 | for (final span in spans) { |
597 | + if (isRTL) { | ||
598 | + final xOffset = span.offset.x + span.width; | ||
599 | + span.offset = | ||
600 | + PdfPoint((totalWidth - xOffset) - x, span.offset.y - baseline); | ||
601 | + } else { | ||
591 | span.offset = span.offset.translate(x, -baseline); | 602 | span.offset = span.offset.translate(x, -baseline); |
603 | + } | ||
592 | x += delta; | 604 | x += delta; |
593 | } | 605 | } |
594 | return; | 606 | return; |
595 | } | 607 | } |
596 | 608 | ||
597 | - if (textDirection == TextDirection.rtl) { | 609 | + if (isRTL) { |
598 | for (final span in spans) { | 610 | for (final span in spans) { |
599 | span.offset = PdfPoint( | 611 | span.offset = PdfPoint( |
600 | totalWidth - (span.offset.x + span.width) - delta, | 612 | totalWidth - (span.offset.x + span.width) - delta, |
601 | span.offset.y - baseline, | 613 | span.offset.y - baseline, |
602 | ); | 614 | ); |
603 | } | 615 | } |
604 | - | ||
605 | return; | 616 | return; |
606 | } | 617 | } |
607 | 618 | ||
@@ -688,7 +699,6 @@ class RichText extends Widget with SpanningWidget { | @@ -688,7 +699,6 @@ class RichText extends Widget with SpanningWidget { | ||
688 | return; | 699 | return; |
689 | } | 700 | } |
690 | } | 701 | } |
691 | - | ||
692 | _decorations.add(td); | 702 | _decorations.add(td); |
693 | } | 703 | } |
694 | 704 | ||
@@ -863,8 +873,13 @@ class RichText extends Widget with SpanningWidget { | @@ -863,8 +873,13 @@ class RichText extends Widget with SpanningWidget { | ||
863 | final theme = Theme.of(context); | 873 | final theme = Theme.of(context); |
864 | final _softWrap = softWrap ?? theme.softWrap; | 874 | final _softWrap = softWrap ?? theme.softWrap; |
865 | final _maxLines = maxLines ?? theme.maxLines; | 875 | final _maxLines = maxLines ?? theme.maxLines; |
866 | - _textAlign = textAlign ?? theme.textAlign; | ||
867 | final _textDirection = textDirection ?? Directionality.of(context); | 876 | final _textDirection = textDirection ?? Directionality.of(context); |
877 | + _textAlign = textAlign ?? | ||
878 | + theme.textAlign ?? | ||
879 | + (_textDirection == TextDirection.rtl | ||
880 | + ? TextAlign.right | ||
881 | + : TextAlign.left); | ||
882 | + | ||
868 | final _overflow = this.overflow ?? theme.overflow; | 883 | final _overflow = this.overflow ?? theme.overflow; |
869 | 884 | ||
870 | final constraintWidth = constraints.hasBoundedWidth | 885 | final constraintWidth = constraints.hasBoundedWidth |
@@ -80,8 +80,8 @@ class ThemeData extends Inherited { | @@ -80,8 +80,8 @@ class ThemeData extends Inherited { | ||
80 | required this.tableCell, | 80 | required this.tableCell, |
81 | required this.softWrap, | 81 | required this.softWrap, |
82 | required this.overflow, | 82 | required this.overflow, |
83 | - required this.textAlign, | ||
84 | required this.iconTheme, | 83 | required this.iconTheme, |
84 | + this.textAlign, | ||
85 | this.maxLines, | 85 | this.maxLines, |
86 | }) : assert(defaultTextStyle.inherit == false), | 86 | }) : assert(defaultTextStyle.inherit == false), |
87 | assert(paragraphStyle.inherit == false), | 87 | assert(paragraphStyle.inherit == false), |
@@ -129,7 +129,6 @@ class ThemeData extends Inherited { | @@ -129,7 +129,6 @@ class ThemeData extends Inherited { | ||
129 | tableCell: defaultStyle.copyWith(fontSize: fontSize * 0.8), | 129 | tableCell: defaultStyle.copyWith(fontSize: fontSize * 0.8), |
130 | softWrap: true, | 130 | softWrap: true, |
131 | overflow: TextOverflow.visible, | 131 | overflow: TextOverflow.visible, |
132 | - textAlign: TextAlign.left, | ||
133 | iconTheme: IconThemeData.fallback(icons), | 132 | iconTheme: IconThemeData.fallback(icons), |
134 | ); | 133 | ); |
135 | } | 134 | } |
@@ -156,7 +155,7 @@ class ThemeData extends Inherited { | @@ -156,7 +155,7 @@ class ThemeData extends Inherited { | ||
156 | 155 | ||
157 | final TextStyle tableCell; | 156 | final TextStyle tableCell; |
158 | 157 | ||
159 | - final TextAlign textAlign; | 158 | + final TextAlign? textAlign; |
160 | final bool softWrap; | 159 | final bool softWrap; |
161 | final int? maxLines; | 160 | final int? maxLines; |
162 | final TextOverflow overflow; | 161 | final TextOverflow overflow; |
@@ -3,7 +3,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl | @@ -3,7 +3,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl | ||
3 | homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf | 3 | homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf |
4 | repository: https://github.com/DavBfr/dart_pdf | 4 | repository: https://github.com/DavBfr/dart_pdf |
5 | issue_tracker: https://github.com/DavBfr/dart_pdf/issues | 5 | issue_tracker: https://github.com/DavBfr/dart_pdf/issues |
6 | -version: 3.8.2 | 6 | +version: 3.8.3 |
7 | 7 | ||
8 | environment: | 8 | environment: |
9 | sdk: ">=2.12.0 <3.0.0" | 9 | sdk: ">=2.12.0 <3.0.0" |
@@ -492,6 +492,31 @@ void main() { | @@ -492,6 +492,31 @@ void main() { | ||
492 | )); | 492 | )); |
493 | }); | 493 | }); |
494 | 494 | ||
495 | + test('Text Widgets Arabic with TextAlign.justify', () { | ||
496 | + pdf.addPage(Page( | ||
497 | + build: (Context context) => RichText( | ||
498 | + textDirection: TextDirection.rtl, | ||
499 | + textAlign: TextAlign.justify, | ||
500 | + text: TextSpan( | ||
501 | + text: 'قهوة\n', | ||
502 | + style: TextStyle( | ||
503 | + font: arabicFont, | ||
504 | + fontSize: 30, | ||
505 | + ), | ||
506 | + children: const <TextSpan>[ | ||
507 | + TextSpan( | ||
508 | + text: | ||
509 | + 'القهوة مشروب يعد من بذور الب المحمصة، وينمو في أكثر من 70 لداً. خصوصاً في المناطق الاستوائية في أمريكا الشمالية والجنوبية وجنوب شرق آسيا وشبه القارة الهندية وأفريقيا. ويقال أن البن الأخضر هو ثاني أكثر السلع تداولاً في العالم بعد النفط الخام.', | ||
510 | + style: TextStyle( | ||
511 | + fontSize: 20, | ||
512 | + ), | ||
513 | + ), | ||
514 | + ], | ||
515 | + ), | ||
516 | + ), | ||
517 | + )); | ||
518 | + }); | ||
519 | + | ||
495 | test( | 520 | test( |
496 | 'Text Widgets, Mixed Arabic and Latin words should be rendered in order ', | 521 | 'Text Widgets, Mixed Arabic and Latin words should be rendered in order ', |
497 | () { | 522 | () { |
No preview for this file type
-
Please register or login to post a comment