Terminal: Certain "emoji" are still half-sized

Created on 19 May 2019  ยท  17Comments  ยท  Source: microsoft/terminal

Environment

Windows build number: 10.0.18899.1000
Windows Terminal version: 0.1.1361.0

Steps to reproduce

Setup a standard PowerLine using FiraCode in WSL(2) and navigate to a git repository that contains edits. Note if you
printf 'โœ' that the pencil is double the size of the one in the Powerline prompt.

image

Expected behavior

I expect emojis in the prompt to appear at the same size as those later in the same line.

Actual behavior

emoji size appears to be halved? See pic.

Area-Rendering Issue-Bug Priority-2 Product-Terminal Resolution-Fix-Committed v1-Scrubbed

Most helpful comment

Fascinating! I think we're doing this _technically_ right, but it doesn't turn out looking right.

According to Unicode, \u270E (LOWER RIGHT PENCIL) is not supposed to be an Emoji. It's not in any of the tables . . . so the real issue here is that we here at Microsoft gave it a glyph and made it one.

image

All 17 comments

Fascinating! I think we're doing this _technically_ right, but it doesn't turn out looking right.

According to Unicode, \u270E (LOWER RIGHT PENCIL) is not supposed to be an Emoji. It's not in any of the tables . . . so the real issue here is that we here at Microsoft gave it a glyph and made it one.

image

๐Ÿ›  is Also

ๆ‰นๆณจ 2019-05-20 202131

Seems kinda similar to #455 and maybe #714

Maybe ๐Ÿ•ท Spider also ? (Store Version v0.2.1715.0)

image

This issue may be related to https://github.com/microsoft/terminal/blob/master/src/types/CodepointWidthDetector.cpp. The width obtained by emoji ๐Ÿ›  (\U0001F6E0) is actually 1.

In this project https://github.com/fumiyas/wcwidth-cjk , the open emoji detection width is 2.

////
// https://github.com/microsoft/terminal/blob/734fc1dcc6de4315d4cc91944c5ea83b7b8a7e1a/src/types/CodepointWidthDetector.cpp
#include <iterator>
#include <algorithm>
#include <array>

