diff --git a/docs/BUILD.gn b/docs/BUILD.gn index f6a2091ea6..509229d413 100644 --- a/docs/BUILD.gn +++ b/docs/BUILD.gn @@ -233,6 +233,7 @@ _doxygen_input_files = [ # keep-sorted: start "$dir_pw_crypto/public/pw_crypto/sha256.h", "$dir_pw_digital_io/public/pw_digital_io/digital_io.h", "$dir_pw_digital_io/public/pw_digital_io/digital_io_mock.h", + "$dir_pw_display/public/pw_display/color.h", "$dir_pw_function/public/pw_function/function.h", "$dir_pw_function/public/pw_function/pointer.h", "$dir_pw_function/public/pw_function/scope_guard.h", diff --git a/pw_display/BUILD.bazel b/pw_display/BUILD.bazel index e3ed04fe68..bc7f22883f 100644 --- a/pw_display/BUILD.bazel +++ b/pw_display/BUILD.bazel @@ -12,6 +12,27 @@ # License for the specific language governing permissions and limitations under # the License. +load( + "@pigweed//pw_build:pigweed.bzl", + "pw_cc_test", +) + package(default_visibility = ["//visibility:public"]) licenses(["notice"]) + +cc_library( + name = "color", + hdrs = [ + "public/pw_display/color.h", + "public/pw_display/colors_endesga64.h", + "public/pw_display/colors_pico8.h", + ], + includes = ["public"], +) + +pw_cc_test( + name = "color_test", + srcs = ["color_test.cc"], + deps = [":color"], +) diff --git a/pw_display/BUILD.gn b/pw_display/BUILD.gn index 54b0f34784..cd2082cea0 100644 --- a/pw_display/BUILD.gn +++ b/pw_display/BUILD.gn @@ -19,10 +19,31 @@ import("$dir_pw_docgen/docs.gni") import("$dir_pw_sync/backend.gni") import("$dir_pw_unit_test/test.gni") +config("public_include_path") { + include_dirs = [ "public" ] +} + +pw_source_set("color") { + public_configs = [ ":public_include_path" ] + public = [ + "public/pw_display/color.h", + "public/pw_display/colors_endesga64.h", + "public/pw_display/colors_pico8.h", + ] +} + +pw_test("color_test") { + deps = [ ":color" ] + sources = [ "color_test.cc" ] +} + pw_test_group("tests") { - tests = [] + tests = [ ":color_test" ] } pw_doc_group("docs") { - sources = [ "docs.rst" ] + sources = [ + "api.rst", + "docs.rst", + ] } diff --git a/pw_display/CMakeLists.txt b/pw_display/CMakeLists.txt index aae99b7e4e..995a2a7429 100644 --- a/pw_display/CMakeLists.txt +++ b/pw_display/CMakeLists.txt @@ -13,3 +13,22 @@ # the License. include($ENV{PW_ROOT}/pw_build/pigweed.cmake) + +pw_add_library(pw_display.color INTERFACE + HEADERS + public/pw_display/color.h + public/pw_display/colors_endesga64.h + public/pw_display/colors_pico8.h + PUBLIC_INCLUDES + public +) + +pw_add_test(pw_display.color_test + SOURCES + color_test.cc + PRIVATE_DEPS + pw_display.color + GROUPS + modules + pw_display +) diff --git a/pw_display/api.rst b/pw_display/api.rst new file mode 100644 index 0000000000..7de54bd7af --- /dev/null +++ b/pw_display/api.rst @@ -0,0 +1,363 @@ +.. _module-pw_display-api: + +============= +API reference +============= +.. pigweed-module-subpage:: + :name: pw_display + +.. _module-pw_display-api-color: + +--------- +Color API +--------- +.. doxygengroup:: pw_display_color + :members: + +--------------- +Color Constants +--------------- + +.. role:: raw-html(raw) + :format: html + +``pw_display/colors_pico8.h`` +============================= +.. list-table:: + :widths: 40 40 20 + :header-rows: 1 + + * - Constant + - Color + - Hex Value + * - ``pw::display::colors::rgb565::pico8::kBlack`` + - :raw-html:`Black` + - ``#000000`` + * - ``pw::display::colors::rgb565::pico8::kDarkBlue`` + - :raw-html:`Dark blue` + - ``#1d2b53`` + * - ``pw::display::colors::rgb565::pico8::kDarkPurple`` + - :raw-html:`Dark purple` + - ``#7e2553`` + * - ``pw::display::colors::rgb565::pico8::kDarkGreen`` + - :raw-html:`Dark green` + - ``#008751`` + * - ``pw::display::colors::rgb565::pico8::kBrown`` + - :raw-html:`Brown` + - ``#ab5236`` + * - ``pw::display::colors::rgb565::pico8::kDarkGray`` + - :raw-html:`Dark gray` + - ``#5f574f`` + * - ``pw::display::colors::rgb565::pico8::kLightGray`` + - :raw-html:`Light gray` + - ``#c2c3c7`` + * - ``pw::display::colors::rgb565::pico8::kWhite`` + - :raw-html:`White` + - ``#fff1e8`` + * - ``pw::display::colors::rgb565::pico8::kRed`` + - :raw-html:`Red` + - ``#ff004d`` + * - ``pw::display::colors::rgb565::pico8::kOrange`` + - :raw-html:`Orange` + - ``#ffa300`` + * - ``pw::display::colors::rgb565::pico8::kYellow`` + - :raw-html:`Yellow` + - ``#ffec27`` + * - ``pw::display::colors::rgb565::pico8::kGreen`` + - :raw-html:`Green` + - ``#00e436`` + * - ``pw::display::colors::rgb565::pico8::kBlue`` + - :raw-html:`Blue` + - ``#29adff`` + * - ``pw::display::colors::rgb565::pico8::kIndigo`` + - :raw-html:`Indigo` + - ``#83769c`` + * - ``pw::display::colors::rgb565::pico8::kPink`` + - :raw-html:`Pink` + - ``#ff77a8`` + * - ``pw::display::colors::rgb565::pico8::kPeach`` + - :raw-html:`Peach` + - ``#ffccaa`` + +``pw_display/colors_endesga64.h`` +================================= +.. list-table:: + :widths: 40 40 20 + :header-rows: 1 + + * - Constant + - Color + - Hex Value + + * - ``pw::display::colors::rgb565::e64::kBlood`` + - :raw-html:` ` + - ``#ff0040`` + * - ``pw::display::colors::rgb565::e64::kBlack0`` + - :raw-html:` ` + - ``#131313`` + * - ``pw::display::colors::rgb565::e64::kBlack1`` + - :raw-html:` ` + - ``#1b1b1b`` + * - ``pw::display::colors::rgb565::e64::kGray0`` + - :raw-html:` ` + - ``#272727`` + * - ``pw::display::colors::rgb565::e64::kGray1`` + - :raw-html:` ` + - ``#3d3d3d`` + * - ``pw::display::colors::rgb565::e64::kGray2`` + - :raw-html:` ` + - ``#5d5d5d`` + * - ``pw::display::colors::rgb565::e64::kGray3`` + - :raw-html:` ` + - ``#858585`` + * - ``pw::display::colors::rgb565::e64::kGray4`` + - :raw-html:` ` + - ``#b4b4b4`` + * - ``pw::display::colors::rgb565::e64::kWhite`` + - :raw-html:` ` + - ``#ffffff`` + * - ``pw::display::colors::rgb565::e64::kSteel6`` + - :raw-html:` ` + - ``#c7cfdd`` + * - ``pw::display::colors::rgb565::e64::kSteel5`` + - :raw-html:` ` + - ``#92a1b9`` + * - ``pw::display::colors::rgb565::e64::kSteel4`` + - :raw-html:` ` + - ``#657392`` + * - ``pw::display::colors::rgb565::e64::kSteel3`` + - :raw-html:` ` + - ``#424c6e`` + * - ``pw::display::colors::rgb565::e64::kSteel2`` + - :raw-html:` ` + - ``#2a2f4e`` + * - ``pw::display::colors::rgb565::e64::kSteel1`` + - :raw-html:` ` + - ``#1a1932`` + * - ``pw::display::colors::rgb565::e64::kSteel0`` + - :raw-html:` ` + - ``#0e071b`` + * - ``pw::display::colors::rgb565::e64::kCoffee0`` + - :raw-html:` ` + - ``#1c121c`` + * - ``pw::display::colors::rgb565::e64::kCoffee1`` + - :raw-html:` ` + - ``#391f21`` + * - ``pw::display::colors::rgb565::e64::kCoffee2`` + - :raw-html:` ` + - ``#5d2c28`` + * - ``pw::display::colors::rgb565::e64::kCoffee3`` + - :raw-html:` ` + - ``#8a4836`` + * - ``pw::display::colors::rgb565::e64::kCoffee4`` + - :raw-html:` ` + - ``#bf6f4a`` + * - ``pw::display::colors::rgb565::e64::kCoffee5`` + - :raw-html:` ` + - ``#e69c69`` + * - ``pw::display::colors::rgb565::e64::kCoffee6`` + - :raw-html:` ` + - ``#f6ca9f`` + * - ``pw::display::colors::rgb565::e64::kCoffee7`` + - :raw-html:` ` + - ``#f9e6cf`` + * - ``pw::display::colors::rgb565::e64::kOrange3`` + - :raw-html:` ` + - ``#edab50`` + * - ``pw::display::colors::rgb565::e64::kOrange2`` + - :raw-html:` ` + - ``#e07438`` + * - ``pw::display::colors::rgb565::e64::kOrange1`` + - :raw-html:` ` + - ``#c64524`` + * - ``pw::display::colors::rgb565::e64::kOrange0`` + - :raw-html:` ` + - ``#8e251d`` + * - ``pw::display::colors::rgb565::e64::kBrightOrange0`` + - :raw-html:` ` + - ``#ff5000`` + * - ``pw::display::colors::rgb565::e64::kBrightOrange1`` + - :raw-html:` ` + - ``#ed7614`` + * - ``pw::display::colors::rgb565::e64::kBrightOrange2`` + - :raw-html:` ` + - ``#ffa214`` + * - ``pw::display::colors::rgb565::e64::kYellow0`` + - :raw-html:` ` + - ``#ffc825`` + * - ``pw::display::colors::rgb565::e64::kYellow1`` + - :raw-html:` ` + - ``#ffeb57`` + * - ``pw::display::colors::rgb565::e64::kGreen5`` + - :raw-html:` ` + - ``#d3fc7e`` + * - ``pw::display::colors::rgb565::e64::kGreen4`` + - :raw-html:` ` + - ``#99e65f`` + * - ``pw::display::colors::rgb565::e64::kGreen3`` + - :raw-html:` ` + - ``#5ac54f`` + * - ``pw::display::colors::rgb565::e64::kGreen2`` + - :raw-html:` ` + - ``#33984b`` + * - ``pw::display::colors::rgb565::e64::kGreen1`` + - :raw-html:` ` + - ``#1e6f50`` + * - ``pw::display::colors::rgb565::e64::kGreen0`` + - :raw-html:` ` + - ``#134c4c`` + * - ``pw::display::colors::rgb565::e64::kOcean0`` + - :raw-html:` ` + - ``#0c2e44`` + * - ``pw::display::colors::rgb565::e64::kOcean1`` + - :raw-html:` ` + - ``#00396d`` + * - ``pw::display::colors::rgb565::e64::kOcean2`` + - :raw-html:` ` + - ``#0069aa`` + * - ``pw::display::colors::rgb565::e64::kOcean3`` + - :raw-html:` ` + - ``#0098dc`` + * - ``pw::display::colors::rgb565::e64::kOcean4`` + - :raw-html:` ` + - ``#00cdf9`` + * - ``pw::display::colors::rgb565::e64::kOcean5`` + - :raw-html:` ` + - ``#0cf1ff`` + * - ``pw::display::colors::rgb565::e64::kOcean6`` + - :raw-html:` ` + - ``#94fdff`` + * - ``pw::display::colors::rgb565::e64::kCandyGrape3`` + - :raw-html:` ` + - ``#fdd2ed`` + * - ``pw::display::colors::rgb565::e64::kCandyGrape2`` + - :raw-html:` ` + - ``#f389f5`` + * - ``pw::display::colors::rgb565::e64::kCandyGrape1`` + - :raw-html:` ` + - ``#db3ffd`` + * - ``pw::display::colors::rgb565::e64::kCandyGrape0`` + - :raw-html:` ` + - ``#7a09fa`` + * - ``pw::display::colors::rgb565::e64::kRoyalBlue2`` + - :raw-html:` ` + - ``#3003d9`` + * - ``pw::display::colors::rgb565::e64::kRoyalBlue1`` + - :raw-html:` ` + - ``#0c0293`` + * - ``pw::display::colors::rgb565::e64::kRoyalBlue0`` + - :raw-html:` ` + - ``#03193f`` + * - ``pw::display::colors::rgb565::e64::kPurple0`` + - :raw-html:` ` + - ``#3b1443`` + * - ``pw::display::colors::rgb565::e64::kPurple1`` + - :raw-html:` ` + - ``#622461`` + * - ``pw::display::colors::rgb565::e64::kPurple2`` + - :raw-html:` ` + - ``#93388f`` + * - ``pw::display::colors::rgb565::e64::kPurple3`` + - :raw-html:` ` + - ``#ca52c9`` + * - ``pw::display::colors::rgb565::e64::kSalmon0`` + - :raw-html:` ` + - ``#c85086`` + * - ``pw::display::colors::rgb565::e64::kSalmon1`` + - :raw-html:` ` + - ``#f68187`` + * - ``pw::display::colors::rgb565::e64::kRed4`` + - :raw-html:` ` + - ``#f5555d`` + * - ``pw::display::colors::rgb565::e64::kRed3`` + - :raw-html:` ` + - ``#ea323c`` + * - ``pw::display::colors::rgb565::e64::kRed2`` + - :raw-html:` ` + - ``#c42430`` + * - ``pw::display::colors::rgb565::e64::kRed1`` + - :raw-html:` ` + - ``#891e2b`` + * - ``pw::display::colors::rgb565::e64::kRed0`` + - :raw-html:` ` + - ``#571c27`` diff --git a/pw_display/color_test.cc b/pw_display/color_test.cc new file mode 100644 index 0000000000..63884e63d5 --- /dev/null +++ b/pw_display/color_test.cc @@ -0,0 +1,61 @@ +// Copyright 2024 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#include "pw_display/color.h" + +#include "gtest/gtest.h" +#include "pw_display/colors_endesga64.h" +#include "pw_display/colors_pico8.h" + +namespace pw::display { +namespace { + +TEST(ColorsPico8Rgb565, EncodedRgb565) { + EXPECT_EQ(colors::rgb565::pico8::kDarkBlue, static_cast(0x194a)); +} + +TEST(ColorsEndesga64Rgb565, EncodedRgb565) { + EXPECT_EQ(colors::rgb565::e64::kBlood, static_cast(0xf808)); + EXPECT_EQ(colors::rgb565::e64::kRed0, static_cast(0x50e4)); +} + +TEST(ColorToRGB565, FromRGB) { + EXPECT_EQ(EncodeRgb565(0x1d, 0x2b, 0x53), colors::rgb565::pico8::kDarkBlue); + // Check each channel + EXPECT_EQ(EncodeRgb565(0xff, 0x00, 0x00), + static_cast(0b1111100000000000)); + EXPECT_EQ(EncodeRgb565(0x00, 0xff, 0x00), + static_cast(0b0000011111100000)); + EXPECT_EQ(EncodeRgb565(0x00, 0x00, 0xff), + static_cast(0b0000000000011111)); +} + +TEST(ColorToRGBA8888, FromRGB) { + EXPECT_EQ(EncodeRgba8888(0xff, 0x00, 0x00, 0x00), + static_cast(0b00000000000000000000000011111111)); + EXPECT_EQ(EncodeRgba8888(0x00, 0xff, 0x00, 0x00), + static_cast(0b00000000000000001111111100000000)); + EXPECT_EQ(EncodeRgba8888(0x00, 0x00, 0xff, 0x00), + static_cast(0b00000000111111110000000000000000)); + EXPECT_EQ(EncodeRgba8888(0x00, 0x00, 0x00, 0xff), + static_cast(0b11111111000000000000000000000000)); +} + +TEST(ColorToRGB565, FromRGBA8888) { + EXPECT_EQ(EncodeRgb565(static_cast(0xff43143b)), + colors::rgb565::e64::kPurple0); +} + +} // namespace +} // namespace pw::display diff --git a/pw_display/docs.rst b/pw_display/docs.rst index 5f6ce5e472..f920bcabc1 100644 --- a/pw_display/docs.rst +++ b/pw_display/docs.rst @@ -7,4 +7,50 @@ pw_display :name: pw_display .. attention:: - This module is undergoing implementation as part of SEED :ref:`seed-0104`. + This module's initial implementation is informed by SEED :ref:`seed-0104`, + but is being reevaluated as it is migrated from `Pigweed's experimental + repsitory `_. + +--------- +Libraries +--------- + +Color +----- +.. seealso:: + Color API: :ref:`module-pw_display-api-color` + +The color library defines base pixel format types and the `ColorRgba` class for +converting between various types. + +Display controllers often support a variety of data formats for representing a +single pixel. For example: + +256 color grayscale: + 8 bits per pixel for a total of 256 shades of gray +4k color: RGB444 + 12 bits total; 4 bits for each color: red, green, blue +65k color: RGB565 + 16 bits total; 5 bits for red, 6 bits for green and 5 bits for blue +262k color: RGB666 + 18 bits total; 6 bits for each color: red, green, blue +16.7M color: RGB888 + 24 bits total; 8 bits for each color: red, green, blue + +.. note:: + ``pw_display`` drawing libraries will initially only operate on RGB565 pixels + for a few reasons: + + - 16 bits per color is easily represented as a single 16 bit unsigned + integer. No special framebuffer data packing logic is needed for 100% + memory utilization. + - RGB565 is 65k color which is a good compromise on color fidelity and memory + footprint. + - RGB565 has wide support by common display controllers used in the embedded + space. + +.. toctree:: + :hidden: + :maxdepth: 1 + + api diff --git a/pw_display/public/pw_display/color.h b/pw_display/public/pw_display/color.h new file mode 100644 index 0000000000..0b7b0d162a --- /dev/null +++ b/pw_display/public/pw_display/color.h @@ -0,0 +1,78 @@ +// Copyright 2024 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +#pragma once + +#include +#include + +#include +#include + +namespace pw::display { + +/// Base type for pixels in RGBA8888 format. +using ColorRgba8888 = uint32_t; + +/// Base type for pixels in RGB565 format. +using ColorRgb565 = uint16_t; + +/// @defgroup pw_display_color +/// Color conversion functions used by the pw_display draw library and +/// tests. +/// @{ + +/// Encode an RGB565 value from individual red, green, blue and alpha +/// values. +/// +/// This will introduce some loss in color as values are mapped from 8 +/// bits per color down to 5 for red, 6 for green, and 5 for blue. +constexpr ColorRgb565 EncodeRgb565(uint8_t r, uint8_t g, uint8_t b) { + return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3); +} + +/// Encode an RGBA8888 value into RGB565. +constexpr ColorRgb565 EncodeRgb565(ColorRgba8888 rgba8888) { + uint8_t r = (rgba8888 & 0xFF); + uint8_t g = (rgba8888 & 0xFF00) >> 8; + uint8_t b = (rgba8888 & 0xFF0000) >> 16; + // Alpha is ignored for RGB565. + return EncodeRgb565(r, g, b); +} + +/// Encode an RGBA8888 value from individual red, green, blue and +/// alpha values. +constexpr ColorRgba8888 EncodeRgba8888(uint8_t r, + uint8_t g, + uint8_t b, + uint8_t a) { + return (a << 24) | (b << 16) | (g << 8) | r; +} + +/// Encode an RGBA8888 value from RGB565. +/// +/// This will scale each color up to 8 bits per pixel. Red and blue +/// are scaled from 5 bits to 8 bits. Green from 6 bits to 8 +/// bits. There is no alpha channel in the RGB565 format so alpha is +/// set to 255 representing 100% opaque. +constexpr ColorRgba8888 EncodeRgba8888(ColorRgb565 rgb565) { + uint8_t r = 255 * ((rgb565 & 0xF800) >> 11) / 31; + uint8_t g = 255 * ((rgb565 & 0x7E0) >> 5) / 63; + uint8_t b = 255 * (rgb565 & 0x1F) / 31; + uint8_t a = 255; + return EncodeRgba8888(r, g, b, a); +} + +/// @} + +} // namespace pw::display diff --git a/pw_display/public/pw_display/colors_endesga64.h b/pw_display/public/pw_display/colors_endesga64.h new file mode 100644 index 0000000000..b984189126 --- /dev/null +++ b/pw_display/public/pw_display/colors_endesga64.h @@ -0,0 +1,93 @@ +// Copyright 2022 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +#pragma once + +#include "pw_display/color.h" + +namespace pw::display::colors::rgb565::e64 { + +/// @defgroup pw_display_color_palette_endesga64 +/// Named colors for the Endesga64 palette. +/// @{ + +// clang-format off +constexpr ColorRgb565 kBlood = EncodeRgb565(0xff, 0x00, 0x40); +constexpr ColorRgb565 kBlack0 = EncodeRgb565(0x13, 0x13, 0x13); +constexpr ColorRgb565 kBlack1 = EncodeRgb565(0x1b, 0x1b, 0x1b); +constexpr ColorRgb565 kGray0 = EncodeRgb565(0x27, 0x27, 0x27); +constexpr ColorRgb565 kGray1 = EncodeRgb565(0x3d, 0x3d, 0x3d); +constexpr ColorRgb565 kGray2 = EncodeRgb565(0x5d, 0x5d, 0x5d); +constexpr ColorRgb565 kGray3 = EncodeRgb565(0x85, 0x85, 0x85); +constexpr ColorRgb565 kGray4 = EncodeRgb565(0xb4, 0xb4, 0xb4); +constexpr ColorRgb565 kWhite = EncodeRgb565(0xff, 0xff, 0xff); +constexpr ColorRgb565 kSteel6 = EncodeRgb565(0xc7, 0xcf, 0xdd); +constexpr ColorRgb565 kSteel5 = EncodeRgb565(0x92, 0xa1, 0xb9); +constexpr ColorRgb565 kSteel4 = EncodeRgb565(0x65, 0x73, 0x92); +constexpr ColorRgb565 kSteel3 = EncodeRgb565(0x42, 0x4c, 0x6e); +constexpr ColorRgb565 kSteel2 = EncodeRgb565(0x2a, 0x2f, 0x4e); +constexpr ColorRgb565 kSteel1 = EncodeRgb565(0x1a, 0x19, 0x32); +constexpr ColorRgb565 kSteel0 = EncodeRgb565(0x0e, 0x07, 0x1b); +constexpr ColorRgb565 kCoffee0 = EncodeRgb565(0x1c, 0x12, 0x1c); +constexpr ColorRgb565 kCoffee1 = EncodeRgb565(0x39, 0x1f, 0x21); +constexpr ColorRgb565 kCoffee2 = EncodeRgb565(0x5d, 0x2c, 0x28); +constexpr ColorRgb565 kCoffee3 = EncodeRgb565(0x8a, 0x48, 0x36); +constexpr ColorRgb565 kCoffee4 = EncodeRgb565(0xbf, 0x6f, 0x4a); +constexpr ColorRgb565 kCoffee5 = EncodeRgb565(0xe6, 0x9c, 0x69); +constexpr ColorRgb565 kCoffee6 = EncodeRgb565(0xf6, 0xca, 0x9f); +constexpr ColorRgb565 kCoffee7 = EncodeRgb565(0xf9, 0xe6, 0xcf); +constexpr ColorRgb565 kOrange3 = EncodeRgb565(0xed, 0xab, 0x50); +constexpr ColorRgb565 kOrange2 = EncodeRgb565(0xe0, 0x74, 0x38); +constexpr ColorRgb565 kOrange1 = EncodeRgb565(0xc6, 0x45, 0x24); +constexpr ColorRgb565 kOrange0 = EncodeRgb565(0x8e, 0x25, 0x1d); +constexpr ColorRgb565 kBrightOrange0 = EncodeRgb565(0xff, 0x50, 0x00); +constexpr ColorRgb565 kBrightOrange1 = EncodeRgb565(0xed, 0x76, 0x14); +constexpr ColorRgb565 kBrightOrange2 = EncodeRgb565(0xff, 0xa2, 0x14); +constexpr ColorRgb565 kYellow0 = EncodeRgb565(0xff, 0xc8, 0x25); +constexpr ColorRgb565 kYellow1 = EncodeRgb565(0xff, 0xeb, 0x57); +constexpr ColorRgb565 kGreen5 = EncodeRgb565(0xd3, 0xfc, 0x7e); +constexpr ColorRgb565 kGreen4 = EncodeRgb565(0x99, 0xe6, 0x5f); +constexpr ColorRgb565 kGreen3 = EncodeRgb565(0x5a, 0xc5, 0x4f); +constexpr ColorRgb565 kGreen2 = EncodeRgb565(0x33, 0x98, 0x4b); +constexpr ColorRgb565 kGreen1 = EncodeRgb565(0x1e, 0x6f, 0x50); +constexpr ColorRgb565 kGreen0 = EncodeRgb565(0x13, 0x4c, 0x4c); +constexpr ColorRgb565 kOcean0 = EncodeRgb565(0x0c, 0x2e, 0x44); +constexpr ColorRgb565 kOcean1 = EncodeRgb565(0x00, 0x39, 0x6d); +constexpr ColorRgb565 kOcean2 = EncodeRgb565(0x00, 0x69, 0xaa); +constexpr ColorRgb565 kOcean3 = EncodeRgb565(0x00, 0x98, 0xdc); +constexpr ColorRgb565 kOcean4 = EncodeRgb565(0x00, 0xcd, 0xf9); +constexpr ColorRgb565 kOcean5 = EncodeRgb565(0x0c, 0xf1, 0xff); +constexpr ColorRgb565 kOcean6 = EncodeRgb565(0x94, 0xfd, 0xff); +constexpr ColorRgb565 kCandyGrape3 = EncodeRgb565(0xfd, 0xd2, 0xed); +constexpr ColorRgb565 kCandyGrape2 = EncodeRgb565(0xf3, 0x89, 0xf5); +constexpr ColorRgb565 kCandyGrape1 = EncodeRgb565(0xdb, 0x3f, 0xfd); +constexpr ColorRgb565 kCandyGrape0 = EncodeRgb565(0x7a, 0x09, 0xfa); +constexpr ColorRgb565 kRoyalBlue2 = EncodeRgb565(0x30, 0x03, 0xd9); +constexpr ColorRgb565 kRoyalBlue1 = EncodeRgb565(0x0c, 0x02, 0x93); +constexpr ColorRgb565 kRoyalBlue0 = EncodeRgb565(0x03, 0x19, 0x3f); +constexpr ColorRgb565 kPurple0 = EncodeRgb565(0x3b, 0x14, 0x43); +constexpr ColorRgb565 kPurple1 = EncodeRgb565(0x62, 0x24, 0x61); +constexpr ColorRgb565 kPurple2 = EncodeRgb565(0x93, 0x38, 0x8f); +constexpr ColorRgb565 kPurple3 = EncodeRgb565(0xca, 0x52, 0xc9); +constexpr ColorRgb565 kSalmon0 = EncodeRgb565(0xc8, 0x50, 0x86); +constexpr ColorRgb565 kSalmon1 = EncodeRgb565(0xf6, 0x81, 0x87); +constexpr ColorRgb565 kRed4 = EncodeRgb565(0xf5, 0x55, 0x5d); +constexpr ColorRgb565 kRed3 = EncodeRgb565(0xea, 0x32, 0x3c); +constexpr ColorRgb565 kRed2 = EncodeRgb565(0xc4, 0x24, 0x30); +constexpr ColorRgb565 kRed1 = EncodeRgb565(0x89, 0x1e, 0x2b); +constexpr ColorRgb565 kRed0 = EncodeRgb565(0x57, 0x1c, 0x27); +// clang-format on + +/// @} + +} // namespace pw::display::colors::rgb565::e64 diff --git a/pw_display/public/pw_display/colors_pico8.h b/pw_display/public/pw_display/colors_pico8.h new file mode 100644 index 0000000000..3def9a99db --- /dev/null +++ b/pw_display/public/pw_display/colors_pico8.h @@ -0,0 +1,45 @@ +// Copyright 2024 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +#pragma once + +#include "pw_display/color.h" + +namespace pw::display::colors::rgb565::pico8 { + +/// @defgroup pw_display_color_palette_pico8 +/// Named colors for the Pico-8 palette. +/// @{ + +// clang-format off +constexpr ColorRgb565 kBlack = EncodeRgb565(0x00, 0x00, 0x00); +constexpr ColorRgb565 kDarkBlue = EncodeRgb565(0x1d, 0x2b, 0x53); +constexpr ColorRgb565 kDarkPurple = EncodeRgb565(0x7e, 0x25, 0x53); +constexpr ColorRgb565 kDarkGreen = EncodeRgb565(0x00, 0x87, 0x51); +constexpr ColorRgb565 kBrown = EncodeRgb565(0xab, 0x52, 0x36); +constexpr ColorRgb565 kDarkGray = EncodeRgb565(0x5f, 0x57, 0x4f); +constexpr ColorRgb565 kLightGray = EncodeRgb565(0xc2, 0xc3, 0xc7); +constexpr ColorRgb565 kWhite = EncodeRgb565(0xff, 0xf1, 0xe8); +constexpr ColorRgb565 kRed = EncodeRgb565(0xff, 0x00, 0x4d); +constexpr ColorRgb565 kOrange = EncodeRgb565(0xff, 0xa3, 0x00); +constexpr ColorRgb565 kYellow = EncodeRgb565(0xff, 0xec, 0x27); +constexpr ColorRgb565 kGreen = EncodeRgb565(0x00, 0xe4, 0x36); +constexpr ColorRgb565 kBlue = EncodeRgb565(0x29, 0xad, 0xff); +constexpr ColorRgb565 kIndigo = EncodeRgb565(0x83, 0x76, 0x9c); +constexpr ColorRgb565 kPink = EncodeRgb565(0xff, 0x77, 0xa8); +constexpr ColorRgb565 kPeach = EncodeRgb565(0xff, 0xcc, 0xaa); +// clang-format on + +/// @} + +} // namespace pw::display::colors::rgb565::pico8