forked from moononournation/Arduino_GFX
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathArduino_Canvas.cpp
122 lines (114 loc) · 3.4 KB
/
Arduino_Canvas.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* start rewrite from:
* https://github.com/adafruit/Adafruit-GFX-Library.git
*/
#include "Arduino_DataBus.h"
#include "Arduino_GFX.h"
#include "Arduino_Canvas.h"
Arduino_Canvas::Arduino_Canvas(int16_t w, int16_t h, Arduino_G *output, int16_t output_x, int16_t output_y)
: Arduino_GFX(w, h), _output(output), _output_x(output_x), _output_y(output_y)
{
}
void Arduino_Canvas::begin(int speed)
{
#if defined(ESP32)
if (psramFound())
{
_framebuffer = (uint16_t *)ps_malloc(_width * _height * 2);
}
else
{
// _framebuffer = (uint16_t *)malloc(_width * _height * 2);
// hack for allocate memory over 63,360 pixels
uint16_t *tmp;
_framebuffer = (uint16_t *)malloc(_width * _height);
tmp = (uint16_t *)malloc(_width * _height);
log_v("_framebuffer delta: %d", tmp - _framebuffer);
}
#else
_framebuffer = (uint16_t *)malloc(_width * _height * 2);
#endif
if (!_framebuffer)
{
Serial.println(F("_framebuffer allocation failed."));
}
_output->begin(speed);
_output->fillScreen(BLACK);
}
void Arduino_Canvas::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
{
_framebuffer[((int32_t)y * _width) + x] = color;
}
void Arduino_Canvas::writeFastVLine(int16_t x, int16_t y,
int16_t h, uint16_t color)
{
if (_ordered_in_range(x, 0, _max_x) && h)
{ // X on screen, nonzero height
if (h < 0)
{ // If negative height...
y += h + 1; // Move Y to top edge
h = -h; // Use positive height
}
if (y <= _max_y)
{ // Not off bottom
int16_t y2 = y + h - 1;
if (y2 >= 0)
{ // Not off top
// Line partly or fully overlaps screen
if (y < 0)
{
y = 0;
h = y2 + 1;
} // Clip top
if (y2 > _max_y)
{
h = _max_y - y + 1;
} // Clip bottom
uint16_t *fb = _framebuffer + ((int32_t)y * _width) + x;
while (h--)
{
*fb = color;
fb += _width;
}
}
}
}
}
void Arduino_Canvas::writeFastHLine(int16_t x, int16_t y,
int16_t w, uint16_t color)
{
if (_ordered_in_range(y, 0, _max_y) && w)
{ // Y on screen, nonzero width
if (w < 0)
{ // If negative width...
x += w + 1; // Move X to left edge
w = -w; // Use positive width
}
if (x <= _max_x)
{ // Not off right
int16_t x2 = x + w - 1;
if (x2 >= 0)
{ // Not off left
// Line partly or fully overlaps screen
if (x < 0)
{
x = 0;
w = x2 + 1;
} // Clip left
if (x2 > _max_x)
{
w = _max_x - x + 1;
} // Clip right
uint16_t *fb = _framebuffer + ((int32_t)y * _width) + x;
while (w--)
{
*(fb++) = color;
}
}
}
}
}
void Arduino_Canvas::flush()
{
_output->draw16bitRGBBitmap(_output_x, _output_y, _framebuffer, _width, _height);
}