namespace unicode {
enum class CodepointWidth : uint8_t {
  Narrow,
  Wide,
  Ambiguous, // could be narrow or wide depending on the current codepage and
             // font
  Invalid    // not a valid unicode codepoint
};

// used to store range data in CodepointWidthDetector's internal map
struct UnicodeRange final {
  unsigned int lowerBound;
  unsigned int upperBound;
  CodepointWidth width;
};

static bool operator<(const UnicodeRange &range,
                      const unsigned int searchTerm) {
  return range.upperBound < searchTerm;
}

static constexpr std::array<UnicodeRange, 285> s_wideAndAmbiguousTable{
    // generated from
    // http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt
    // anything not present here is presumed to be Narrow.
    UnicodeRange{0xa1, 0xa1, CodepointWidth::Ambiguous},
    UnicodeRange{0xa4, 0xa4, CodepointWidth::Ambiguous},
    UnicodeRange{0xa7, 0xa8, CodepointWidth::Ambiguous},
    UnicodeRange{0xaa, 0xaa, CodepointWidth::Ambiguous},
    UnicodeRange{0xad, 0xae, CodepointWidth::Ambiguous},
    UnicodeRange{0xb0, 0xb4, CodepointWidth::Ambiguous},
    UnicodeRange{0xb6, 0xba, CodepointWidth::Ambiguous},
    UnicodeRange{0xbc, 0xbf, CodepointWidth::Ambiguous},
    UnicodeRange{0xc6, 0xc6, CodepointWidth::Ambiguous},
    UnicodeRange{0xd0, 0xd0, CodepointWidth::Ambiguous},
    UnicodeRange{0xd7, 0xd8, CodepointWidth::Ambiguous},
    UnicodeRange{0xde, 0xe1, CodepointWidth::Ambiguous},
    UnicodeRange{0xe6, 0xe6, CodepointWidth::Ambiguous},
    UnicodeRange{0xe8, 0xea, CodepointWidth::Ambiguous},
    UnicodeRange{0xec, 0xed, CodepointWidth::Ambiguous},
    UnicodeRange{0xf0, 0xf0, CodepointWidth::Ambiguous},
    UnicodeRange{0xf2, 0xf3, CodepointWidth::Ambiguous},
    UnicodeRange{0xf7, 0xfa, CodepointWidth::Ambiguous},
    UnicodeRange{0xfc, 0xfc, CodepointWidth::Ambiguous},
    UnicodeRange{0xfe, 0xfe, CodepointWidth::Ambiguous},
    UnicodeRange{0x101, 0x101, CodepointWidth::Ambiguous},
    UnicodeRange{0x111, 0x111, CodepointWidth::Ambiguous},
    UnicodeRange{0x113, 0x113, CodepointWidth::Ambiguous},
    UnicodeRange{0x11b, 0x11b, CodepointWidth::Ambiguous},
    UnicodeRange{0x126, 0x127, CodepointWidth::Ambiguous},
    UnicodeRange{0x12b, 0x12b, CodepointWidth::Ambiguous},
    UnicodeRange{0x131, 0x133, CodepointWidth::Ambiguous},
    UnicodeRange{0x138, 0x138, CodepointWidth::Ambiguous},
    UnicodeRange{0x13f, 0x142, CodepointWidth::Ambiguous},
    UnicodeRange{0x144, 0x144, CodepointWidth::Ambiguous},
    UnicodeRange{0x148, 0x14b, CodepointWidth::Ambiguous},
    UnicodeRange{0x14d, 0x14d, CodepointWidth::Ambiguous},
    UnicodeRange{0x152, 0x153, CodepointWidth::Ambiguous},
    UnicodeRange{0x166, 0x167, CodepointWidth::Ambiguous},
    UnicodeRange{0x16b, 0x16b, CodepointWidth::Ambiguous},
    UnicodeRange{0x1ce, 0x1ce, CodepointWidth::Ambiguous},
    UnicodeRange{0x1d0, 0x1d0, CodepointWidth::Ambiguous},
    UnicodeRange{0x1d2, 0x1d2, CodepointWidth::Ambiguous},
    UnicodeRange{0x1d4, 0x1d4, CodepointWidth::Ambiguous},
    UnicodeRange{0x1d6, 0x1d6, CodepointWidth::Ambiguous},
    UnicodeRange{0x1d8, 0x1d8, CodepointWidth::Ambiguous},
    UnicodeRange{0x1da, 0x1da, CodepointWidth::Ambiguous},
    UnicodeRange{0x1dc, 0x1dc, CodepointWidth::Ambiguous},
    UnicodeRange{0x251, 0x251, CodepointWidth::Ambiguous},
    UnicodeRange{0x261, 0x261, CodepointWidth::Ambiguous},
    UnicodeRange{0x2c4, 0x2c4, CodepointWidth::Ambiguous},
    UnicodeRange{0x2c7, 0x2c7, CodepointWidth::Ambiguous},
    UnicodeRange{0x2c9, 0x2cb, CodepointWidth::Ambiguous},
    UnicodeRange{0x2cd, 0x2cd, CodepointWidth::Ambiguous},
    UnicodeRange{0x2d0, 0x2d0, CodepointWidth::Ambiguous},
    UnicodeRange{0x2d8, 0x2db, CodepointWidth::Ambiguous},
    UnicodeRange{0x2dd, 0x2dd, CodepointWidth::Ambiguous},
    UnicodeRange{0x2df, 0x2df, CodepointWidth::Ambiguous},
    UnicodeRange{0x300, 0x36f, CodepointWidth::Ambiguous},
    UnicodeRange{0x391, 0x3a1, CodepointWidth::Ambiguous},
    UnicodeRange{0x3a3, 0x3a9, CodepointWidth::Ambiguous},
    UnicodeRange{0x3b1, 0x3c1, CodepointWidth::Ambiguous},
    UnicodeRange{0x3c3, 0x3c9, CodepointWidth::Ambiguous},
    UnicodeRange{0x401, 0x401, CodepointWidth::Ambiguous},
    UnicodeRange{0x410, 0x44f, CodepointWidth::Ambiguous},
    UnicodeRange{0x451, 0x451, CodepointWidth::Ambiguous},
    UnicodeRange{0x1100, 0x115f, CodepointWidth::Wide},
    UnicodeRange{0x2010, 0x2010, CodepointWidth::Ambiguous},
    UnicodeRange{0x2013, 0x2016, CodepointWidth::Ambiguous},
    UnicodeRange{0x2018, 0x2019, CodepointWidth::Ambiguous},
    UnicodeRange{0x201c, 0x201d, CodepointWidth::Ambiguous},
    UnicodeRange{0x2020, 0x2022, CodepointWidth::Ambiguous},
    UnicodeRange{0x2024, 0x2027, CodepointWidth::Ambiguous},
    UnicodeRange{0x2030, 0x2030, CodepointWidth::Ambiguous},
    UnicodeRange{0x2032, 0x2033, CodepointWidth::Ambiguous},
    UnicodeRange{0x2035, 0x2035, CodepointWidth::Ambiguous},
    UnicodeRange{0x203b, 0x203b, CodepointWidth::Ambiguous},
    UnicodeRange{0x203e, 0x203e, CodepointWidth::Ambiguous},
    UnicodeRange{0x2074, 0x2074, CodepointWidth::Ambiguous},
    UnicodeRange{0x207f, 0x207f, CodepointWidth::Ambiguous},
    UnicodeRange{0x2081, 0x2084, CodepointWidth::Ambiguous},
    UnicodeRange{0x20ac, 0x20ac, CodepointWidth::Ambiguous},
    UnicodeRange{0x2103, 0x2103, CodepointWidth::Ambiguous},
    UnicodeRange{0x2105, 0x2105, CodepointWidth::Ambiguous},
    UnicodeRange{0x2109, 0x2109, CodepointWidth::Ambiguous},
    UnicodeRange{0x2113, 0x2113, CodepointWidth::Ambiguous},
    UnicodeRange{0x2116, 0x2116, CodepointWidth::Ambiguous},
    UnicodeRange{0x2121, 0x2122, CodepointWidth::Ambiguous},
    UnicodeRange{0x2126, 0x2126, CodepointWidth::Ambiguous},
    UnicodeRange{0x212b, 0x212b, CodepointWidth::Ambiguous},
    UnicodeRange{0x2153, 0x2154, CodepointWidth::Ambiguous},
    UnicodeRange{0x215b, 0x215e, CodepointWidth::Ambiguous},
    UnicodeRange{0x2160, 0x216b, CodepointWidth::Ambiguous},
    UnicodeRange{0x2170, 0x2179, CodepointWidth::Ambiguous},
    UnicodeRange{0x2189, 0x2189, CodepointWidth::Ambiguous},
    UnicodeRange{0x2190, 0x2199, CodepointWidth::Ambiguous},
    UnicodeRange{0x21b8, 0x21b9, CodepointWidth::Ambiguous},
    UnicodeRange{0x21d2, 0x21d2, CodepointWidth::Ambiguous},
    UnicodeRange{0x21d4, 0x21d4, CodepointWidth::Ambiguous},
    UnicodeRange{0x21e7, 0x21e7, CodepointWidth::Ambiguous},
    UnicodeRange{0x2200, 0x2200, CodepointWidth::Ambiguous},
    UnicodeRange{0x2202, 0x2203, CodepointWidth::Ambiguous},
    UnicodeRange{0x2207, 0x2208, CodepointWidth::Ambiguous},
    UnicodeRange{0x220b, 0x220b, CodepointWidth::Ambiguous},
    UnicodeRange{0x220f, 0x220f, CodepointWidth::Ambiguous},
    UnicodeRange{0x2211, 0x2211, CodepointWidth::Ambiguous},
    UnicodeRange{0x2215, 0x2215, CodepointWidth::Ambiguous},
    UnicodeRange{0x221a, 0x221a, CodepointWidth::Ambiguous},
    UnicodeRange{0x221d, 0x2220, CodepointWidth::Ambiguous},
    UnicodeRange{0x2223, 0x2223, CodepointWidth::Ambiguous},
    UnicodeRange{0x2225, 0x2225, CodepointWidth::Ambiguous},
    UnicodeRange{0x2227, 0x222c, CodepointWidth::Ambiguous},
    UnicodeRange{0x222e, 0x222e, CodepointWidth::Ambiguous},
    UnicodeRange{0x2234, 0x2237, CodepointWidth::Ambiguous},
    UnicodeRange{0x223c, 0x223d, CodepointWidth::Ambiguous},
    UnicodeRange{0x2248, 0x2248, CodepointWidth::Ambiguous},
    UnicodeRange{0x224c, 0x224c, CodepointWidth::Ambiguous},
    UnicodeRange{0x2252, 0x2252, CodepointWidth::Ambiguous},
    UnicodeRange{0x2260, 0x2261, CodepointWidth::Ambiguous},
    UnicodeRange{0x2264, 0x2267, CodepointWidth::Ambiguous},
    UnicodeRange{0x226a, 0x226b, CodepointWidth::Ambiguous},
    UnicodeRange{0x226e, 0x226f, CodepointWidth::Ambiguous},
    UnicodeRange{0x2282, 0x2283, CodepointWidth::Ambiguous},
    UnicodeRange{0x2286, 0x2287, CodepointWidth::Ambiguous},
    UnicodeRange{0x2295, 0x2295, CodepointWidth::Ambiguous},
    UnicodeRange{0x2299, 0x2299, CodepointWidth::Ambiguous},
    UnicodeRange{0x22a5, 0x22a5, CodepointWidth::Ambiguous},
    UnicodeRange{0x22bf, 0x22bf, CodepointWidth::Ambiguous},
    UnicodeRange{0x2312, 0x2312, CodepointWidth::Ambiguous},
    UnicodeRange{0x231a, 0x231b, CodepointWidth::Wide},
    UnicodeRange{0x2329, 0x232a, CodepointWidth::Wide},
    UnicodeRange{0x23e9, 0x23ec, CodepointWidth::Wide},
    UnicodeRange{0x23f0, 0x23f0, CodepointWidth::Wide},
    UnicodeRange{0x23f3, 0x23f3, CodepointWidth::Wide},
    UnicodeRange{0x2460, 0x24e9, CodepointWidth::Ambiguous},
    UnicodeRange{0x24eb, 0x254b, CodepointWidth::Ambiguous},
    UnicodeRange{0x2550, 0x2573, CodepointWidth::Ambiguous},
    UnicodeRange{0x2580, 0x258f, CodepointWidth::Ambiguous},
    UnicodeRange{0x2592, 0x2595, CodepointWidth::Ambiguous},
    UnicodeRange{0x25a0, 0x25a1, CodepointWidth::Ambiguous},
    UnicodeRange{0x25a3, 0x25a9, CodepointWidth::Ambiguous},
    UnicodeRange{0x25b2, 0x25b3, CodepointWidth::Ambiguous},
    UnicodeRange{0x25b6, 0x25b7, CodepointWidth::Ambiguous},
    UnicodeRange{0x25bc, 0x25bd, CodepointWidth::Ambiguous},
    UnicodeRange{0x25c0, 0x25c1, CodepointWidth::Ambiguous},
    UnicodeRange{0x25c6, 0x25c8, CodepointWidth::Ambiguous},
    UnicodeRange{0x25cb, 0x25cb, CodepointWidth::Ambiguous},
    UnicodeRange{0x25ce, 0x25d1, CodepointWidth::Ambiguous},
    UnicodeRange{0x25e2, 0x25e5, CodepointWidth::Ambiguous},
    UnicodeRange{0x25ef, 0x25ef, CodepointWidth::Ambiguous},
    UnicodeRange{0x25fd, 0x25fe, CodepointWidth::Wide},
    UnicodeRange{0x2605, 0x2606, CodepointWidth::Ambiguous},
    UnicodeRange{0x2609, 0x2609, CodepointWidth::Ambiguous},
    UnicodeRange{0x260e, 0x260f, CodepointWidth::Ambiguous},
    UnicodeRange{0x2614, 0x2615, CodepointWidth::Wide},
    UnicodeRange{0x261c, 0x261c, CodepointWidth::Ambiguous},
    UnicodeRange{0x261e, 0x261e, CodepointWidth::Ambiguous},
    UnicodeRange{0x2640, 0x2640, CodepointWidth::Ambiguous},
    UnicodeRange{0x2642, 0x2642, CodepointWidth::Ambiguous},
    UnicodeRange{0x2648, 0x2653, CodepointWidth::Wide},
    UnicodeRange{0x2660, 0x2661, CodepointWidth::Ambiguous},
    UnicodeRange{0x2663, 0x2665, CodepointWidth::Ambiguous},
    UnicodeRange{0x2667, 0x266a, CodepointWidth::Ambiguous},
    UnicodeRange{0x266c, 0x266d, CodepointWidth::Ambiguous},
    UnicodeRange{0x266f, 0x266f, CodepointWidth::Ambiguous},
    UnicodeRange{0x267f, 0x267f, CodepointWidth::Wide},
    UnicodeRange{0x2693, 0x2693, CodepointWidth::Wide},
    UnicodeRange{0x269e, 0x269f, CodepointWidth::Ambiguous},
    UnicodeRange{0x26a1, 0x26a1, CodepointWidth::Wide},
    UnicodeRange{0x26aa, 0x26ab, CodepointWidth::Wide},
    UnicodeRange{0x26bd, 0x26be, CodepointWidth::Wide},
    UnicodeRange{0x26bf, 0x26bf, CodepointWidth::Ambiguous},
    UnicodeRange{0x26c4, 0x26c5, CodepointWidth::Wide},
    UnicodeRange{0x26c6, 0x26cd, CodepointWidth::Ambiguous},
    UnicodeRange{0x26ce, 0x26ce, CodepointWidth::Wide},
    UnicodeRange{0x26cf, 0x26d3, CodepointWidth::Ambiguous},
    UnicodeRange{0x26d4, 0x26d4, CodepointWidth::Wide},
    UnicodeRange{0x26d5, 0x26e1, CodepointWidth::Ambiguous},
    UnicodeRange{0x26e3, 0x26e3, CodepointWidth::Ambiguous},
    UnicodeRange{0x26e8, 0x26e9, CodepointWidth::Ambiguous},
    UnicodeRange{0x26ea, 0x26ea, CodepointWidth::Wide},
    UnicodeRange{0x26eb, 0x26f1, CodepointWidth::Ambiguous},
    UnicodeRange{0x26f2, 0x26f3, CodepointWidth::Wide},
    UnicodeRange{0x26f4, 0x26f4, CodepointWidth::Ambiguous},
    UnicodeRange{0x26f5, 0x26f5, CodepointWidth::Wide},
    UnicodeRange{0x26f6, 0x26f9, CodepointWidth::Ambiguous},
    UnicodeRange{0x26fa, 0x26fa, CodepointWidth::Wide},
    UnicodeRange{0x26fb, 0x26fc, CodepointWidth::Ambiguous},
    UnicodeRange{0x26fd, 0x26fd, CodepointWidth::Wide},
    UnicodeRange{0x26fe, 0x26ff, CodepointWidth::Ambiguous},
    UnicodeRange{0x2705, 0x2705, CodepointWidth::Wide},
    UnicodeRange{0x270a, 0x270b, CodepointWidth::Wide},
    UnicodeRange{0x2728, 0x2728, CodepointWidth::Wide},
    UnicodeRange{0x273d, 0x273d, CodepointWidth::Ambiguous},
    UnicodeRange{0x274c, 0x274c, CodepointWidth::Wide},
    UnicodeRange{0x274e, 0x274e, CodepointWidth::Wide},
    UnicodeRange{0x2753, 0x2755, CodepointWidth::Wide},
    UnicodeRange{0x2757, 0x2757, CodepointWidth::Wide},
    UnicodeRange{0x2776, 0x277f, CodepointWidth::Ambiguous},
    UnicodeRange{0x2795, 0x2797, CodepointWidth::Wide},
    UnicodeRange{0x27b0, 0x27b0, CodepointWidth::Wide},
    UnicodeRange{0x27bf, 0x27bf, CodepointWidth::Wide},
    UnicodeRange{0x2b1b, 0x2b1c, CodepointWidth::Wide},
    UnicodeRange{0x2b50, 0x2b50, CodepointWidth::Wide},
    UnicodeRange{0x2b55, 0x2b55, CodepointWidth::Wide},
    UnicodeRange{0x2b56, 0x2b59, CodepointWidth::Ambiguous},
    UnicodeRange{0x2e80, 0x2e99, CodepointWidth::Wide},
    UnicodeRange{0x2e9b, 0x2ef3, CodepointWidth::Wide},
    UnicodeRange{0x2f00, 0x2fd5, CodepointWidth::Wide},
    UnicodeRange{0x2ff0, 0x2ffb, CodepointWidth::Wide},
    UnicodeRange{0x3000, 0x303e, CodepointWidth::Wide},
    UnicodeRange{0x3041, 0x3096, CodepointWidth::Wide},
    UnicodeRange{0x3099, 0x30ff, CodepointWidth::Wide},
    UnicodeRange{0x3105, 0x312e, CodepointWidth::Wide},
    UnicodeRange{0x3131, 0x318e, CodepointWidth::Wide},
    UnicodeRange{0x3190, 0x31ba, CodepointWidth::Wide},
    UnicodeRange{0x31c0, 0x31e3, CodepointWidth::Wide},
    UnicodeRange{0x31f0, 0x321e, CodepointWidth::Wide},
    UnicodeRange{0x3220, 0x3247, CodepointWidth::Wide},
    UnicodeRange{0x3248, 0x324f, CodepointWidth::Ambiguous},
    UnicodeRange{0x3250, 0x32fe, CodepointWidth::Wide},
    UnicodeRange{0x3300, 0x4dbf, CodepointWidth::Wide},
    UnicodeRange{0x4e00, 0xa48c, CodepointWidth::Wide},
    UnicodeRange{0xa490, 0xa4c6, CodepointWidth::Wide},
    UnicodeRange{0xa960, 0xa97c, CodepointWidth::Wide},
    UnicodeRange{0xac00, 0xd7a3, CodepointWidth::Wide},
    UnicodeRange{0xe000, 0xf8ff, CodepointWidth::Ambiguous},
    UnicodeRange{0xf900, 0xfaff, CodepointWidth::Wide},
    UnicodeRange{0xfe00, 0xfe0f, CodepointWidth::Ambiguous},
    UnicodeRange{0xfe10, 0xfe19, CodepointWidth::Wide},
    UnicodeRange{0xfe30, 0xfe52, CodepointWidth::Wide},
    UnicodeRange{0xfe54, 0xfe66, CodepointWidth::Wide},
    UnicodeRange{0xfe68, 0xfe6b, CodepointWidth::Wide},
    UnicodeRange{0xff01, 0xff60, CodepointWidth::Wide},
    UnicodeRange{0xffe0, 0xffe6, CodepointWidth::Wide},
    UnicodeRange{0xfffd, 0xfffd, CodepointWidth::Ambiguous},
    UnicodeRange{0x16fe0, 0x16fe1, CodepointWidth::Wide},
    UnicodeRange{0x17000, 0x187ec, CodepointWidth::Wide},
    UnicodeRange{0x18800, 0x18af2, CodepointWidth::Wide},
    UnicodeRange{0x1b000, 0x1b11e, CodepointWidth::Wide},
    UnicodeRange{0x1b170, 0x1b2fb, CodepointWidth::Wide},
    UnicodeRange{0x1f004, 0x1f004, CodepointWidth::Wide},
    UnicodeRange{0x1f0cf, 0x1f0cf, CodepointWidth::Wide},
    UnicodeRange{0x1f100, 0x1f10a, CodepointWidth::Ambiguous},
    UnicodeRange{0x1f110, 0x1f12d, CodepointWidth::Ambiguous},
    UnicodeRange{0x1f130, 0x1f169, CodepointWidth::Ambiguous},
    UnicodeRange{0x1f170, 0x1f18d, CodepointWidth::Ambiguous},
    UnicodeRange{0x1f18e, 0x1f18e, CodepointWidth::Wide},
    UnicodeRange{0x1f18f, 0x1f190, CodepointWidth::Ambiguous},
    UnicodeRange{0x1f191, 0x1f19a, CodepointWidth::Wide},
    UnicodeRange{0x1f19b, 0x1f1ac, CodepointWidth::Ambiguous},
    UnicodeRange{0x1f200, 0x1f202, CodepointWidth::Wide},
    UnicodeRange{0x1f210, 0x1f23b, CodepointWidth::Wide},
    UnicodeRange{0x1f240, 0x1f248, CodepointWidth::Wide},
    UnicodeRange{0x1f250, 0x1f251, CodepointWidth::Wide},
    UnicodeRange{0x1f260, 0x1f265, CodepointWidth::Wide},
    UnicodeRange{0x1f300, 0x1f320, CodepointWidth::Wide},
    UnicodeRange{0x1f32d, 0x1f335, CodepointWidth::Wide},
    UnicodeRange{0x1f337, 0x1f37c, CodepointWidth::Wide},
    UnicodeRange{0x1f37e, 0x1f393, CodepointWidth::Wide},
    UnicodeRange{0x1f3a0, 0x1f3ca, CodepointWidth::Wide},
    UnicodeRange{0x1f3cf, 0x1f3d3, CodepointWidth::Wide},
    UnicodeRange{0x1f3e0, 0x1f3f0, CodepointWidth::Wide},
    UnicodeRange{0x1f3f4, 0x1f3f4, CodepointWidth::Wide},
    UnicodeRange{0x1f3f8, 0x1f43e, CodepointWidth::Wide},
    UnicodeRange{0x1f440, 0x1f440, CodepointWidth::Wide},
    UnicodeRange{0x1f442, 0x1f4fc, CodepointWidth::Wide},
    UnicodeRange{0x1f4ff, 0x1f53d, CodepointWidth::Wide},
    UnicodeRange{0x1f54b, 0x1f54e, CodepointWidth::Wide},
    UnicodeRange{0x1f550, 0x1f567, CodepointWidth::Wide},
    UnicodeRange{0x1f57a, 0x1f57a, CodepointWidth::Wide},
    UnicodeRange{0x1f595, 0x1f596, CodepointWidth::Wide},
    UnicodeRange{0x1f5a4, 0x1f5a4, CodepointWidth::Wide},
    UnicodeRange{0x1f5fb, 0x1f64f, CodepointWidth::Wide},
    UnicodeRange{0x1f680, 0x1f6c5, CodepointWidth::Wide},
    UnicodeRange{0x1f6cc, 0x1f6cc, CodepointWidth::Wide},
    UnicodeRange{0x1f6d0, 0x1f6d2, CodepointWidth::Wide},
    UnicodeRange{0x1f6eb, 0x1f6ec, CodepointWidth::Wide},
    UnicodeRange{0x1f6f4, 0x1f6f8, CodepointWidth::Wide},
    UnicodeRange{0x1f910, 0x1f93e, CodepointWidth::Wide},
    UnicodeRange{0x1f940, 0x1f94c, CodepointWidth::Wide},
    UnicodeRange{0x1f950, 0x1f96b, CodepointWidth::Wide},
    UnicodeRange{0x1f980, 0x1f997, CodepointWidth::Wide},
    UnicodeRange{0x1f9c0, 0x1f9c0, CodepointWidth::Wide},
    UnicodeRange{0x1f9d0, 0x1f9e6, CodepointWidth::Wide},
    UnicodeRange{0x20000, 0x2fffd, CodepointWidth::Wide},
    UnicodeRange{0x30000, 0x3fffd, CodepointWidth::Wide},
    UnicodeRange{0xe0100, 0xe01ef, CodepointWidth::Ambiguous},
    UnicodeRange{0xf0000, 0xffffd, CodepointWidth::Ambiguous},
    UnicodeRange{0x100000, 0x10fffd, CodepointWidth::Ambiguous}};

size_t CalculateWidthInternal(char32_t rune) {
  const auto it = std::lower_bound(s_wideAndAmbiguousTable.begin(),
                                   s_wideAndAmbiguousTable.end(), rune);

  // For characters that are not _in_ the table, lower_bound will return the
  // nearest item that is. We must check its bounds to make sure that our hit
  // was a true hit.
  if (it != s_wideAndAmbiguousTable.end() && rune >= it->lowerBound &&
      rune <= it->upperBound) {
    switch (it->width) {
    case CodepointWidth::Ambiguous:
      return 0;
    case CodepointWidth::Wide:
      return 2;
    case CodepointWidth::Narrow:
      return 1;
    default:
      break;
    }
    return 0;
  }
  return 1;
}

} // namespace unicode

