Search code examples
flutterdartarabic

Arabic text not connected when specifying stroke width


Arabic text is not connected when I specify a stroke width. Here's what I see:

enter image description here

The connections within the circled portion shouldn't be there, but instead each character should be connected, like in cursive text. Here's the code:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Text.rich(TextSpan(
            text: 'كيف الحال',
            style: TextStyle(
                fontSize: 80,
                foreground: Paint()
                  ..style = PaintingStyle.stroke
                  ..strokeWidth = 2
                  ..color = Colors.blue))));
  }
}

If I use PaintingStyle.fill instead of PaintingStyle.stroke above, I don't see any issue because the text is filled in.

How can I get rid of these connections? Is there a way to merge paths?


Solution

  • If you stack another Text widget that just colors the text, then the connections between two letters is hidden:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text(widget.title),
            ),
            body: Stack(
              children: [
                Text('كيف الحال',
                    style: TextStyle(
                        fontSize: 80,
                        foreground: Paint()
                          ..style = PaintingStyle.stroke
                          ..strokeWidth = 2
                          ..color = Colors.blue)),
                Text('كيف الحال',
                    style: TextStyle(
                      fontSize: 80,
                      color: Colors.white,
                    ))
              ],
            ));
      }
    }
    

    You must stack because Flutter only allows specifying one of color/foreground/background.

    If the color has transparency, then the connections are shown. So my question isn't fully addressed, but I don't need transparency.