Add faint, blink, reverse and conceal to the emphases
Picking up the work of @data-man from #2303, since he had to close his PR because of personal matters.

Closes #2302.
{"label": "fmtlib:master", "ref": "master", "sha": "cfc05e05f08dc0b6fe619831c96f00ee27d99613"}
```c++
int main() {
  fmt::print("normal\n");
  fmt::print(fmt::emphasis::bold,             "bold\n");
  fmt::print(fmt::emphasis::faint,            "faint\n");
  fmt::print(fmt::emphasis::italic,           "italic\n");
  fmt::print(fmt::emphasis::underline,        "underline\n");
  fmt::print(fmt::emphasis::blink,            "blink\n");
  fmt::print(fmt::emphasis::invert,           "invert\n");
  fmt::print(fmt::emphasis::conceal,          "conceal\n");
  fmt::print(fmt::emphasis::strikethrough,    "strikethrough\n");
}
```
![ksnip_20210521-185715_myfmtlib](https://user-images.githubusercontent.com/1754269/119149571-144e3680-ba67-11eb-9795-9ea9a913bf7b.png)
Really blinked in a real terminal :)
And the conceal style isn't supported by many terminals.

```diff
diff --git a/include/fmt/color.h b/include/fmt/color.h
index 8cddbfe1..ab7e8dd0 100644
--- a/include/fmt/color.h
+++ b/include/fmt/color.h
@@ -185,9 +185,17 @@ enum class terminal_color : uint8_t {
 
 enum class emphasis : uint8_t {
   bold = 1,
-  italic = 1 << 1,
-  underline = 1 << 2,
-  strikethrough = 1 << 3
+  faint = 1 << 1,
+  dim = faint,
+  italic = 1 << 2,
+  underline = 1 << 3,
+  blink = 1 << 4,
+  slow_blink = blink,
+  reverse = 1 << 5,
+  invert = reverse,
+  conceal = 1 << 6,
+  hide = conceal,
+  strikethrough = 1 << 7,
 };
 
 // rgb is a struct for red, green and blue colors.
@@ -399,7 +407,7 @@ template <typename Char> struct ansi_color_escape {
       return;
     }
 
-    for (int i = 0; i < 7; i++) {
+    for (int i = 0; i < 8; i++) {
       buffer[i] = static_cast<Char>(esc[i]);
     }
     rgb color(text_color.value.rgb_color);
@@ -409,16 +417,19 @@ template <typename Char> struct ansi_color_escape {
     buffer[19] = static_cast<Char>(0);
   }
   FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT {
-    uint8_t em_codes[4] = {};
+    uint8_t em_codes[8] = {};
     uint8_t em_bits = static_cast<uint8_t>(em);
     if (em_bits & static_cast<uint8_t>(emphasis::bold)) em_codes[0] = 1;
-    if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[1] = 3;
-    if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[2] = 4;
-    if (em_bits & static_cast<uint8_t>(emphasis::strikethrough))
-      em_codes[3] = 9;
+    if (em_bits & static_cast<uint8_t>(emphasis::faint)) em_codes[1] = 2;
+    if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[2] = 3;
+    if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[3] = 4;
+    if (em_bits & static_cast<uint8_t>(emphasis::blink)) em_codes[4] = 5;
+    if (em_bits & static_cast<uint8_t>(emphasis::reverse)) em_codes[5] = 7;
+    if (em_bits & static_cast<uint8_t>(emphasis::conceal)) em_codes[6] = 8;
+    if (em_bits & static_cast<uint8_t>(emphasis::strikethrough)) em_codes[7] = 9;

     size_t index = 0;
-    for (int i = 0; i < 4; ++i) {
+    for (int i = 0; i < 8; ++i) {
       if (!em_codes[i]) continue;
       buffer[index++] = static_cast<Char>('\x1b');
       buffer[index++] = static_cast<Char>('[');
@@ -435,7 +446,7 @@ template <typename Char> struct ansi_color_escape {
   }

  private:
-  Char buffer[7u + 3u * 4u + 1u];
+  Char buffer[7u + 3u * 8u + 1u];

   static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
                                    char delimiter) FMT_NOEXCEPT {
```
Add more emphases
diff --git a/include/fmt/color.h b/include/fmt/color.h
index 3d5490e87f40..dfbe482938e7 100644
--- a/include/fmt/color.h
+++ b/include/fmt/color.h
@@ -185,9 +185,13 @@ enum class terminal_color : uint8_t {
 
 enum class emphasis : uint8_t {
   bold = 1,
-  italic = 1 << 1,
-  underline = 1 << 2,
-  strikethrough = 1 << 3
+  faint = 1 << 1,
+  italic = 1 << 2,
+  underline = 1 << 3,
+  blink = 1 << 4,
+  reverse = 1 << 5,
+  conceal = 1 << 6,
+  strikethrough = 1 << 7,
 };
 
 // rgb is a struct for red, green and blue colors.
@@ -409,16 +413,18 @@ template <typename Char> struct ansi_color_escape {
     buffer[19] = static_cast<Char>(0);
   }
   FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT {
-    uint8_t em_codes[4] = {};
-    uint8_t em_bits = static_cast<uint8_t>(em);
-    if (em_bits & static_cast<uint8_t>(emphasis::bold)) em_codes[0] = 1;
-    if (em_bits & static_cast<uint8_t>(emphasis::italic)) em_codes[1] = 3;
-    if (em_bits & static_cast<uint8_t>(emphasis::underline)) em_codes[2] = 4;
-    if (em_bits & static_cast<uint8_t>(emphasis::strikethrough))
-      em_codes[3] = 9;
+    uint8_t em_codes[num_emphases] = {};
+    if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1;
+    if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2;
+    if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3;
+    if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4;
+    if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5;
+    if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7;
+    if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8;
+    if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9;
 
     size_t index = 0;
-    for (int i = 0; i < 4; ++i) {
+    for (size_t i = 0; i < num_emphases; ++i) {
       if (!em_codes[i]) continue;
       buffer[index++] = static_cast<Char>('\x1b');
       buffer[index++] = static_cast<Char>('[');
@@ -435,7 +441,8 @@ template <typename Char> struct ansi_color_escape {
   }
 
  private:
-  Char buffer[7u + 3u * 4u + 1u];
+  static constexpr size_t num_emphases = 8;
+  Char buffer[7u + 3u * num_emphases + 1u];
 
   static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
                                    char delimiter) FMT_NOEXCEPT {
@@ -444,6 +451,10 @@ template <typename Char> struct ansi_color_escape {
     out[2] = static_cast<Char>('0' + c % 10);
     out[3] = static_cast<Char>(delimiter);
   }
+  static FMT_CONSTEXPR bool has_emphasis(emphasis em,
+                                         emphasis mask) FMT_NOEXCEPT {
+    return static_cast<uint8_t>(em) & static_cast<uint8_t>(mask);
+  }
 };
 
 template <typename Char>

diff --git a/test/color-test.cc b/test/color-test.cc
index e2408ca1d940..af8f14942603 100644
--- a/test/color-test.cc
+++ b/test/color-test.cc
@@ -20,10 +20,16 @@ TEST(color_test, format) {
       fmt::format(fg(fmt::color::blue) | bg(fmt::color::red), "two color"),
       "\x1b[38;2;000;000;255m\x1b[48;2;255;000;000mtwo color\x1b[0m");
   EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold"), "\x1b[1mbold\x1b[0m");
+  EXPECT_EQ(fmt::format(fmt::emphasis::faint, "faint"), "\x1b[2mfaint\x1b[0m");
   EXPECT_EQ(fmt::format(fmt::emphasis::italic, "italic"),
             "\x1b[3mitalic\x1b[0m");
   EXPECT_EQ(fmt::format(fmt::emphasis::underline, "underline"),
             "\x1b[4munderline\x1b[0m");
+  EXPECT_EQ(fmt::format(fmt::emphasis::blink, "blink"), "\x1b[5mblink\x1b[0m");
+  EXPECT_EQ(fmt::format(fmt::emphasis::reverse, "reverse"),
+            "\x1b[7mreverse\x1b[0m");
+  EXPECT_EQ(fmt::format(fmt::emphasis::conceal, "conceal"),
+            "\x1b[8mconceal\x1b[0m");
   EXPECT_EQ(fmt::format(fmt::emphasis::strikethrough, "strikethrough"),
             "\x1b[9mstrikethrough\x1b[0m");
   EXPECT_EQ(

{"compile-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ostream-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ranges-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "core-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "scan-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "color-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "chrono-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "args-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "gtest-extra-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "unicode-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "assert-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "posix-mock-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "printf-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "enforce-checks-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-impl-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "os-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "xchar-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"compile-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ostream-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "ranges-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "core-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "scan-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "color-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "chrono-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "args-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "gtest-extra-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "unicode-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "assert-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "posix-mock-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "printf-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "enforce-checks-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "format-impl-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "os-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "xchar-test": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"passed_count": 18, "failed_count": 0, "skipped_count": 0, "passed_tests": ["xchar-test", "format-test", "args-test", "gtest-extra-test", "compile-test", "ostream-test", "ranges-test", "assert-test", "unicode-test", "posix-mock-test", "core-test", "printf-test", "color-test", "scan-test", "format-impl-test", "enforce-checks-test", "os-test", "chrono-test"], "failed_tests": [], "skipped_tests": []}
{"passed_count": 0, "failed_count": 0, "skipped_count": 0, "passed_tests": [], "failed_tests": [], "skipped_tests": []}
{"passed_count": 18, "failed_count": 0, "skipped_count": 0, "passed_tests": ["xchar-test", "format-test", "args-test", "gtest-extra-test", "compile-test", "ostream-test", "ranges-test", "assert-test", "unicode-test", "posix-mock-test", "core-test", "printf-test", "color-test", "scan-test", "format-impl-test", "enforce-checks-test", "os-test", "chrono-test"], "failed_tests": [], "skipped_tests": []}