It's... slightly more complicated than that. In addition to the table laid out in UCD EastAsianWidth 12.0, which expressly avoids specifying Emoji, there's the Emoji 12.0 table. That specifies which characters are _emoji_, but we can't just import that table as-is. It specifies a lot of things that _aren't_ emoji as being emoji.

Like this:

0023          ; Emoji                #  1.1  [1] (#๏ธ)       number sign

If we ingest this table as is, we'll look even more wrong than we already are.

@DHowett-MSFT After testing, I found that I only need to add an emoji_width table and add the missing emoji symbols to this table to get these emoji widths correctly.

(Some emoji display different widths in different fonts.)

The unicode interval to be supplemented is as follows:

struct interval {
  char32_t first;
  char32_t last;
};
constexpr const interval emoji_width[] = {
      {0x2194, 0x2199},
      {0x21A9, 0x21AA},
      {0x231A, 0x231B},
      {0x2328, 0x2328},
      {0x23CF, 0x23CF},
      {0x23E9, 0x23F3},
      {0x23F8, 0x23FA},
      {0x24C2, 0x24C2},
      {0x25AA, 0x25AB},
      {0x25B6, 0x25B6},
      {0x25C0, 0x25C0},
      {0x25FB, 0x25FE},
      // u2600~u27BF // fast check
      {0x2600, 0x27BF},
      //---
      {0x2934, 0x2935},
      {0x2B05, 0x2B07},
      {0x2B1B, 0x2B1C},
      {0x2B50, 0x2B50},
      {0x2B55, 0x2B55},
      {0x3030, 0x3030},
      {0x3297, 0x3297},
      {0x3299, 0x3299},
      // 0x1F004 0x1F0CF ... unicode double width 2
      {0x1F300, 0x1F64F},
      {0x1F680, 0x1F6FF},
      {0x1F900, 0x1F9FF},
  };
