feat: add display UI with splash screen, dashboard, and RSSI sparkline

Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
swaitsandClaude Opus 4.6 committed 2026-03-29 20:42:54 -06:00
1 parent 7064110293
commit 3102fc747a
17624 files changed
+4564928 -38

No files matched your search

+1
View File
@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"295980b52dad678d5d5e23200c57cc01300d5d9c75a1d073462ef98165bc0c82",".dockerignore":"cdbcae15105d6b781e620813c79c7e868740d4e9cc53ce6f5fcbbc12387adf4b","CHANGELOG.md":"9355cad81dc56c3fab52fa2b719d40c52dc5bfa5a7157b035060ccf0c3e5a6dc","Cargo.lock":"c5f4073c33237f52b441426e2cf08014a76ccf1ea7edac9cd7b914e981a27bd1","Cargo.toml":"fd4b277dcc40fff2d91a8094acd819febcb6fb4e3e474eb3e3e14ca55d7229f1","Cargo.toml.orig":"9dbc739861ca9b2c23c6f85fd6241892be1f5b52cae7fcab342e5bcf50252ab7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"4ed59ae6666cce57ee6865ed25e0acd4452bf95f5f4f081248b1a6e22eb609a4","MIGRATING-0.5-0.6.md":"48a3750496a3cd38b5faafd7fb6153f4323ad127ee4f2fd2b73d258fd22ed1cc","MIGRATING-0.6-0.7.md":"4955b5b8e65cc2cdda2a1078430f878a1237bf2d15d60cf91dc175595b218a58","README.md":"66827f04dd2487b32f4aa4fe897f38ba7a7d865fd1e2b5052b522e09d8c0aab9","README.tpl":"bd0279d78fd6557f99d96592f4387b95c2a55ff5035b6ee8e4c3c2f2a580a1dc","RELEASES.md":"b0b8d88cf83eadfac068c2df1e5c6a41c410772df9408db624b88f2ba814ca64","assets/README.md":"66a055bd2fbb852dfae88334c16fcbb2f44d944ee6e309730b82095317a225ac","assets/banner-photo.jpg":"ffe5b6f60ef6e79e58f44a19cbe3d2d58a880f5500cc3da275709e0de03bedf5","assets/hello-world-simulator.png":"fb850cdab822cd8979db341e7cb707f72ae844efb14be510346555a3a7bc1248","assets/logo.svg":"c1d9200772d0e9e1daa4cedcabb72c9d2e51ab36b9058d0c3eef8b4b8dfaf097","assets/logo_core.svg":"bb38c211dd54a4c925df9338383b3e6e92e293e7733dd40d408e7f7321519a6a","assets/logo_core_src.svg":"1fd9a4c24042febc9c9363223efac8bbee91437c082411a9caa78ae454523b57","assets/patch.png":"1b5a454f377d75744ce99dbe61dc89c0642f1fb57e9d091939e5471e7cdd8bab","assets/patch.tga":"7ae2233a8b2c15b69ce9649c4f56c4ff50631d29e760f023b9f83739a8b5ce22","assets/patch_16bpp.bmp":"d953cb2f4f74c1ee914e484a8fd3454147a6696c462c06f019253cb16d92ff5d","assets/patch_16bpp.raw":"c6095b54f3a35b950a06e1d36112c8aec9e28b07a70d5c46760485609df8c2c4","assets/patch_1bpp.raw":"9a1d2b284ce4418bcb7e9d3efecc951780318309bcf1358a43ea09ffd0e80f98","assets/patch_8bpp.raw":"0e42708bc1d4afce5606a8efd6e5b1e39a860229becd5b8dc2992af19d01a95d","assets/rust-pride.tga":"f9466ed44990c516e2ecf23a49ab860b215d203b3acdc53c4eb2b20658be6ffe","assets/simulator-demo.png":"1bcb814ebbcea7d90cba7d068b548b461c05a59a19aadfb55e470361d9081089","assets/simulator-demo.xcf":"7494d1bc6b339f638aabf98564267e518f0ee8e733358a253851f77f316dd736","assets/tiles.tga":"ef4edc0b8c5b24b60499400a54c6714b729c9c354e4fea72f4d8ec5692e9522e","benches/color_conversion.rs":"64fbeeb703a08283d806a13397a9ebc17113a1600e3d8441ce39b514e03c0d0d","benches/common.rs":"efb96bc8935d106559c0186107664322f37379cd1cad76b2d668436517e0a149","benches/contains.rs":"0a8fdcd4877bfe4dbd308995d62a8f3858925382f16785a7866ccb1cf1faeaee","benches/fonts.rs":"1e9ca31831efc6b10363979d94f03e79abffca0955dc3a01c3b430e6f214855b","benches/framebuffer.rs":"751aef70a2d3d40f1be6f3f9c9c3ea466a8cfbb92ffb418ebb04649a11ea8cff","benches/image.rs":"c7f17ae1ab29b65b25e832b5fb202088f2d41beb669f8cb11ab7d035092b9f77","benches/primitives.rs":"8ab4816c270b46db2e4d224805c041ac64132ac5378226cff722388700097c8c","benches/primitives_fixed_point.rs":"336005ad3d6872671a185e63d0bbaf4dc340fe7a1fb16ef0edbd028fce812401","benches/raw_data_iter.rs":"a576ddf8a208b47637a7294e39d42f25a93d12b1fd272420ed6cc8df1aca6e72","doc/assets/all_drawing_ops.png":"010b8bde66ff78aac7fb21efbe9e4743382e98a03f2264d744074f8df7795f87","doc/development-setup.md":"41f5e27ea8ee61abb51aac62e10d53eb864661d6587683c207316b76b48fd486","doc/releasing.md":"40d1c855dee3abec32b932c67287ea6654f354d72f1b9792b11135dae622acbd","filter-readme.sed":"d0da07b4694ed90fdc9094e17cb8caf08b8efde9c64a3789f2dad9538310f332","fonts/png/ascii/font_10x20.png":"4119a27b911ad53f0013f3ba53e9355f2407c9efdf1a47530fa3b93f52033405","fonts/png/ascii/font_4x6.png":"88942c34507807f28015a73bdf25047c2cfaa8a910871865596083dd7b000f1b","fonts/png/ascii/font_5x7.png":"2d420452b30e9382fc9f32602d75091444af1dc85150de94f9e2c70a04ba9305","fonts/png/ascii/font_5x8.png":"e29bd7f586771d05dfe82427359eec6a47f83d9336efa160fac9b8efe0515f4b","fonts/png/ascii/font_6x10.png":"363fede673187096c1731d69be475225af006485c31eb5553a6029101e7c7c35","fonts/png/ascii/font_6x12.png":"aba554d8b7b3c1d211ffdcc996863b096348ee80f3db96c2d86f3ee1819f36ea","fonts/png/ascii/font_6x13.png":"b6504299021cc53db51f0b43cd87afa125152bf6b0d25e4e481457fce04d0080","fonts/png/ascii/font_6x13_bold.png":"671e5100bc130097b8da81c81be89965b5ae0822629562e497a680b27205482f","fonts/png/ascii/font_6x13_italic.png":"d690dfb5ebddbc6a634a3ba0950a7c22d8e7cab7e887e6075a2db2baaed4ee69","fonts/png/ascii/font_6x9.png":"c315c3e6c00f20a1bbe857cddc3b207ead24fa1d04143bd06c4cfbaa5fc55e16","fonts/png/ascii/font_7x13.png":"797837214354ccf3c421739941df0d6d570085e66e2a0b8a7358a0dc7199b9e7","fonts/png/ascii/font_7x13_bold.png":"58caeaadcdaff5cd1b0a57e79a558d26abd2d8ef7faae9c2f4e0e0b1796198a3","fonts/png/ascii/font_7x13_italic.png":"d8e0aa7104a5d23Line truncated
+6
View File
@@ -0,0 +1,6 @@
{
"git": {
"sha1": "f785ffab09059a3dc1243cffe8f5c769548dcc69"
},
"path_in_vcs": ""
}
+1
View File
@@ -0,0 +1 @@
*
+785
View File
@@ -0,0 +1,785 @@
# Changelog
Embedded Graphics is a `no_std` library for adding graphics features to display drivers. It aims to use the minimum amount of memory for builtin graphics objects by leveraging Rust's iterators to avoid large allocations. It targets embedded environments, but can run anywhere like a Raspberry Pi up to full desktop machines.
<!-- next-header -->
## [Unreleased] - ReleaseDate
## [0.8.2] - 2026-02-15
### Fixed
- [#806](https://github.com/embedded-graphics/embedded-graphics/pull/806) Fixed build on MSRV by using tighter dependencies.
- [#806](https://github.com/embedded-graphics/embedded-graphics/pull/806) Added Cargo.lock for dev-dependencies.
- [#806](https://github.com/embedded-graphics/embedded-graphics/pull/806) Fixed some broken documentation links.
## [0.8.1] - 2023-08-10
### Changed
- (technically breaking) [#731](https://github.com/embedded-graphics/embedded-graphics/pull/731) Bump MSRV to 1.71.1
- [#730](https://github.com/embedded-graphics/embedded-graphics/pull/730) Made the following methods `const`:
- `MonoFontStyleBuilder::font`
- `MonoFontStyleBuilder::underline`
- `MonoFontStyleBuilder::strikethrough`
- `MonoFontStyleBuilder::reset_text_color`
- `MonoFontStyleBuilder::reset_background_color`
- `MonoFontStyleBuilder::reset_underline`
- `MonoFontStyleBuilder::reset_strikethrough`
- `MonoTextStyle::new`
## [0.8.0] - 2023-05-14
### Added
- [#592](https://github.com/embedded-graphics/embedded-graphics/pull/592) Add support for defmt behind a feature (`defmt`).
- [#612](https://github.com/embedded-graphics/embedded-graphics/pull/612), [#699](https://github.com/embedded-graphics/embedded-graphics/pull/699) Added `GetPixel` trait and implementations for `ImageRaw` and `Framebuffer`.
- [#621](https://github.com/embedded-graphics/embedded-graphics/pull/621) Added `Rgb666` and `Bgr666` color type support.
- [#641](https://github.com/embedded-graphics/embedded-graphics/pull/641) Added `Line::with_delta` constructor.
- [#656](https://github.com/embedded-graphics/embedded-graphics/pull/656) Added `Rgb666` and `Bgr666` conversions.
- [#673](https://github.com/embedded-graphics/embedded-graphics/pull/673) Added `Framebuffer`.
- [#709](https://github.com/embedded-graphics/embedded-graphics/pull/709) Added `Image::with_center`.
- [#710](https://github.com/embedded-graphics/embedded-graphics/pull/710) Added `AnchorX`, `AnchorY`, `AnchorPoint::x`, `AnchorPoint::y` and `AnchorPoint::from_xy`.
- [#710](https://github.com/embedded-graphics/embedded-graphics/pull/710) Added `Rectangle::resized_width`, `Rectangle::resized_height`, `Rectangle::anchor_x` and `Rectangle::anchor_y`.
### Changed
- **(breaking)** [#660](https://github.com/embedded-graphics/embedded-graphics/pull/660) Remove `RawU18` color storage type and use `RawU24` in is place for `Rgb666` and `Bgr666`.
- [#639](https://github.com/embedded-graphics/embedded-graphics/pull/639) Made the following functions `const`:
- **(breaking)** [#690](https://github.com/embedded-graphics/embedded-graphics/pull/690) Remove `ImageRaw::new_binary` `const` helper method. `ImageRaw::new` can now be used in `const` contexts, so use it instead of `new_binary`.
- [#639](https://github.com/embedded-graphics/embedded-graphics/pull/639), [#690](https://github.com/embedded-graphics/embedded-graphics/pull/690) Made the following functions `const`:
- `Point::component_mul`
- `Point::component_div`
- `Size::saturating_add`
- `Size::saturating_sub`
- `Size::component_mul`
- `Size::component_div`
- `BinaryColor::invert`
- `BinaryColor::is_on`
- `BinaryColor::is_off`
- `Rectangle::with_center`
- `Rectangle::is_zero_sized`
- `RawDataSlice::new`
- `MonoTextStyle::new`
- `Arc::with_center`
- `Arc::from_circle`
- `Arc::to_circle`
- `Circle::with_center`
- `Ellipse::with_center`
- `Sector::with_center`
- `Sector::from_circle`
- `Sector::to_circle`
- `Styled::new`
- `ImageRaw::new`
- `ImageRaw::data_width`
- `Image::new`
- `FancyDisplay::new`
- `MockDisplay::get_pixel`
- `MonoFont::mime`
- `MonoFont::glyph_mapping`
- `MonoTextStyleBuilder::new`
- `MonoTextStyleBuilder::text_color`
- `MonoTextStyleBuilder::background_color`
- `MonoTextStyleBuilder::underline_with_color`
- `MonoTextStyleBuilder::strikethrough_with_color`
- `MonoTextStyleBuilder::build`
- `Ellipse::new`
- `Ellipse::contains`
- `PrimitiveStyle::new`
- `PrimitiveStyle::with_stroke`
- `PrimitiveStyle::with_fill`
- `PrimitiveStyle::is_transparent`
- `PrimitiveStyleBuilder::new`
- `PrimitiveStyleBuilder::fill_color`
- `PrimitiveStyleBuilder::reset_fill_color`
- `PrimitiveStyleBuilder::stroke_color`
- `PrimitiveStyleBuilder::reset_stroke_color`
- `PrimitiveStyleBuilder::stroke_width`
- `PrimitiveStyleBuilder::stroke_alignment`
- `PrimitiveStyleBuilder::build`
- `DecorationColor::is_none`
- `DecorationColor::is_text_color`
- `DecorationColor::is_custom`
- [#651](https://github.com/embedded-graphics/embedded-graphics/pull/651), [#652](https://github.com/embedded-graphics/embedded-graphics/pull/652) Improved performance of color conversions.
- [#653](https://github.com/embedded-graphics/embedded-graphics/pull/653) Don't ignore trailing newlines in `Text`.
- [#662](https://github.com/embedded-graphics/embedded-graphics/pull/662) `ImageRaw::new` no longer panics if `width == 0`.
- **(breaking)** [#688](https://github.com/embedded-graphics/embedded-graphics/pull/688) `MonoFont` is now `Send + Sync`; implementations of `GlyphMapping` must be `Sync`.
- **(breaking)** [#663](https://github.com/embedded-graphics/embedded-graphics/pull/663) Upgraded Cargo dependencies to their latest versions.
- **(breaking)** [#689](https://github.com/embedded-graphics/embedded-graphics/pull/689) Bump Minimum Supported Rust Version (MSRV) to 1.61.
- **(breaking)** [#715](https://github.com/embedded-graphics/embedded-graphics/pull/715) Changed the direction of angles. Positive angles are now clockwise.
### Fixed
- [#648](https://github.com/embedded-graphics/embedded-graphics/pull/648) Fixed incorrect text bounding box calculation when multi-byte characters are used.
- [#713](https://github.com/embedded-graphics/embedded-graphics/pull/713) Fixed possible panic when drawing an invalid `MonoFont`.
## [0.7.1] - 2021-06-15
### Changed
- [#606](https://github.com/embedded-graphics/embedded-graphics/pull/606) Bump minimum embedded-graphics-core version from `0.3.0` to `0.3.2`
## [0.7.0] - 2021-06-05
### Added
- [#602](https://github.com/embedded-graphics/embedded-graphics/pull/602) Implemented `core::fmt::Display` for `Point` and `Size`.
### Changed
- **(breaking)** - [#600](https://github.com/embedded-graphics/embedded-graphics/pull/600) Renamed `Mapping::all` to `Mapping::iter`.
- **(breaking)** - [#603](https://github.com/embedded-graphics/embedded-graphics/pull/603) `MockDisplay::eq` was replaced by a `PartialEq` implementation for `MockDisplay`.
### Removed
- **(breaking)** - [#604](https://github.com/embedded-graphics/embedded-graphics/pull/604) Removed incomplete JIS X 0201 fonts.
## [0.7.0-beta.2] - 2021-05-24
### Added
- [#587](https://github.com/embedded-graphics/embedded-graphics/pull/587) Added `From<&TextStyle>` impl for `TextStyleBuilder` and `From<&MonoFont>` for `MonoFontBuilder`.
- [#589](https://github.com/embedded-graphics/embedded-graphics/pull/589) Implemented `From` trait to convert from RGB colors to grayscale colors, between different grayscale colors and from grayscale and RGB colors to `BinaryColor`.
### Changed
- **(breaking)** - [#596](https://github.com/embedded-graphics/embedded-graphics/pull/596) Added more ISO8859 glyph subsets as well as JIS_X0201 for bundled `MonoFont`s, supporting more languages. The `latin1` subset was renamed to `iso_8859_1`.
## [0.7.0-beta.1] - 2021-04-19
### Added
- **(breaking)** [#552](https://github.com/embedded-graphics/embedded-graphics/pull/552) Added the `Output` associated type to `Drawable` to allow returning non-`()` values from drawing operations.
- [#563](https://github.com/embedded-graphics/embedded-graphics/pull/563) Added `is_none`, `is_text_color` and `is_custom` methods to `DecorationColor`.
- [#563](https://github.com/embedded-graphics/embedded-graphics/pull/563) Added `is_transparent` methods to `PrimitiveStyle` and `MonoTextStyle`.
- [#569](https://github.com/embedded-graphics/embedded-graphics/pull/569) Added a `line_height` field to `TextStyle`.
- [#571](https://github.com/embedded-graphics/embedded-graphics/pull/571) Added `MockDisplay::set_pixels` to set pixels from an iterator.
- [#572](https://github.com/embedded-graphics/embedded-graphics/pull/572) Added `ImageRaw::new_binary` to create `const` images with binary image data.
- [#576](https://github.com/embedded-graphics/embedded-graphics/pull/576) Added reset methods for color settings to `MonoTextStyleBuilder` and `PrimitiveStyleBuilder`.
- [#582](https://github.com/embedded-graphics/embedded-graphics/pull/582) Added `StyledDrawable`, `StyledDimensions` and `StyledPixels` traits.
### Changed
- **(breaking)** [#561](https://github.com/embedded-graphics/embedded-graphics/pull/561) Renamed `HorizontalAlignment` and `VerticalAlignment` to `Alignment` and `Baseline`.
- **(breaking)** [#561](https://github.com/embedded-graphics/embedded-graphics/pull/561) Replaced `TextRenderer::vertical_offset` by `baseline` arguments for the other `TextRenderer` methods.
- **(breaking)** [#563](https://github.com/embedded-graphics/embedded-graphics/pull/563) The bounding boxes returned by `Dimensions` implementations for styled primitives no longer depend on the fill and stroke color.
- **(breaking)** [#563](https://github.com/embedded-graphics/embedded-graphics/pull/563) Drawing a primitive with a transparent stroke (`stroke_color == None && stroke_width > 0`) will now reduce the filled area.
- **(breaking)** [#566](https://github.com/embedded-graphics/embedded-graphics/pull/566) The `Drawable::Output` type was changed to `Point` for styled `Text` objects. The returned point can be used to chain texts with different styles.
- **(breaking)** [#569](https://github.com/embedded-graphics/embedded-graphics/pull/569) Moved the text rendering API into a separate `text::renderer` submodule.
- **(breaking)** [#569](https://github.com/embedded-graphics/embedded-graphics/pull/569) The `non_exhaustive` attribute was added to the `TextStyle` struct.
- **(breaking)** [#571](https://github.com/embedded-graphics/embedded-graphics/pull/571) Added color argument to `MockDisplay::from_points` to make it usable for all color types.
- **(breaking)** [#572](https://github.com/embedded-graphics/embedded-graphics/pull/572) Removed the `height` argument from `ImageRaw::new`. The `height` is now calculated based on the width and data length.
- **(breaking)** [#572](https://github.com/embedded-graphics/embedded-graphics/pull/572) Replaced `pixelcolor::raw::RawDataIter` by the types in the `iterator::raw` module.
- **(breaking)** [#573](https://github.com/embedded-graphics/embedded-graphics/pull/573) Changed `MonoFont` from a trait to a struct.
- **(breaking)** [#580](https://github.com/embedded-graphics/embedded-graphics/pull/580) Changed `Text` to directly contain the styling information without needing a `Styled` wrapper.
- **(breaking)** [#580](https://github.com/embedded-graphics/embedded-graphics/pull/580) Removed `character_style` from `TextStyle`. Character and text style can now be set independently in the `Text` object.
- **(breaking)** [#580](https://github.com/embedded-graphics/embedded-graphics/pull/580) Moved `Styled` from the crate root to the `primitives` module.
### Removed
- **(breaking)** [#582](https://github.com/embedded-graphics/embedded-graphics/pull/582) Removed `iterator::IntoPixels` trait. Use `Styled::pixels` instead.
### Fixed
- [#571](https://github.com/embedded-graphics/embedded-graphics/pull/571) `Rectangle::points` did return a non empty iterator for rectangles with zero width.
## [0.7.0-alpha.3] - 2021-02-03
### Added
- [#508](https://github.com/embedded-graphics/embedded-graphics/pull/508) Added `MockDisplay::assert_eq_with_message` and `MockDisplay::assert_pattern_with_message`.
- [#510](https://github.com/embedded-graphics/embedded-graphics/pull/510) Added `vertical_alignment` and `horizontal_alignment` to `MonoTextStyle`.
- [#510](https://github.com/embedded-graphics/embedded-graphics/pull/510) Added `From` impl to convert an existing `MonoTextStyle` into a `MonoTextStyleBuilder`.
- [#523](https://github.com/embedded-graphics/embedded-graphics/pull/523) Added support for underline and strikethrough attributes for `MonoTextStyle`.
### Changed
- **(breaking)** [#523](https://github.com/embedded-graphics/embedded-graphics/pull/523) The external text renderer API was rewritten and the `TextStyle` trait was renamed to `TextRenderer`.
- **(breaking)** [#523](https://github.com/embedded-graphics/embedded-graphics/pull/523) The `fonts` module was split into `text` and `mono_font` modules.
- **(breaking)** [#523](https://github.com/embedded-graphics/embedded-graphics/pull/523) The vertical and horizontal alignment of `Text` objects must now be set using the new `TextStyle` struct.
- **(breaking)** [#535](https://github.com/embedded-graphics/embedded-graphics/pull/535) Replaced the builtin fonts with new fonts, that are generated from BDF files.
- **(breaking)** [#538](https://github.com/embedded-graphics/embedded-graphics/pull/538) The types inside the `style` module were moved to other locations and the module itself has been removed.
- **(breaking)** [#540](https://github.com/embedded-graphics/embedded-graphics/pull/540) Renamed the `iterator::pixel::Translate` struct to `Translated`and the `translate` method in `PixelIteratorExt` to `translated`.
### Removed
- **(breaking)** [#508](https://github.com/embedded-graphics/embedded-graphics/pull/508) `MockDisplay` no longer implements `PartialEq`, use `MockDisplay::assert_eq` instead.
- **(breaking)** [#509](https://github.com/embedded-graphics/embedded-graphics/pull/509) Styled text can no longer be converted into a pixel iterator, because `IntoPixels` is no longer implemented for `Styled<Text<'_>, S>`.
- **(breaking)** [#510](https://github.com/embedded-graphics/embedded-graphics/pull/510) `MonoTextStyleBuilder::new` no longer takes a font as an argument, use `MonoTextStyleBuilder::new().font(SomeFont)` instead.
### Fixed
- [#507](https://github.com/embedded-graphics/embedded-graphics/pull/507) Fixed drawing of the join between the radial lines for sectors with a sweep angle close to 360°.
- [#525](https://github.com/embedded-graphics/embedded-graphics/pull/525) `Triangle`s and `Polyline`s with thick strokes would overdraw in some cases.
- [#527](https://github.com/embedded-graphics/embedded-graphics/pull/527) Some cases where the ends of `Polyline`s would draw unwanted "spurs" are now fixed.
## [0.7.0-alpha.2] - 2020-11-29
### Added
- [#386](https://github.com/embedded-graphics/embedded-graphics/pull/386) Added `Line::midpoint` to get the midpoint of a line.
- [#386](https://github.com/embedded-graphics/embedded-graphics/pull/386) `Polyline`s can now be drawn with stroke widths greater than 1.
- [#386](https://github.com/embedded-graphics/embedded-graphics/pull/386) Added the `delta` method to `Line` to compute the difference between start and end points.
- [#450](https://github.com/embedded-graphics/embedded-graphics/pull/450) Added `ColorConverted` and `DrawTargetExt::color_converted` to support color conversion for draw targets.
- [#438](https://github.com/embedded-graphics/embedded-graphics/pull/438) Added majority CSS web colors as associated `const`s to the RGB color types.
- [#470](https://github.com/embedded-graphics/embedded-graphics/pull/470) Added support for external text renderers. External text renderers can be implemented using the new `TextStyle` trait.
- [#475](https://github.com/embedded-graphics/embedded-graphics/pull/475) `Triangle`s can now be drawn with stroke widths greater than 1.
- [#478](https://github.com/embedded-graphics/embedded-graphics/pull/478) Added `resized`, `anchor_point`, `rows`, `columns` and `is_zero_sized` methods to `Rectangle`.
- [#493](https://github.com/embedded-graphics/embedded-graphics/pull/493) Added `assert_eq`, `assert_pattern` and `diff` methods to `MockDisplay`. Improved error messages for failing assertions can be enabled by setting the `EG_FANCY_PANIC` environment variable to `1` at compile time.
- [#498](https://github.com/embedded-graphics/embedded-graphics/pull/498) Added `Size::saturating_add` and `Size::saturating_sub`.
### Changed
- **(breaking)** [#466](https://github.com/embedded-graphics/embedded-graphics/pull/466) Upgrade Nalgebra from 0.19.0 to 0.23.0.
- **(breaking)** [#470](https://github.com/embedded-graphics/embedded-graphics/pull/470) Renamed `Font`, `TextStyle` and `TextStyleBuilder` to `MonoFont`, `MonoTextStyle` and `MonoTextStyleBuilder`.
- **(breaking)** [#494](https://github.com/embedded-graphics/embedded-graphics/pull/494) Triangle vertices are now stored in an array of 3 points, under the `vertices` field.
### Removed
- **(breaking)** [#470](https://github.com/embedded-graphics/embedded-graphics/pull/470) Support for fonts with variable character width was removed from the internal text renderer.
- **(breaking)** [#470](https://github.com/embedded-graphics/embedded-graphics/pull/470) `Font6x6` was removed.
- **(breaking)** [#494](https://github.com/embedded-graphics/embedded-graphics/pull/494) `Triangle::from_points` is removed. To create a triangle from a slice of `Point`s, use the new `Triangle::from_slice` method.
- **(breaking)** [#498](https://github.com/embedded-graphics/embedded-graphics/pull/498) `Primitive::from_points` is removed. The `points` method is now available on the `PointsIter` trait, which must be implemented for all `Primitive`s.
### Fixed
- [#477](https://github.com/embedded-graphics/embedded-graphics/pull/477) Drawing a 90° `Arc` is now equal to drawing a quarter of a circle.
## [0.7.0-alpha.1] - 2020-09-19
### Added
- [#307](https://github.com/embedded-graphics/embedded-graphics/pull/307) Added `Primitive::points` to get an iterator over all points inside a primitive.
- [#317](https://github.com/embedded-graphics/embedded-graphics/pull/317) Added `Rectangle::center` to get the center point of a rectangle.
- [#318](https://github.com/embedded-graphics/embedded-graphics/pull/317) Added `ContainsPoint` trait to check if a point is inside a closed shape.
- [#320](https://github.com/embedded-graphics/embedded-graphics/pull/320) Added the `Ellipse` primitive.
- [#333](https://github.com/embedded-graphics/embedded-graphics/pull/333) Added `Rectangle::bottom_right` to get the bottom right corner of a rectangle.
- [#331](https://github.com/embedded-graphics/embedded-graphics/pull/331) Added stroke alignment to `PrimitiveStyle`.
- [#331](https://github.com/embedded-graphics/embedded-graphics/pull/331) Added `Rectangle::with_center`.
- [#331](https://github.com/embedded-graphics/embedded-graphics/pull/331) Added `From<&PrimitiveStyle>` for `PrimitiveStyleBuilder`.
- [#292](https://github.com/embedded-graphics/embedded-graphics/pull/292) Added the `Polyline` primitive.
- [#337](https://github.com/embedded-graphics/embedded-graphics/pull/337) Add `Point::x_axis`, `Point::y_axis`, `Size::x_axis` and `Size::y_axis`.
- [#337](https://github.com/embedded-graphics/embedded-graphics/pull/337) Add `Point::new_equal` and `Size::new_equal`.
- [#336](https://github.com/embedded-graphics/embedded-graphics/pull/336) Add `RoundedRectangle` primitive.
- [#353](https://github.com/embedded-graphics/embedded-graphics/pull/353) Add `MockDisplay::swap_xy` method.
- [#357](https://github.com/embedded-graphics/embedded-graphics/pull/357) Add `MockDisplay::map` method.
- [#357](https://github.com/embedded-graphics/embedded-graphics/pull/357) Allow usage of all RGB color types in `MockDisplay` patterns.
- [#366](https://github.com/embedded-graphics/embedded-graphics/pull/366) Allow usage of all grayscale color types in `MockDisplay` patterns.
- [#342](https://github.com/embedded-graphics/embedded-graphics/pull/342) Added `Rectangle::intersection` method.
- [#363](https://github.com/embedded-graphics/embedded-graphics/pull/363) Export `primitives::ContainsPoint` trait in prelude.
- [#310](https://github.com/embedded-graphics/embedded-graphics/pull/320) Added the `Arc` primitive.
- [#310](https://github.com/embedded-graphics/embedded-graphics/pull/320) Added the `Sector` primitive.
- [#398](https://github.com/embedded-graphics/embedded-graphics/pull/398) Added `Point::length_squared` and `component_min`, `component_max`, `component_mul` and `component_div` for `Point` and `Size`.
- [#400](https://github.com/embedded-graphics/embedded-graphics/pull/400) Added `OffsetOutline` and `StyledPrimitiveAreas` traits.
- [#409](https://github.com/embedded-graphics/embedded-graphics/pull/409) Added `Clipped`, `Cropped` and `Translated` draw targets.
- [#409](https://github.com/embedded-graphics/embedded-graphics/pull/409) Added `OriginDimensions` trait for dimensions with `top_left == Point::zero()`.
- [#420](https://github.com/embedded-graphics/embedded-graphics/pull/420) Added support for `SubImage`s.
- [#429](https://github.com/embedded-graphics/embedded-graphics/pull/429) Added `ToBytes` trait to convert colors into byte arrays.
- [#431](https://github.com/embedded-graphics/embedded-graphics/pull/431) Added `MockDisplay::affected_area` to get the area affected by previous drawing operations.
- [#439](https://github.com/embedded-graphics/embedded-graphics/pull/439) Added support to render transparent characters with a colored background.
- [#494](https://github.com/embedded-graphics/embedded-graphics/pull/494) Add `Triangle::from_slice` to create a triangle from a slice of `Point`s.
### Changed
- **(breaking)** [#274](https://github.com/embedded-graphics/embedded-graphics/pull/274) The `Circle` is now defined by its bounding box top-left corner and its diameter instead of its center and its radius. To convert your code, you can replace `Circle::new(point, radius)` by `Circle::with_center(point, 2 * radius + 1)`.
- **(breaking)** [#306](https://github.com/embedded-graphics/embedded-graphics/pull/306) The `Rectangle` is now defined by its top-left corner and its size instead of the top-left and bottom-right corner. To convert your code, you can replace `Rectangle::new` by `Rectangle::with_corners`.
- **(breaking)** [#312](https://github.com/embedded-graphics/embedded-graphics/pull/312) The methods in the `Dimension` trait are replaced by a single `bounding_box` method that returns a `Rectangle`.
- **(breaking)** [#353](https://github.com/embedded-graphics/embedded-graphics/pull/353) Lines with equal start and end points are now drawn by assuming they are oriented horizontally. This means that they are now drawn as a `stroke_width` high and 1px wide rectangle, instead of not being drawn at all.
- **(breaking)** [#353](https://github.com/embedded-graphics/embedded-graphics/pull/353) `primitives::line::StyledLineIterator` was renamed to `primitives::line::StyledIterator`.
- **(breaking)** [#357](https://github.com/embedded-graphics/embedded-graphics/pull/357) Additional checks for overdraw and out of bounds drawing were added to `MockDisplay` which can cause tests to panic. See the `mock_display` module docs for more information.
- **(breaking)** [#342](https://github.com/embedded-graphics/embedded-graphics/pull/342) Refactored the `DrawTarget` trait to better support common hardware capabilities.
- **(breaking)** [#360](https://github.com/embedded-graphics/embedded-graphics/pull/360) Make the `drawable` module private. `drawable::Drawable` and `drawable::Pixel` are now exported from the crate root.
- **(breaking)** [#390](https://github.com/embedded-graphics/embedded-graphics/pull/390) `Triangle.contains` now always returns `false` for colinear triangles.
- **(breaking)** [#393](https://github.com/embedded-graphics/embedded-graphics/pull/393) `DrawTarget::draw` now uses a reference to `self` instead of taking ownership of `self`. Because of this change `DrawTarget` can no longer be implemented for pixel iterators (`Iterator<Item = C>`), which can now be drawn using the `draw` method provided by the `PixelIteratorExt` extension trait.
- **(breaking)** [#383](https://github.com/embedded-graphics/embedded-graphics/pull/383) Replaced all `IntoIterator` impls with a custom `IntoPixels` trait. To get an iterator over pixels in an item, replace calls to `into_iter()` with `into_pixels()`.
- **(breaking)** [#403](https://github.com/embedded-graphics/embedded-graphics/pull/403) Use an associated type to define the color type for `Drawable`s.
- **(breaking)** [#409](https://github.com/embedded-graphics/embedded-graphics/pull/409) `DrawTarget::size` was removed and `DrawTarget`s are now required also implement `Dimensions`.
- **(breaking)** [#409](https://github.com/embedded-graphics/embedded-graphics/pull/409) The `DrawTarget` trait was moved from the root of the crate to a new `draw_target` module. Projects that use the `prelude` to import `DrawTarget` won't be affected by this change.
- **(breaking)** [#420](https://github.com/embedded-graphics/embedded-graphics/pull/420) To add support for additional image formats now `ImageDrawable` and `OriginDimensions` needs to be implemented instead of `IntoPixelIterator` and `ImageDimensions`.
- **(breaking)** [#420](https://github.com/embedded-graphics/embedded-graphics/pull/420) The color type parameter was removed from the `Image` struct and is now defined by the associated `Color` type of an `ImageDrawable` implementation.
### Fixed
- [#317](https://github.com/embedded-graphics/embedded-graphics/pull/317) The bounding box size for `Circle`s was off by one.
- [#401](https://github.com/embedded-graphics/embedded-graphics/pull/401) Triangle pixel iterators no longer produce a pixel for each node twice.
- [#431](https://github.com/embedded-graphics/embedded-graphics/pull/431) Styled primitive bounding boxes now take the stroke width and alignment into account.
### Removed
- **(breaking)** [#351](https://github.com/embedded-graphics/embedded-graphics/pull/351) Removed the `egtext!`, `text_style!` and `primitive_style!` macros. Use the `Text`, `TextStyleBuilder` and `PrimitiveStyleBuilder` respectively instead.
- **(breaking)** [#351](https://github.com/embedded-graphics/embedded-graphics/pull/351) Removed the `egcircle!`, `egrectangle!`, `egline!` and `egtriangle!` macros.
## [0.6.2] - 2020-04-20
### Fixed
- [#309](https://github.com/embedded-graphics/embedded-graphics/pull/309) Prevent triangles with off-screen vertices from infinitely looping.
## [0.6.1] - 2020-04-01
### Added
- [#285](https://github.com/embedded-graphics/embedded-graphics/pull/285) Add multiplication and division by a scalar for `Point` and `Size`.
### Fixed
- [#271](https://github.com/embedded-graphics/embedded-graphics/pull/271) Styled `Line`s are now drawn using the `stroke_with` specified in the `PrimitiveStyle` and no longer default to 1px width.
## [0.6.0] - 2020-03-20
### Added
- [#269](https://github.com/embedded-graphics/embedded-graphics/pull/269) Support for multiline text.
- [#267](https://github.com/embedded-graphics/embedded-graphics/pull/267) Added a `6x6` hand-drawn variable width font.
- [#267](https://github.com/embedded-graphics/embedded-graphics/pull/267) Support for variable width fonts.
### Fixed
- [#267](https://github.com/embedded-graphics/embedded-graphics/pull/267) Fonts with CHARACTER_SPACING now properly render the background color between characters.
- [#276](https://github.com/embedded-graphics/embedded-graphics/pull/276) Fixed Chars like '°' and similar for `Font12x16` & `Font24x32`
## [0.6.0-beta.2] - 2020-03-06
### Fixed
- [#262](https://github.com/embedded-graphics/embedded-graphics/pull/262) `Triangle`s with a fill color but no stroke color are now rendered instead of not rendered at all.
- [#262](https://github.com/embedded-graphics/embedded-graphics/pull/262) A triangle with a different stroke and fill color now renders its left-most border with the stroke color, instead of fill color
- [#262](https://github.com/embedded-graphics/embedded-graphics/pull/262) Triangles and lines with a stroke width of 0 (and no fill for triangles) are no longer drawn.
### Added
- Added `draw_image` to `DrawTarget` trait with default implementation.
## [0.6.0-beta.1] - 2020-02-17
### Added
- [#257](https://github.com/embedded-graphics/embedded-graphics/pull/257) added the `.into_storage()` method on `PixelColor`s via the `IntoStorage` trait to allow for more ergonomic conversion from a color to its raw storage type.
```diff
// IntoStorage is included in the prelude.
// You can also import it with use embedded_graphics::pixelcolor::IntoStorage.
+ use embedded_graphics::prelude::*;
- RawU1::from(color).into_inner()
+ color.into_storage()
```
- Added as many `#[derive()]`s as possible to all embedded-graphics, tinybmp and tinytga types.
- Added `From<Point> for [i32; 2]`
- Added `From<Size> for [u32; 2]`
- Added the following fallible conversions to/from `Point`
- `TryFrom<Point>` for `(u32, u32)`
- `TryFrom<(u32, u32)>` for `Point`
- `TryFrom<Point>` for `[u32; 2]`
- `TryFrom<[u32; 2]>` for `Point`
- `TryFrom<&[u32; 2]>` for `Point`
- #247 Added the `ImageData` trait. This trait can be implemented in an image format crate to add embedded-graphics support.
- #247 Added `Image` drawable. The `Image` drawable is used to make an implementation of `ImageData`, e.g. from `tinytga` or `tinybmp`, drawable to a `DrawTarget`, like a display.
### Changed
- **(breaking)** [#256](https://github.com/embedded-graphics/embedded-graphics/pull/256) Make `PrimitiveStyleBuilder` and `TextStyleBuilder` consuming by following the [consuming builder pattern](https://doc.rust-lang.org/1.0.0/style/ownership/builders.html#consuming-builders:).
- **(breaking)** #247 The raw data `Image` struct is renamed to `ImageRaw`. The `Image` name is reused as a wrapper for other image types that implement the `ImageData` trait.
- **(breaking)** #247 `ImageLE` and `ImageBE` are renamed to `ImageRawLE` and `ImageRawBE` respectively.
- **(breaking)** #247 `ImageTga` and `ImageTga` are removed, along with their respective enabling features `bmp` and `tga`. To use BMP or TGA images, add `tinybmp` or `tinytga` to your dependencies with the `graphics` feature enabled. This allows usage of `Bmp` and `Tga` in embedded-graphics contexts. Tinybmp or tinytga usage now looks like this:
`Cargo.toml`:
```toml
[dependencies]
embedded-graphics = "0.6.0"
tinybmp = { version = "0.2.0", features = [ "graphics" ]}
```
Your code:
```rust
use embedded_graphics::{prelude::*, image::Image};
use tinybmp::Bmp;
let image = Bmp::new(include_bytes!("../../../assets/patch.bmp")).unwrap();
let image = Image::new(&image);
display.draw(&image);
```
- **(breaking)** #243 All methods on `DrawTarget` that handle drawing to/updating the display are now fallible and return `Result<(), Self::Error>` to allow for error handling in user code. This also affects `Drawable::draw()`, which now propagates any errors that occur while drawing.
- **(breaking)** #243 `DrawTarget::flush()` is removed. The display driver itself should provide this method if required.
- Expose `mock_display::MockDisplay` for use in tests, examples, etc in crates that pull embedded-graphics in as a dependency.
## 0.6.0-alpha.3
### Added
- #170 Added a `24x32` font based on the existing `12x16` font.
* #221 Implemented `Drawable` for `Pixel` to draw single pixels.
* #215 Added `PrimitiveStyleBuilder`.
* #215 Added `TextStyleBuilder`.
* #224 Added `Triangle::from_points` which accepts either `[Point; 3]`, or an array of length 3 containing any item that implements `Into<Point>`.
### Fixed
- #143, #209 Circles with no stroke are now drawn correctly
### Changed
- **(breaking)** The `Drawable` trait now has a required trait method `draw()`, which describes how the object will be drawn on the screen. See the docs for more details.
- **(breaking)** The `Drawing` trait has been renamed to `DrawTarget`. The required trait method to implement has changed from `draw()` to `draw_pixel()`, and optional trait methods have been added to allow an implementing display driver to specify hardware-accelerated methods for drawing graphics primitives.
- **(breaking)** #161 The `.fill()` and `.stroke()` style methods are renamed to `.fill_color()` and `.stroke_color()` respectively. This is to reduce confusion between names like `.stroke()` and `.stroke_width()`. Example:
```rust
use embedded_graphics::{
prelude::*,
primitives::Circle,
egcircle
};
let circle = Circle::new(Point::new(20, 20), 5)
.stroke_width(10)
.stroke_color(Some(BinaryColor::On))
.fill_color(Some(BinaryColor::Off));
```
* **(breaking)** The type of `Style::stroke_width` changed from `u8` to `u32`.
* **(breaking)** Primitives shapes need to be converted into `Styled`s to be drawn.
* **(breaking)** The primitive macros like `egline` don't accept a `style` setting anymore. Use `object.style = new_style` instead.
* **(breaking)** The `Style` struct was replaced by `PrimitiveStyle` and `TextStyle`.
- **(breaking)** Text rendering is now implemented using `Text`, `TextStyle` and `Font` objects instead of using `Font::render_str`.
* **(breaking)** #224 Embedded Graphics macros now use named instead of positional parameters. Styling is now achieved using the `style` property which receives a `PrimitiveStyle` for primitives, and a `TextStyle`. There are convenience macros (`primitive_style!()` and `text_style!()` respectively) to make styling objects easier.
```rust
use embedded_graphics::{egcircle, egline, egrectangle, egtext, egtriangle, text_style};
// OLD
egcircle!(
(15, 20),
10,
stroke = Some(Rgb565::RED),
fill = Some(Rgb565::GREEN)
);
// NEW
egcircle!(
center = (15, 20),
radius = 10,
style = primitive_style!(stroke = Rgb565::RED, fill = Rgb565::GREEN)
);
// OLD
egrectangle!(
(0, 0),
(64, 64),
stroke = Some(Rgb565::RED),
fill = Some(Rgb565::GREEN)
);
// NEW
egrectangle!(
top_left = (0, 0),
bottom_right = (64, 64),
style = primitive_style!(stroke = Rgb565::RED, fill = Rgb565::GREEN)
);
// OLD
egtriangle!((32, 0), (0, 64), (64, 64));
// NEW
egtriangle!(
points = [(32, 0), (0, 64), (64, 64)],
style = primitive_style!(stroke = Rgb565::RED, fill = Rgb565::GREEN)
);
// OLD
egline!((32, 0), (0, 64));
// NEW
egline!(
start = (32, 0),
end = (0, 64),
style = primitive_style!(stroke = Rgb565::RED,)
);
// OLD
egtext!("456", (10, 10), font = Font6x8, stroke = Some(Rgb565::RED));
// NEW
egtext!(
text = "456",
top_left = (10, 10),
style = text_style!(font = Font6x8, text_color = Rgb565::RED)
);
```
### Removed
- **(breaking)** The `SizedDrawing` trait is removed.
## 0.6.0-alpha.2
### Changed
- **(breaking)** `Coord` and `UnsignedCoord` are replaced by [`Point`] and [`Size`].
- **(breaking)** The `Image` struct is removed from the prelude. Import it with `use embedded_graphics::image::Image` instead.
- **(breaking)** Integration with Nalgebra through the `nalgebra_support` feature is now achieved by converting Nalgebra types into `Point` or `Size` instead of Embedded Graphics aliasing [`Point`] and [`Size`] to [`nalgebra::Vector2<i32>`] and [`nalgebra::Vector2<u32>`] respectively. Integration now requires calling `Point::from(my_nalgebra_var)` or `my_nalgebra_var.into()`.
The benefit of this change is to allow more integer primitive types in [`Vector2`]. Embedded Graphics should now support `u8`, `u16` and `u32` conversions to `Size`, and `u8`, `u16`, `i8`, `i16` and `i32` conversions to [`Point`]. It also reduces coupling between Nalgebra and Embedded Graphics.
- **(breaking)** `Point`s can no longer be created from `(u32, u32)`, `[u32; 2]` or `&[u32; 2]`; these conversions are dangerous as the full range of `u32` values cannot be represented by the `i32` used for storage inside [`Point`].
* **(breaking)** `Pixel` now uses the signed [`Point`] type as the first element. Display drivers need to implement an additional check if `x` and `y` are greater or equal to zero.
* **(breaking)** The image module has been rewritten to support big- and little-endian image formats. [`Image1BPP`], [`Image8BPP`] and [`Image16BPP`] are no longer available, and have been replaced with the single [`Image`] type. To migrate from the previous image types, use [`Image`] with a specified pixel color, like this:
```rust
use embedded_graphics::{
image::Image,
pixelcolor::{BinaryColor, Gray8, Rgb565}
};
// Image1BPP
let image: Image<BinaryColor> = Image::new(DATA, 12, 5);
// Image8BPP
let image: Image<Gray8> = Image::new(DATA, 12, 5);
// Image16BPP
let image: Image<Rgb565> = Image::new(DATA, 12, 5);
```
There are other pixel color types available. Take a look at the [`pixelcolor`] module for a full list.
If you need to specify an endianness for the image data (like when using multiple bytes per pixel), the [`ImageLE`] and [`ImageBE`] type aliases have been added.
### Removed
- **(breaking)** `Coord::clamp_positive` is removed.
- **(breaking)** The `icoord!()` and `ucoord!()` macros are removed. Use [`Point::new()`] or [`Size::new()`] respectively instead.
### Fixed
- The code examples `README.md` are now checked in CI during crate compilation. They were woefully outdated and have now been fixed.
[`point`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/geometry/struct.Point.html
[`point::new()`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/geometry/struct.Point.html#method.new
[`size`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/geometry/struct.Size.html
[`size::new()`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/geometry/struct.Size.html#method.new
[`pixelcolor`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/pixelcolor/index.html
[`image1bpp`]: https://docs.rs/embedded-graphics/0.5.1/embedded_graphics/image/type.Image1BPP.html
[`image8bpp`]: https://docs.rs/embedded-graphics/0.5.1/embedded_graphics/image/type.Image8BPP.html
[`image16bpp`]: https://docs.rs/embedded-graphics/0.5.1/embedded_graphics/image/type.Image16BPP.html
[`image`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/image/struct.Image.html
[`imagele`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/image/type.ImageLE.html
[`imagebe`]: https://docs.rs/embedded-graphics/0.6.0-alpha.2/embedded_graphics/image/type.ImageBE.html
[`nalgebra::vector2<i32>`]: https://docs.rs/nalgebra/0.18.0/nalgebra/base/type.Vector2.html
[`nalgebra::vector2<u32>`]: https://docs.rs/nalgebra/0.18.0/nalgebra/base/type.Vector2.html
[`vector2`]: https://docs.rs/nalgebra/0.18.0/nalgebra/base/type.Vector2.html
## 0.6.0-alpha.1
Major breaking changes ahead! @rfuest has been hard at work making the colours story in Embedded Graphics much richer and easier to use.
As this is an alpha version, please give it a test and report back any issues you find!
### Changed
- **(breaking)** Added many colour types
## 0.5.2
Small doc fixes and other minor changes.
### Added
- Added low-effort Embedded Graphics logo for <https://docs.rs/embedded-graphics>
### Fixed
- Wrap `Coord` code example in backticks so it's rendered as code by Rustdoc
## 0.5.1
A couple of breaking changes around naming, mostly polish around public APIs
### Added
### Changed
- **(breaking)** Primitives macros have been renamed. This is primarily to fix conflicts with `std`'s `line!()` macro, but I thought I'd take the opportunity to make the names a bit better/more consistent at the same time:
- `line` -> `egline`
- `triangle` -> `egtriangle`
- `rect` -> `egrectangle`
- `circle` -> `egcircle`
- **(breaking)** The `Rect` primitive is now renamed to `Rectangle` to fit with the other non-truncated primitive names.
## 0.5.0
A big release, focussed on ergonomics. There are new macros to make drawing and positioning primitives and text much less noisy, as well as changes to the `Drawing` trait to remove the explicit `.into_iter()` call when passing objects to it.
### Added
- Add `SizedDrawing` trait. This is useful for displays that support partial screen updates. If the passed object has known dimensions (via the `Dimensions`) trait, a smaller draw area can be specified, reducing the number of bytes sent over the wire. This also opens up the possibility of bufferless display drivers!
- Macros for primitives, text, `UnsignedCoord` and `Coord`! This should make graphics-heavy code much quicker to write, and much cleaner to read. For example, to create a line and a circle:
Code that looked like this:
```rust
display.draw(
Circle::new(Coord::new(10, 10), 10 as u32)
.with_stroke(Some(0u8))
.with_fill(Some(1u8))
.into_iter(),
);
display.draw(
Circle::new(Coord::new(10, 10), 10 as u32)
.translate(Coord::new(10, 10))
.with_stroke(Some(0u8))
.with_fill(Some(0u8))
.into_iter(),
);
display.draw(
Rect::new(Coord::new(0, 0), Coord::new(64, 64))
.translate(Coord::new(96 + 32, 32))
.with_stroke(Some(0u8))
.with_fill(Some(0u8))
.into_iter(),
);
display.draw(
Triangle::new(Coord::new(32, 0), Coord::new(0, 64), Coord::new(64, 64))
.translate(Coord::new(96 * 2 + 16, 16))
.with_stroke(Some(0u8))
.with_fill(Some(1u8))
.into_iter(),
);
```
Now looks like this:
```rust
display.draw(circle!((10, 10), 10 as u32, stroke = Some(0u8), fill = Some(1u8)));
display.draw(
circle!((10, 10), 10 as u32, stroke = Some(0u8), fill = Some(0u8))
.translate(icoord!(10, 10)),
);
display.draw(
rect!((0, 0), (64, 64), stroke = Some(0u8), fill = Some(1u8))
.translate(icoord!(96 + 16, 16)),
);
display.draw(
triangle!(
(32, 0),
(0, 64),
(64, 64),
stroke = Some(0u8),
fill = Some(1u8)
)
.translate(icoord!(96 * 2 + 16, 16)),
);
```
- Added `pixelcolor::RGB565` to make working with displays and images in the common [RGB565](http://www.barth-dev.de/online/rgb565-color-picker/) pixel format.
### Changed
- `Drawing#draw` now accepts `IntoIterator` instead of `Iter`.
**This is a breaking change for driver implementors. Client code should still be fine, as `.into_iter()` can still be called.**
This allows passing of embedded_graphics objects without having to explicitly call `.into_iter`:
```rust
// Before (still works)
display.draw(
Circle::new(Coord::new(10, 10), 10 as u32)
.into_iter()
);
// After
display.draw(
Circle::new(Coord::new(10, 10), 10 as u32)
);
```
This also means that objects can be passed by reference too:
```rust
let circle = Circle::new(Coord::new(10, 10), 10 as u32);
display.draw(&circle);
// Reuse `circle` here
```
- **(breaking)** All `with_<prop>()` style methods are replaced by their unprefixed `<prop>()` counterparts - #106
- `with_style()` -> `style()`
- `with_stroke()` -> `stroke()`
- `with_stroke_width()` -> `stroke_width()`
- `with_fill()` -> `fill()`
- **(breaking)** `ImageBMP` and `ImageTGA` are now disabled by default behind Cargo features
- Get `ImageBMP` by adding the `bmp` feature to your `Cargo.toml`
- Get `ImageTGA` by adding the `tga` feature to your `Cargo.toml`
- **(breaking)** fonts now render with a transparent background by default. To get the old behaviour back, add a `fill` like this:
```rust
// Without macros
Font6x8::render_str("Hello Rust!").fill(Some(1u8.into()));
// With macros
text_6x8!("Hello Rust!", fill = Some(1u8.into()));
```
- Added a bunch of examples and docs. I hope it makes the crate easier to use! Please open an issue if anything is missing or hard to understand.
- `From` is implemented for a few more types for `Coord` and `UnsignedCoord`. Among other things, they can now be converted to tuples by calling `.into()`.
### Removed
- **(breaking)** `PixelColorU*` types. Use vanilla `u8`, `u16` or `u32` instead.
- `PixelColorU8` -> `u8`
- `PixelColorU16` -> `u16`
- `PixelColorU32` -> `u32`
- **(breaking)** The deprecated `.dimensions()` method for fonts is replaced by the `.size()` method from the `WithStyle` trait. This makes fonts consistent with other embedded-graphics objects
### Fixed
- Circles with no stroke but `Some(...)` fill are now rendered instead of skipped.
- Embedded graphics objects can now be returned from functions, chained or not. For example:
```rust
fn multi() -> impl Iterator<Item = Pixel<u8>> {
let line = Line::new(Coord::new(0, 1), Coord::new(2, 3))
.stroke(Some(1u8.into()));
let circle = Circle::new(Coord::new(5, 5), 3)
.stroke(Some(1u8.into()));
line.into_iter().chain(circle)
}
```
<!-- next-url -->
[unreleased]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.8.2...HEAD
[0.8.2]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.8.1...embedded-graphics-v0.8.2
[0.8.1]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.8.0...embedded-graphics-v0.8.1
[0.8.0]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.7.1...embedded-graphics-v0.8.0
[0.7.1]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.7.0...embedded-graphics-v0.7.1
[0.7.0]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.7.0-beta.2...embedded-graphics-v0.7.0
[0.7.0-beta.2]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.7.0-beta.1...embedded-graphics-v0.7.0-beta.2
[0.7.0-beta.1]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.7.0-alpha.3...embedded-graphics-v0.7.0-beta.1
[0.7.0-alpha.3]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.7.0-alpha.2...embedded-graphics-v0.7.0-alpha.3
[0.7.0-alpha.2]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.7.0-alpha.1...embedded-graphics-v0.7.0-alpha.2
[0.7.0-alpha.1]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.6.2...embedded-graphics-v0.7.0-alpha.1
[0.6.2]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.6.1...embedded-graphics-v0.6.2
[0.6.1]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.6.0...embedded-graphics-v0.6.1
[0.6.0]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.6.0-beta.2...embedded-graphics-v0.6.0
[0.6.0-beta.2]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.6.0-beta.1...embedded-graphics-v0.6.0-beta.2
[0.6.0-beta.1]: https://github.com/embedded-graphics/embedded-graphics/compare/embedded-graphics-v0.6.0-alpha.3...embedded-graphics-v0.6.0-beta.1
+667
View File
@@ -0,0 +1,667 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
dependencies = [
"num-traits",
]
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "az"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytemuck"
version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "ciborium"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
[[package]]
name = "ciborium-ll"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "clap"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
"bitflags",
"clap_lex",
"indexmap",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "criterion"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb"
dependencies = [
"anes",
"atty",
"cast",
"ciborium",
"clap",
"criterion-plot",
"itertools",
"lazy_static",
"num-traits",
"oorandom",
"regex",
"serde",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
dependencies = [
"cast",
"itertools",
]
[[package]]
name = "crunchy"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "defmt"
version = "0.3.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad"
dependencies = [
"defmt 1.0.1",
]
[[package]]
name = "defmt"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
dependencies = [
"bitflags",
"defmt-macros",
]
[[package]]
name = "defmt-macros"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
dependencies = [
"defmt-parser",
"proc-macro-error2",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "defmt-parser"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
dependencies = [
"thiserror",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "embedded-graphics"
version = "0.8.2"
dependencies = [
"arrayvec",
"az",
"byteorder",
"criterion",
"defmt 0.3.100",
"embedded-graphics-core",
"fixed",
"float-cmp",
"half",
"micromath",
]
[[package]]
name = "embedded-graphics-core"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95743bef3ff70fcba3930246c4e6872882bbea0dcc6da2ca860112e0cd4bd09f"
dependencies = [
"az",
"byteorder",
"defmt 0.3.100",
"nalgebra",
]
[[package]]
name = "fixed"
version = "1.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fc715d38bea7b5bf487fcd79bcf8c209f0b58014f3018a7a19c2b855f472048"
dependencies = [
"az",
"bytemuck",
"half",
"typenum",
]
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "half"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
dependencies = [
"cfg-if",
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.182"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "micromath"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
[[package]]
name = "nalgebra"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be"
dependencies = [
"approx",
"num-complex",
"num-rational",
"num-traits",
"simba",
"typenum",
]
[[package]]
name = "num-complex"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "oorandom"
version = "11.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
[[package]]
name = "os_str_bytes"
version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "proc-macro-error2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "simba"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3fd720c48c53cace224ae62bef1bbff363a70c68c4802a78b5cc6159618176"
dependencies = [
"approx",
"num-complex",
"num-traits",
"paste",
]
[[package]]
name = "syn"
version = "2.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "textwrap"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+173
View File
@@ -0,0 +1,173 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
name = "embedded-graphics"
version = "0.8.2"
authors = [
"James Waples <james@wapl.es>",
"Ralf Fuest <mail@rfuest.de>",
]
build = false
exclude = [
"/.circleci/",
"/.github/",
".gitignore",
"convert_1bpp.sh",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Embedded graphics library for small hardware displays"
documentation = "https://docs.rs/embedded-graphics"
readme = "README.md"
keywords = [
"embedded-graphics",
"graphics",
"embedded",
]
categories = [
"embedded",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/embedded-graphics/embedded-graphics"
[package.metadata.docs.rs]
all-features = true
[badges.circle-ci]
branch = "master"
repository = "embedded-graphics/embedded-graphics"
[features]
default = []
defmt = [
"dep:defmt",
"embedded-graphics-core/defmt",
]
fixed_point = [
"fixed",
"half",
]
nalgebra_support = ["embedded-graphics-core/nalgebra_support"]
[lib]
name = "embedded_graphics"
path = "src/lib.rs"
[[test]]
name = "chaining"
path = "tests/chaining.rs"
[[test]]
name = "custom_primitive"
path = "tests/custom_primitive.rs"
[[test]]
name = "custom_primitive_style"
path = "tests/custom_primitive_style.rs"
[[test]]
name = "font"
path = "tests/font.rs"
[[test]]
name = "text_renderer_generic"
path = "tests/text_renderer_generic.rs"
[[bench]]
name = "color_conversion"
path = "benches/color_conversion.rs"
harness = false
[[bench]]
name = "common"
path = "benches/common.rs"
[[bench]]
name = "contains"
path = "benches/contains.rs"
harness = false
[[bench]]
name = "fonts"
path = "benches/fonts.rs"
harness = false
[[bench]]
name = "framebuffer"
path = "benches/framebuffer.rs"
harness = false
[[bench]]
name = "image"
path = "benches/image.rs"
harness = false
[[bench]]
name = "primitives"
path = "benches/primitives.rs"
harness = false
[[bench]]
name = "primitives_fixed_point"
path = "benches/primitives_fixed_point.rs"
harness = false
required-features = ["fixed_point"]
[[bench]]
name = "raw_data_iter"
path = "benches/raw_data_iter.rs"
harness = false
[dependencies.az]
version = "~1.2.0"
[dependencies.byteorder]
version = "1.4.3"
default-features = false
[dependencies.defmt]
version = "0.3.2"
optional = true
[dependencies.embedded-graphics-core]
version = "^0.4.1"
[dependencies.fixed]
version = "~1.27.0"
optional = true
default-features = false
[dependencies.float-cmp]
version = "0.9.0"
[dependencies.half]
version = "~2.4.1"
optional = true
default-features = false
[dependencies.micromath]
version = "2.0.0"
default-features = false
[dev-dependencies.arrayvec]
version = "0.7.2"
default-features = false
[dev-dependencies.criterion]
version = "0.4.0"
features = ["html_reports"]
default-features = false
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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
http://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.
+25
View File
@@ -0,0 +1,25 @@
Copyright (c) 2020 James Waples
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+487
View File
@@ -0,0 +1,487 @@
# Migrating from embedded-graphics 0.5.x to 0.6.0
**Are you a driver author? Please see the [for driver authors](#for-driver-authors) section for required changes.**
**Are you a font author? Please see the [for font authors](#for-font-authors) section for required changes.**
As a general user of embedded-graphics, please read on.
## Table of contents
- [Table of contents](#table-of-contents)
- [Pixel colors](#pixel-colors)
- [Color constants](#color-constants)
- [Upgrading from the old `Rgb565` color type](#upgrading-from-the-old-rgb565-color-type)
- [General drawing operations](#general-drawing-operations)
- [Coordinates, sizing and positioning](#coordinates-sizing-and-positioning)
- [Text](#text)
- [Primitives and their styling](#primitives-and-their-styling)
- [Images](#images)
- [For driver authors](#for-driver-authors)
- [Choosing the right pixel color type](#choosing-the-right-pixel-color-type)
- [For font authors](#for-font-authors)
## Pixel colors
The `u8`, `u16` or `u32` primitive types can no longer directly be used as pixel colors, because these don't allow the exact color format to be specified at the type level. This could lead to errors when colors were used in different places without being converted explicitly (e.g. when displaying a grayscale image on a color display).
Instead, multiple color types for commonly used color formats have been added. These pixel types distinguish their underlying storage from their color representation using the `Raw*` types. The table below lists the new colors and accompanying storage types.
| Type name | Storage type | Underlying storage |
| ------------- | ------------ | ------------------ |
| `BinaryColor` | `RawU1` | `u8` |
| `Gray2` | `RawU2` | `u8` |
| `Gray4` | `RawU4` | `u8` |
| `Gray8` | `RawU8` | `u8` |
| `Rgb555` | `RawU16` | `u16` |
| `Rgb565` | `RawU16` | `u16` |
| `Bgr555` | `RawU16` | `u16` |
| `Bgr565` | `RawU16` | `u16` |
| `Rgb888` | `RawU24` | `u32` |
| `Bgr888` | `RawU24` | `u32` |
Additional color types can be created for targets where no suitable builtin color type exists.
Creating various colors now works like this:
```rust
use embedded_graphics::{
pixelcolor::{BinaryColor, Rgb565, Rgb888},
prelude::*,
};
// Binary color (off/on)
let on = BinaryColor::On;
// Red with a small amount of green creates a deep orange color
let rust = Rgb565::new(0x1f, 0x07, 0x00);
// Use a color constant provided by the RGB color types
let magenta = Rgb888::MAGENTA;
```
Pixels can also be converted to their underlying storage by calling `.into_storage()`:
```rust
use embedded_graphics::{
pixelcolor::Rgb565,
prelude::*,
};
let raw_value: u16 = Rgb565::MAGENTA.into_storage();
```
### Color constants
Predefined color constants have been added to all grayscale and RGB colors.
Usage:
```rust
use embedded_graphics::{prelude::*, pixelcolor::{Gray8, Rgb565}};
let white = Gray8::WHITE;
let cyan = Rgb565::CYAN;
```
#### Predefined colors for `Gray2`, `Gray4` and `Gray8`
These are provided by the `GrayColor` trait impl.
- `BLACK`
- `WHITE`
#### Predefined colors for `Rgb555` `Rgb565`, `Bgr555`, `Bgr565`, `Rgb888` and `Bgr888`
These are provided by the `RgbColor` trait impl.
- `BLACK`
- `WHITE`
- `RED`
- `GREEN`
- `BLUE`
- `CYAN`
- `MAGENTA`
- `YELLOW`
### Upgrading from the old `Rgb565` color type
0.5 also includes the `Rgb565` color type. Previously creating a new `Rgb565` required a tuple of 3 values. This is now replaced by the `Rgb565::new` method:
```diff
// Create an orange color
- let color: Rgb565 = (0x1f, 0x07, 0x00).into();
+ let color = Rgb565::new(0x1f, 0x07, 0x00);
```
## General drawing operations
Drawing operations are "reversed" in 0.6.0. Instead of calling `display.draw(thing)`, call `thing.draw(&mut display)`:
```diff
- let rect = Rectangle::new(Coord::new(50, 20), Coord::new(60, 35))
- .stroke(Some(5u8))
- .stroke_width(3)
- .fill(Some(10u8));
-
- display.draw(rect);
+ let style = PrimitiveStyleBuilder::new()
+ .stroke_color(Rgb565::RED)
+ .stroke_width(3)
+ .fill_color(Rgb565::GREEN)
+ .build();
+
+ Rectangle::new(Point::new(50, 20), Point::new(60, 35))
+ .into_styled(style)
+ .draw(&mut display)?;
```
Chaining now looks like this:
```rust
Circle::new(Point::new(64, 64), 64)
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.into_iter()
.chain(
&Line::new(Point::new(64, 64), Point::new(0, 64))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)),
)
.chain(
&Line::new(Point::new(64, 64), Point::new(80, 80))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)),
)
.chain(
&Text::new("Hello World!", Point::new(5, 50))
.into_styled(TextStyle::new(Font6x8, BinaryColor::On)),
)
.draw(&mut display);
```
Drawing operations are now fallible, with `.draw()` calls returning a `Result`. This allows for error handling if an error occurs during a drawing operation. The error type of this `Result` is dependent on the associated `Error` type as defined by the display driver's `DrawTarget` impl.
## Coordinates, sizing and positioning
The `Coord` and `UnsignedCoord` have been replaced with `Point` and `Size` respectively. Both items are no longer tuple structs, but structs with the named fields `x` and `y` for `Point` and `width` and `height` for `Size`. `Point`s can store negative coordinates, whereas `Size`s must be positive as each dimension is stored as a `u32`.
It is important to note that the `Pixel` type now uses `Point` for it's coordinate component. In 0.5, `UnsignedCoord` was used. This change now allows `Pixel`s to represent negative coordinates, however drivers must check that pixels to be drawn to the display are non-negative.
The `icoord` and `ucoord` macros have been removed. Instead, use `Point::new(x, y)` and `Size::new(x, y)` respectively.
`Point::zero()` and `Size::zero()` were also added to get zero-filled coordinates.
```diff
- let c = Coord::new(-10, 20);
+ let c = Point::new(-10, 20);
- println!("X: {}, Y: {}", c.0, c.1);
+ println!("X: {}, Y: {}", c.x, c.y);
- let p = UnsignedCoord::new(5, 15);
+ let p = Size::new(5, 15);
- println!("X: {}, Y: {}", p.0, p.1);
+ println!("X: {}, Y: {}", p.width, p.height);
```
## Text
Text is now drawn with the `Text` struct. A `TextStyle` must be provided which selects which font and color to draw the text with. The `stroke_color` property from 0.5 is renamed to `text_color`. Likewise, `fill_color` is renamed to `background_color`.
```diff
- use embedded_graphics::{
- prelude::*,
- fonts::Font6x8,
- };
-
- display.draw(
- Font6x8::render_str("Hello Rust!")
- .translate(Coord::new(20, 30))
- .fill(Some(1u8))
- .stroke(Some(0u8)),
- );
+ use embedded_graphics::{
+ fonts::{Font6x8, Text},
+ pixelcolor::BinaryColor,
+ prelude::*,
+ style::TextStyleBuilder,
+ };
+
+ // Create a new text style
+ let style = TextStyleBuilder::new(Font6x8)
+ .text_color(BinaryColor::On)
+ .background_color(BinaryColor::Off)
+ .build();
+
+ // Create a text at position (20, 30) and draw it using style defined above
+ Text::new("Hello Rust!", Point::new(20, 30))
+ .into_styled(style)
+ .draw(&mut display)?;
```
- A new `Text` struct is introduced. Instead of `YourFont::render_str("text")`, use `Text::new("text", Point::zero())`.
- Text must be given a `TextStyle` for it to be drawn on a display. Create a style with either:
- `TextStyleBuilder` or
- `TextStyle::new(font, text_color)` to create a basic style in a more concise way.
Styles are applied to the text object by calling `.into_styled(style)` as shown above.
- The chosen font is now part of the `TextStyleBuilder` creation process. Set it with `TextStyleBuilder::new(<your font here>)`.
Macro usage has also changed:
```diff
- use embedded_graphics::{prelude::*, text_6x8};
-
- display.draw(
- text_6x8!(
- "Hello Rust!",
- stroke = Some(1u8.into()),
- fill = Some(0u8.into())
- )
- .translate(Coord::new(20, 30))
- );
+ use embedded_graphics::{egtext, text_style, fonts::Font6x8, pixelcolor::BinaryColor, prelude::*};
+
+ egtext!(
+ text = "Hello Rust!",
+ top_left = (20, 30),
+ style = text_style!(
+ font = Font6x8,
+ text_color = BinaryColor::On,
+ background_color = BinaryColor::Off,
+ )
+ )
+ .draw(&mut display)?;
```
- All built in `text_*!()` macros are removed and replaced with the `egtext!()` macro.
- The `text_style!()` macro can be used to create more complex text styles. For simple styles, `TextStyle::new(font, text_color)` can be used instead:
```rust
egtext!(
text = "Hello Rust!",
top_left = (20, 30),
style = TextStyle::new(Font6x8, BinaryColor::On)
)
.draw(&mut display)?;
```
Multiline text is now supported:
```diff
- use embedded_graphics::{prelude::*, text_6x8};
-
- display.draw(
- text_6x8!(
- "Hello,",
- stroke = Some(1u8.into()),
- fill = Some(0u8.into())
- )
- .translate(Coord::new(0, 8))
- );
- display.draw(
- text_6x8!(
- "World!",
- stroke = Some(1u8.into()),
- fill = Some(0u8.into())
- )
- .translate(Coord::new(0, 8))
- );
+ use embedded_graphics::{egtext, text_style, fonts::Font6x8, pixelcolor::BinaryColor, prelude::*};
+
+ egtext!(
+ text = "Hello,\nworld!",
+ top_left = (0, 0),
+ style = text_style!(
+ font = Font6x8,
+ text_color = BinaryColor::On,
+ background_color = BinaryColor::Off,
+ )
+ )
+ .draw(&mut display)?;
```
## Primitives and their styling
Note: The `Triangle` primitive was added in 0.4.8. If you were using 3 separate lines, this primitive is suggested instead.
**Primitive styles now default to a stroke width of `0` instead of `1`.** If nothing is drawn to the display, it may be that `stroke_width` is set to 0.
To style a primitive, a `PrimitiveStyle` must be used. To create simple styles, the `PrimitiveStyle::with_stroke()` and `PrimitiveStyle::with_fill()` methods can be used. For a more flexible way of creating styles, use `PrimitiveStyleBuilder`:
```rust
use embedded_graphics::{
pixelcolor::{BinaryColor, Rgb565},
prelude::*,
style::{PrimitiveStyle, PrimitiveStyleBuilder},
};
// Simple style with only a 1px stroke
let style = PrimitiveStyle::with_stroke(BinaryColor::On, 1);
// Create a more complex style using the builder
let style: PrimitiveStyle<Rgb565> = PrimitiveStyleBuilder::new()
.stroke_color(Rgb565::RED)
.stroke_width(3)
.fill_color(Rgb565::GREEN)
.build();
```
## Images
The `ImageBMP` and `ImageTGA` built-in image types are removed in favour of using the new `graphics` features of the [tinybmp](https://crates.io/crates/tinybmp) and [tinytga](https://crates.io/crates/tinytga) crates. These must be wrapped in the `Image` struct for use with embedded-graphics.
First, change the imports in `Cargo.toml`:
```diff
[dependencies]
- embedded-graphics = { version = "0.5.1", features = [ "tga", "bmp" ] }
+ embedded-graphics = "0.6.0"
+ tinytga = { version = "0.3.0", features = [ "graphics" ] }
+ tinybmp = { version = "0.2.0", features = [ "graphics" ] }
```
Then any image code:
```diff
- use embedded_graphics::{prelude::*, image::ImageBmp};
-
- let image = ImageBmp::new(include_bytes!("../../../assets/patch_16bpp.bmp")).unwrap();
-
- display.draw(&image);
+ use embedded_graphics::{prelude::*, image::Image, geometry::Point}
+ use tinybmp::Bmp;
+
+ let bmp = Bmp::from_slice(include_bytes!("../../../assets/patch_16bpp.bmp")).unwrap();
+
+ let image = Image::new(&bmp, Point::zero());
+
+ image.draw(&mut display)?;
```
## For driver authors
Adding embedded-graphics support to a display driver has changed somewhat. The `Drawing` trait has been replaced by the `DrawTarget` trait which provides a slightly different interface.
An associated error type is also added to `DrawTarget` to allow for better error handling than a `panic!()`.
Below is a reduced example taken from the [ssd1306](https://crates.io/crates/ssd1306) driver. It uses `BinaryColor` as pixels on the SSD1306 can only be on or off.
```rust
use embedded_graphics::{
drawable,
geometry::Size,
pixelcolor::{
raw::{RawData, RawU1},
BinaryColor, PixelColor,
},
DrawTarget,
};
impl DrawTarget<BinaryColor> for DisplayDriver
{
type Error = DI::Error;
fn draw_pixel(&mut self, pixel: drawable::Pixel<BinaryColor>) -> Result<(), Self::Error> {
let drawable::Pixel(pos, color) = pixel;
// Guard against negative values. All positive i32 values from `pos` can be represented in
// the `u32`s that `set_pixel()` accepts...
if pos.x < 0 || pos.y < 0 {
return Ok(());
}
// ... which makes the `as` coercions here safe.
self.set_pixel(
pos.x as u32,
pos.y as u32,
RawU1::from(color).into_inner()
);
Ok(())
}
fn size(&self) -> Size {
let (w, h) = self.get_dimensions();
Size::new(w as u32, h as u32)
}
}
```
Some notes on the above:
- The `Drawing` trait is renamed to `DrawTarget`.
- This implementation takes a `BinaryColor` as it's color type as pixels the SSD1306 can only be off or on. [Other pixel types](#pixel-colors) can be used for displays with a higher color depth.
- The `Drawing::draw` method is replaced by `DrawTarget::draw_pixel`. This method should handle setting of individual pixels on the display. How it does this is at the discretion of the display driver (pixel buffer, immediate mode, etc).
- A new `DrawTarget::size` method is now a required, which should return the width and height of the display in pixels as a `Size`.
- The implementation of `DrawTarget` must now provide an associated `Error` type. If drawing operations can't fail, for example if the driver uses a framebuffer in RAM, `core::convert::Infallible` can used. If drawing operations can fail a better error type should be used to communicate hardware failures, etc to the user.
- Any pixels drawn to offscreen coordinates need to be ignored by `DrawTarget` implementations and not result in panics or any modification of the display content. In the example above, `self.set_pixel()` (defined by the SSD1306 driver) will not attempt to set any pixels beyond the positive screen limits.
- `draw_pixel()` now returns `Result<(), Self::Error>` to account for driver error handling.
New methods have been added to `DrawTarget` that can be overridden by hardware accelerated implementations:
- `DrawTarget::draw_circle`
- `DrawTarget::draw_rectangle`
- `DrawTarget::draw_triangle`
- `DrawTarget::draw_line`
- `DrawTarget::draw_image`
Methods that aren't overridden by the `DrawTarget` impl delegate to `DrawTarget::draw_iter` by default.
More information is provided in the [`DrawTarget` trait documentation](https://docs.rs/embedded-graphics/0.6.0/embedded_graphics/trait.DrawTarget.html).
### Choosing the right pixel color type
Below are some common use cases to help choose the right pixel color for a given display module. The full list of pixel colors is described in [the table above](#pixel-colors).
#### `BinaryColor`
If the display only supports two states, use `BinaryColor`. This is applicable to monochrome OLED displays like the SSD1306 or SH1106, character/bitmap LCDs and even LED matrices.
#### `Rgb565`
Use `Rgb565` for displays advertised as 16 bit color displays will often use a 5R 6G 5B pixel packing, storing each pixel color as a `u16`.
#### `Bgr565`
If the display's pixel order is reversed (BGR instead of RGB) and cannot be changed in configuration, use this type instead of `Rgb565`.
#### `Rgb888`
24 bit color, most useful in the embedded graphics simulator, or for high color display modules.
## For font authors
The `FontBuilderConf` trait is renamed to `Font`. This is the only trait impl that is required for embedded-graphics integration. `FontBuilder` is now removed, along with the `embedded_graphics::fonts::font_builder` module.
The `Font` trait implementation has changed slightly, replacing `CHAR_WIDTH` and `CHAR_HEIGHT` with a single `CHARACTER_SIZE` constant, using the `Size` struct:
```diff
- use embedded_graphics::fonts::font_builder::{FontBuilder, FontBuilderConf};
+ use embedded_graphics::fonts::Font;
+ use embedded_graphics::geometry::Size;
#[derive(Debug, Copy, Clone)]
pub struct MyFont;
impl Font for MyFont {
const FONT_IMAGE: &'static [u8] = include_bytes!("../data/my_font.raw");
- const CHAR_WIDTH: u32 = 12;
- const CHAR_HEIGHT: u32 = 22;
+ const CHARACTER_SIZE: Size = Size::new(12, 22);
const FONT_IMAGE_WIDTH: u32 = 480;
}
```
The `CHARACTER_SPACING` constant is added, providing configurable fixed spacing between characters. This is useful for fonts where there is no built-in spacing in the source bitmap data.
The `VARIABLE_WIDTH` constants is also added, creating support for basic variable width fonts. Setting this to `true` will trim empty pixels to the right of a glyph and add `CHARACTER_SPACING` between each character.
+554
View File
@@ -0,0 +1,554 @@
# Migrating from embedded-graphics 0.6.x to 0.7.0
> Please note that this migration guide may be incomplete in some sections. If any missing or incorrect information is found, please [open an issue](https://github.com/embedded-graphics/embedded-graphics/issues/new) or [join the Matrix chatroom](https://matrix.to/#/#rust-embedded-graphics:matrix.org) to bring it to our attention.
## Table of contents
- [Macros are removed](#macros-are-removed)
- [Primitives](#primitives)
- [Styling](#styling)
- [Circle](#circle)
- [Rectangle](#rectangle)
- [Triangle](#triangle)
- [Geometry](#geometry)
- [Style module](#style-module)
- [Text and fonts](#text-and-fonts)
- [General](#general)
- [`Drawable`](#drawable)
- [`IntoIterator` changes](#intoiterator-changes)
- [Mock display](#mock-display)
- [The `embedded-graphics-core` crate](#the-embedded-graphics-core-crate)
- [For display driver authors](#for-display-driver-authors)
- [Method changes](#method-changes)
- [Example migration](#example-migration)
- [Image format support crates](#image-format-support-crates)
- [For text rendering crates](#for-text-rendering-crates)
- [Monospace fonts](#monospace-fonts)
- [More complex fonts](#more-complex-fonts)
## Macros are removed
All text, primitive and style macros have been removed. To create text, primitives and styles, use the appropriate constructors or builders instead.
For example, a styled rectangle is now built like this:
```diff
- let filled_rect: Styled<Rectangle, PrimitiveStyle<Rgb565>> = egrectangle!(
- top_left = (10, 20),
- bottom_right = (30, 40),
- style = primitive_style!(stroke_color = Rgb565::RED, fill_color = Rgb565::GREEN)
- );
+ let filled_rect = Rectangle::with_corners(Point::new(10, 20), Point::new(30, 40))
+ .into_styled(
+ PrimitiveStyleBuilder::new()
+ .stroke_color(Rgb565::RED)
+ .fill_color(Rgb565::GREEN)
+ .build()
+ );
```
## Primitives
### Styling
Previously, drawing a filled shape with a transparent stroke of non-zero width would bleed the fill under the stroke. This is changed in 0.7 to honor the stroke width and alignment, even if it is the stroke color is `None`, allowing for filled shapes with transparent borders.
The stroke and fill color no longer affect the primitive's bounding box returned by `Dimensions::bounding_box`. The stroke width is now always considered even if the stroke is transparent.
### Circle
A circle is now defined by it's top-left corner and diameter. This has the advantage that circles
with odd diameters are now also supported.
```diff
// Create a circle centered around (30, 30) with a diameter of 20px
use embedded_graphics::{geometry::Point, primitives::Circle};
- let circle = Circle::new(Point::new(30, 30), 10);
+ let circle = Circle::new(Point::new(20, 20), 20);
```
To create a circle from a center point and diameter, use `Circle::with_center`:
```diff
use embedded_graphics::{geometry::Point, primitives::Circle};
- let circle = Circle::new(Point::new(20, 20), 5);
+ let circle = Circle::with_center(Point::new(20, 20), 10);
```
### Rectangle
Rectangles are now defined by their top-left corner and size instead of the top-left and bottom-right corner.
```diff
use embedded_graphics::{geometry::{Point, Size}, primitives::Rectangle};
- let rectangle = Rectangle::new(Point::new(20, 30), Point::new(40, 50));
+ let rectangle = Rectangle::new(Point::new(20, 30), Size::new(20, 30));
```
To retain the old behavior, use `Rectangle::with_corners` instead:
```diff
use embedded_graphics::{geometry::Point, primitives::Rectangle};
- let rectangle = Rectangle::new(Point::new(20, 30), Point::new(40, 50));
+ let rectangle = Rectangle::with_corners(Point::new(20, 30), Point::new(40, 50));
```
### Triangle
The vertices of a triangle are now stored in a single `vertices` field with the type `[Point; 3]`. Previously, they were stored in three separate fields `p1`, `p2` and `p3`.
To access an individual vertex of a triangle, use `triangle.vertices[]`.
```diff
use embedded_graphics::{prelude::*, primitives::Triangle};
let triangle = Triangle::new(Point::new(20, 30), Point::new(40, 50), Point::new(60, 70));
- let p1 = triangle.p1;
- let p2 = triangle.p2;
- let p3 = triangle.p3;
+ let p1 = triangle.vertices[0];
+ let p2 = triangle.vertices[1];
+ let p3 = triangle.vertices[2];
```
To create a triangle from a slice, use the new `Triangle::from_slice` method:
```rust
use embedded_graphics::{geometry::{Point}, primitives::Triangle};
let points = [Point::new(20, 30), Point::new(40, 50), Point::new(60, 70)];
let triangle = Triangle::from_slice(&points);
```
It is no longer possible to create a triangle from an array of `Point`s. Instead, pass a reference to `Triangle::from_slice`.
## Geometry
Inconsistencies in the coordinate system, like an off by one error in the size of rectangles, have been fixed.
The three methods in the `Dimensions` trait were replaced by a single `bounding_box` method. This should return a `Rectangle` which encompasses the entire shape.
## Style module
The `style` module has been removed. The items in it have been moved:
- `PrimitiveStyle`, `PrimitiveStyleBuilder` and `Styled` are now available in the `embedded_graphics::primitives` module.
- `TextStyle` and `TextStyleBuilder` were renamed are now available under `embedded_graphics::mono_font::{MonoTextStyle, MonoTextStyleBuilder}`.
Note that usage with `Text` has changed. See [the text changes section](#text-and-fonts) for more.
## Text and fonts
The `fonts` module has been split into a `text` and a `mono_font` module. The `text` module contains
a `Text` drawable which can be used with different text renderers. The `mono_font` module contains
a text renderer for monospaced fonts and the builtin fonts.
`Text` drawable now use two style objects to define the output format. The first style object is
a character style, which defines parameters like the font and text color. This object is provided
by the used text renderer and the available settings will differ between different renderers.
For the builtin monospaced font support the character style is `MonoTextStyle`, which replaces the
`TextStyle` object from embedded-graphics 0.6.
The second style is the new `TextStyle` which defines how the text should be laid out. Available
settings are horizontal alignment, baseline and line height. This style is independent of the used
text renderer.
The collection of builtin fonts are now sourced from public domain BDF fonts in the XOrg project.
Due to this, they have slightly different dimensions and glyphs and so have changed names. Some
sizes are not the same in the new set, but a rough mapping is as follows:
| Old font | Visually closest new font |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `fonts::Font6x6`<br>![Font6x6 glpyh bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.6.2/embedded-graphics/data/font6x6.png) | `mono_font::ascii::FONT_4X6`<br>![FONT_4X6 glyph bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.7.0-beta.1/fonts/ascii/png/4x6.png) |
| `fonts::Font6x8`<br>![Font6x8 glpyh bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.6.2/embedded-graphics/data/font6x8.png) | `mono_font::ascii::FONT_6X10`<br>![FONT_6X10 glyph bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.7.0-beta.1/fonts/ascii/png/6x10.png) |
| `fonts::Font6x12`<br>![Font6x12 glpyh bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.6.2/embedded-graphics/data/font6x12.png) | `mono_font::ascii::FONT_6X13`<br>![FONT_6X13 glyph bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.7.0-beta.1/fonts/ascii/png/6x13.png) |
| `fonts::Font8x16`<br>![Font8x16 glpyh bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.6.2/embedded-graphics/data/font8x16.png) | `mono_font::ascii::FONT_9X15_BOLD`<br>![FONT_9X15_BOLD glyph bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.7.0-beta.1/fonts/ascii/png/9x15B.png) |
| `fonts::Font12x16`<br>![Font12x16 glpyh bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.6.2/embedded-graphics/data/font12x16.png) | `mono_font::ascii::FONT_10X20`<br>![FONT_10X20 glyph bitmap](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/embedded-graphics-v0.7.0-beta.1/fonts/ascii/png/10x20.png) |
| `fonts::Font24x32` | The largest available new font is `FONT_10X20`, which is significantly smaller than the old `Font24x32`. Larger fonts are available in [external crates](https://github.com/embedded-graphics/embedded-graphics#additional-functions-provided-by-external-crates). |
Note that all fonts are available in with different glyph subsets to support a wide variety of languages. The table above only shows the new fonts' `ascii` variants. The new fonts tend to use a larger glyph height for the same cap height, which improves readability but may require some layout changes.
The default baseline for fonts is now the font's alphabetic baseline instead of the top of the glyph bounding box. To retain the 0.6 behavior and position text using its top-left corner, set the `baseline` property to `Baseline::Top`:
```rust
use embedded_graphics::text::{Baseline, TextStyle, TextStyleBuilder};
let style = TextStyle::with_baseline(Baseline::Top);
// OR
let style = TextStyleBuilder::new().baseline(Baseline::Top).build();
```
## General
### `Drawable`
The `Drawable` trait now uses an associated type for its pixel color instead of a type parameters.
An associated type, `Output`, has also been added which can be used to return values
from drawing operations. The unit type `()` can be used if the `draw` method doesn't need to return
anything, e.g. `type Output = ();`
```diff
- impl<'a, C: 'a> Drawable<C> for &Button<'a, C>
- where
- C: PixelColor + From<BinaryColor>,
- {
- fn draw<D>(self, display: &mut D) -> Result<(), D::Error> where D: DrawTarget<C> {
- // ...
- }
- }
+ impl<C> Drawable for Button<'_, C>
+ where
+ C: PixelColor + From<BinaryColor>,
+ {
+ type Color = C;
+
+ type Output = ();
+
+ fn draw<D>(&self, display: &mut D) -> Result<Self::Output, D::Error>
+ where
+ D: DrawTarget<Color = C>,
+ {
+ Rectangle::new(self.top_left, self.size)
+ .into_styled(PrimitiveStyle::with_fill(self.bg_color))
+ .draw(display)?;
+ Text::new(self.text, Point::new(6, 6))
+ .into_styled(TextStyle::new(Font6x8, self.fg_color))
+ .draw(display)
+ }
+ }
```
### `IntoIterator` changes
Styled primitives no longer implement `IntoIterator` to create a pixel iterator. Use the new `Styled::pixels` method instead.
For example, chaining two pixel iterators together now requires explicit calls to `pixels()`:
```diff
+ use embedded_graphics::prelude::*;
let background = Rectangle::new(...);
let text = Text::new(...);
- background.into_iter().chain(&text)
+ background.pixels().chain(text.pixels())
```
## Mock display
The `MockDisplay`, used often for unit testing, now checks for pixel overdraw and out of bounds drawing by default. These additional checks can be disabled by using the `set_allow_overdraw` and `set_allow_out_of_bounds_drawing` methods, if required.
The `width` and `height` methods have been removed. Use the `bounding_box` method provided by the `Dimensions` trait instead:
```rust
// Or: use embedded_graphics::prelude::*;
use embedded_graphics::geometry::Dimensions;
use embedded_graphics::mock_display::MockDisplay;
let display = MockDisplay::new();
let width = display.bounding_box().size.width;
let height = display.bounding_box().size.height;
```
An advanced visual representation of failing `MockDisplay` assertions can be enabled by setting the `EG_FANCY_PANIC` environment variable to `1`, for example, by calling `EG_FANCY_PANIC=1 cargo test`.
To use `EG_FANCY_PANIC` the new `MockDisplay::assert_eq` and `assert_eq_with_message` must be used instead of the `assert_eq!` macro.
```rust
#[test]
fn check_equality() {
let expected = MockDisplay::from_pattern(&[ /* ... */ ]);
let mut display = MockDisplay::new();
Circle::new(Point::new(1, 1), 1)
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.draw(&mut display)?;
display.assert_eq(&expected);
}
```
The `assert_pattern` and `assert_pattern_with_message` can be used to check the display state against a pattern without using `MockDisplay::from_pattern` and a separate assertion.
```diff
- #[test]
- fn tiny_circle_filled() {
- let mut display = MockDisplay::new();
-
- Circle::new(Point::new(1, 1), 1)
- .into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
- .draw(&mut display)?;
-
- assert_eq!(
- display,
- MockDisplay::from_pattern(&[
- " # ",
- "###",
- " # "
- ])
- );
- }
+ #[test]
+ fn tiny_circle_filled() {
+ let mut display = MockDisplay::new();
+
+ Circle::new(Point::new(0, 0), 3)
+ .into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
+ .draw(&mut display)
+ .unwrap();
+
+ display.assert_pattern(&[
+ " # ",
+ "###",
+ " # ",
+ ]);
+ }
```
## The `embedded-graphics-core` crate
Types that are required by other crates that extend the functionality of `embedded-graphics` have been moved into the new [`embedded-graphics-core`](https://crates.io/crates/embedded-graphics-core) crate. The core crate is intended to provide a more stable interface for display drivers and image libraries to make them work across multiple major releases of `embedded-graphics`.
It is recommended that `embedded-graphics` is used for applications and `embedded-graphics-core` be used for crates that extend embedded graphics where possible. Note that some features required by e.g. image crates are currently only present in `embedded-graphics`, so using `embedded-graphics-core` is not always possible.
## For display driver authors
`DrawTarget` now uses an associated type for the target color instead of a type parameter. As this can be a limitation versus older code which implements `DrawTarget` for e.g. `C: Into<Rgb565>`, the `color_converted` method can be used to create a draw target which converts the drawable's color format to the display's color format.
The `DrawTarget` trait now has an additional bound on the `Dimensions` trait to replace the removed `size` method. By using the `Dimensions` trait the drawable area of a draw targets can be positioned freely and is no longer limited to start in the origin at `(0, 0)`. But for display drivers it is recommended that the drawable area does start at `(0, 0)`. To simplify implementation and provide a type level guarantee that the drawable area starts at the origin, `OriginDimensions` can be implemented instead of `Dimensions`. The `Dimensions` trait is automatically implemented for all types that implement `OriginDimensions`.
Note that `Dimensions` and `OriginDimensions` should be imported from `embedded-graphics-core`, not `embedded-graphics`. See the [relevant section](#the-embedded-graphics-core-crate) for more details.
### Method changes
All `draw_*` methods to draw specific primitives (`draw_circle`, `draw_triangle`, etc) have been removed. These methods were hard to implement correctly and consistently between different drivers. The new lower level draw methods are easier to implement and still improve performance over pixel by pixel drawing.
- `draw_iter`
Draws individual pixels to the display without a defined order. This is the only required method in this trait, however will likely be the slowest pixel drawing implementation as it cannot take advantage of hardware accelerated features (e.g. filling a given area with a solid color with `fill_solid`).
- `fill_contiguous`
Fills a given area with an iterator providing a contiguous stream of pixel colors. This may be used to efficiently draw an image or other non-transparent item to the display. The given pixel iterator can be assumed to be contiguous, iterating from top to bottom, each row left to right. This assumption potentially allows more efficient streaming of pixel data to a display.
- `fill_solid`
Fills a given area with a solid color.
- `clear`
Fills the entire display with a solid color.
These methods aim to be more compatible with hardware-accelerated drawing commands. Where possible, embedded-graphics drawables will use `fill_contiguous` and `fill_solid` to improve performance, however may fall back to `draw_iter` by default.
To reduce duplication, please search the `DrawTarget` documentation on <https://docs.rs/embedded-graphics-core> for more details on the usage and arguments of the above methods.
### Example migration
The following example updates the `SSD1306` driver using the `BinaryColor` color type.
```diff
- use crate::{
- drawable::Pixel,
- geometry::Size,
- pixelcolor::{PixelColor, BinaryColor},
- DrawTarget,
- };
-
- impl DrawTarget<BinaryColor> for Ssd1306 {
- type Error = core::convert::Infallible;
-
- fn draw_pixel(&mut self, pixel: Pixel<BinaryColor>) -> Result<(), Self::Error> {
- // ...
-
- Ok(())
- }
-
- fn size(&self) -> Size {
- // ...
- }
- }
+ use embedded_graphics_core::{
+ draw_target::DrawTarget,
+ geometry::{OriginDimensions, Size},
+ pixelcolor::{PixelColor, BinaryColor},
+ Pixel,
+ };
+
+ DrawTarget for Ssd1306 {
+ type Color = BinaryColor;
+ type Error = core::convert::Infallible;
+
+ fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
+ where
+ I: IntoIterator<Item = Pixel<Self::Color>>,
+ {
+ // ...
+
+ Ok(())
+ }
+ }
+
+ impl OriginDimensions for Ssd1306 {
+ fn size(&self) -> Size {
+ // ...
+ }
+ }
```
## Image format support crates
Image format support crates must now implement the `ImageDrawable` and `OriginDimensions` traits from [`embedded-graphics-core`](#the-embedded-graphics-core-crate) to integrate with embedded-graphics.
The below examples shows an implementation for an imaginary `MyRgb888Image` which uses 24 bit RGB color.
```rust
use embedded_graphics::{
draw_target::{DrawTarget, DrawTargetExt},
geometry::{OriginDimensions, Size},
image::ImageDrawable,
pixelcolor::{PixelColor, Rgb888},
primitives::Rectangle,
};
struct MyRgb888Image {
// ...
}
impl ImageDrawable for MyRgb888Image {
type Color = Rgb888;
fn draw<D>(&self, target: &mut D) -> Result<(), D::Error>
where
D: DrawTarget<Color = Rgb888>,
{
// Draw the image to the target, e.g. by calling `target.fill_contiguous` or by using another `Drawable`.
}
fn draw_sub_image<D>(&self, target: &mut D, area: &Rectangle) -> Result<(), D::Error>
where
D: DrawTarget<Color = Self::Color>,
{
// Delegate to the draw() method using a reduced draw target
self.draw(&mut target.translated(-area.top_left).clipped(area))
}
}
impl OriginDimensions for MyRgb888Image {
fn size(&self) -> Size {
// Return image width and height in pixels
}
}
```
## For text rendering crates
### Monospace fonts
Monospaced fonts no longer use a separate type per font and are now defined by using a `MonoFont` object. In most applications fonts will be declared as a compile time constant, but fonts can now also be loaded or generated at runtime.
```diff
- // The font bitmap has 32 character glyphs per row.
- const CHARS_PER_ROW: u32 = 32;
-
- // Map a given character to an index in the glyph bitmap
- fn char_offset_impl(c: char) -> u32 {
- let fallback = '?' as u32 - ' ' as u32;
- if c < ' ' {
- return fallback;
- }
- if c <= '\u{007f}' {
- return c as u32 - ' ' as u32;
- }
- if c < '\u{00A0}' || c > 'ÿ' {
- return fallback;
- }
- c as u32 - ' ' as u32 - 32
- }
-
- #[derive(Debug, Copy, Clone)]
- pub struct ExampleFont {}
- impl Font for ExampleFont {
- const FONT_IMAGE: &'static [u8] = include_bytes!("../data/ExampleFont.raw");
- const CHARACTER_SIZE: Size = Size::new(5, 9);
- const FONT_IMAGE_WIDTH: u32 = Self::CHARACTER_SIZE.width * CHARS_PER_ROW;
-
- fn char_offset(c: char) -> u32 {
- char_offset_impl(c)
- }
- }
+ use embedded_graphics::{
+ geometry::Size,
+ image::ImageRaw,
+ mono_font::{mapping::ISO_8859_1, DecorationDimensions, MonoFont},
+ };
+
+ pub const EXAMPLE_FONT: MonoFont = MonoFont {
+ image: ImageRaw::new_binary(
+ // This example uses 32 characters per row, each character 5px across.
+ 32 * 5,
+ ),
+ glyph_mapping: &ISO_8859_1,
+ character_size: Size::new(5, 9),
+ character_spacing: 0,
+ baseline: 7,
+ underline: DecorationDimensions::new(8, 1),
+ strikethrough: DecorationDimensions::new(4, 1),
+ };
```
Custom mappings between characters and glyph positions can be used by using `StrGlyphMapping`, using a function or implementing the `GlyphMapping` trait:
```rust
use embedded_graphics::{
geometry::Size,
image::ImageRaw,
mono_font::{mapping::StrGlyphMapping, DecorationDimensions, MonoFont},
};
pub const EXAMPLE_FONT: MonoFont = MonoFont {
image: ImageRaw::new_binary(
include_bytes!("../data/digits.raw"),
// In this example, this equals 10 characters per row, each character 15px across.
10 * 15,
),
glyph_mapping: &StrGlyphMapping::new("\009", 0),
// or use a function:
// glyph_mapping: &digit_mapping,
character_size: Size::new(15, 30),
character_spacing: 5,
baseline: 29,
underline: DecorationDimensions::default_underline(30),
strikethrough: DecorationDimensions::default_strikethrough(30),
};
fn digit_mapping(c: char) -> usize {
if c >= '0' || c <= '9' {
c as usize - '0' as usize
} else {
0
}
}
```
### More complex fonts
Crates that handle text rendering more complex than simple monospace fonts should now implement the
`CharacterStyle` and `TextRenderer` traits. These are used for both text styling and layout.
Please refer to their respective docs for implementation details.
An implementation of more complex font rendering using BDF font files is available in the [eg-bdf](https://github.com/embedded-graphics/embedded-bdf) crate, which may be useful as a reference for other implementations.
+284
View File
@@ -0,0 +1,284 @@
<p align="center">
<img width="150" src="https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/191fe7f8a0fedc713f9722b9dc59208dacadee7e/assets/logo.svg?sanitize=true" alt="Embedded graphics logo">
</p>
<p align="center">
<a href="https://circleci.com/gh/embedded-graphics/embedded-graphics/tree/master"><img src="https://circleci.com/gh/embedded-graphics/embedded-graphics/tree/master.svg?style=shield" alt="Build Status"></a>
<a href="https://crates.io/crates/embedded-graphics"><img src="https://img.shields.io/crates/v/embedded-graphics.svg" alt="Crates.io"></a>
<a href="https://docs.rs/embedded-graphics"><img src="https://docs.rs/embedded-graphics/badge.svg" alt="Docs.rs"></a>
<a href="https://matrix.to/#/#rust-embedded-graphics:matrix.org"><img src="https://img.shields.io/matrix/rust-embedded-graphics:matrix.org" alt="embedded-graphics on Matrix"></a>
</p>
# Embedded graphics
Embedded-graphics is a 2D graphics library that is focused on memory constrained embedded devices.
A core goal of embedded-graphics is to draw graphics without using any buffers; the crate is
`no_std` compatible and works without a dynamic memory allocator, and without pre-allocating
large chunks of memory. To achieve this, it takes an `Iterator` based approach, where pixel
colors and positions are calculated on the fly, with the minimum of saved state. This allows the
consuming application to use far less RAM at little to no performance penalty.
It contains built in items that make it easy to draw 2D graphics primitives:
* [Raw data images]
* [Primitives]
* [Lines]
* [Rectangles (and squares)]
* [Circles]
* [Ellipses]
* [Arcs]
* [Sectors]
* [Triangles]
* [Polylines]
* [Rounded rectangles]
* [Text]
* [Monospaced fonts]
## Additional functions provided by external crates
Embedded-graphics is designed to be extended by the application or other crates. Examples of
this are adding support for different image formats or implementing custom fonts.
* [BMP images - `tinybmp`](https://crates.io/crates/tinybmp)
* [TGA images - `tinytga`](https://crates.io/crates/tinytga)
* [QOI images - `tinyqoi`](https://crates.io/crates/tinyqoi)
* [Large collection of fonts - `u8g2-fonts`](https://crates.io/crates/u8g2-fonts)
* [ProFont monospace font - `profont`](https://crates.io/crates/profont)
* [Picofont Pico8 font - `embedded-picofont`](https://crates.io/crates/embedded_picofont)
* [IBM437 font - `ibm437`](https://crates.io/crates/ibm437)
* [The fonts shipped with `embedded-graphics` 0.6 - `embedded-vintage-fonts`](https://crates.io/crates/embedded-vintage-fonts)
* [Simple layout/alignment functions - `embedded-layout`](https://crates.io/crates/embedded-layout)
* [TextBox with text alignment options - `embedded-text`](https://crates.io/crates/embedded-text)
* [Heapless plotting library for small embedded targets - `embedded-plots`](https://crates.io/crates/embedded-plots)
* [Virtual seven-segment displays - `eg-seven-segment`](https://crates.io/crates/eg-seven-segment)
* [Canvas for drawing onto before drawing on the display - `embedded-canvas`](https://crates.io/crates/embedded-canvas)
* [Frames Per Second counter for embedded devices - `embedded-fps`](https://crates.io/crates/embedded-fps)
* [Framebuffer with DMA support - `embedded-graphics-framebuf`](https://crates.io/crates/embedded-graphics-framebuf)
Note that some of these crates may not support the latest version of embedded-graphics.
If you know of a crate that is not in this list, please [open an
issue](https://github.com/embedded-graphics/embedded-graphics/issues/new) to add it.
## Display drivers
To support many different kinds of display, embedded-graphics doesn't include any drivers
directly but provides the [`DrawTarget`] API in [`embedded-graphics-core`] that can be
implemented by external crates. In addition to the drivers for real displays, the
[simulator](https://docs.rs/embedded-graphics-simulator/) can be used to test code during
development.
![Photographs showing embedded-graphics running on physical display hardware.](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/4c680418cc4c37b8f7ed92d8b26edfde880d4c96/assets/banner-photo.jpg)
These are just some of the displays the community has added embedded-graphics support to. This
list is taken from the [dependent crates
list](https://crates.io/crates/embedded-graphics/reverse_dependencies) on crates.io so might be
missing some unpublished entries. Please [open an
issue](https://github.com/embedded-graphics/embedded-graphics/issues/new) if there's a display driver
that should be added to this list.
Note that some drivers may not support the latest version of embedded-graphics.
* [embedded-graphics-web-simulator](https://crates.io/crates/embedded-graphics-web-simulator): Simulated display in your browser via Webassembly
* [epd-waveshare](https://crates.io/crates/epd-waveshare) Driver for various ePaper displays (EPD) from Waveshare
* [hub75](https://crates.io/crates/hub75): A rust driver for hub75 rgb matrix displays
* [ili9341](https://crates.io/crates/ili9341): A platform agnostic driver to interface with the ILI9341 (and ILI9340C) TFT LCD display
* [ls010b7dh01](https://crates.io/crates/ls010b7dh01): A platform agnostic driver for the LS010B7DH01 memory LCD display
* [push2_display](https://crates.io/crates/push2_display): Ableton Push2 embedded-graphics display driver
* [sh1106](https://crates.io/crates/sh1106): I2C driver for the SH1106 OLED display
* [smart-leds-matrix](https://github.com/smart-leds-rs/smart-leds-matrix): Driver for smart LED (like ws2812) based LED matrixes.
* [ssd1306](https://crates.io/crates/ssd1306): I2C and SPI (4 wire) driver for the SSD1306 OLED display
* [ssd1309](https://crates.io/crates/ssd1309): I2C/SPI driver for the SSD1309 OLED display written in 100% Rust.
* [ssd1322](https://crates.io/crates/ssd1322): Pure Rust driver for the SSD1322 OLED display chip
* [ssd1331](https://crates.io/crates/ssd1331): SPI (4 wire) driver for the SSD1331 OLED display
* [ssd1351](https://crates.io/crates/ssd1351): SSD1351 driver
* [ssd1675](https://crates.io/crates/ssd1675): Rust driver for the Solomon Systech SSD1675 e-Paper display (EPD) controller
* [st7565](https://crates.io/crates/st7565): SPI driver for ST7565 based displays
* [st7735-lcd](https://crates.io/crates/st7735-lcd): Rust library for displays using the ST7735 driver
* [st7789](https://crates.io/crates/st7789): A Rust driver library for ST7789 displays
* [st7920](https://crates.io/crates/st7920): ST7920 LCD driver in Rust
* [gc9a01-rs](https://crates.io/crates/gc9a01-rs): SPI 4-wire driver for the Gc9a01 display driver
## Simulator
Embedded graphics comes with a [simulator]! The simulator can be used to test and debug
embedded graphics code, or produce examples and interactive demos to show off embedded graphics
features.
![A screenshot of embedded-graphics running in its simulator.](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/4c680418cc4c37b8f7ed92d8b26edfde880d4c96/assets/simulator-demo.png)
Take a look at the [examples repository](https://github.com/embedded-graphics/examples) to see what
embedded-graphics can do, and how it might look on a display. You can run the examples like
this:
```bash
git clone https://github.com/embedded-graphics/examples.git
cd examples/eg-0.7
cargo run --example hello-world
```
## Crate features
Additional features can be enabled by adding the following features to your `Cargo.toml`.
* `nalgebra_support` - use the [Nalgebra](https://crates.io/crates/nalgebra) crate with `no_std`
support to enable conversions from `nalgebra::Vector2` to [`Point`] and [`Size`].
* `fixed_point` - use fixed point arithmetic instead of floating point for all trigonometric
calculation.
* `defmt` - provide implementations of `defmt::Format` for all types where possible. [`defmt`]
is a library for logging that moves as much work as possible over to a separate logging
machine, making it especially suited to low-resource MCUs. Note that `defmt` might not work with
older versions of rustc that are otherwise supported by embedded-graphics.
## Migrating from older versions
* [Migration guide from 0.5 to 0.6](https://github.com/embedded-graphics/embedded-graphics/blob/master/MIGRATING-0.5-0.6.md).
* [Migration guide from 0.6 to 0.7](https://github.com/embedded-graphics/embedded-graphics/blob/master/MIGRATING-0.6-0.7.md).
## Implementing `embedded_graphics` support for a display driver
To add support for embedded-graphics to a display driver, [`DrawTarget`] from
[`embedded-graphics-core`] must be implemented. This allows all embedded-graphics items to be
rendered by the display. See the [`DrawTarget`] documentation for implementation details.
## Examples
### Drawing examples
[![A grid of screenshots showing primitives, text and other items that can be drawn using embedded-graphics.](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/4c680418cc4c37b8f7ed92d8b26edfde880d4c96/doc/assets/all_drawing_ops.png)][examples]
Example usage of drawing primitives, text and images with embedded-graphics can be found [here][examples].
### Shapes and text
The following example draws some shapes and text to a [`MockDisplay`] in place of target
hardware. The [simulator](https://docs.rs/embedded-graphics-simulator/) can also be used for
debugging, development or if hardware is not available.
```rust
use embedded_graphics::{
mono_font::{ascii::FONT_6X10, MonoTextStyle},
pixelcolor::BinaryColor,
prelude::*,
primitives::{
Circle, PrimitiveStyle, PrimitiveStyleBuilder, Rectangle, StrokeAlignment, Triangle,
},
text::{Alignment, Text},
mock_display::MockDisplay,
};
fn main() -> Result<(), std::convert::Infallible> {
// Create a new mock display
let mut display: MockDisplay<BinaryColor> = MockDisplay::new();
// Create styles used by the drawing operations.
let thin_stroke = PrimitiveStyle::with_stroke(BinaryColor::On, 1);
let thick_stroke = PrimitiveStyle::with_stroke(BinaryColor::On, 3);
let border_stroke = PrimitiveStyleBuilder::new()
.stroke_color(BinaryColor::On)
.stroke_width(3)
.stroke_alignment(StrokeAlignment::Inside)
.build();
let fill = PrimitiveStyle::with_fill(BinaryColor::On);
let character_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
let yoffset = 10;
// Draw a 3px wide outline around the display.
display
.bounding_box()
.into_styled(border_stroke)
.draw(&mut display)?;
// Draw a triangle.
Triangle::new(
Point::new(16, 16 + yoffset),
Point::new(16 + 16, 16 + yoffset),
Point::new(16 + 8, yoffset),
)
.into_styled(thin_stroke)
.draw(&mut display)?;
// Draw a filled square
Rectangle::new(Point::new(52, yoffset), Size::new(16, 16))
.into_styled(fill)
.draw(&mut display)?;
// Draw a circle with a 3px wide stroke.
Circle::new(Point::new(88, yoffset), 17)
.into_styled(thick_stroke)
.draw(&mut display)?;
// Draw centered text.
let text = "embedded-graphics";
Text::with_alignment(
text,
display.bounding_box().center() + Point::new(0, 15),
character_style,
Alignment::Center,
)
.draw(&mut display)?;
Ok(())
}
```
This example is also included in the [examples](https://github.com/embedded-graphics/examples) repository and
can be run using `cargo run --example hello-world`. It produces this output:
![Embedded Graphics Simulator example screenshot](https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/4c680418cc4c37b8f7ed92d8b26edfde880d4c96/assets/hello-world-simulator.png)
Additional examples can be found in the [examples](https://github.com/embedded-graphics/examples) repository.
[`Circle`]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/circle/struct.Circle.html
[`MockDisplay`]: https://docs.rs/embedded-graphics/latest/embedded_graphics/mock_display/struct.MockDisplay.html
[`Point`]: https://docs.rs/embedded-graphics/latest/embedded_graphics/geometry/struct.Point.html
[`Size`]: https://docs.rs/embedded-graphics/latest/embedded_graphics/geometry/struct.Size.html
[Raw data images]: https://docs.rs/embedded-graphics/latest/embedded_graphics/image/struct.ImageRaw.html
[Primitives]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/index.html
[Lines]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/line/struct.Line.html
[Rectangles (and squares)]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/rectangle/struct.Rectangle.html
[Circles]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/circle/struct.Circle.html
[Ellipses]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/ellipse/struct.Ellipse.html
[Arcs]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/arc/struct.Arc.html
[Sectors]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/sector/struct.Sector.html
[Triangles]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/triangle/struct.Triangle.html
[Polylines]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/polyline/struct.Polyline.html
[Rounded rectangles]: https://docs.rs/embedded-graphics/latest/embedded_graphics/primitives/rounded_rectangle/struct.RoundedRectangle.html
[Text]: https://docs.rs/embedded-graphics/latest/embedded_graphics/text/index.html
[Monospaced fonts]: https://docs.rs/embedded-graphics/latest/embedded_graphics/mono_font/index.html
[examples]: https://docs.rs/embedded-graphics/latest/embedded_graphics/examples/index.html
[`DrawTarget`]: https://docs.rs/embedded-graphics-core/latest/embedded_graphics_core/draw_target/trait.DrawTarget.html
[`embedded-graphics-core`]: https://docs.rs/embedded-graphics-core/
[simulator]: https://github.com/embedded-graphics/simulator
[simulator examples]: https://github.com/embedded-graphics/simulator/tree/master/examples
[`defmt`]: https://defmt.ferrous-systems.com/
## Minimum supported Rust version
The minimum supported Rust version for embedded-graphics is `1.71.1` or greater.
Ensure you have the correct version of Rust installed, preferably through <https://rustup.rs>.
## Development setup
Please see the [development setup guide](https://github.com/embedded-graphics/embedded-graphics/blob/master/doc/development-setup.md).
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the
work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
+38
View File
@@ -0,0 +1,38 @@
<p align="center">
<img width="150" src="https://raw.githubusercontent.com/embedded-graphics/embedded-graphics/191fe7f8a0fedc713f9722b9dc59208dacadee7e/assets/logo.svg?sanitize=true" alt="Embedded graphics logo">
</p>
<p align="center">
<a href="https://circleci.com/gh/embedded-graphics/embedded-graphics/tree/master"><img src="https://circleci.com/gh/embedded-graphics/embedded-graphics/tree/master.svg?style=shield" alt="Build Status"></a>
<a href="https://crates.io/crates/embedded-graphics"><img src="https://img.shields.io/crates/v/embedded-graphics.svg" alt="Crates.io"></a>
<a href="https://docs.rs/embedded-graphics"><img src="https://docs.rs/embedded-graphics/badge.svg" alt="Docs.rs"></a>
<a href="https://matrix.to/#/#rust-embedded-graphics:matrix.org"><img src="https://img.shields.io/matrix/rust-embedded-graphics:matrix.org" alt="embedded-graphics on Matrix"></a>
</p>
# Embedded graphics
{{readme}}
## Minimum supported Rust version
The minimum supported Rust version for embedded-graphics is `1.71.1` or greater.
Ensure you have the correct version of Rust installed, preferably through <https://rustup.rs>.
## Development setup
Please see the [development setup guide](https://github.com/embedded-graphics/embedded-graphics/blob/master/doc/development-setup.md).
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the
work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
+168
View File
@@ -0,0 +1,168 @@
# Releases
Release notes for [embedded-graphics](https://crates.io/crates/embedded-graphics).
## 0.8.1
- `MonoTextStyleBuilder` methods are now `const`
- MSRV bumped to 1.71.1
## 0.7.0
### Primitives
New primitives have been added:
- `Arc`
- `Sector`
- `Polyline`
- `Ellipse`
- `RoundedRectangle`
The `Line` and `Triangle` primitives now support stroke widths greater than 1px.
Primitives now support stroke alignment using the `StrokeAlignment` enum.
The outline of all closed shapes now can now be offset by using the `OffsetOutline::offset` method.
The `ContainsPoint::contains` method can be used to check if a point is inside a primitive.
All primitives can be converted into an iterator over the contained points by using the `PointsIter::points` method.
### Geometry
Adds the `Point::x_axis`, `Point::y_axis`, `Size::x_axis` and `Size::y_axis` methods to get one axis of a point or size, with the other set to zero.
```rust
use embedded_graphics::geometry::Point;
let point = Point::new(15, 23);
assert_eq!(point.x_axis() = Point::new(15, 0));
assert_eq!(point.y_axis() = Point::new(0, 23));
```
`Point::new_equal` and `Size::new_equal` have also been added as convenience methods to create points or sizes with equal coordinates.
```diff
use embedded_graphics::geometry::Size;
- let size = Size::new(20, 20);
+ let size = Size::new_equal(20);
```
Other methods added to both `Point` and `Size` are:
- `component_min`
- `component_max`
- `component_mul`
- `component_div`
`Angle` was added to represent angles in `Arc` and `Sector` primitives.
The `Rectangle::intersection` method was added to get the intersecting area of two rectangles.
### Color
New color constants for the CSS colors were added for all RGB color types. The color constants are
defined in the `WebColors` trait, which is included in the prelude. The names of the constants are
prefixed by `CSS_` to avoid naming conflicts with the existing color constants. The CSS color
`hotpink` can, for example, be accessed by using `Rgb888::CSS_HOT_PINK`.
The `ToBytes` trait has been added to support conversion of colors into byte arrays.
All builtin color types can now be converted to any other builtin color type by using `From` or `Into`.
### Draw target adapters
The `DrawTargetExt` trait is introduced to allow a translated, cropped or clipped sub-area of a `DrawTarget` to be drawn to.
`DrawTargetExt` is implemented for `DrawTarget`.
Please search for `DrawTargetExt` at <https://docs.rs/embedded-graphics> for usage examples.
### Fonts and text
Support for external text renderers was added. To support this the existing `fonts` module has been
split into one for the generic `Text` drawable and one for the builtin monospaced text renderer.
Refer to the migration guide for more information about this change.
Additional languages are supported by new fonts which are available in ASCII, multiple ISO-8859 and
JIS X 201 glpyh subsets.
`Text` drawables now support horizontal alignment, baseline and line height settings.
The builtin monospaced text renderer now supports underline and strikethough decorations.
```rust
use embedded_graphics::{
mono_font::{ascii::FONT_8X13, MonoTextStyleBuilder},
pixelcolor::Rgb888,
prelude::*,
text::{Alignment, Baseline, Text, TextStyleBuilder},
};
// Use the builtin 8x13 monospace font with red foreground color
let character_style = MonoTextStyleBuilder::new()
.font(&FONT_8X13)
.text_color(Rgb888::CSS_TOMATO)
.build();
// Anchor the text relative to its horizontal center point and vertical middle
let center_aligned = TextStyleBuilder::new()
.alignment(Alignment::Center)
.baseline(Baseline::Middle)
.build();
Text::with_text_style(
"Center aligned text",
Point::new(100, 20),
character_style,
center_aligned,
)
.draw(&mut display)?;
```
### Images
`SubImage` was added to draw a part of an image.
```rust
use embedded_graphics::{image::Image, pixelcolor::Rgb888, prelude::*, primitives::Rectangle};
use tinytga::Tga;
// Load spritemap TGA image
let tiles: Tga<Rgb888> = Tga::from_slice(include_bytes!("assets/sprites.tga")).unwrap();
// Grab a 64x64px subsection of the image
let sprite_a = tiles.sub_image(&Rectangle::new(Point::new(0, 0), Size::new(64, 64)));
// Draw the sprite with its top left corner at (25, 35)
Image::new(&sprite_a, Point::new(25, 35)).draw(&mut display)?;
```
### Performance
The performance of many drawing operations has been improved by drawing larger contiguous regions
of pixels instead of individual pixels.
### Mock display
`MockDisplay` now supports all RGB and grayscale color types in its patterns.
By setting the environment variable `EG_FANCY_PANIC=1` when running the tests, failing `MockDisplay` assertions can now pretty print the difference between two `MockDisplay`s.
New methods:
- `affected_area` - gets the bounding box of all changes made to the display.
- `assert_eq_with_message` - the same as above, but with the ability to write custom messages in the test output.
- `assert_eq` - check for equality against another `MockDisplay` and panic if they are not the same.
- `assert_pattern_with_message` - the same as above, but with the ability to write custom messages in the test output.
- `assert_pattern` - check for equality against a pattern and panic if they do not match.
- `diff` - compare the display against another `MockDisplay`, producing a new `MockDisplay` containing the colored difference between them.
- `from_points` - create a `MockDisplay` from an iterator over `Point`s.
- `map` - create a copy of the current display with a predicate applied to all pixels.
- `set_allow_out_of_bounds_drawing` - if set to `true`, disables the panicking behavior when a drawing operation attempts to draw pixels outside the visible mock display area.
- `set_allow_overdraw` - if set to `true`, disables the panicking behavior when a pixel is drawn to twice.
- `set_pixels` - sets the points in an iterator to the given color.
- `swap_xy` - copies the current display with X and Y coordinates swapped.
+3
View File
@@ -0,0 +1,3 @@
# Assets
This is a folder for storing all sorts of misc junk in like documentation screenshots.
Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

+180
View File
@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="103.92305mm"
height="140mm"
viewBox="0 0 103.92305 140"
version="1.1"
id="svg2682"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="logo.svg">
<defs
id="defs2676">
<linearGradient
inkscape:collect="always"
id="linearGradient3358">
<stop
style="stop-color:#001428;stop-opacity:0.03778338"
offset="0"
id="stop3354" />
<stop
id="stop3362"
offset="0.5"
style="stop-color:#001428;stop-opacity:1" />
<stop
style="stop-color:#001428;stop-opacity:0.10327456"
offset="1"
id="stop3356" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1596">
<path
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 106.59697,167.55936 v 12.0003 l 10.39213,5.99963 v -3.99975 l -6.88936,-3.88663 -0.0389,-8.11316 -3.46387,-2.00039 v 0"
id="path1598"
inkscape:connector-curvature="0" />
</clipPath>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3358"
id="linearGradient3360"
x1="60.621777"
y1="97"
x2="51.961525"
y2="82"
gradientUnits="userSpaceOnUse" />
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter3390"
x="-0.10849742"
width="1.2169948"
y="-0.13423075"
height="1.2684615">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.97876582"
id="feGaussianBlur3392" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4142136"
inkscape:cx="218.96698"
inkscape:cy="247.05113"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:snap-grids="true"
inkscape:window-width="1686"
inkscape:window-height="980"
inkscape:window-x="84"
inkscape:window-y="240"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="axonomgrid"
id="grid3229"
units="mm"
empspacing="5"
spacingy="5"
originx="-25.980763"
originy="-140" />
</sodipodi:namedview>
<metadata
id="metadata2679">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-25.980763,-17.000001)">
<path
style="opacity:1;vector-effect:none;fill:#001428;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 25.980763,47 77.942286,17.000001 129.90381,47 v 80 L 77.942286,157 25.980763,127 Z"
id="path3306"
inkscape:connector-curvature="0" />
<path
style="opacity:1;vector-effect:none;fill:#00d2ff;fill-opacity:1;stroke:none;stroke-width:2.83464575;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 294.58594,102.04688 130.92578,196.53516 V 385.51172 L 294.58594,480 425.51172,404.41016 v 37.79492 L 294.58594,517.79492 130.92578,423.30664 v 37.79492 l 163.66016,94.48828 163.6582,-94.48828 v -264.5664 z m 0,37.79492 130.92578,75.59179 V 366.61328 L 294.58594,442.20508 163.6582,366.61328 V 215.43359 Z m 0,75.59179 49.0957,28.34571 -114.56055,66.14258 v -56.69336 z m 98.19409,94.48767 -98.19409,56.69202 -49.09766,-28.3457 147.29102,-85.03906 v -18.89844 l -98.19336,-56.69141 -98.19532,56.69141 V 347.7168 l 98.19532,56.69336 98.19336,-56.69336 z"
transform="scale(0.26458333)"
id="path3328"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccc" />
<g
id="g3350"
style="fill:#00c2ec;fill-opacity:1">
<path
inkscape:connector-curvature="0"
id="path3231"
d="m 34.641015,112 v 10 l 43.301271,25 v -10 z"
style="opacity:1;vector-effect:none;fill:#00c2ec;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccc"
style="opacity:1;vector-effect:none;fill:#00c2ec;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 34.641016,52.000001 V 102 l 43.301271,25 V 117 L 43.30127,97.000001 v -40 z"
id="path3233"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path3235"
d="m 51.961524,62.000001 v 30 L 77.942286,107 v -9.999999 l -17.320508,-10 v -20 z"
style="opacity:1;vector-effect:none;fill:#00c2ec;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g3345"
style="fill:#00b0d8;fill-opacity:1">
<path
sodipodi:nodetypes="ccccccccccc"
style="opacity:1;vector-effect:none;fill:#00b0d8;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 77.942286,147 V 137 L 112.58331,117 V 107 L 77.942286,127 V 117 L 112.58331,97.000001 v -40 l 8.66025,-5 V 122 Z"
id="path3237"
inkscape:connector-curvature="0" />
<path
style="opacity:1;vector-effect:none;fill:#00b0d8;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 103.92305,92 77.942284,107 V 97 L 103.92305,82 Z"
id="path3241"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</g>
<path
style="opacity:0.25;vector-effect:none;fill:#001428;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter3390)"
d="M 47.631397,89.5 64.951906,79.499999 69.282031,87 51.961523,96.999998 Z"
id="path3364"
inkscape:connector-curvature="0" />
<path
style="opacity:1;vector-effect:none;fill:#00d2ff;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 51.961523,62.000001 77.942286,47 103.92305,62.000001 v 5 l -47.631399,27.5 -4.330127,-2.5 v -5 l 38.971143,-22.5 -12.990381,-7.5 -17.320509,10.000001 z"
id="path3243"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="103.92mm" height="160mm" version="1.1" viewBox="0 0 103.92 160" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(-25.981 -17)">
<path d="m25.981 47 51.962-30 51.962 30v130h-103.92z" fill="#001428"/>
<path transform="scale(.26458)" d="m294.59 102.05-163.66 94.488v188.98l163.66 94.488 130.93-75.59v37.795l-130.93 75.59-163.66-94.488v37.795l163.66 94.488 163.66-94.488v-264.57zm0 37.795 130.93 75.592v151.18l-130.93 75.592-130.93-75.592v-151.18zm0 75.592 49.096 28.346-114.56 66.143v-56.693zm98.194 94.488-98.194 56.692-49.098-28.346 147.29-85.039v-18.898l-98.193-56.691-98.195 56.691v113.39l98.195 56.693 98.193-56.693z" fill="#00c2ec"/>
<path d="m34.641 152h86.603" fill="none" stroke="#00c2ec" stroke-width="2"/>
<g fill="#00c2ec" stroke-width=".26458" aria-label="CORE">
<path d="m60.542 172.15q0.82507 0 1.63-0.20124 0.80495-0.20123 1.4489-0.70432 0.66408-0.52322 1.0062-1.2879 0.3421-0.78483 0.3421-1.6099h-2.274q0 0.52322-0.32198 0.96594-0.30186 0.44272-0.80495 0.62384-0.50309 0.16098-1.0263 0.16098-0.58359 0-1.1471-0.24148-0.54334-0.26161-0.80495-0.80495-0.24148-0.56346-0.24148-1.147v-6.6207q0-0.58358 0.24148-1.1269 0.26161-0.56347 0.80495-0.80495 0.56346-0.26161 1.1471-0.26161 0.52322 0 1.0263 0.16099 0.50309 0.16099 0.80495 0.62384 0.32198 0.44272 0.32198 0.96593h2.274q0-0.82507-0.3421-1.5898-0.3421-0.78482-1.0062-1.308-0.64396-0.52322-1.4489-0.70433-0.80495-0.20124-1.63-0.20124-0.70433 0-1.4087 0.14087-0.68421 0.14087-1.2879 0.52322-0.60371 0.36222-1.0263 0.94581-0.40247 0.56346-0.58359 1.2477-0.16099 0.6842-0.16099 1.3885v6.6207q0 0.70433 0.16099 1.3885 0.18111 0.6842 0.58359 1.2678 0.4226 0.56346 1.0263 0.94581 0.60371 0.36223 1.2879 0.5031 0.70433 0.14086 1.4087 0.14086z"/>
<path d="m72.174 172.15q0.70433 0 1.3885-0.14086 0.70433-0.14087 1.308-0.5031 0.62384-0.38235 1.0464-0.94581 0.4226-0.58359 0.58359-1.2678 0.18111-0.68421 0.18111-1.3885v-6.6207q0-0.70433-0.18111-1.3885-0.16099-0.70433-0.58359-1.2678-0.4226-0.58359-1.0464-0.94582-0.60371-0.36222-1.308-0.50309-0.68421-0.14087-1.3885-0.14087-0.70433 0-1.4087 0.14087-0.6842 0.14087-1.308 0.50309-0.60371 0.36223-1.0263 0.94582-0.4226 0.56346-0.60371 1.2678-0.16099 0.6842-0.16099 1.3885v6.6207q0 0.70433 0.16099 1.3885 0.18111 0.6842 0.60371 1.2678 0.4226 0.56346 1.0263 0.94581 0.62384 0.36223 1.308 0.5031 0.70433 0.14086 1.4087 0.14086zm0-2.0526q-0.44272 0-0.88544-0.12074-0.4226-0.14086-0.74458-0.44272-0.32198-0.32198-0.46284-0.74458-0.14087-0.44272-0.14087-0.88544v-6.6207q0-0.44272 0.14087-0.86531 0.14087-0.44273 0.46284-0.76471 0.32198-0.32197 0.74458-0.44272 0.44272-0.12074 0.88544-0.12074 0.44272 0 0.86532 0.12074 0.44272 0.12075 0.7647 0.44272 0.3421 0.32198 0.46284 0.76471 0.14087 0.42259 0.14087 0.86531v6.6207q0 0.44272-0.14087 0.88544-0.12074 0.4226-0.46284 0.74458-0.32198 0.30186-0.7647 0.44272-0.4226 0.12074-0.86532 0.12074z"/>
<path d="m79.418 171.98h2.274v-5.695h1.1471l3.4009 5.695h2.435l-3.4412-5.8158q0.70433-0.16099 1.3282-0.56346 0.62383-0.4226 1.0062-1.0464 0.40247-0.64396 0.54334-1.3684 0.16099-0.72446 0.16099-1.4489 0-0.70433-0.14087-1.4087t-0.50309-1.308q-0.36223-0.62383-0.94581-1.0464-0.56346-0.44272-1.2678-0.60371-0.68421-0.18112-1.3885-0.18112h-4.6083zm4.6083-7.7476h-2.3343v-4.9907h2.3343q0.44272 0 0.86532 0.20124 0.4226 0.18111 0.66408 0.56346 0.26161 0.38235 0.3421 0.82507 0.10062 0.44272 0.10062 0.90557 0 0.44272-0.10062 0.88544-0.08049 0.44272-0.3421 0.8452-0.24148 0.38235-0.66408 0.58358-0.4226 0.18112-0.86532 0.18112z"/>
<path d="m91.734 171.98h7.969v-2.0526h-5.695v-4.7693h4.387v-2.0526h-4.387v-3.8638h5.695v-2.0526h-7.969z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

+137
View File
@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="103.92305mm"
height="160.00002mm"
viewBox="0 0 103.92305 160.00002"
version="1.1"
id="svg2682"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
sodipodi:docname="logo_core_src.svg">
<defs
id="defs2676">
<linearGradient
inkscape:collect="always"
id="linearGradient3358">
<stop
style="stop-color:#001428;stop-opacity:0.03778338"
offset="0"
id="stop3354" />
<stop
id="stop3362"
offset="0.5"
style="stop-color:#001428;stop-opacity:1" />
<stop
style="stop-color:#001428;stop-opacity:0.10327456"
offset="1"
id="stop3356" />
</linearGradient>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath1596">
<path
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 106.59697,167.55936 v 12.0003 l 10.39213,5.99963 v -3.99975 l -6.88936,-3.88663 -0.0389,-8.11316 -3.46387,-2.00039 v 0"
id="path1598"
inkscape:connector-curvature="0" />
</clipPath>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3358"
id="linearGradient3360"
x1="60.621777"
y1="97"
x2="51.961525"
y2="82"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.70710678"
inkscape:cx="191.60865"
inkscape:cy="511.05691"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-grids="true"
inkscape:window-width="3056"
inkscape:window-height="1123"
inkscape:window-x="84"
inkscape:window-y="240"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:document-rotation="0"
inkscape:snap-text-baseline="true"
inkscape:snap-global="true"
inkscape:snap-page="false">
<inkscape:grid
type="axonomgrid"
id="grid3229"
units="mm"
empspacing="5"
spacingy="5"
originx="-25.980763"
originy="-140" />
</sodipodi:namedview>
<metadata
id="metadata2679">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-25.980763,-17.000002)">
<path
style="opacity:1;vector-effect:none;fill:#001428;fill-opacity:1;stroke:none;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 25.980763,47.000002 51.961523,-30 51.961524,30 V 177.00001 H 25.980763 Z"
id="path3306"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="opacity:1;vector-effect:none;fill:#00c2ec;fill-opacity:1;stroke:none;stroke-width:2.83465;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 294.58594,102.04688 130.92578,196.53516 V 385.51172 L 294.58594,480 425.51172,404.41016 v 37.79492 L 294.58594,517.79492 130.92578,423.30664 v 37.79492 l 163.66016,94.48828 163.6582,-94.48828 v -264.5664 z m 0,37.79492 130.92578,75.59179 V 366.61328 L 294.58594,442.20508 163.6582,366.61328 V 215.43359 Z m 0,75.59179 49.0957,28.34571 -114.56055,66.14258 v -56.69336 z m 98.19409,94.48767 -98.19409,56.69202 -49.09766,-28.3457 147.29102,-85.03906 v -18.89844 l -98.19336,-56.69141 -98.19532,56.69141 V 347.7168 l 98.19532,56.69336 98.19336,-56.69336 z"
id="path3328"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccc"
transform="scale(0.26458333)" />
<path
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#00c2ec;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 34.641023,152 H 121.24356"
id="path2929" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:expanded;font-size:20.1237px;line-height:9.25;font-family:Iosevka;-inkscape-font-specification:'Iosevka Semi-Bold Expanded';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#00c2ec;fill-opacity:1;stroke-width:0.264583"
x="77.969116"
y="171.98451"
id="text2927"><tspan
sodipodi:role="line"
id="tspan2925"
x="77.969116"
y="171.98451"
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:expanded;font-family:Iosevka;-inkscape-font-specification:'Iosevka Semi-Bold Expanded';fill:#00c2ec;fill-opacity:1;stroke-width:0.264583">CORE</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.
+1
View File
@@ -0,0 +1 @@
�P�P
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.
Binary file not shown.
+34
View File
@@ -0,0 +1,34 @@
use criterion::*;
use embedded_graphics::{
pixelcolor::{Gray8, Rgb555, Rgb565, Rgb888},
prelude::*,
};
fn impl_bench<CFrom, CTo>(c: &mut Criterion, name: &str)
where
CFrom: PixelColor + Default + Into<CTo>,
CTo: PixelColor + Default,
{
c.bench_function(name, |b| {
let input = &[CFrom::default(); 320 * 240];
let mut output = [CTo::default(); 320 * 240];
b.iter(|| {
for (i, o) in black_box(input).iter().copied().zip(output.iter_mut()) {
*o = i.into();
}
})
});
}
fn color_conversions(c: &mut Criterion) {
impl_bench::<Rgb555, Rgb565>(c, "Rgb555 to Rgb565");
impl_bench::<Rgb565, Rgb555>(c, "Rgb565 to Rgb555");
impl_bench::<Rgb565, Rgb888>(c, "Rgb565 to Rgb888");
impl_bench::<Rgb888, Rgb565>(c, "Rgb888 to Rgb565");
impl_bench::<Gray8, Rgb888>(c, "Gray8 to Rgb888");
impl_bench::<Rgb888, Gray8>(c, "Rgb888 to Gray8");
}
criterion_group!(benches, color_conversions);
criterion_main!(benches);
+58
View File
@@ -0,0 +1,58 @@
use embedded_graphics::prelude::*;
use std::convert::TryFrom;
const SIZE: usize = 256;
pub struct Framebuffer<C> {
pixels: [[C; SIZE]; SIZE],
}
impl<C> Framebuffer<C>
where
C: PixelColor + Default,
{
pub fn new() -> Self {
Self {
pixels: [[C::default(); 256]; 256],
}
}
fn set_pixel(&mut self, position: Point, color: C) {
if let (Ok(x), Ok(y)) = (usize::try_from(position.x), usize::try_from(position.y)) {
self.pixels
.get_mut(y)
.and_then(|row| row.get_mut(x))
.map(|pixel| *pixel = color);
} else {
panic!(
"tried to set pixel outside the framebuffer at {:?}",
position
);
}
}
}
impl<C> DrawTarget for Framebuffer<C>
where
C: PixelColor + Default,
{
type Color = C;
type Error = core::convert::Infallible;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
for Pixel(position, color) in pixels {
self.set_pixel(position, color);
}
Ok(())
}
}
impl<C> OriginDimensions for Framebuffer<C> {
fn size(&self) -> Size {
Size::new_equal(SIZE as u32)
}
}
+28
View File
@@ -0,0 +1,28 @@
use criterion::*;
use embedded_graphics::{prelude::*, primitives::*};
fn triangle_contains_inside(c: &mut Criterion) {
c.bench_function("triangle contains point (inside)", |b| {
let object = Triangle::new(Point::new(5, 10), Point::new(15, 20), Point::new(5, 20));
let midpoint = object.bounding_box().center();
b.iter(|| object.contains(midpoint))
});
}
// Point outside triangle but still within bounding box. If point is outside bounding box, this
// benchmark doesn't exercise the expensive point-in-triangle code.
fn triangle_contains_outside(c: &mut Criterion) {
c.bench_function("triangle contains point (outside)", |b| {
let object = Triangle::new(Point::new(5, 10), Point::new(55, 20), Point::new(30, 40));
b.iter(|| object.contains(Point::new(50, 13)))
});
}
criterion_group!(
contains,
triangle_contains_inside,
triangle_contains_outside
);
criterion_main!(contains);
+108
View File
@@ -0,0 +1,108 @@
use criterion::*;
use embedded_graphics::{
geometry::Point,
mono_font::{
ascii::{FONT_10X20, FONT_6X9},
MonoTextStyle, MonoTextStyleBuilder,
},
pixelcolor::Gray8,
prelude::*,
text::Text,
};
mod common;
use common::Framebuffer;
fn one_line<S>(style: S) -> Text<'static, S> {
Text::new("Hello world!", Point::new_equal(20), style)
}
fn three_lines<S>(style: S) -> Text<'static, S> {
Text::new("line 1\nl2\nThis is line 3", Point::new_equal(20), style)
}
fn font_6x9(c: &mut Criterion) {
let mut group = c.benchmark_group("font 6x9");
let style = MonoTextStyle::new(&FONT_6X9, Gray8::WHITE);
let style_with_bg = MonoTextStyleBuilder::new()
.font(&FONT_6X9)
.text_color(Gray8::WHITE)
.background_color(Gray8::BLACK)
.build();
group.bench_function("one line", |b| {
let object = one_line(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("one line with background", |b| {
let object = one_line(style_with_bg);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("three lines", |b| {
let object = three_lines(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("three lines with background)", |b| {
let object = three_lines(style_with_bg);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.finish();
}
fn font_10x20(c: &mut Criterion) {
let mut group = c.benchmark_group("font 10x20");
let style = MonoTextStyle::new(&FONT_10X20, Gray8::WHITE);
let style_with_bg = MonoTextStyleBuilder::new()
.font(&FONT_10X20)
.text_color(Gray8::WHITE)
.background_color(Gray8::BLACK)
.build();
group.bench_function("one line", |b| {
let object = one_line(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("one line with background", |b| {
let object = one_line(style_with_bg);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("three lines", |b| {
let object = three_lines(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("three lines with background)", |b| {
let object = three_lines(style_with_bg);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.finish();
}
criterion_group!(fonts, font_6x9, font_10x20);
criterion_main!(fonts);
+112
View File
@@ -0,0 +1,112 @@
use criterion::*;
use embedded_graphics::{
framebuffer::{buffer_size, Framebuffer},
geometry::Point,
image::GetPixel,
pixelcolor::{raw::LittleEndian, BinaryColor, Rgb565},
prelude::{DrawTarget, Size, WebColors},
primitives::{Primitive, PrimitiveStyle, Rectangle},
};
fn framebuffer_set_1bpp(c: &mut Criterion) {
c.bench_function("framebuffer set pixel 1bpp", |b| {
let mut fb = Framebuffer::<
BinaryColor,
_,
LittleEndian,
320,
240,
{ buffer_size::<BinaryColor>(320, 240) },
>::new();
b.iter(|| {
fb.set_pixel(Point::new(1, 1), BinaryColor::On);
fb.set_pixel(Point::new(300, 200), BinaryColor::On);
})
});
}
fn framebuffer_get_1bpp(c: &mut Criterion) {
c.bench_function("framebuffer get pixel 1bpp", |b| {
let fb = Framebuffer::<
BinaryColor,
_,
LittleEndian,
320,
240,
{ buffer_size::<BinaryColor>(320, 240) },
>::new();
b.iter(|| {
fb.pixel(Point::new(1, 1));
fb.pixel(Point::new(300, 200));
})
});
}
fn framebuffer_1bpp_draw_iter(c: &mut Criterion) {
c.bench_function("framebuffer 1bpp draw iter", |b| {
let mut fb = Framebuffer::<
BinaryColor,
_,
LittleEndian,
320,
240,
{ buffer_size::<BinaryColor>(320, 240) },
>::new();
b.iter(|| {
let rect = Rectangle::new(Point::new(20, 30), Size::new(40, 50))
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
.pixels();
fb.draw_iter(rect).unwrap();
})
});
}
fn framebuffer_set_rgb565(c: &mut Criterion) {
c.bench_function("framebuffer set pixel rgb565", |b| {
let mut fb = Framebuffer::<
Rgb565,
_,
LittleEndian,
320,
240,
{ buffer_size::<Rgb565>(320, 240) },
>::new();
b.iter(|| {
fb.set_pixel(Point::new(1, 1), Rgb565::CSS_DARK_SALMON);
fb.set_pixel(Point::new(300, 200), Rgb565::CSS_TEAL);
})
});
}
fn framebuffer_get_rgb565(c: &mut Criterion) {
c.bench_function("framebuffer get pixel rgb565", |b| {
let fb = Framebuffer::<
Rgb565,
_,
LittleEndian,
320,
240,
{ buffer_size::<Rgb565>(320, 240) },
>::new();
b.iter(|| {
fb.pixel(Point::new(1, 1));
fb.pixel(Point::new(300, 200));
})
});
}
criterion_group!(
framebuffer,
framebuffer_set_1bpp,
framebuffer_get_1bpp,
framebuffer_set_rgb565,
framebuffer_get_rgb565,
framebuffer_1bpp_draw_iter
);
criterion_main!(framebuffer);
+25
View File
@@ -0,0 +1,25 @@
use criterion::*;
use embedded_graphics::{
image::{Image, ImageRaw},
pixelcolor::BinaryColor,
prelude::*,
};
mod common;
use common::Framebuffer;
fn image_1bpp(c: &mut Criterion) {
c.bench_function("image 4x4px", |b| {
let bytes = include_bytes!("../assets/patch_1bpp.raw");
let image: ImageRaw<BinaryColor> = ImageRaw::new(bytes, 4);
let object = Image::new(&image, Point::zero());
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
}
criterion_group!(images, image_1bpp);
criterion_main!(images);
+239
View File
@@ -0,0 +1,239 @@
use criterion::*;
use embedded_graphics::{geometry::AnchorPoint, pixelcolor::Gray8, prelude::*, primitives::*};
mod common;
use common::Framebuffer;
const BOUNDING_BOX: Rectangle = Rectangle::new(Point::new_equal(32), Size::new_equal(192));
fn rectangle(c: &mut Criterion) {
closed_shape_benches(c, "rectangle", || BOUNDING_BOX);
}
fn rounded_rectangle(c: &mut Criterion) {
closed_shape_benches(c, "rounded rectangle", || {
RoundedRectangle::new(BOUNDING_BOX, CornerRadii::new(Size::new(10, 12)))
});
}
fn rounded_rectangle_corners(c: &mut Criterion) {
closed_shape_benches(c, "rounded rectangle corners", || {
RoundedRectangle::new(
BOUNDING_BOX,
CornerRadii {
top_left: Size::new(10, 12),
top_right: Size::new(14, 16),
bottom_right: Size::new(18, 20),
bottom_left: Size::new(22, 24),
},
)
});
}
fn triangle(c: &mut Criterion) {
closed_shape_benches(c, "triangle", || {
Triangle::new(
BOUNDING_BOX.anchor_point(AnchorPoint::BottomLeft),
BOUNDING_BOX.anchor_point(AnchorPoint::TopCenter),
BOUNDING_BOX.anchor_point(AnchorPoint::BottomRight),
)
});
}
fn circle(c: &mut Criterion) {
closed_shape_benches(c, "circle", || {
Circle::new(BOUNDING_BOX.top_left, BOUNDING_BOX.size.width)
});
}
fn ellipse(c: &mut Criterion) {
closed_shape_benches(c, "ellipse", || {
Ellipse::with_center(BOUNDING_BOX.center(), BOUNDING_BOX.size - Size::new(0, 20))
});
}
fn sector_150(c: &mut Criterion) {
closed_shape_benches(c, "sector 150°", || {
Sector::with_center(
BOUNDING_BOX.center(),
BOUNDING_BOX.size.width,
-30.0.deg(),
150.0.deg(),
)
});
}
fn sector_360(c: &mut Criterion) {
closed_shape_benches(c, "sector 360°", || {
Sector::with_center(
BOUNDING_BOX.center(),
BOUNDING_BOX.size.width,
-30.0.deg(),
150.0.deg(),
)
});
}
fn line(c: &mut Criterion) {
open_shape_benches(c, "line", || {
Line::new(
BOUNDING_BOX.anchor_point(AnchorPoint::TopLeft),
// move point up a bit, because non 45° lines might be slower
BOUNDING_BOX.anchor_point(AnchorPoint::BottomRight) - Point::new(0, 20),
)
});
}
fn polyline(c: &mut Criterion) {
let points = [
BOUNDING_BOX.anchor_point(AnchorPoint::BottomLeft),
BOUNDING_BOX.anchor_point(AnchorPoint::TopCenter) - Point::new(20, 0),
BOUNDING_BOX.anchor_point(AnchorPoint::BottomCenter),
BOUNDING_BOX.anchor_point(AnchorPoint::TopRight),
BOUNDING_BOX.anchor_point(AnchorPoint::BottomRight),
];
open_shape_benches(c, "polyline", || Polyline::new(&points));
}
fn arc_150(c: &mut Criterion) {
open_shape_benches(c, "arc 150°", || {
Arc::with_center(
BOUNDING_BOX.center(),
BOUNDING_BOX.size.width,
-30.0.deg(),
150.0.deg(),
)
});
}
fn arc_360(c: &mut Criterion) {
open_shape_benches(c, "arc 360°", || {
Arc::with_center(
BOUNDING_BOX.center(),
BOUNDING_BOX.size.width,
0.0.deg(),
360.0.deg(),
)
});
}
criterion_group!(
primitives,
rectangle,
rounded_rectangle,
rounded_rectangle_corners,
triangle,
circle,
ellipse,
line,
polyline,
sector_150,
sector_360,
arc_150,
arc_360,
);
criterion_main!(primitives);
fn closed_shape_benches<P>(c: &mut Criterion, name: &str, build: impl Fn() -> P)
where
P: Primitive,
Styled<P, PrimitiveStyle<Gray8>>: Drawable<Color = Gray8>,
{
let mut group = c.benchmark_group(name);
group.bench_function("fill", |b| {
let style = PrimitiveStyle::with_fill(Gray8::WHITE);
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("stroke 1px", |b| {
let style = PrimitiveStyleBuilder::new()
.stroke_color(Gray8::BLACK)
.stroke_width(1)
.stroke_alignment(StrokeAlignment::Inside)
.build();
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("stroke 10px", |b| {
let style = PrimitiveStyleBuilder::new()
.stroke_color(Gray8::BLACK)
.stroke_width(10)
.stroke_alignment(StrokeAlignment::Inside)
.build();
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("stroke 1px and fill", |b| {
let style = PrimitiveStyleBuilder::new()
.fill_color(Gray8::WHITE)
.stroke_color(Gray8::BLACK)
.stroke_width(1)
.stroke_alignment(StrokeAlignment::Inside)
.build();
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("stroke 10px and fill", |b| {
let style = PrimitiveStyleBuilder::new()
.fill_color(Gray8::WHITE)
.stroke_color(Gray8::BLACK)
.stroke_width(10)
.stroke_alignment(StrokeAlignment::Inside)
.build();
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.finish()
}
fn open_shape_benches<P>(c: &mut Criterion, name: &str, build: impl Fn() -> P)
where
P: Primitive,
Styled<P, PrimitiveStyle<Gray8>>: Drawable<Color = Gray8>,
{
let mut group = c.benchmark_group(name);
group.bench_function("stroke 1px", |b| {
let style = PrimitiveStyle::with_stroke(Gray8::WHITE, 1);
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("stroke 10px", |b| {
let style = PrimitiveStyle::with_stroke(Gray8::WHITE, 10);
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.bench_function("stroke 50px", |b| {
let style = PrimitiveStyle::with_stroke(Gray8::WHITE, 50);
let object = build().into_styled(style);
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
group.finish()
}
@@ -0,0 +1,39 @@
use criterion::*;
use embedded_graphics::{geometry::AngleUnit, pixelcolor::Gray8, prelude::*, primitives::*};
mod common;
use common::Framebuffer;
fn arc(c: &mut Criterion) {
c.bench_function("arc", |b| {
let object = &Arc::new(Point::new(100, 100), 100, -30.0.deg(), 150.0.deg())
.into_styled(PrimitiveStyle::with_stroke(Gray8::new(1), 1));
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
}
fn sector(c: &mut Criterion) {
c.bench_function("sector", |b| {
let object = &Sector::new(Point::new(100, 100), 100, -30.0.deg(), 150.0.deg())
.into_styled(PrimitiveStyle::with_stroke(Gray8::new(1), 1));
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
}
fn filled_sector(c: &mut Criterion) {
c.bench_function("filled_sector", |b| {
let object = &Sector::new(Point::new(100, 100), 100, -30.0.deg(), 150.0.deg())
.into_styled(PrimitiveStyle::with_fill(Gray8::new(1)));
let mut framebuffer = Framebuffer::new();
b.iter(|| object.draw(&mut framebuffer))
});
}
criterion_group!(primitives_fixed_point, arc, sector, filled_sector);
criterion_main!(primitives_fixed_point);
+42
View File
@@ -0,0 +1,42 @@
use criterion::*;
use embedded_graphics::{iterator::raw::RawDataSlice, pixelcolor::raw::*};
const TEST_DATA: &[u8] = include_bytes!("../fonts/src/10x20.bdf");
macro_rules! impl_bench {
($fn:ident, $type:ident) => {
fn $fn(c: &mut Criterion) {
c.bench_function(stringify!($type), |b| {
let slice = RawDataSlice::<$type, LittleEndian>::new(TEST_DATA);
b.iter(|| slice.into_iter().collect::<Vec<_>>())
});
c.bench_function(concat!(stringify!($type), " step by 20"), |b| {
let slice = RawDataSlice::<$type, LittleEndian>::new(TEST_DATA);
b.iter(|| slice.into_iter().step_by(20).collect::<Vec<_>>())
});
}
};
}
impl_bench!(raw_u1, RawU1);
impl_bench!(raw_u2, RawU2);
impl_bench!(raw_u4, RawU4);
impl_bench!(raw_u8, RawU8);
impl_bench!(raw_u16, RawU16);
impl_bench!(raw_u24, RawU24);
impl_bench!(raw_u32, RawU32);
criterion_group!(
raw_data_iter,
raw_u1,
raw_u2,
raw_u4,
raw_u8,
raw_u16,
raw_u24,
raw_u32
);
criterion_main!(raw_data_iter);
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

+40
View File
@@ -0,0 +1,40 @@
# Development setup
## Ubuntu/Linux Mint
```bash
# Update to latest stable version of Rust
rustup update
# Ensure rustfmt is installed
rustup component add rustfmt
# Install `cargo-readme`, `cargo-deadlinks` and `lychee`
cargo install cargo-readme cargo-deadlinks lychee
# Install `just`
cargo install just
# Install SDL2 for simulator for build script
sudo apt install libsdl2-dev
```
## Generating readmes
The various `README.md` files in this project are generated from each crate's `lib.rs` comment. To
regenerate a readme, ensure [`cargo-readme`](https://crates.io/crates/cargo-readme) and
[`just`](https://github.com/casey/just) are installed then run:
```bash
just generate-readme <crate>
# e.g.
just generate-readme simulator
```
All readmes can be generated at the same time by running `just generate-readmes` in the project
root.
Running `just build` will check if the readme was successfully updated. The updated `README.md`
should be committed into git.
+62
View File
@@ -0,0 +1,62 @@
# Release process
Target audience: crate maintainers who wish to release `embedded-graphics` or `embedded-graphics-core`.
> Please take a cautious approach to this. If any step doesn't feel right or doesn't succeed smoothly, stop and rectify any issues before continuing.
## On GitHub
- Check that all desired PRs are merged and all desired issues are closed/resolved.
- Check that the latest master build passed in CircleCI.
## On your local machine
- `cd` to the repository root
- Use the crate MSRV of 1.71.1 by running `rustup override set 1.71.1`
- Check that `just` and `cargo-release` are installed and available in `$PATH`.
- `just --version`
- `cargo release --version`
- Ensure you have the latest changes with `git switch master` and `git pull --rebase`
- Check that your local repository is clean with no uncommitted changes and no unpushed commits. Ideally, use `git reset --hard origin/master` to ensure your local state is up to date with `origin/master`. You may need to change `origin` to the name of the remote pointing to <https://github.com/embedded-graphics/embedded-graphics>.
- Before a **stable** release:
- Search the repository for any `TODO` or `FIXME` comments. If any need resolving before release, stop this process and fix them with one or more PRs.
- Ensure the `RELEASES.md` file is up to date with any new features added between the previous stable release and the current one.
- Check that the crate version in `Cargo.toml` and `core/Cargo.toml` match the latest released versions on <https://crates.io/crates/embedded-graphics> and <https://crates.io/crates/embedded-graphics-core> respectively.
- Run `just build` to ensure the build passes locally.
- If the build fails for any reason, stop the release process and fix any issues by creating PRs. The upstream master branch must remain the source of truth. Restart this checklist once `just build` passes.
- Double check the release level (major, minor, patch)
- Release the crates in the following order:
1. For `embedded-graphics-core` **if there are changes to release**: `just release-core --push-remote <push-remote> <level>`
a. When the above command completes, check the `embedded-graphics-core` version in `Cargo.toml` in the project root. It should have been updated automatically to the just-released core version.
2. For `embedded-graphics`: `just release-e-g --push-remote <push-remote> <level>`
Where `<level>` is `major`, `minor`, `patch`, or a specific SemVer version number, and where `<push-remote>` is the git remote for the upstream repository `embedded-graphics/embedded-graphics`.
## Post release
- Check that the release commands pushed a Git tag for each crate published, something like `embedded-graphics-v0.7.0` or `embedded-graphics-core-v0.2.0`.
- For each crate's tag, go to its page at e.g. <https://github.com/embedded-graphics/embedded-graphics/releases/tag/embedded-graphics-v0.7.0-alpha.3>, click <kbd>Edit tag</kbd> and draft a release:
- Add the crate name to the `Release title` field
- Copy and paste the latest released section out of the crate's `CHANGELOG.md` file into the `Describe this release` field. Do not include the version header, e.g.:
```markdown
### Added
- [#111](https://github.com/embedded-graphics/embedded-graphics/pull/111) Added something
### Removed
- [#222](https://github.com/embedded-graphics/embedded-graphics/pull/222) Removed a thing
```
- Checkbox For `alpha` or `beta` releases, check the `This is a pre-release` checkbox.
- Hit <kbd>Publish release</kbd>
- Check that the release is displayed on the [repository homepage](https://github.com/embedded-graphics/embedded-graphics).
- Post a link to the released tag (e.g. <https://github.com/embedded-graphics/embedded-graphics/releases/tag/embedded-graphics-v0.7.0-alpha.3>) to the embedded-graphics Matrix room at <https://matrix.to/#/!SfJCDXZbMHXkPovtKL:matrix.org>
- If you are @jamwaffles, post a Tweet tagging @rustembedded with a happy announcement message.
- Check the other repositories in the [embedded-graphics organization](https://github.com/embedded-graphics) for dependencies on `embedded-graphics` and `embedded-graphics-core`. The versions should be updated to the latest releases made whilst following this guide.
+5
View File
@@ -0,0 +1,5 @@
# Delete lines containing reference links like `[Foo]: bar::Foo`
/\[([^]]+)\]\: ([A-Za-z_]+::)*[A-Za-z_]+$/d
/<!-- README-LINKS/d
/README-LINKS -->/d
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Loaded 100 of 17624 files, more files were not shown because too many files have changed in this diff. Show more