Skip to content

Commit

Permalink
XOR cursor support in Notepad (portapack-mayhem#1311)
Browse files Browse the repository at this point in the history
* XOR cursor support in Notepad

* XOR cursor support

* XOR cursor support

* Revert change

* Use static buffer

* Use static buffer

* Clang
  • Loading branch information
NotherNgineer authored Jul 27, 2023
1 parent 8c565bb commit b27c738
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 16 deletions.
42 changes: 29 additions & 13 deletions firmware/application/apps/ui_text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ void TextViewer::paint(Painter& painter) {
paint_state_.first_line = first_line;
paint_state_.first_col = first_col;
paint_state_.redraw_text = true;
paint_state_.line = UINT32_MAX; // forget old cursor position when overwritten
}

if (paint_state_.redraw_text) {
Expand Down Expand Up @@ -221,28 +222,43 @@ void TextViewer::paint_text(Painter& painter, uint32_t line, uint16_t col) {
r.top() + (int)i * char_height,
clear_width * char_width, char_height},
style().background);

// if cursor line got overwritten, disable XOR of old cursor when displaying new cursor
if (i == paint_state_.line)
paint_state_.line = UINT32_MAX;
}
}

void TextViewer::paint_cursor(Painter& painter) {
if (!has_focus())
return;

auto draw_cursor = [this, &painter](uint32_t line, uint16_t col, Color c) {
auto r = screen_rect();
line = line - paint_state_.first_line;
col = col - paint_state_.first_col;

painter.draw_rectangle(
{(int)col * char_width - 1,
r.top() + (int)line * char_height,
char_width + 1, char_height},
c);
auto xor_cursor = [this, &painter](int32_t line, uint16_t col) {
int cursor_width = char_width + 1;
int x = (col - paint_state_.first_col) * char_width - 1;
if (x < 0) { // cursor is one pixel narrower when in left column
cursor_width--;
x = 0;
}
int y = screen_rect().top() + (line - paint_state_.first_line) * char_height;

// Converting one row at a time to reduce buffer size
auto pbuf8 = cursor_.pixel_buffer8;
auto pbuf = cursor_.pixel_buffer;
for (auto col = 0; col < char_height; col++) {
// Annoyingly, read_pixels uses a 24-bit pixel format vs draw_pixels which uses 16-bit
portapack::display.read_pixels({x, y + col, cursor_width, 1}, pbuf8, cursor_width);
for (auto i = 0; i < cursor_width; i++)
pbuf[i] = Color(pbuf8[i].r, pbuf8[i].g, pbuf8[i].b).v ^ 0xFFFF;
portapack::display.draw_pixels({x, y + col, cursor_width, 1}, pbuf, cursor_width);
}
};

// Clear old cursor. CONSIDER: XOR cursor?
draw_cursor(paint_state_.line, paint_state_.col, style().background);
draw_cursor(cursor_.line, cursor_.col, style().foreground);
if (paint_state_.line != UINT32_MAX) // only XOR old cursor if it still appears on the screen
xor_cursor(paint_state_.line, paint_state_.col);

xor_cursor(cursor_.line, cursor_.col);

paint_state_.line = cursor_.line;
paint_state_.col = cursor_.col;
}
Expand Down
4 changes: 4 additions & 0 deletions firmware/application/apps/ui_text_editor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ class TextViewer : public Widget {
uint32_t line{};
uint16_t col{};
ScrollDirection dir{ScrollDirection::Vertical};

// Pixel buffer used for cursor XOR'ing - Max cursor width = Max char width + 1
ColorRGB888 pixel_buffer8[ui::char_width + 1]{};
Color pixel_buffer[ui::char_width + 1]{};
} cursor_{};
};

Expand Down
6 changes: 3 additions & 3 deletions firmware/common/lcd_ili9341.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class ILI9341 {
constexpr ui::Dim height() const { return 320; }
constexpr ui::Rect screen_rect() const { return {0, 0, width(), height()}; }

void draw_pixels(const ui::Rect r, const ui::Color* const colors, const size_t count);
void read_pixels(const ui::Rect r, ui::ColorRGB888* const colors, const size_t count);

private:
struct scroll_t {
ui::Coord top_area;
Expand All @@ -109,9 +112,6 @@ class ILI9341 {
};

scroll_t scroll_state;

void draw_pixels(const ui::Rect r, const ui::Color* const colors, const size_t count);
void read_pixels(const ui::Rect r, ui::ColorRGB888* const colors, const size_t count);
};

} /* namespace lcd */
Expand Down

0 comments on commit b27c738

Please sign in to comment.