\U00000023 width: 1 #
\U0000002A width: 1 *
\U00000030 width: 1 0
\U000032FF width: 2 ใ‹ฟ
\U000000A9 width: 1 ยฉ
\U000000AE width: 1 ยฎ
\U00002934 width: 2 โคด
\U0001F600 width: 2 ๐Ÿ˜€
\U0000203C width: 1 โ€ผ
\U00002194 width: 2 โ†”
\U00002122 width: 1 โ„ข
\U0001F603 width: 2 ๐Ÿ˜ƒ
\U0001F496 width: 2 ๐Ÿ’–
\U0001F499 width: 2 ๐Ÿ’™
\U0001F92A width: 2 ๐Ÿคช
\U00004E2D width: 2 ไธญ
\U000025B6 width: 2 โ–ถ
\U00002600 width: 2 โ˜€
\U000000A1 width: 1 ยก
\U0001F6E0 width: 2 ๐Ÿ› 
\U0000231A width: 2 โŒš
\U0000231B width: 2 โŒ›
\U00002328 width: 2 โŒจ
\U000023CF width: 2 โ
\U0000FE6F width: 2 ๏นฏ
\U0001F004 width: 2 ๐Ÿ€„
\U0001F0CF width: 2 ๐Ÿƒ
\U0000270F width: 2 โœ
\U0001F577 width: 2 ๐Ÿ•ท

