6

I'm new to Flutter, trying a code to change the color of specific Unicode characters in a string. Color coding \u0951, \u0952, and \u1cda to say blue, red and green. The output string is not matching the expected format. I'm seeing some characters repeating and in some characters, the color is being applied to neighboring characters. Any help in figuring out the issue is greatly appreciated. I want the code to work in both Android and IOS platforms.

Earlier I had a similar code in Kotlin when I developed this app in Android using spannableStr worked as expected. The Flutter Dart code is:

import 'package:flutter/material.dart';

import 'package:flutter/painting.dart';
import 'package:google_fonts/google_fonts.dart';

class TextModifierScreen extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return TextModifierScreenState();
  }
}

class TextModifierScreenState extends State{

  List<TextSpan> _displaySpans = [];
  String inputString = "मृ॒त्यवे॒ यो॑ स्वाहा᳚ भू॒ मु॒भयो॒रा ॥";

  void replaceVowelsWithColor(String input) {
    List<TextSpan> spans = [];
    for (int i = 0; i < input.length; i++) {
      String char = input[i];
      int unicode = char.codeUnitAt(0);
      String unicodeString = '\\u${unicode.toRadixString(16).padLeft(4, '0')}';
      print('Unicode of $char is $unicodeString');
      if(char == '\u0952'){
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.red, ),
        ));
      }else if(char == '\u0951'){
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.blue),
        ));
      }else if(char == '\u1cda'){
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.green),
        ));
      }else{
        spans.add(TextSpan(
            text: char,
          style: TextStyle(color: Colors.black),
        ));
      }
    }
    setState(() {
      _displaySpans = spans;
    });
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Accents Color Replacer'),
      ),
      body: Center(
        child: Padding(
          padding: EdgeInsets.only(left: 20, right: 20),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RichText(
              text: TextSpan(
                style: GoogleFonts.tiroDevanagariSanskrit(
                  fontSize: 20,
                  color: Colors.black,
                ),
                children: <TextSpan>[
                  TextSpan(text: 'Original Text:\n '),
                  TextSpan(text: inputString),
                ],
              ),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                replaceVowelsWithColor(inputString);
              },
              child: Text('Replace colors'),
            ),
            SizedBox(height: 20),
            RichText(
              text: TextSpan(
                style: GoogleFonts.tiroDevanagariSanskrit(
                  fontSize: 20,
                  color: Colors.black,
                ),
                children: <TextSpan>[
                  TextSpan(text: 'Modifed Text: \n'),
                  ..._displaySpans,
                  //_displaySpans[0],_displaySpans[2],_displaySpans[9],_displaySpans[2]
                ],
              ),
            ),
          ],
        ),
      ),
      ),
    );
  }
}

The first image is what I'm seeing. The second image is the expected output. enter image description here enter image description here

Thanks in advance!!!

[Update] If I replace the code to replace colors of vowels in an English text, it seems to work properly. enter image description here

void replaceVowelsWithColor(String input) {

    List<TextSpan> spans = [];
    for (int i = 0; i < input.length; i++) {
      String char = input[i];
      int unicode = char.codeUnitAt(0);
      String unicodeString = '\\u${unicode.toRadixString(16).padLeft(4, '0')}';
      print('Unicode of $char is $unicodeString');
      if(char == '\u0061'){
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.red, ),
        ));
      }else if(char == '\u0065'){
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.blue),
        ));
      }else if(char == '\u0069'){
        spans.add(TextSpan(
          text: char,
          //color: Colors.green,
          style: TextStyle(color: Colors.green),
        ));
      }else if(char == '\u006F'){
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.yellow),
        ));
      }else if(char == '\u0075'){
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.pink),
          ));
      }else{
        spans.add(TextSpan(
          text: char,
          style: TextStyle(color: Colors.black),
        ));
      }
    }
    setState(() {
      _displayEngSpans = spans;
    });
  }
ShreevatsaR
  • 38,402
  • 17
  • 102
  • 126
user2901219
  • 371
  • 1
  • 3
  • 15

1 Answers1

2

Resolved the issue. The issue was with the specific font being used. Here are the outputs of Vedic Devanagari script using different Devanagari Google fonts. As per current versions, the Noto Serif Devanagari and Pragati Narrow looks to render the required Vedic accents. The Tiro font has an issue with some special characters if we change colors.

enter image description here

user2901219
  • 371
  • 1
  • 3
  • 15
  • It may be worth reporting this issue to the font developers (Tiro Typeworks). It may be either a bug in the font or, if the same font works fine in Android/Kotlin, some quirk specific to the interaction between Flutter/Dart and this font. – ShreevatsaR Aug 07 '23 at 22:08