@@ -224,6 +224,14 @@ class Converters {
224224 segments.add (
225225 {'type' : 'image' , 'index' : int .parse (text[i + 2 ] + text[i + 3 ])});
226226 i += 6 ;
227+ } else if (text[i] == '\f ' ) {
228+ // Frame separator: flush current text then pad to next screen boundary.
229+ if (currentText.isNotEmpty) {
230+ segments.add ({'type' : 'text' , 'content' : currentText});
231+ currentText = '' ;
232+ }
233+ segments.add ({'type' : 'frame_break' });
234+ i++ ;
227235 } else {
228236 currentText += text[i];
229237 i++ ;
@@ -237,7 +245,9 @@ class Converters {
237245
238246 // Process each segment
239247 for (var segment in segments) {
240- if (segment['type' ] == 'text' ) {
248+ if (segment['type' ] == 'frame_break' ) {
249+ _padMatrixToNextFrame (combinedMatrix);
250+ } else if (segment['type' ] == 'text' ) {
241251 String text = segment['content' ];
242252 for (int i = 0 ; i < text.length; i++ ) {
243253 String char = text[i];
@@ -325,6 +335,27 @@ class Converters {
325335 return hexStrings;
326336 }
327337
338+ /// Pads [combinedMatrix] with empty columns until its width is a multiple of
339+ /// [badgeScreenWidth] (default 44). Used to align frames at screen boundaries
340+ /// when the "Animation" (Splitting) transition is active.
341+ void _padMatrixToNextFrame (
342+ List <List <bool >> combinedMatrix, {
343+ int badgeScreenWidth = 44 ,
344+ }) {
345+ final currentWidth =
346+ combinedMatrix.isNotEmpty ? combinedMatrix[0 ].length : 0 ;
347+ if (currentWidth == 0 ) return ;
348+ final remainder = currentWidth % badgeScreenWidth;
349+ if (remainder == 0 ) return ; // already aligned
350+ final paddingNeeded = badgeScreenWidth - remainder;
351+ final emptyCol = List <bool >.filled (11 , false );
352+ for (int p = 0 ; p < paddingNeeded; p++ ) {
353+ for (int row = 0 ; row < 11 ; row++ ) {
354+ combinedMatrix[row].add (emptyCol[row]);
355+ }
356+ }
357+ }
358+
328359 Future <List <String >> _processDefaultFont (String text) async {
329360 List <Map <String , dynamic >> segments = [];
330361 String currentText = '' ;
@@ -339,6 +370,15 @@ class Converters {
339370 segments.add (
340371 {'type' : 'image' , 'index' : int .parse (text[i + 2 ] + text[i + 3 ])});
341372 i += 6 ;
373+ } else if (text[i] == '\f ' ) {
374+ // Frame separator: flush current text segment then pad matrix to the
375+ // next 44-column screen boundary so the following frame starts fresh.
376+ if (currentText.isNotEmpty) {
377+ segments.add ({'type' : 'text' , 'content' : currentText});
378+ currentText = '' ;
379+ }
380+ segments.add ({'type' : 'frame_break' });
381+ i++ ;
342382 } else {
343383 currentText += text[i];
344384 i++ ;
@@ -351,7 +391,10 @@ class Converters {
351391 List <List <bool >> combinedMatrix = List .generate (11 , (_) => []);
352392
353393 for (var segment in segments) {
354- if (segment['type' ] == 'text' ) {
394+ if (segment['type' ] == 'frame_break' ) {
395+ // Pad to the next full badge screen (44 columns).
396+ _padMatrixToNextFrame (combinedMatrix);
397+ } else if (segment['type' ] == 'text' ) {
355398 String segmentText = segment['content' ];
356399 for (final char in segmentText.split ('' )) {
357400 if (! converter.charCodes.containsKey (char)) continue ;
0 commit comments