@miniksa So definitely all the ZWJ emojis that force a "character" to an emoji render are affected, as mentioned probably because it's jamming two characters into one width, hence why the emoji comes out small. Spider (U+1F577๏ธ U+FE0F) previously being mentioned as an example.

So detecting a vs16 and adjusting the character width based on the number of following characters would do it, is that part of the #2928 PR?

This has been driving me crazy, I thought it was something I was doing wrong

For example. the cloud glyph I've added to my prompt, is tiny
image
but in the vs code terminal it's fine
image

@benc-uk yep, it's because the actual icon is two characters, a "standard" cloud character, and then a ZWJ character which tells the terminal to "force" it to emoji style rather than the character style.

VSCode uses xterm internally and it knows how to interpret that (though it has other spacing issues). Windows Terminal currently only sees it as "one character" in terms of width, so that's why it's half-sized.

@JustinGrote, @benc-uk, we just haven't put in any sort of ZWJ support yet at all. I plan to get to it in #1472 probably which I haven't been able to book yet because other priorities keep bumping it down my list.

@miniksa thanks for your hard work, obviously operational issues trump cosmetic ones :). Its just unfortunate so many emojis are common with another character and use the ZWJ for presentation, so the scope of them are limited, and with more build/test tools using emojis to indicate success, it is more and more of an issue :)

