kopia lustrzana https://github.com/pimoroni/pimoroni-pico
fixed up markdown-esque text algorithms
rodzic
f90f103da8
commit
6d0f359a91
|
@ -97,26 +97,25 @@ int main() {
|
|||
};
|
||||
|
||||
std::vector<pt> shapes;
|
||||
for(int i = 0; i < 1000; i++) {
|
||||
for(int i = 0; i < 250; i++) {
|
||||
pt shape;
|
||||
shape.x = rand() % 240;
|
||||
shape.y = rand() % 135;
|
||||
shape.r = (rand() % 10) + 3;
|
||||
shape.r = (rand() % 10) + 5;
|
||||
shape.dx = float(rand() % 255) / 128.0f;
|
||||
shape.dy = float(rand() % 255) / 128.0f;
|
||||
shape.pen = pico_display.create_pen(rand() % 255, rand() % 255, rand() % 255);
|
||||
shape.pen = pico_display.create_pen(rand() % 100, rand() % 100, rand() % 100);
|
||||
shapes.push_back(shape);
|
||||
}
|
||||
|
||||
uint32_t i = 0;
|
||||
while(true) {
|
||||
pico_display.remove_clip();
|
||||
|
||||
pico_display.set_pen(20, 30, 40);
|
||||
pico_display.clear();
|
||||
|
||||
pico_display.set_pen(200, 220, 240);
|
||||
pico_display.text("Markdown? *Zoiks!*\n\nIt _helps_ to /emphasize/.\n\n-a bulleted list?\n-sure, why not!?\n\nMade a mistake? ~Fix it~.", Point(5, 5), 230);
|
||||
|
||||
/*
|
||||
for(auto &shape : shapes) {
|
||||
shape.x += shape.dx;
|
||||
shape.y += shape.dy;
|
||||
|
@ -129,11 +128,41 @@ int main() {
|
|||
pico_display.circle(Point(shape.x, shape.y), shape.r);
|
||||
}
|
||||
|
||||
pico_display.set_pen(200, 220, 240);
|
||||
|
||||
std::string text =
|
||||
"We've sourced a new LCD screen especially for our Pico Display Pack - "
|
||||
"it's a lovely, bright *18-bit capable 240x135 pixel IPS display* and fits "
|
||||
"the Pico perfectly.\n\nWe've surrounded it with *four tactile buttons* so you "
|
||||
"can easily interface your Pico with your human fingers and an *RGB LED* that "
|
||||
"you can use as an indicator, for notifications or just for adding extra rainbows."
|
||||
"\n\n"
|
||||
"*Features:*\n\n"
|
||||
"-1.14\" 240x135 pixel IPS LCD screen\n"
|
||||
"-4 x tactile buttons\n"
|
||||
"-RGB LED\n"
|
||||
"-Pre-soldered female headers for attaching to Pico\n"
|
||||
"-Compatible with Raspberry Pi Pico.\n"
|
||||
"-Fully assembled\n"
|
||||
"-No soldering required (as long as your Pico has header pins attached).\n"
|
||||
"-Dimensions: approx 53mm x 25mm x 9mm (L x W x H)\n"
|
||||
"-Programmable with C/C++ and MicroPython"
|
||||
;
|
||||
|
||||
pico_display.set_clip(Rect(10, 10, 220, 115));
|
||||
|
||||
int32_t y = cos(float(i) / 100.0f) * 200.0f - 200.0f;
|
||||
pico_display.text(text, Point(10, y + 10), pico_display.clip.w - 2);
|
||||
|
||||
|
||||
// "Markdown? *Zoiks!*\n\nIt _helps_ to /emphasize/.\n\n-a bulleted list?\n-sure, why not!?\n\nMade a mistake? ~Fix it~."
|
||||
|
||||
|
||||
float led_step = fmod(i / 20.0f, M_PI * 2.0f);
|
||||
int r = (sin(led_step) * 25.0f) + 25.0f;
|
||||
pico_display.set_led(r, r / 1.2f, r);
|
||||
|
||||
|
||||
/*
|
||||
std::vector<Point> poly;
|
||||
poly.push_back(Point(30, 30));
|
||||
poly.push_back(Point(50, 35));
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
enum flags {BOLD = 1, ITALIC = 2, UNDERLINE = 4, STRIKETHROUGH = 8};
|
||||
enum flags {BOLD = 1, ITALIC = 2, UNDERLINE = 4, STRIKETHROUGH = 8, BULLET = 16};
|
||||
|
||||
uint8_t *character_data(uint8_t i) {
|
||||
uint32_t bytes_per_character = (font_data[0] * font_data[1]) + 1;
|
||||
|
@ -112,7 +112,11 @@ namespace pimoroni {
|
|||
}
|
||||
|
||||
uint8_t character_width(uint8_t i) {
|
||||
return character_data(i)[0];
|
||||
return character_data(i)[0] + 2;
|
||||
}
|
||||
|
||||
uint8_t character_height() {
|
||||
return font_data[1] - 2;
|
||||
}
|
||||
|
||||
void PicoGraphics::character(const char c, const Point &p, uint32_t flags) {
|
||||
|
@ -142,7 +146,6 @@ namespace pimoroni {
|
|||
pixel(Point(p.x + cx + italic, p.y + cy));
|
||||
if(flags & flags::BOLD) {
|
||||
pixel(Point(p.x + cx + 1, p.y + cy));
|
||||
pixel(Point(p.x + cx - 1, p.y + cy));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +156,7 @@ namespace pimoroni {
|
|||
if(flags & flags::UNDERLINE || flags & flags::STRIKETHROUGH) {
|
||||
for(int8_t cx = -1; cx < character_width(c) + 1; cx++) {
|
||||
if(flags & flags::UNDERLINE) {
|
||||
pixel(Point(p.x + cx, p.y + character_height));
|
||||
pixel(Point(p.x + cx, p.y + character_height - 1));
|
||||
}
|
||||
|
||||
if(flags & flags::STRIKETHROUGH) {
|
||||
|
@ -163,74 +166,98 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
void PicoGraphics::text(const std::string &t, const Point &p, int32_t wrap) {
|
||||
void PicoGraphics::text(const std::string &text, const Point &p, int32_t wrap) {
|
||||
uint32_t flags = 0; // style flags
|
||||
uint32_t co = 0, lo = 0; // character and line (if wrapping) offset
|
||||
|
||||
uint32_t character_height = font_data[1] - 2;
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
uint32_t flags = 0;
|
||||
|
||||
while(i < t.length()) {
|
||||
if(t[i] == '\n') {
|
||||
co = 0;
|
||||
lo += character_height;
|
||||
i++;
|
||||
continue;
|
||||
}else if(t[i] == ' '){
|
||||
i++;
|
||||
}
|
||||
|
||||
// find length of current word
|
||||
size_t next_space = std::min(t.find(' ', i + 1), t.find('\n', i + 1));
|
||||
|
||||
if(next_space == std::string::npos) {
|
||||
next_space = t.length();
|
||||
}
|
||||
|
||||
uint16_t word_width = 0;
|
||||
for(size_t j = i; j < next_space; j++) {
|
||||
char c = t[j];
|
||||
if(c != '*' && c != '_' && c != '/' && c != '~') {
|
||||
uint8_t bold = flags & flags::BOLD ? 1 : 0;
|
||||
word_width += (character_width(c) + bold);
|
||||
}
|
||||
}
|
||||
|
||||
// if this word would exceed the wrap limit then
|
||||
// move to the next line
|
||||
if(co != 0 && co + word_width > wrap) {
|
||||
co = 0;
|
||||
lo += character_height;
|
||||
}
|
||||
|
||||
// draw word
|
||||
for(size_t j = i; j < next_space; j++) {
|
||||
char c = t[j];
|
||||
if(c == '*') {
|
||||
for (std::string::size_type i = 0; i < text.size(); i++) {
|
||||
char c = text[i];
|
||||
// handle special characters
|
||||
switch(c) {
|
||||
case '\n': { // line break
|
||||
co = 0;
|
||||
lo += character_height();
|
||||
flags &= ~flags::BULLET;
|
||||
continue;
|
||||
} break;
|
||||
case '-': { // bulleted list
|
||||
if(co == 0) { // only if first character on line
|
||||
co += character_height(); // line height as indent for bullet
|
||||
character(249, Point(p.x + co, p.y + lo), flags); // kinda bullet point thingy
|
||||
co += character_width(249) + character_width(32); // bullet + space
|
||||
flags |= flags::BULLET;
|
||||
continue;
|
||||
}
|
||||
} break;
|
||||
case '*': { // bold
|
||||
flags ^= flags::BOLD;
|
||||
}else if(c == '_') {
|
||||
flags ^= flags::UNDERLINE;
|
||||
}else if(c == '/') {
|
||||
continue;
|
||||
} break;
|
||||
case '/': { // italic
|
||||
flags ^= flags::ITALIC;
|
||||
}else if(c == '~') {
|
||||
continue;
|
||||
} break;
|
||||
case '_': { // underline
|
||||
flags ^= flags::UNDERLINE;
|
||||
continue;
|
||||
} break;
|
||||
case '~': { // strikethrough
|
||||
flags ^= flags::STRIKETHROUGH;
|
||||
}else if(c == '-') {
|
||||
character(249, Point(p.x + co, p.y + lo), flags); // kinda bullet point thingy
|
||||
co += 7;
|
||||
i++;
|
||||
}else{
|
||||
character(t[j], Point(p.x + co, p.y + lo), flags);
|
||||
uint8_t bold = flags & flags::BOLD ? 1 : 0;
|
||||
co += (character_width(c) + bold) + 2;
|
||||
}
|
||||
continue;
|
||||
} break;
|
||||
case '\\': { // escaped character
|
||||
// skip forward to escaped character so that it is
|
||||
// rendered in this iteration of the loop and
|
||||
// isn't evaluated for special behaviour
|
||||
if(i < text.size() - 1) {
|
||||
i++;
|
||||
c = text[i + 1];
|
||||
}
|
||||
} break;
|
||||
case ' ': { // space
|
||||
// determine if we need to wordwrap
|
||||
size_t next_whitespace = std::min(text.find(' ', i + 1), text.find('\n', i + 1));
|
||||
if(next_whitespace == std::string::npos) { // not found, use end of text
|
||||
next_whitespace = text.size();
|
||||
}
|
||||
|
||||
// calculate width of the word including this leading space
|
||||
uint16_t word_width = character_width(' ');
|
||||
for(std::string::size_type j = i + 1; j < next_whitespace; j++) {
|
||||
if(text[j] == '\\') {
|
||||
if(j < next_whitespace - 1) {
|
||||
j++;
|
||||
// skip forward to escaped character so that it is
|
||||
// rendered in this iteration of the loop and
|
||||
// isn't evaluated for special behaviour
|
||||
word_width += character_width(text[j]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(text[j] == '*' || text[j] == '~') {
|
||||
continue;
|
||||
}
|
||||
|
||||
word_width += character_width(c);
|
||||
}
|
||||
|
||||
// if word too long for this line then wrap
|
||||
if(co + word_width >= wrap) {
|
||||
if(flags & flags::BULLET) {
|
||||
co = character_height() + character_width(249) + character_width(32); // bullet + space
|
||||
}else{
|
||||
co = 0;
|
||||
}
|
||||
|
||||
lo += character_height();
|
||||
continue;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
// move character offset to end of word and add a space
|
||||
character(' ', Point(p.x + co, p.y + lo), flags);
|
||||
co += (character_width(' '));
|
||||
i = next_space;
|
||||
character(text[i], Point(p.x + co, p.y + lo), flags);
|
||||
co += character_width(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue