Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add string rotation function #222

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 74 additions & 28 deletions components/micropython/port/src/omv/img/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,25 @@ void imlib_draw_ellipse(image_t *img, int cx, int cy, int rx, int ry, int rotati
scratch_draw_rotated_ellipse(img, cx, cy, rx * 2, ry * 2, rotation, fill, c, thickness);
}

void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int c, float scale, int x_spacing, int y_spacing, bool mono_space)
void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int c, float scale, int x_spacing, int y_spacing, bool mono_space,
int char_rotation, bool char_hmirror, bool char_vflip, int string_rotation, bool string_hmirror, bool string_vflip)
{
char_rotation %= 360;
if (char_rotation < 0) char_rotation += 360;
char_rotation = (char_rotation / 90) * 90;

string_rotation %= 360;
if (string_rotation < 0) string_rotation += 360;
string_rotation = (string_rotation / 90) * 90;

bool char_swap_w_h = (char_rotation == 90) || (char_rotation == 270);
bool char_upsidedown = (char_rotation == 180) || (char_rotation == 270);

if (string_hmirror) x_off -= fast_floorf(font[0].w * scale) - 1;
if (string_vflip) y_off -= fast_floorf(font[0].h * scale) - 1;

int org_x_off = x_off;
int org_y_off = y_off;
const int anchor = x_off;

for(char ch, last = '\0'; (ch = *str); str++, last = ch) {
Expand All @@ -280,17 +297,11 @@ void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int

if ((ch == '\n') || (ch == '\r')) { // handle '\n' or '\r' strings
x_off = anchor;
y_off += fast_roundf(font[0].h * scale) + y_spacing; // newline height == space height
y_off += (string_vflip ? -1 : +1) * (fast_floorf((char_swap_w_h ? font[0].w : font[0].h) * scale) + y_spacing); // newline height == space height
continue;
}

if ((ch < ' ') || (ch > '~')) { // handle unknown characters
imlib_draw_rectangle(img,
x_off + (fast_roundf(scale * 3) / 2),
y_off + (fast_roundf(scale * 3) / 2),
fast_roundf(font[0].w * scale) - ((fast_roundf(scale * 3) / 2) * 2),
fast_roundf(font[0].h * scale) - ((fast_roundf(scale * 3) / 2) * 2),
c, fast_roundf(scale), false);
continue;
}

Expand All @@ -300,46 +311,81 @@ void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int
// Find the first pixel set and offset to that.
bool exit = false;

for (int x = 0, xx = g->w; x < xx; x++) {
for (int y = 0, yy = g->h; y < yy; y++) {
if (g->data[y] & (1 << (g->w - 1 - x))) {
x_off -= fast_roundf(x * scale);
exit = true;
break;
if (!char_swap_w_h) {
for (int x = 0, xx = g->w; x < xx; x++) {
for (int y = 0, yy = g->h; y < yy; y++) {
if (g->data[(char_upsidedown ^ char_vflip) ? (g->h - 1 - y) : y] &
(1 << ((char_upsidedown ^ char_hmirror ^ string_hmirror) ? x : (g->w - 1 - x)))) {
x_off += (string_hmirror ? +1 : -1) * fast_floorf(x * scale);
exit = true;
break;
}
}

if (exit) break;
}
} else {
for (int y = g->h - 1; y >= 0; y--) {
for (int x = 0, xx = g->w; x < xx; x++) {
if (g->data[(char_upsidedown ^ char_vflip) ? (g->h - 1 - y) : y] &
(1 << ((char_upsidedown ^ char_hmirror ^ string_hmirror) ? x : (g->w - 1 - x)))) {
x_off += (string_hmirror ? +1 : -1) * fast_floorf((g->h - 1 - y) * scale);
exit = true;
break;
}
}

if (exit) break;
if (exit) break;
}
}
}

for (int y = 0, yy = fast_roundf(g->h * scale); y < yy; y++) {
for (int x = 0, xx = fast_roundf(g->w * scale); x < xx; x++) {
if (g->data[fast_roundf(y / scale)] & (1 << (g->w - 1 - fast_roundf(x / scale)))) {
imlib_set_pixel(img, (x_off + x), (y_off + y), c);
for (int y = 0, yy = fast_floorf(g->h * scale); y < yy; y++) {
for (int x = 0, xx = fast_floorf(g->w * scale); x < xx; x++) {
if (g->data[fast_floorf(y / scale)] & (1 << (g->w - 1 - fast_floorf(x / scale)))) {
int16_t x_tmp = x_off + (char_hmirror ? (xx - x - 1) : x), y_tmp = y_off + (char_vflip ? (yy - y - 1) : y);
point_rotate(x_tmp, y_tmp, IM_DEG2RAD(char_rotation), x_off + (xx / 2), y_off + (yy / 2), &x_tmp, &y_tmp);
point_rotate(x_tmp, y_tmp, IM_DEG2RAD(string_rotation), org_x_off, org_y_off, &x_tmp, &y_tmp);
imlib_set_pixel(img, x_tmp, y_tmp, c);
}
}
}

if (mono_space) {
x_off += fast_roundf(g->w * scale) + x_spacing;
x_off += (string_hmirror ? -1 : +1) * (fast_floorf((char_swap_w_h ? g->h : g->w) * scale) + x_spacing);
} else {
// Find the last pixel set and offset to that.
bool exit = false;

for (int x = g->w - 1; x >= 0; x--) {
for (int y = g->h - 1; y >= 0; y--) {
if (g->data[y] & (1 << (g->w - 1 - x))) {
x_off += fast_roundf((x + 2) * scale) + x_spacing;
exit = true;
break;
if (!char_swap_w_h) {
for (int x = g->w - 1; x >= 0; x--) {
for (int y = g->h - 1; y >= 0; y--) {
if (g->data[(char_upsidedown ^ char_vflip) ? (g->h - 1 - y) : y] &
(1 << ((char_upsidedown ^ char_hmirror ^ string_hmirror) ? x : (g->w - 1 - x)))) {
x_off += (string_hmirror ? -1 : +1) * (fast_floorf((x + 2) * scale) + x_spacing);
exit = true;
break;
}
}

if (exit) break;
}
} else {
for (int y = 0, yy = g->h; y < yy; y++) {
for (int x = g->w - 1; x >= 0; x--) {
if (g->data[(char_upsidedown ^ char_vflip) ? (g->h - 1 - y) : y] &
(1 << ((char_upsidedown ^ char_hmirror ^ string_hmirror) ? x : (g->w - 1 - x)))) {
x_off += (string_hmirror ? -1 : +1) * (fast_floorf(((g->h - 1 - y) + 2) * scale) + x_spacing);
exit = true;
break;
}
}

if (exit) break;
if (exit) break;
}
}

if (!exit) x_off += fast_roundf(scale * 3); // space char
if (!exit) x_off += (string_hmirror ? -1 : +1) * fast_floorf(scale * 3); // space char
}
}
}
Expand Down