kopia lustrzana https://github.com/pimoroni/pimoroni-pico
TEST: PicoVector: Break things until they work.
rodzic
7cd9187d80
commit
88bd71e56f
|
@ -2,4 +2,5 @@ extern "C" {
|
|||
void *af_malloc(size_t size);
|
||||
void *af_realloc(void *p, size_t size);
|
||||
void af_free(void *p);
|
||||
void af_debug(const char *fmt, ...);
|
||||
}
|
|
@ -52,6 +52,10 @@
|
|||
#define AF_FGETC(stream) fgetc(stream)
|
||||
#endif
|
||||
|
||||
#ifndef AF_DEBUG
|
||||
#define AF_DEBUG(...)
|
||||
#endif
|
||||
|
||||
#include "pretty-poly.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -99,9 +103,9 @@ typedef struct {
|
|||
} af_text_metrics_t;
|
||||
|
||||
bool af_load_font_file(AF_FILE file, af_face_t *face);
|
||||
void af_render_character(af_face_t *face, wchar_t codepoint, af_text_metrics_t *tm);
|
||||
void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm);
|
||||
pp_rect_t af_measure(af_face_t *face, const wchar_t *text, af_text_metrics_t *tm);
|
||||
void af_render_character(af_face_t *face, const char codepoint, af_text_metrics_t *tm);
|
||||
void af_render(af_face_t *face, const char *text, af_text_metrics_t *tm);
|
||||
pp_rect_t af_measure(af_face_t *face, const char *text, af_text_metrics_t *tm);
|
||||
|
||||
#ifdef AF_USE_PRETTY_POLY
|
||||
#endif
|
||||
|
@ -146,6 +150,11 @@ bool af_load_font_file(AF_FILE file, af_face_t *face) {
|
|||
void *buffer = AF_MALLOC(sizeof(af_glyph_t) * glyph_count + \
|
||||
sizeof( af_path_t) * path_count + \
|
||||
sizeof(af_point_t) * point_count);
|
||||
|
||||
if(!buffer) {
|
||||
return false; // failed memory allocation
|
||||
}
|
||||
|
||||
af_glyph_t *glyphs = (af_glyph_t *) buffer;
|
||||
af_path_t *paths = ( af_path_t *)(glyphs + (sizeof(af_glyph_t) * glyph_count));
|
||||
af_point_t *points = (af_point_t *)( paths + (sizeof( af_path_t) * path_count));
|
||||
|
@ -193,7 +202,7 @@ bool af_load_font_file(AF_FILE file, af_face_t *face) {
|
|||
return true;
|
||||
}
|
||||
|
||||
af_glyph_t *find_glyph(af_face_t *face, wchar_t c) {
|
||||
af_glyph_t *find_glyph(af_face_t *face, char c) {
|
||||
for(int i = 0; i < face->glyph_count; i++) {
|
||||
if(face->glyphs[i].codepoint == c) {
|
||||
return &face->glyphs[i];
|
||||
|
@ -223,12 +232,12 @@ void af_render_glyph(af_glyph_t* glyph, af_text_metrics_t *tm) {
|
|||
|
||||
for(uint32_t i = 0; i < poly.count; i++) {
|
||||
pp_path_t *path = &poly.paths[i];
|
||||
free(path->points);
|
||||
AF_FREE(path->points);
|
||||
}
|
||||
free(poly.paths);
|
||||
AF_FREE(poly.paths);
|
||||
}
|
||||
|
||||
void af_render_character(af_face_t *face, wchar_t c, af_text_metrics_t *tm) {
|
||||
void af_render_character(af_face_t *face, const char c, af_text_metrics_t *tm) {
|
||||
af_glyph_t *glyph = find_glyph(face, c);
|
||||
if(!glyph) {
|
||||
return;
|
||||
|
@ -236,10 +245,10 @@ void af_render_character(af_face_t *face, wchar_t c, af_text_metrics_t *tm) {
|
|||
af_render_glyph(glyph, tm);
|
||||
}
|
||||
|
||||
int get_line_width(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
|
||||
int get_line_width(af_face_t *face, const char *text, af_text_metrics_t *tm) {
|
||||
int line_width = 0;
|
||||
wchar_t *end = wcschr(text, L'\n');
|
||||
for(wchar_t c = *text; text < end; text++, c = *text) {
|
||||
char *end = strchr(text, '\n');
|
||||
for(char c = *text; text < end; text++, c = *text) {
|
||||
af_glyph_t *glyph = find_glyph(face, c);
|
||||
if(!glyph) {
|
||||
continue;
|
||||
|
@ -254,22 +263,22 @@ int get_line_width(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
|
|||
return line_width;
|
||||
}
|
||||
|
||||
int get_max_line_width(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
|
||||
int get_max_line_width(af_face_t *face, const char *text, af_text_metrics_t *tm) {
|
||||
int max_width = 0;
|
||||
|
||||
wchar_t *end = wcschr(text, L'\n');
|
||||
char *end = strchr(text, '\n');
|
||||
while(end) {
|
||||
int width = get_line_width(face, text, tm);
|
||||
max_width = max_width < width ? width : max_width;
|
||||
text = end + 1;
|
||||
end = wcschr(text, L'\n');
|
||||
end = strchr(text, '\n');
|
||||
}
|
||||
|
||||
return max_width;
|
||||
}
|
||||
|
||||
|
||||
void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
|
||||
void af_render(af_face_t *face, const char *text, af_text_metrics_t *tm) {
|
||||
pp_mat3_t *old = pp_transform(NULL);
|
||||
|
||||
float line_height = (tm->line_height * 128.0f) / 100.0f;
|
||||
|
@ -285,11 +294,11 @@ void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
|
|||
caret.x = 0;
|
||||
caret.y = 0;
|
||||
|
||||
wchar_t *end = wcschr(text, L'\n');
|
||||
char *end = strchr(text, '\n');
|
||||
while(end) {
|
||||
int line_width = get_line_width(face, text, tm);
|
||||
|
||||
for(wchar_t c = *text; text < end; text++, c = *text) {
|
||||
for(char c = *text; text < end; text++, c = *text) {
|
||||
af_glyph_t *glyph = find_glyph(face, c);
|
||||
if(!glyph) {
|
||||
continue;
|
||||
|
@ -320,7 +329,7 @@ void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
|
|||
}
|
||||
|
||||
text = end + 1;
|
||||
end = wcschr(text, L'\n');
|
||||
end = strchr(text, '\n');
|
||||
|
||||
caret.x = 0;
|
||||
caret.y += line_height;
|
||||
|
@ -331,12 +340,12 @@ void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
|
|||
pp_transform(old);
|
||||
}
|
||||
|
||||
pp_rect_t af_measure(af_face_t *face, const wchar_t *text, af_text_metrics_t *tm) {
|
||||
pp_rect_t af_measure(af_face_t *face, const char *text, af_text_metrics_t *tm) {
|
||||
pp_rect_t result;
|
||||
bool first = true;
|
||||
pp_mat3_t t = *tm->transform;
|
||||
|
||||
for(size_t i = 0; i < wcslen(text); i++) {
|
||||
for(size_t i = 0; i < strlen(text); i++) {
|
||||
af_glyph_t *glyph = find_glyph(face, text[i]);
|
||||
if(!glyph) {
|
||||
continue;
|
||||
|
|
|
@ -56,9 +56,15 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
pp_point_t PicoVector::text(std::wstring_view text, pp_point_t offset, pp_mat3_t *t) {
|
||||
pp_point_t PicoVector::text(std::string_view text, pp_mat3_t *t) {
|
||||
pp_point_t caret = {0, 0};
|
||||
|
||||
text_metrics.transform = t;
|
||||
|
||||
af_render(text_metrics.face, text.data(), &text_metrics);
|
||||
|
||||
return caret;
|
||||
/*
|
||||
// Align text from the bottom left
|
||||
caret.y += (PP_COORD_TYPE)text_metrics.line_height;
|
||||
|
||||
|
@ -69,7 +75,7 @@ namespace pimoroni {
|
|||
pp_point_t space;
|
||||
pp_point_t carriage_return = {0, -(PP_COORD_TYPE)text_metrics.line_height};
|
||||
|
||||
wchar_t spc = L' ';
|
||||
char spc = ' ';
|
||||
|
||||
space.x = af_measure(text_metrics.face, &spc, &text_metrics).w;
|
||||
if (space.x == 0) {
|
||||
|
@ -110,10 +116,10 @@ namespace pimoroni {
|
|||
}
|
||||
|
||||
for(size_t j = i; j < std::min(next_break + 1, text.length()); j++) {
|
||||
if (text[j] == L'\n') { // Linebreak
|
||||
if (text[j] == '\n') { // Linebreak
|
||||
caret = pp_point_sub(&caret, &carriage_return);
|
||||
carriage_return = initial_carriage_return;
|
||||
} else if (text[j] == L' ') { // Space
|
||||
} else if (text[j] == ' ') { // Space
|
||||
caret = pp_point_add(&caret, &space);
|
||||
carriage_return = pp_point_add(&carriage_return, &space);
|
||||
} else {
|
||||
|
@ -125,7 +131,7 @@ namespace pimoroni {
|
|||
af_render_character(text_metrics.face, text[j], &text_metrics);
|
||||
}
|
||||
pp_point_t advance = {
|
||||
(PP_COORD_TYPE)af_measure(text_metrics.face, (const wchar_t *)text[j], &text_metrics).w + text_metrics.letter_spacing,
|
||||
(PP_COORD_TYPE)af_measure(text_metrics.face, &text[j], &text_metrics).w + text_metrics.letter_spacing,
|
||||
(PP_COORD_TYPE)0
|
||||
};
|
||||
advance = pp_point_transform(&advance, t);
|
||||
|
@ -137,5 +143,6 @@ namespace pimoroni {
|
|||
}
|
||||
|
||||
return {caret.x, caret.y};
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -14,6 +14,8 @@
|
|||
#define PP_REALLOC(p, size) af_realloc(p, size)
|
||||
#define PP_FREE(p) af_free(p)
|
||||
|
||||
#define AF_DEBUG(...) af_debug(__VA_ARGS__)
|
||||
|
||||
#include "pretty-poly.h"
|
||||
#include "alright-fonts.h"
|
||||
#include "pico_graphics.hpp"
|
||||
|
@ -40,6 +42,15 @@ namespace pimoroni {
|
|||
pp_antialias(graphics->supports_alpha_blend() ? PP_AA_X4 : PP_AA_NONE);
|
||||
|
||||
pp_clip(graphics->clip.x, graphics->clip.y, graphics->clip.w, graphics->clip.h);
|
||||
|
||||
text_metrics.align = AF_H_ALIGN_LEFT;
|
||||
text_metrics.line_height = 110;
|
||||
text_metrics.letter_spacing = 95;
|
||||
text_metrics.word_spacing = 200;
|
||||
text_metrics.size = 48;
|
||||
// Shoud be set before rendering chars
|
||||
//text_metrics.transform = (pp_mat3_t *)af_malloc(sizeof(pp_mat3_t));
|
||||
//*text_metrics.transform = pp_mat3_identity();
|
||||
}
|
||||
|
||||
static void tile_callback(const pp_tile_t *tile) {
|
||||
|
@ -86,17 +97,21 @@ namespace pimoroni {
|
|||
}
|
||||
|
||||
bool set_font(std::string_view font_path, unsigned int font_size) {
|
||||
if(text_metrics.face) {
|
||||
af_free(text_metrics.face->glyphs);
|
||||
af_free(text_metrics.face);
|
||||
}
|
||||
text_metrics.face = (af_face_t *)af_malloc(sizeof(af_face_t));
|
||||
//bool result = text_metrics.face.load(font_path);
|
||||
void* font = fileio_open(font_path.data());
|
||||
af_load_font_file(font, text_metrics.face);
|
||||
bool result = false;
|
||||
bool result = af_load_font_file(font, text_metrics.face);
|
||||
|
||||
set_font_size(font_size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pp_point_t text(std::wstring_view text, pp_point_t origin, pp_mat3_t *t);
|
||||
pp_point_t text(std::string_view text, pp_mat3_t *t);
|
||||
|
||||
void transform(pp_path_t *path, pp_mat3_t *t);
|
||||
void transform(pp_poly_t *poly, pp_mat3_t *t);
|
||||
|
|
|
@ -10,6 +10,7 @@ extern "C" {
|
|||
#include "py/stream.h"
|
||||
#include "py/reader.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct _ModPicoGraphics_obj_t {
|
||||
mp_obj_base_t base;
|
||||
|
@ -29,10 +30,31 @@ typedef struct _PATH_obj_t {
|
|||
pp_path_t path;
|
||||
} _PATH_obj_t;
|
||||
|
||||
void __printf_debug_flush() {
|
||||
for(auto i = 0u; i < 10; i++) {
|
||||
sleep_ms(1);
|
||||
mp_event_handle_nowait();
|
||||
}
|
||||
}
|
||||
|
||||
int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args);
|
||||
|
||||
void af_debug(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = mp_vprintf(&mp_plat_print, fmt, ap);
|
||||
va_end(ap);
|
||||
__printf_debug_flush();
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
void *af_malloc(size_t size) {
|
||||
mp_printf(&mp_plat_print, "af_malloc %lu\n", size);
|
||||
mp_event_handle_nowait();
|
||||
return m_tracked_calloc(sizeof(uint8_t), size);
|
||||
//mp_printf(&mp_plat_print, "af_malloc %lu\n", size);
|
||||
//__printf_debug_flush();
|
||||
void *addr = m_tracked_calloc(sizeof(uint8_t), size);
|
||||
//mp_printf(&mp_plat_print, "addr %lu\n", addr);
|
||||
//__printf_debug_flush();
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *af_realloc(void *p, size_t size) {
|
||||
|
@ -40,16 +62,16 @@ void *af_realloc(void *p, size_t size) {
|
|||
}
|
||||
|
||||
void af_free(void *p) {
|
||||
mp_printf(&mp_plat_print, "af_free\n");
|
||||
mp_event_handle_nowait();
|
||||
//mp_printf(&mp_plat_print, "af_free\n");
|
||||
//__printf_debug_flush();
|
||||
m_tracked_free(p);
|
||||
}
|
||||
|
||||
void* fileio_open(const char *filename) {
|
||||
mp_obj_t fn = mp_obj_new_str(filename, (mp_uint_t)strlen(filename));
|
||||
|
||||
mp_printf(&mp_plat_print, "Opening file %s\n", filename);
|
||||
mp_event_handle_nowait();
|
||||
//mp_printf(&mp_plat_print, "Opening file %s\n", filename);
|
||||
//__printf_debug_flush();
|
||||
|
||||
mp_obj_t args[2] = {
|
||||
fn,
|
||||
|
@ -58,10 +80,10 @@ void* fileio_open(const char *filename) {
|
|||
|
||||
// Stat the file to get its size
|
||||
// example tuple response: (32768, 0, 0, 0, 0, 0, 5153, 1654709815, 1654709815, 1654709815)
|
||||
mp_obj_t stat = mp_vfs_stat(fn);
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR2(stat, mp_obj_tuple_t);
|
||||
int filesize = mp_obj_get_int(tuple->items[6]);
|
||||
mp_printf(&mp_plat_print, "Size %lu\n", filesize);
|
||||
//mp_obj_t stat = mp_vfs_stat(fn);
|
||||
//mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR2(stat, mp_obj_tuple_t);
|
||||
//int filesize = mp_obj_get_int(tuple->items[6]);
|
||||
//mp_printf(&mp_plat_print, "Size %lu\n", filesize);
|
||||
|
||||
mp_obj_t fhandle = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map);
|
||||
|
||||
|
@ -73,14 +95,17 @@ void fileio_close(void* fhandle) {
|
|||
}
|
||||
|
||||
size_t fileio_read(void* fhandle, void *buf, size_t len) {
|
||||
mp_printf(&mp_plat_print, "Reading %lu bytes\n", len);
|
||||
//mp_printf(&mp_plat_print, "Reading %lu bytes\n", len);
|
||||
//__printf_debug_flush();
|
||||
int error;
|
||||
return mp_stream_read_exactly((mp_obj_t)fhandle, buf, len, &error);
|
||||
}
|
||||
|
||||
int fileio_getc(void* fhandle) {
|
||||
unsigned char buf;
|
||||
fileio_read((mp_obj_t)fhandle, &buf, 1);
|
||||
//mp_printf(&mp_plat_print, "Reading char\n");
|
||||
//__printf_debug_flush();
|
||||
fileio_read(fhandle, (void *)&buf, 1);
|
||||
return (int)buf;
|
||||
}
|
||||
|
||||
|
@ -413,7 +438,7 @@ mp_obj_t VECTOR_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
|
|||
|
||||
GET_STR_DATA_LEN(text_obj, str, str_len);
|
||||
|
||||
const std::wstring_view t((const wchar_t *)str, str_len);
|
||||
const std::string_view t((const char *)str, str_len);
|
||||
|
||||
int x = args[ARG_x].u_int;
|
||||
int y = args[ARG_y].u_int;
|
||||
|
@ -426,7 +451,12 @@ mp_obj_t VECTOR_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
|
|||
pp_mat3_rotate(&tt, mp_obj_get_float(args[ARG_angle].u_obj));
|
||||
}
|
||||
|
||||
self->vector->text(t, {(float)x, (float)y}, &tt);
|
||||
pp_mat3_translate(&tt, (float)x, (float)y);
|
||||
|
||||
//mp_printf(&mp_plat_print, "self->vector->text()\n");
|
||||
//__printf_debug_flush();
|
||||
|
||||
self->vector->text(t, &tt);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue