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); } }
void nxbe_clipper(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *dest, uint8_t order, FAR struct nxbe_clipops_s *cops, FAR struct nxbe_plane_s *plane) { struct nxbe_clipstack_s stack; FAR struct nxbe_window_s *currw; struct nxgl_rect_s rect; struct nxgl_rect_s obscuredrect; struct nxgl_rect_s currbounds; struct nxgl_rect_s nonoverlapped[4]; int i; /* Initialize the stack where we will keep deferred rectangle operations */ stack.npushed = 0; stack.mxrects = 0; stack.stack = NULL; /* Loop until there are no further pending operations */ nxgl_rectcopy(&rect, dest); /* Start with the whole dest rectangle */ do { /* Loop for every window from the current window and above. Only windows * above the current window can obscure the current window */ for (currw = wnd; currw; currw = currw->above) { /* Does the current window overlap the dest rectangle? */ currbounds = currw->bounds; if (nxgl_rectoverlap(&rect, &currbounds)) { /* Yes.. then it obscures all or part of the dest rectangle. * Divide the potentially visible, non-overlapping regions into 4 * smaller rectangles and push them onto the stack for processing * on the next time through the outer loop. */ nxgl_nonintersecting(nonoverlapped, &rect, &currbounds); for (i = 3; i >= 0; i--) { /* Push the rectangles in the order specific by the input * argument of that name. */ struct nxgl_rect_s *candidate = &nonoverlapped[g_nxcliporder[order][i]]; if (!nxgl_nullrect(candidate)) { nxbe_pushrectangle(&stack, currw->above, candidate); } } /* Now performed any required processing on the obscurred, * overlapped region. */ nxgl_rectintersect(&obscuredrect, &rect, &currbounds); cops->obscured(cops, plane, &obscuredrect); /* Break out of the loop to process the pushed rectangles */ break; } } /* If there are no other windows overlapping this rectangle, then this * rectangular region must be visible. */ if (!currw && !nxgl_nullrect(&rect)) { cops->visible(cops, plane, &rect); } } while (nxbe_poprectangle(&stack, &wnd, &rect)); /* Done! If any stack was allocated, then free it before exit-ting */ if (stack.stack) { free(stack.stack); } }