#include #include #include #include #include #include #include #include #include #include "nanovg.h" #define NANOVG_GLES3_IMPLEMENTATION #include "nanovg_gl.h" #include "nanovg_gl_utils.h" #include "common/framebuffer.h" #include "common/touch.h" #define COLOR_WHITE nvgRGBA(255, 255, 255, 255) #define MAX_TEXT_SIZE 2048 extern const unsigned char _binary_opensans_regular_ttf_start[]; extern const unsigned char _binary_opensans_regular_ttf_end[]; static void set_brightness(int brightness) { FILE *f = fopen("/sys/class/leds/lcd-backlight/brightness", "wb"); if (f != NULL) { fprintf(f, "%d", brightness); fclose(f); } } int main(int argc, char** argv) { int err; // spinner int fb_w, fb_h; FramebufferState *fb = framebuffer_init("text", 0x00001000, false, &fb_w, &fb_h); assert(fb); NVGcontext *vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); assert(vg); int font = nvgCreateFontMem(vg, "regular", (unsigned char*)_binary_opensans_regular_ttf_start, _binary_opensans_regular_ttf_end-_binary_opensans_regular_ttf_start, 0); assert(font >= 0); // Awake framebuffer_set_power(fb, HWC_POWER_MODE_NORMAL); set_brightness(255); glClearColor(0.1, 0.1, 0.1, 1.0); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); nvgBeginFrame(vg, fb_w, fb_h, 1.0f); // background nvgBeginPath(vg); NVGpaint bg = nvgLinearGradient(vg, fb_w, 0, fb_w, fb_h, nvgRGBA(0, 0, 0, 175), nvgRGBA(0, 0, 0, 255)); nvgFillPaint(vg, bg); nvgRect(vg, 0, 0, fb_w, fb_h); nvgFill(vg); // Text nvgFillColor(vg, COLOR_WHITE); nvgFontSize(vg, 75.0f); if (argc >= 2) { float x = 150; float y = 150; // Copy text char * text = malloc(MAX_TEXT_SIZE); strncpy(text, argv[1], MAX_TEXT_SIZE); float lineh; nvgTextMetrics(vg, NULL, NULL, &lineh); // nvgTextBox strips leading whitespace. We have to reimplement char * next = strtok(text, "\n"); while (next != NULL){ nvgText(vg, x, y, next, NULL); y += lineh; next = strtok(NULL, "\n"); } } // Button int b_x = 1500; int b_y = 800; int b_w = 300; int b_h = 150; nvgBeginPath(vg); nvgFillColor(vg, nvgRGBA(8, 8, 8, 255)); nvgRoundedRect(vg, b_x, b_y, b_w, b_h, 20); nvgFill(vg); nvgFillColor(vg, nvgRGBA(255, 255, 255, 255)); nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); nvgText(vg, b_x+b_w/2, b_y+b_h/2, "Exit", NULL); nvgBeginPath(vg); nvgStrokeColor(vg, nvgRGBA(255, 255, 255, 50)); nvgStrokeWidth(vg, 5); nvgRoundedRect(vg, b_x, b_y, b_w, b_h, 20); nvgStroke(vg); // Draw to screen nvgEndFrame(vg); framebuffer_swap(fb); assert(glGetError() == GL_NO_ERROR); // Wait for button TouchState touch; touch_init(&touch); while (true){ int touch_x = -1, touch_y = -1; int res = touch_poll(&touch, &touch_x, &touch_y, 0); if (res){ if (touch_x > b_x && touch_x < b_x + b_w){ if (touch_y > b_y && touch_y < b_y + b_h){ return 1; } } } usleep(1000000 / 60); } return 0; }