Also seeing tiny emojis, thought it was DPI related but could be related to this issue. โœ…โš ๏ธโŒ๐Ÿ”ฅ are the emoji's in our test results and devops scripts, so slightly higher priority for us.

I also wanted to give kudos to the engineering and design efforts steering a giant legacy ship while improving terminal and emoji support. To us, as long as VSCode and the new terminal can sort this out, we're all set.

On a side note, it's kinda fun to see the inconsistent emoji behavior on Windows 10 v1909 (released just now). It's like a digital anachronistic circus-show with the legacy terminals thrown in :) .. here is a screenshot for the morbidly curious!

2019-12-13 11_45_12-Windows PowerShell

:tada:This issue was addressed in #5795, which has now been successfully released as Windows Terminal Release Candidate v0.11.1333.0 (1.0rc2).:tada:

Handy links:

Hey I was linked here from 4747, I made a post back in late April asking if there was a way I could revert the glyph scaling.. I was pretty hopeful when I saw came across the post again

I followed the link above to the store and downloaded the recent version. (I dont know if it helps or not but I am on the win10 slow ring?). nyway things to note:

pros

  • powerline Glyph rendering issues are gone, no longer are the tips of my prompt mismatched.

cons

  • I dont see any diference in terms of scaling.

I bounce between a few monospaced fonts customized with the devicon/font-awesome/powerline font type packages. At first I thouhgt all I had to do was simply find a sweet spot for the glyphs, and believe me I tried to cheat the system with my own font builds before I gave up and moved on.. Anyway I digress,

Some of the BASIC wingdings and things like the check marks, and other glyphss which maintain similar advances to the main font chars dont appear to be affected all that much.

Heres an example of how extreme the scaling can be is:

https://i.imgur.com/nzdWrK9.png.

moved away towards hyper because of the customization it provides and kind of forgot about win term, until the other day. Its actually such a clean experience, my ONLY gripes are the tabs being massive and the font issue and I guess take my fonts pretty seriously so its something I do care about although I know not everyone does... . I can live without full blown UI customizatiions abd what have you but the display gotta be good.

(and for the record, it is super crisp. I REALLY like what has been done)

(just give me my full width glyphs)

So, icon fonts occupy codepoints that are reserved in all versions of Unicode and _do not have the "wide glyph" or "emoji presentation" flags set._ The best we can do going forward is to render them over two cells (spill) and let the righthand cell destroy the right half of the spillover.

Folks who take fonts seriously should attempt to get those glyph width changes made standard ๐Ÿ˜‰ until then, it's an absolute crapshoot. More info at https://github.com/microsoft/terminal/issues/5095#issuecomment-619186373 (closed).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dev-logan picture dev-logan  ยท  3Comments

ghost picture ghost  ยท  3Comments

waf picture waf  ยท  3Comments

TayYuanGeng picture TayYuanGeng  ยท  3Comments

ghvanderweg picture ghvanderweg  ยท  3Comments