# Find the width of a character

**URL:** <https://forums.swift.org/t/find-the-width-of-a-character/41943>\
**Category:** Using Swift\
**Created:** [November 12, 2020, 12:41am UTC](https://forums.swift.org/t/find-the-width-of-a-character/41943 "2020-11-12T00:41:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![wowbagger](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/wowbagger/32/13847_2.png) [@wowbagger](https://forums.swift.org/u/wowbagger)\
**Post date:** [November 12, 2020, 12:41am UTC](https://forums.swift.org/t/find-the-width-of-a-character/41943/1 "2020-11-12T00:41:57Z")

</div>

Let me start with an example to illustrate what I mean by "width":

```swift
let string1 = "abc"
let string2 = "甲乙丙"

```

Although both `string1` and `string2` contain the same number of characters, `string2` takes 2x as much space as `string1` does when printed in terminal, or anywhere on screen in monospaced fonts. So, each character in `string2` has 2x the width of each in `string1`.

This becomes a problem if I want to generate a table with all cells well-aligned, because simply using each string's `count` property won't be enough:

```swift
   | abc |
---|-----|---
   | 甲乙丙 |

```

I considered assigning a width of 2 to a scalar if its `Unicode.Scalar.Properties.isUnifiedIdeograph` is `true`. However, a character is not always a scalar (because of combining characters), and there are also scalars like `U+00A0` that has zero width.

Is there a way to find the width of a character in Swift?

---

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [November 12, 2020, 1:03am UTC](https://forums.swift.org/t/find-the-width-of-a-character/41943/2 "2020-11-12T01:03:06Z")

</div>

“Monospace” becomes meaningless once you venture outside ASCII. Different fonts and terminals won’t agree with each other about how wide any particular string is.

When trying to hack together a table like that, it’s not just natural width you are fighting against, but plenty of other aspects like ligation, stacking and reordering (to name a few):

> [@Table style print for 2D Array, Dictionary and Tuples](https://forums.swift.org/t/table-style-print-for-2d-array-dictionary-and-tuples/35121/3):
>
> Text really isn’t suited for faking layout: +------+------------+ |Hebrew|Arabic | +------+------------+ |שלום |السلام عليكم| +------+------------+scream But if you are a stickler for old‐fashioned hacks, then [the actual box‐drawing characters](https://www.unicode.org/charts/PDF/U2500.pdf) will look nicer with any text that does obey their bounds.

---

<div class="post-metadata">

**Author:** ![cukr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cukr/32/889_2.png) [@cukr](https://forums.swift.org/u/cukr)\
**Post date:** [November 12, 2020, 1:23am UTC](https://forums.swift.org/t/find-the-width-of-a-character/41943/3 "2020-11-12T01:23:37Z")

</div>

If you are satisfied with it working with a specific terminal emulator, you can look at their source code, and copy-paste their guesswork. That way your behavior will match. For example iterm2 has a giant list of characters.

> <https://github.com/gnachman/iTerm2/blob/bc3d152d4beb683b4d5f259545d9f96b81ba8076/sources/NSStringITerm.m#L54>

> <https://github.com/gnachman/iTerm2/blob/bc3d152d4beb683b4d5f259545d9f96b81ba8076/sources/NSCharacterSet%2BiTerm.m#L464>

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [November 12, 2020, 3:10am UTC](https://forums.swift.org/t/find-the-width-of-a-character/41943/4 "2020-11-12T03:10:54Z")

</div>

As others said, monospace fonts don't do much between the texts with different [East Asian Width](http://unicode.org/reports/tr11/). Most seem to use different "width" between narrow characters (e.g. basic latin) and half-width characters, so it'd misalign if you mix full-width and narrow characters:

```swift
12345678901234567890| // 20 chars
１２３４５６７８９０１２| // 12 chars and a bit

```

And most terminals don't use duospace fonts (below is Unifont Regular):

![Screen Shot 2563-11-11 at 22.23.01](https://global.discourse-cdn.com/swift/original/2X/8/855f28d76b47b070e3f3982a2bad3e8a5b8e74a1.png)

---

<div class="post-metadata">

**Author:** ![phoneyDev](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@phoneyDev](https://forums.swift.org/u/phoneyDev)\
**Post date:** [November 12, 2020, 11:56pm UTC](https://forums.swift.org/t/find-the-width-of-a-character/41943/5 "2020-11-12T23:56:30Z")

</div>

You don't really mention your use case. `NSAttributedString().size` tells you the dimensions of the string and that's valid on iOS and macOS on the screen in a view. That doesn't work for Terminal output though.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [November 14, 2020, 11:28am UTC](https://forums.swift.org/t/find-the-width-of-a-character/41943/6 "2020-11-14T11:28:10Z")

</div>

Yeah this is a really hard problem.

[This blog post](http://behdad.org/text/) by the maintainer of HarfBuzz gives a good overview of what the various pieces are (e.g. FreeType, HarfBuzz, Pango) and what they do. It's a little bit old but still worth reading if you're curious about this topic. HarfBuzz is like the FOSS alternative of Apple’s CoreText, and is [used by projects](https://en.wikipedia.org/wiki/HarfBuzz) such as Android, Chromium, Gnome, and the PlayStation 4 UI.

It's kind of sad, because text is pretty fundamental for people to be able to work with computers, but it's so complex that you really do need a massive stack of libraries to do it correctly. The [HarfBuzz documentation](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html) does a good job of explaining why things like "text shaping" are necessary and why they are so difficult.
