void osd_alert(struct osd_t* osd, char* text) { uint32_t text_length; uint32_t width,height; uint32_t y_offset; uint32_t x_offset; uint32_t text_size = 40; pthread_mutex_lock(&osd->osd_mutex); /* TODO: Only clear alert area */ graphics_resource_fill(osd->img, 0, 0, osd->display_width, osd->display_height, GRAPHICS_RGBA32(0,0,0,0)); if (text) { fprintf(stderr,"[OSD ALERT]: %s\n",text); text_length = strlen(text); graphics_resource_text_dimensions_ext(osd->img, text, text_length, &width, &height, text_size); x_offset = ((1920 - width) / 2); y_offset = (1080 - height) / 2; osd_draw_window(osd,x_offset,y_offset,width+100,height+50); graphics_resource_render_text_ext(osd->img, x_offset+50, y_offset+25, width, height, GRAPHICS_RGBA32(0xff,0xff,0xff,0xff), /* fg */ GRAPHICS_RGBA32(0,0,0,0x80), /* bg */ text, text_length, text_size); } graphics_update_displayed_resource(osd->img, 0, 0, 0, 0); pthread_mutex_unlock(&osd->osd_mutex); }
void osd_init(struct osd_t* osd) { uint32_t display_width, display_height; char str[2] = { 0, 0 }; uint32_t width, height; int n; int s; s = gx_graphics_init(tiresias_pcfont, sizeof(tiresias_pcfont)); assert(s == 0); s = graphics_get_display_size(0, &display_width, &display_height); osd->display_width = display_width; osd->display_height = display_height; printf("osd_init: %d %d\n", display_width, display_height); assert(s == 0); //fprintf(stderr,"Display width=%d, height=%d\n",display_width,display_height); /* The main OSD image */ s = gx_create_window(SCREEN, display_width, display_height, GRAPHICS_RESOURCE_RGBA32, &osd->img); assert(s == 0); graphics_resource_fill(osd->img, 0, 0, display_width, display_height, GRAPHICS_RGBA32(0,0,0,0)); graphics_display_resource(osd->img, 0, OSD_LAYER, 0, 0, GRAPHICS_RESOURCE_WIDTH, GRAPHICS_RESOURCE_HEIGHT, VC_DISPMAN_ROT0, 1); /* A full-screen black image to either remove any left-over console text (BG_LAYER) or to hide the video (FG_LAYER) */ s = gx_create_window(SCREEN, display_width, display_height, GRAPHICS_RESOURCE_RGBA32, &osd->img_blank); assert(s == 0); graphics_resource_fill(osd->img_blank, 0, 0, display_width, display_height, GRAPHICS_RGBA32(0,0,0,255)); graphics_display_resource(osd->img_blank, 0, BG_LAYER, 0, 0, GRAPHICS_RESOURCE_WIDTH, GRAPHICS_RESOURCE_HEIGHT, VC_DISPMAN_ROT0, 1); osd->video_blanked = 0; osd->osd_cleartime = 0.0; osd->last_now = time(NULL); pthread_mutex_init(&osd->osd_mutex,NULL); // cache font widths since graphics_resource_text_dimensions_ext is kind of slow for (n = 32; n < 256; n++) { str[0] = n; graphics_resource_text_dimensions_ext(osd->img, str, 1, &width, &height, 40); fontWidth[n] = (uint8_t)width; } (void)s; // remove compiler warning }
int32_t render_subtitle(GRAPHICS_RESOURCE_HANDLE img, const char *text, const int skip, const uint32_t text_size, const uint32_t y_offset) { uint32_t text_length = strlen(text)-skip; uint32_t width=0, height=0; const char *split = text; int32_t s=0; int len = 0; // length of pre-subtitle uint32_t img_w, img_h; graphics_get_resource_size(img, &img_w, &img_h); if (text_length==0) return 0; while (split[0]) { s = graphics_resource_text_dimensions_ext(img, split, text_length-(split-text), &width, &height, text_size); if (s != 0) return s; if (width > img_w) { const char *space = strnchr(split, text_length-(split-text), ' '); if (!space) { len = split+1-text; split = split+1; } else { len = space-text; split = space+1; } } else { break; } } // split now points to last line of text. split-text = length of initial text. text_length-(split-text) is length of last line if (width) { s = graphics_resource_render_text_ext(img, (img_w - width)>>1, y_offset-height, GRAPHICS_RESOURCE_WIDTH, GRAPHICS_RESOURCE_HEIGHT, GRAPHICS_RGBA32(0xff,0xff,0xff,0xff), /* fg */ GRAPHICS_RGBA32(0,0,0,0x80), /* bg */ split, text_length-(split-text), text_size); if (s!=0) return s; } return render_subtitle(img, text, skip+text_length-len, text_size, y_offset - height); }
int32_t render_paragraph(GRAPHICS_RESOURCE_HANDLE img, const char *text, const uint32_t text_size, const uint32_t x_offset, const uint32_t y_offset) { uint32_t text_length; uint32_t line_length; uint32_t width=0, height=0; const char *split = text; int32_t s=0; uint32_t img_w = 1400;; if ((!text) || ((text_length=strlen(text))==0)) return 0; //fprintf(stderr,"render_paragraph(\"%s\",%d)\n",text,text_length); s = graphics_resource_text_dimensions_ext(img, text, text_length, &width, &height, text_size); if (s != 0) return s; if (width <= img_w) { /* We can display the whole line */ line_length = text_length; } else { //fprintf(stderr,"width=%d, img_w=%d, looking for next space\n",width,img_w); const char* space = index(split,' '); if (space) { s = graphics_resource_text_dimensions_ext(img, text, space-text, &width, &height, text_size); if (s != 0) return s; } if ((space == NULL) || (width > img_w)) { /* No spaces, within img_w. Just go through character by character */ line_length = 0; do { line_length++; s = graphics_resource_text_dimensions_ext(img, text, text_length, &width, &height, text_size); if (s != 0) return s; } while (width < img_w); line_length--; } else { /* We have at least one space, so can split line on a space */ width = 0; line_length = space - text; while (width < img_w) { space = index(space+1,' '); s = graphics_resource_text_dimensions_ext(img, text, space - text, &width, &height, text_size); if (s != 0) return s; if (width < img_w) { line_length = space - text; } } } } if (line_length) { //int i; //fprintf(stderr,"Rendering: "); //for (i=0;i<line_length;i++) { fprintf(stderr,"%c",text[i]); } //fprintf(stderr,"\n"); s = graphics_resource_render_text_ext(img, x_offset, y_offset, GRAPHICS_RESOURCE_WIDTH, GRAPHICS_RESOURCE_HEIGHT, GRAPHICS_RGBA32(0xff,0xff,0xff,0xff), /* fg */ GRAPHICS_RGBA32(0,0,0,0x80), /* bg */ text, line_length, text_size); if (s!=0) return s; } if (text[line_length]) { return render_paragraph(img, text + line_length+1, text_size, x_offset, y_offset + height); } else { return 0; } }