Color.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include <AK/Assertions.h>
  2. #include <LibDraw/Color.h>
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. Color::Color(NamedColor named)
  6. {
  7. struct {
  8. u8 r;
  9. u8 g;
  10. u8 b;
  11. } rgb;
  12. switch (named) {
  13. case Black:
  14. rgb = { 0, 0, 0 };
  15. break;
  16. case White:
  17. rgb = { 255, 255, 255 };
  18. break;
  19. case Red:
  20. rgb = { 255, 0, 0 };
  21. break;
  22. case Green:
  23. rgb = { 0, 255, 0 };
  24. break;
  25. case Cyan:
  26. rgb = { 0, 255, 255 };
  27. break;
  28. case Blue:
  29. rgb = { 0, 0, 255 };
  30. break;
  31. case Yellow:
  32. rgb = { 255, 255, 0 };
  33. break;
  34. case Magenta:
  35. rgb = { 255, 0, 255 };
  36. break;
  37. case DarkGray:
  38. rgb = { 64, 64, 64 };
  39. break;
  40. case MidGray:
  41. rgb = { 127, 127, 127 };
  42. break;
  43. case LightGray:
  44. rgb = { 192, 192, 192 };
  45. break;
  46. case MidGreen:
  47. rgb = { 0, 192, 0 };
  48. break;
  49. case MidBlue:
  50. rgb = { 0, 0, 192 };
  51. break;
  52. case MidRed:
  53. rgb = { 192, 0, 0 };
  54. break;
  55. case MidMagenta:
  56. rgb = { 192, 0, 192 };
  57. break;
  58. case DarkGreen:
  59. rgb = { 0, 128, 0 };
  60. break;
  61. case DarkBlue:
  62. rgb = { 0, 0, 128 };
  63. break;
  64. case DarkRed:
  65. rgb = { 128, 0, 0 };
  66. break;
  67. case WarmGray:
  68. rgb = { 212, 208, 200 };
  69. break;
  70. default:
  71. ASSERT_NOT_REACHED();
  72. break;
  73. }
  74. m_value = 0xff000000 | (rgb.r << 16) | (rgb.g << 8) | rgb.b;
  75. }
  76. String Color::to_string() const
  77. {
  78. return String::format("#%b%b%b%b", red(), green(), blue(), alpha());
  79. }
  80. Optional<Color> Color::from_string(const StringView& string)
  81. {
  82. if (string.is_empty())
  83. return {};
  84. if (string[0] != '#')
  85. return {};
  86. if (string.length() != 7 && string.length() != 9)
  87. return {};
  88. auto hex_nibble_to_u8 = [](char nibble) -> Optional<u8> {
  89. if (!isxdigit(nibble))
  90. return {};
  91. if (nibble >= '0' && nibble <= '9')
  92. return nibble - '0';
  93. return 10 + (tolower(nibble) - 'a');
  94. };
  95. auto to_hex = [&](char c1, char c2) -> Optional<u8> {
  96. auto nib1 = hex_nibble_to_u8(c1);
  97. auto nib2 = hex_nibble_to_u8(c2);
  98. if (!nib1.has_value() || !nib2.has_value())
  99. return {};
  100. return nib1.value() << 4 | nib2.value();
  101. };
  102. Optional<u8> r = to_hex(string[1], string[2]);
  103. Optional<u8> g = to_hex(string[3], string[4]);
  104. Optional<u8> b = to_hex(string[5], string[6]);
  105. Optional<u8> a = string.length() == 9 ? to_hex(string[7], string[8]) : Optional<u8>(255);
  106. if (!r.has_value() || !g.has_value() || !b.has_value() || !a.has_value())
  107. return {};
  108. return Color(r.value(), g.value(), b.value(), a.value());
  109. }