static void nxbe_clipmoveobscured(FAR struct nxbe_clipops_s *cops, FAR struct nxbe_plane_s *plane, FAR const struct nxgl_rect_s *rect) { struct nxbe_move_s *info = (struct nxbe_move_s *)cops; struct nxgl_rect_s dst; nxgl_rectoffset(&dst, rect, info->offset.x, info->offset.y); nxfe_redrawreq(info->wnd, &dst); }
void nxfe_redrawreq(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *rect) { struct nxclimsg_redraw_s outmsg; outmsg.msgid = NX_CLIMSG_REDRAW; outmsg.wnd = wnd; outmsg.more = false; nxgl_rectoffset(&outmsg.rect, rect, -wnd->bounds.pt1.x, -wnd->bounds.pt1.y); (void)nxmu_sendclientwindow(wnd, &outmsg, sizeof(struct nxclimsg_redraw_s)); }
void nxtk_subwindowclip(FAR struct nxtk_framedwindow_s *fwnd, FAR struct nxgl_rect_s *dest, FAR const struct nxgl_rect_s *src, FAR const struct nxgl_rect_s *bounds) { struct nxgl_rect_s tmp; /* Temporarily, position the src rectangle in absolute screen coordinates */ nxgl_rectoffset(&tmp, src, bounds->pt1.x, bounds->pt1.y); /* Clip the src rectangle to lie within the client window region */ nxgl_rectintersect(&tmp, &tmp, bounds); /* Then move the rectangle so that is relative to the containing window, not the * client subwindow */ nxgl_rectoffset(dest, &tmp, -fwnd->wnd.bounds.pt1.x, -fwnd->wnd.bounds.pt1.y); }
void nxbe_setposition(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_point_s *pos) { struct nxgl_rect_s before; struct nxgl_rect_s rect; #ifdef CONFIG_DEBUG if (!wnd) { return; } #endif /* Back out the old window origin position from the bounding box */ nxgl_rectoffset(&rect, &wnd->bounds, -wnd->bounds.pt1.x, -wnd->bounds.pt1.y); /* Add the new window origin into the bounding box */ nxgl_rectcopy(&before, &wnd->bounds); nxgl_rectoffset(&wnd->bounds, &rect, pos->x, pos->y); /* Get the union of the 'before' bounding box and the 'after' bounding * this union is the region of the display that must be updated. */ nxgl_rectunion(&rect, &before, &wnd->bounds); nxgl_rectintersect(&rect, &rect, &wnd->be->bkgd.bounds); /* Report the new size/position */ nxfe_reportposition(wnd); /* Then redraw this window AND all windows below it. Having moved the * window, we may have exposed previoulsy obscured portions of windows * below this one. */ nxbe_redrawbelow(wnd->be, wnd, &rect); }
void nxbe_fill(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *rect, nxgl_mxpixel_t color[CONFIG_NX_NPLANES]) { struct nxbe_fill_s info; struct nxgl_rect_s remaining; int i; #ifdef CONFIG_DEBUG if (!wnd || !rect) { return; } #endif /* Offset the rectangle by the window origin to convert it into a * bounding box */ nxgl_rectoffset(&remaining, rect, wnd->bounds.pt1.x, wnd->bounds.pt1.y); /* Clip to the bounding box to the limits of the window and of the * background screen */ nxgl_rectintersect(&remaining, &remaining, &wnd->bounds); nxgl_rectintersect(&remaining, &remaining, &wnd->be->bkgd.bounds); /* Then clip the bounding box due to other windows above this one. * Render the portions of the trapezoid exposed in visible regions. */ if (!nxgl_nullrect(&remaining)) { #if CONFIG_NX_NPLANES > 1 for (i = 0; i < wnd->be->vinfo.nplanes; i++) #else i = 0; #endif { info.cops.visible = nxbe_clipfill; info.cops.obscured = nxbe_clipnull; info.color = color[i]; nxbe_clipper(wnd->above, &remaining, NX_CLIPORDER_DEFAULT, &info.cops, &wnd->be->plane[i]); } } }
static void nxbe_clipmovedest(FAR struct nxbe_clipops_s *cops, FAR struct nxbe_plane_s *plane, FAR const struct nxgl_rect_s *rect) { struct nxbe_move_s *dstdata = (struct nxbe_move_s *)cops; struct nxbe_window_s *wnd = dstdata->wnd; struct nxgl_point_s offset = dstdata->offset; struct nxgl_rect_s src; struct nxgl_rect_s tmprect1; struct nxgl_rect_s tmprect2; struct nxgl_rect_s nonintersecting[4]; int i; /* Redraw dest regions where the source is outside of the bounds of the * background window */ nxgl_rectoffset(&tmprect1, &dstdata->srcrect, offset.x, offset.y); nxgl_rectintersect(&tmprect2, &tmprect1, &wnd->be->bkgd.bounds); nxgl_nonintersecting(nonintersecting, rect, &tmprect2); for (i = 0; i < 4; i++) { if (!nxgl_nullrect(&nonintersecting[i])) { nxfe_redrawreq(dstdata->wnd, &nonintersecting[i]); } } /* Clip to determine what is inside the bounds */ nxgl_rectintersect(&src, rect, &dstdata->srcrect); if (!nxgl_nullrect(&src)) { struct nxbe_move_s srcinfo; srcinfo.cops.visible = nxbe_clipmovesrc; srcinfo.cops.obscured = nxbe_clipmoveobscured; srcinfo.offset = offset; srcinfo.wnd = wnd; nxbe_clipper(dstdata->wnd->above, &src, dstdata->order, &srcinfo.cops, plane); } }
int nxtk_filltraptoolbar(NXTKWINDOW hfwnd, FAR const struct nxgl_trapezoid_s *trap, nxgl_mxpixel_t color[CONFIG_NX_NPLANES]) { FAR struct nxtk_framedwindow_s *fwnd = (FAR struct nxtk_framedwindow_s *)hfwnd; struct nxgl_rect_s relclip; #ifdef CONFIG_DEBUG if (!hfwnd || !trap || !color) { errno = EINVAL; return ERROR; } #endif /* Perform the fill, clipping to the client window */ nxgl_rectoffset(&relclip, &fwnd->tbrect, -fwnd->wnd.bounds.pt1.x, -fwnd->wnd.bounds.pt1.y); return nx_filltrapezoid((NXWINDOW)hfwnd, &relclip, trap, color); }
void nxbe_getrectangle(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *rect, unsigned int plane, FAR uint8_t *dest, unsigned int deststride) { struct nxgl_rect_s remaining; #ifdef CONFIG_DEBUG_FEATURES if (!wnd || !rect || !dest || plane >= wnd->be->vinfo.nplanes) { ginfo("Invalid parameters\n"); return; } #endif /* Offset the rectangle by the window origin to convert it into a * bounding box */ nxgl_rectoffset(&remaining, rect, wnd->bounds.pt1.x, wnd->bounds.pt1.y); /* Clip to the bounding box to the limits of the window and of the * background screen */ nxgl_rectintersect(&remaining, &remaining, &wnd->bounds); nxgl_rectintersect(&remaining, &remaining, &wnd->be->bkgd.bounds); /* The return the graphics memory at this location. NOTE: Since raw * graphic memory is returned, the returned memory content may be * the memory of windows above this one and may not necessarily belong * to this window. */ if (!nxgl_nullrect(&remaining)) { FAR struct nxbe_plane_s *pplane = &wnd->be->plane[plane]; pplane->getrectangle(&pplane->pinfo, &remaining, dest, deststride); } }
void nxbe_filltrapezoid(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *clip, FAR const struct nxgl_trapezoid_s *trap, nxgl_mxpixel_t color[CONFIG_NX_NPLANES]) { struct nxbe_filltrap_s info; struct nxgl_rect_s remaining; int i; #ifdef CONFIG_DEBUG if (!wnd || !trap) { return; } #endif /* Offset the trapezoid by the window origin to position it within * the framebuffer region */ nxgl_trapoffset(&info.trap, trap, wnd->bounds.pt1.x, wnd->bounds.pt1.y); /* Create a bounding box that contains the trapezoid */ remaining.pt1.x = b16toi(ngl_min(info.trap.top.x1, info.trap.bot.x1)); remaining.pt1.y = info.trap.top.y; remaining.pt2.x = b16toi(ngl_max(info.trap.top.x2, info.trap.bot.x2)); remaining.pt2.y = info.trap.bot.y; /* Clip to any user specified clipping window */ if (clip) { struct nxgl_rect_s tmp; nxgl_rectoffset(&tmp, clip, wnd->bounds.pt1.x, wnd->bounds.pt1.y); nxgl_rectintersect(&remaining, &remaining, &tmp); } /* Clip to the limits of the window and of the background screen */ nxgl_rectintersect(&remaining, &remaining, &wnd->bounds); nxgl_rectintersect(&remaining, &remaining, &wnd->be->bkgd.bounds); if (!nxgl_nullrect(&remaining)) { info.cops.visible = nxbe_clipfilltrapezoid; info.cops.obscured = nxbe_clipnull; /* Then process each color plane */ #if CONFIG_NX_NPLANES > 1 for (i = 0; i < wnd->be->vinfo.nplanes; i++) #else i = 0; #endif { info.color = color[i]; nxbe_clipper(wnd->above, &remaining, NX_CLIPORDER_DEFAULT, &info.cops, &wnd->be->plane[i]); } } }
void nxbe_move(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *rect, FAR const struct nxgl_point_s *offset) { struct nxbe_move_s info; int i; #ifdef CONFIG_DEBUG_FEATURES if (!wnd || !rect) { return; } #endif /* Offset the rectangle by the window origin to create a bounding box */ nxgl_rectoffset(&info.srcrect, rect, wnd->bounds.pt1.x, wnd->bounds.pt1.y); /* Clip to the limits of the window and of the background screen */ nxgl_rectintersect(&info.srcrect, &info.srcrect, &wnd->bounds); nxgl_rectintersect(&info.srcrect, &info.srcrect, &wnd->be->bkgd.bounds); if (nxgl_nullrect(&info.srcrect)) { return; } info.cops.visible = nxbe_clipmovedest; info.cops.obscured = nxbe_clipnull; info.offset.x = offset->x; info.offset.y = offset->y; info.wnd = wnd; /* The clip order depends up the direction that the rectangle is being * moved. */ if (offset->y < 0) { /* Moving rectangle up */ if (offset->x < 0) { /* Moving to upper-left */ info.order = NX_CLIPORDER_TLRB; /* Top-left-right-bottom */ } else { /* Moving to upper-right (or just up) */ info.order = NX_CLIPORDER_TRLB; /* Top-right-left-bottom */ } } else { /* Moving rectangle down (or just left/right) */ if (offset->x < 0) { /* Moving to lower-left */ info.order = NX_CLIPORDER_BLRT; /* Bottom-left-right-top */ } else { /* Moving to lower-right */ info.order = NX_CLIPORDER_BRLT; /* Bottom-right-left-top */ } } /* Then perform the move */ #if CONFIG_NX_NPLANES > 1 for (i = 0; i < wnd->be->vinfo.nplanes; i++) #else i = 0; #endif { nxbe_clipper(wnd->above, &info.srcrect, info.order, &info.cops, &wnd->be->plane[i]); } }