static void fb_text_input_remove_caret_cb(fbtk_widget_t *widget) { int c_x, c_y, c_h; if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) { fbtk_request_redraw(widget); } }
static void gui_window_remove_caret(struct gui_window *g) { int c_x, c_y, c_h; if (fbtk_get_caret(g->browser, &c_x, &c_y, &c_h)) { /* browser window owns the caret, so can remove it */ fbtk_set_caret(g->browser, false, 0, 0, 0, NULL); } }
static void gui_window_remove_caret_cb(fbtk_widget_t *widget) { struct browser_widget_s *bwidget = fbtk_get_userpw(widget); int c_x, c_y, c_h; if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) { /* browser window already had caret: * redraw its area to remove it first */ fb_queue_redraw(widget, c_x - bwidget->scrollx, c_y - bwidget->scrolly, c_x + 1 - bwidget->scrollx, c_y + c_h - bwidget->scrolly); } }
/* exported function documented in fbtk.h */ void fbtk_set_text(fbtk_widget_t *widget, const char *text) { plot_font_style_t font_style; int c_x, c_y, c_h; int fh; int border; if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_TEXT)) return; if (widget->u.text.text != NULL) { if (strcmp(widget->u.text.text, text) == 0) return; /* text is being set to the same thing */ free(widget->u.text.text); } widget->u.text.text = strdup(text); widget->u.text.len = strlen(text); widget->u.text.idx = widget->u.text.len; fb_text_font_style(widget, &fh, &border, &font_style); nsfont.font_width(&font_style, widget->u.text.text, widget->u.text.len, &widget->u.text.width); nsfont.font_width(&font_style, widget->u.text.text, widget->u.text.idx, &widget->u.text.idx_offset); if (fbtk_get_caret(widget, &c_x, &c_y, &c_h)) { /* Widget has caret; move it to end of new string */ fbtk_set_caret(widget, true, widget->u.text.idx_offset + border, border, widget->height - border - border, fb_text_input_remove_caret_cb); } fbtk_request_redraw(widget); }
static void fb_redraw(fbtk_widget_t *widget, struct browser_widget_s *bwidget, struct browser_window *bw) { int x; int y; int caret_x, caret_y, caret_h; struct rect clip; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &fb_plotters }; nsfb_t *nsfb = fbtk_get_nsfb(widget); float scale = browser_window_get_scale(bw); LOG(("%d,%d to %d,%d", bwidget->redraw_box.x0, bwidget->redraw_box.y0, bwidget->redraw_box.x1, bwidget->redraw_box.y1)); x = fbtk_get_absx(widget); y = fbtk_get_absy(widget); /* adjust clipping co-ordinates according to window location */ bwidget->redraw_box.y0 += y; bwidget->redraw_box.y1 += y; bwidget->redraw_box.x0 += x; bwidget->redraw_box.x1 += x; nsfb_claim(nsfb, &bwidget->redraw_box); /* redraw bounding box is relative to window */ clip.x0 = bwidget->redraw_box.x0; clip.y0 = bwidget->redraw_box.y0; clip.x1 = bwidget->redraw_box.x1; clip.y1 = bwidget->redraw_box.y1; browser_window_redraw(bw, (x - bwidget->scrollx) / scale, (y - bwidget->scrolly) / scale, &clip, &ctx); if (fbtk_get_caret(widget, &caret_x, &caret_y, &caret_h)) { /* This widget has caret, so render it */ nsfb_bbox_t line; nsfb_plot_pen_t pen; line.x0 = x - bwidget->scrollx + caret_x; line.y0 = y - bwidget->scrolly + caret_y; line.x1 = x - bwidget->scrollx + caret_x; line.y1 = y - bwidget->scrolly + caret_y + caret_h; pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; pen.stroke_width = 1; pen.stroke_colour = 0xFF0000FF; nsfb_plot_line(nsfb, &line, &pen); } nsfb_update(fbtk_get_nsfb(widget), &bwidget->redraw_box); bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX; bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = INT_MIN; bwidget->redraw_required = false; } static int fb_browser_window_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_window *gw = cbi->context; struct browser_widget_s *bwidget; bwidget = fbtk_get_userpw(widget); if (bwidget == NULL) { LOG(("browser widget from widget %p was null", widget)); return -1; } if (bwidget->pan_required) { fb_pan(widget, bwidget, gw->bw); } if (bwidget->redraw_required) { fb_redraw(widget, bwidget, gw->bw); } else { bwidget->redraw_box.x0 = 0; bwidget->redraw_box.y0 = 0; bwidget->redraw_box.x1 = fbtk_get_width(widget); bwidget->redraw_box.y1 = fbtk_get_height(widget); fb_redraw(widget, bwidget, gw->bw); } return 0; } static int fb_browser_window_destroy(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct browser_widget_s *browser_widget; if (widget == NULL) { return 0; } /* Free private data */ browser_widget = fbtk_get_userpw(widget); free(browser_widget); return 0; } static const char *fename; static int febpp; static int fewidth; static int feheight; static const char *feurl; static bool process_cmdline(int argc, char** argv) { int opt; LOG(("argc %d, argv %p", argc, argv)); fename = "mtl"; febpp = 32; fewidth = nsoption_int(window_width); if (fewidth <= 0) { fewidth = 800; } feheight = nsoption_int(window_height); if (feheight <= 0) { feheight = 480; } if ((nsoption_charp(homepage_url) != NULL) && (nsoption_charp(homepage_url)[0] != '\0')) { feurl = nsoption_charp(homepage_url); } else { feurl = NETSURF_HOMEPAGE; } while((opt = getopt(argc, argv, "f:b:w:h:")) != -1) { switch (opt) { case 'f': fename = optarg; break; case 'b': febpp = atoi(optarg); break; case 'w': fewidth = atoi(optarg); break; case 'h': feheight = atoi(optarg); break; default: fprintf(stderr, "Usage: %s [-f frontend] [-b bpp] url\n", argv[0]); return false; } } if (optind < argc) { feurl = argv[optind]; } return true; }
/** Text redraw callback. * * Called when a text widget requires redrawing. * * @param widget The widget to be redrawn. * @param cbi The callback parameters. * @return The callback result. */ static int fb_redraw_text(fbtk_widget_t *widget, fbtk_callback_info *cbi ) { nsfb_bbox_t bbox; nsfb_bbox_t rect; fbtk_widget_t *root; plot_font_style_t font_style; int caret_x, caret_y, caret_h; int fh; int padding; int scroll = 0; bool caret = false; fb_text_font_style(widget, &fh, &padding, &font_style); if (fbtk_get_caret(widget, &caret_x, &caret_y, &caret_h)) { caret = true; } root = fbtk_get_root_widget(widget); fbtk_get_bbox(widget, &bbox); rect = bbox; nsfb_claim(root->u.root.fb, &bbox); /* clear background */ if ((widget->bg & 0xFF000000) != 0) { /* transparent polygon filling isnt working so fake it */ nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg); } /* widget can have a single pixel outline border */ if (widget->u.text.outline) { rect.x1--; rect.y1--; nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0x00000000, false, false); } if (widget->u.text.text != NULL) { int x = bbox.x0 + padding; int y = bbox.y0 + ((fh * 3 + 2) / 4) + padding; #ifdef FB_USE_FREETYPE /* Freetype renders text higher */ y += 1; #endif if (caret && widget->width - padding - padding < caret_x) { scroll = (widget->width - padding - padding) - caret_x; x += scroll; } /* Call the fb text plotting, baseline is 3/4 down the font */ fb_plotters.text(x, y, widget->u.text.text, widget->u.text.len, &font_style); } if (caret) { /* This widget has caret, so render it */ nsfb_t *nsfb = fbtk_get_nsfb(widget); nsfb_bbox_t line; nsfb_plot_pen_t pen; line.x0 = bbox.x0 + caret_x + scroll; line.y0 = bbox.y0 + caret_y; line.x1 = bbox.x0 + caret_x + scroll; line.y1 = bbox.y0 + caret_y + caret_h; pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; pen.stroke_width = 1; pen.stroke_colour = 0xFF0000FF; nsfb_plot_line(nsfb, &line, &pen); } nsfb_update(root->u.root.fb, &bbox); return 0; }