@@ -197,8 +197,10 @@ public LineRange(int start, int end, int endExcludingWhitespace, int endIncludin
197
197
float [ ] _lineHeights ;
198
198
GlyphPosition [ ] glyphPositions ;
199
199
int _lineCount ;
200
- List < PaintRecord > _paintRecords = new List < PaintRecord > ( ) ;
201
- List < CodeUnitRun > _codeUnitRuns = new List < CodeUnitRun > ( ) ;
200
+ PaintRecord [ ] _paintRecords ;
201
+ CodeUnitRun [ ] _codeUnitRuns ;
202
+ int _paintRecordsCount ;
203
+ int _codeUnitRunsCount ;
202
204
bool _didExceedMaxLines ;
203
205
TabStops _tabStops = new TabStops ( ) ;
204
206
@@ -248,11 +250,13 @@ public bool didExceedMaxLines {
248
250
}
249
251
250
252
public void paint ( Canvas canvas , Offset offset ) {
251
- foreach ( var paintRecord in this . _paintRecords ) {
253
+ for ( int i = 0 ; i < this . _paintRecordsCount ; i ++ ) {
254
+ var paintRecord = this . _paintRecords [ i ] ;
252
255
this . paintBackground ( canvas , paintRecord , offset ) ;
253
256
}
254
257
255
- foreach ( var paintRecord in this . _paintRecords ) {
258
+ for ( int i = 0 ; i < this . _paintRecordsCount ; i ++ ) {
259
+ var paintRecord = this . _paintRecords [ i ] ;
256
260
var paint = new Paint {
257
261
filterMode = FilterMode . Bilinear ,
258
262
color = paintRecord . style . color
@@ -276,10 +280,9 @@ public void layout(ParagraphConstraints constraints) {
276
280
277
281
this . _needsLayout = false ;
278
282
this . _width = Mathf . Floor ( constraints . width ) ;
279
- this . _paintRecords . Clear ( ) ;
280
- this . _codeUnitRuns . Clear ( ) ;
281
283
282
- this . _computeLineBreak ( ) ;
284
+ int lineStyleRunsCount = this . _computeLineBreak ( ) ;
285
+
283
286
if ( this . _glyphLines == null || this . _glyphLines . Length < this . _lineRanges . Count ) {
284
287
this . _glyphLines = new GlyphLine [ this . _lineRanges . Count ] ;
285
288
}
@@ -292,6 +295,18 @@ public void layout(ParagraphConstraints constraints) {
292
295
this . _lineHeights = new float [ this . _lineRanges . Count ] ;
293
296
}
294
297
298
+ if ( this . _paintRecords == null || this . _paintRecords . Length < lineStyleRunsCount ) {
299
+ this . _paintRecords = new PaintRecord [ lineStyleRunsCount ] ;
300
+ }
301
+
302
+ this . _paintRecordsCount = 0 ;
303
+
304
+ if ( this . _codeUnitRuns == null || this . _codeUnitRuns . Length < lineStyleRunsCount ) {
305
+ this . _codeUnitRuns = new CodeUnitRun [ lineStyleRunsCount ] ;
306
+ }
307
+
308
+ this . _codeUnitRunsCount = 0 ;
309
+
295
310
int styleMaxLines = this . _paragraphStyle . maxLines ?? int . MaxValue ;
296
311
this . _didExceedMaxLines = this . _lineRanges . Count > styleMaxLines ;
297
312
@@ -461,15 +476,16 @@ public void layout(ParagraphConstraints constraints) {
461
476
var metrics = FontMetrics . fromFont ( font , style . UnityFontSize ) ;
462
477
PaintRecord paintRecord = new PaintRecord ( style , runXOffset , 0 , builder . make ( ) ,
463
478
metrics , advance ) ;
464
- this . _paintRecords . Add ( paintRecord ) ;
479
+ this . _paintRecords [ this . _paintRecordsCount ++ ] = paintRecord ;
465
480
runXOffset += advance ;
466
481
467
482
// Create code unit run
468
- this . _codeUnitRuns . Add ( new CodeUnitRun (
483
+ CodeUnitRun codeUnitRun = new CodeUnitRun (
469
484
this . glyphPositions ,
470
485
new Range < int > ( start , end ) ,
471
486
new Range < float > ( this . glyphPositions [ 0 ] . xPos . start , this . glyphPositions . last ( ) . xPos . end ) ,
472
- lineNumber , TextDirection . ltr , glyphPositionStyleRunStart , textCount ) ) ;
487
+ lineNumber , TextDirection . ltr , glyphPositionStyleRunStart , textCount ) ;
488
+ this . _codeUnitRuns [ this . _codeUnitRunsCount ++ ] = codeUnitRun ;
473
489
474
490
lineStyleRunIndex ++ ;
475
491
}
@@ -504,7 +520,7 @@ void updateLineMetrics(FontMetrics metrics, float styleHeight) {
504
520
505
521
if ( lineStyleRunCount != 0 ) {
506
522
for ( int i = 0 ; i < lineStyleRunCount ; i ++ ) {
507
- var paintRecord = this . _paintRecords [ this . _paintRecords . Count - i - 1 ] ;
523
+ var paintRecord = this . _paintRecords [ this . _paintRecordsCount - i - 1 ] ;
508
524
updateLineMetrics ( paintRecord . metrics , paintRecord . style . height ) ;
509
525
}
510
526
}
@@ -538,9 +554,9 @@ void updateLineMetrics(FontMetrics metrics, float styleHeight) {
538
554
this . _glyphLines [ lineNumber ] =
539
555
new GlyphLine ( this . glyphPositions , glyphPositionLineStart , count , nextLineStart - lineStart ) ;
540
556
for ( int i = 0 ; i < lineStyleRunCount ; i ++ ) {
541
- var paintRecord = this . _paintRecords [ this . _paintRecords . Count - 1 - i ] ;
557
+ var paintRecord = this . _paintRecords [ this . _paintRecordsCount - 1 - i ] ;
542
558
paintRecord . shift ( lineXOffset , yOffset ) ;
543
- this . _paintRecords [ this . _paintRecords . Count - 1 - i ] = paintRecord ;
559
+ this . _paintRecords [ this . _paintRecordsCount - 1 - i ] = paintRecord ;
544
560
}
545
561
}
546
562
@@ -782,33 +798,48 @@ public int getLineCount() {
782
798
return this . _lineCount ;
783
799
}
784
800
785
- void _computeLineBreak ( ) {
801
+ int _computeLineBreak ( ) {
786
802
this . _lineRanges . Clear ( ) ;
787
803
this . _lineWidths . Clear ( ) ;
788
804
this . _maxIntrinsicWidth = 0 ;
789
805
806
+ int lineLimit = this . _paragraphStyle . ellipsized ( )
807
+ ? this . _paragraphStyle . maxLines ?? 1
808
+ : this . _paragraphStyle . maxLines ?? 0 ;
809
+
790
810
var newLinePositions = LineBreaker . newLinePositions ;
791
811
this . _computeNewLinePositions ( newLinePositions ) ;
792
812
793
813
var lineBreaker = LineBreaker . instance ;
794
814
int runIndex = 0 ;
815
+ int countRuns = 0 ;
795
816
for ( var newlineIndex = 0 ; newlineIndex < newLinePositions . Count ; ++ newlineIndex ) {
817
+ if ( lineLimit != 0 && this . _lineRanges . Count >= lineLimit ) {
818
+ break ;
819
+ }
796
820
var blockStart = newlineIndex > 0 ? newLinePositions [ newlineIndex - 1 ] + 1 : 0 ;
797
821
var blockEnd = newLinePositions [ newlineIndex ] ;
798
822
var blockSize = blockEnd - blockStart ;
799
823
if ( blockSize == 0 ) {
800
824
this . _addEmptyLine ( blockStart , blockEnd ) ;
801
825
continue ;
802
826
}
827
+ if ( lineLimit != 0 && this . _lineRanges . Count >= lineLimit ) {
828
+ break ;
829
+ }
803
830
804
- this . _resetLineBreaker ( lineBreaker , blockStart , blockSize ) ;
805
- runIndex = this . _addStyleRuns ( lineBreaker , runIndex , blockStart , blockEnd ) ;
831
+ this . _resetLineBreaker ( lineBreaker , blockStart , blockSize ,
832
+ lineLimit == 0 ? 0 : lineLimit - this . _lineRanges . Count ) ;
833
+ countRuns += this . _addStyleRuns ( lineBreaker , ref runIndex , blockStart , blockEnd ) ;
806
834
807
835
int breaksCount = lineBreaker . computeBreaks ( ) ;
808
- this . _updateBreaks ( lineBreaker , breaksCount , blockStart ) ;
836
+ countRuns += breaksCount - 1 ;
837
+ this . _updateBreaks ( lineBreaker , breaksCount , blockStart , blockEnd ) ;
809
838
810
839
lineBreaker . finish ( ) ;
811
840
}
841
+
842
+ return countRuns ;
812
843
}
813
844
814
845
void _addEmptyLine ( int blockStart , int blockEnd ) {
@@ -817,28 +848,35 @@ void _addEmptyLine(int blockStart, int blockEnd) {
817
848
this . _lineWidths . Add ( 0 ) ;
818
849
}
819
850
820
- void _resetLineBreaker ( LineBreaker lineBreaker , int blockStart , int blockSize ) {
851
+ void _resetLineBreaker ( LineBreaker lineBreaker , int blockStart , int blockSize , int lineLimit ) {
821
852
lineBreaker . setLineWidth ( this . _width ) ;
822
853
lineBreaker . resize ( blockSize ) ;
823
854
lineBreaker . setTabStops ( this . _tabStops ) ;
824
855
lineBreaker . setText ( this . _text , blockStart , blockSize ) ;
856
+ lineBreaker . lineLimit = lineLimit ;
825
857
}
826
858
827
- int _addStyleRuns ( LineBreaker lineBreaker , int runIndex , int blockStart , int blockEnd ) {
859
+ int _addStyleRuns ( LineBreaker lineBreaker , ref int runIndex , int blockStart , int blockEnd ) {
860
+ int countRuns = 0 ;
828
861
while ( runIndex < this . _runs . size ) {
829
862
var run = this . _runs . getRun ( runIndex ) ;
830
863
if ( run . start >= blockEnd ) {
831
864
break ;
832
865
}
833
866
834
- if ( run . end < blockStart ) {
867
+ if ( lineBreaker . lineLimit != 0 && lineBreaker . getBreaks ( ) . Count >= lineBreaker . lineLimit ) {
868
+ break ;
869
+ }
870
+
871
+ if ( run . end <= blockStart ) {
835
872
runIndex ++ ;
836
873
continue ;
837
874
}
838
875
839
876
int runStart = Mathf . Max ( run . start , blockStart ) - blockStart ;
840
877
int runEnd = Mathf . Min ( run . end , blockEnd ) - blockStart ;
841
878
lineBreaker . addStyleRun ( run . style , runStart , runEnd ) ;
879
+ countRuns ++ ;
842
880
843
881
if ( run . end > blockEnd ) {
844
882
break ;
@@ -847,17 +885,17 @@ int _addStyleRuns(LineBreaker lineBreaker, int runIndex, int blockStart, int blo
847
885
runIndex ++ ;
848
886
}
849
887
850
- return runIndex ;
888
+ return countRuns ;
851
889
}
852
890
853
- void _updateBreaks ( LineBreaker lineBreaker , int breaksCount , int blockStart ) {
891
+ void _updateBreaks ( LineBreaker lineBreaker , int breaksCount , int blockStart , int blockEnd ) {
854
892
List < int > breaks = lineBreaker . getBreaks ( ) ;
855
893
List < float > widths = lineBreaker . getWidths ( ) ;
856
894
for ( int i = 0 ; i < breaksCount ; ++ i ) {
857
895
var breakStart = i > 0 ? breaks [ i - 1 ] : 0 ;
858
896
var lineStart = breakStart + blockStart ;
859
897
var lineEnd = breaks [ i ] + blockStart ;
860
- bool hardBreak = i == breaksCount - 1 ;
898
+ bool hardBreak = lineEnd == blockEnd ;
861
899
var lineEndIncludingNewline =
862
900
hardBreak && lineEnd < this . _text . Length ? lineEnd + 1 : lineEnd ;
863
901
var lineEndExcludingWhitespace = lineEnd ;
0 commit comments