# include <stdio.h>
# include <stdlib.h>
# include <stdbool.h>
# include <math.h>
# include <unistd.h>
# include <assert.h>
# include <memory>
# include <GLES3/gl3.h>
# include <EGL/egl.h>
# include <EGL/eglext.h>
# 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 uint8_t bin_opensans_regular [ ] asm ( " _binary_opensans_regular_ttf_start " ) ;
extern const uint8_t * bin_opensans_regular_end asm ( " _binary_opensans_regular_ttf_end " ) ;
int main ( int argc , char * * argv ) {
int err ;
// spinner
int fb_w , fb_h ;
std : : unique_ptr < FrameBuffer > fb = std : : make_unique < FrameBuffer > ( " 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 * ) bin_opensans_regular , ( bin_opensans_regular_end - bin_opensans_regular ) , 0 ) ;
assert ( font > = 0 ) ;
// Awake
fb - > set_power ( 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 = ( char * ) 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 ) ;
fb - > swap ( ) ;
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 ;
}