/** Save the current OpenGL state and initialize OpenGL for 2D * rendering. glaEnd2DDraw should be called on the returned structure * to free it and to return OpenGL to its previous state. The * scissor rectangle is set to match the viewport. * * See glaDefine2DArea for an explanation of why this function uses integers. * * \param screen_rect The screen rectangle to be used for 2D drawing. * \param world_rect The world rectangle that the 2D area represented * by \a screen_rect is supposed to represent. If NULL it is assumed the * world has a 1 to 1 mapping to the screen. */ gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect) { gla2DDrawInfo *di = MEM_mallocN(sizeof(*di), "gla2DDrawInfo"); int sc_w, sc_h; float wo_w, wo_h; glGetIntegerv(GL_VIEWPORT, (GLint *)di->orig_vp); glGetIntegerv(GL_SCISSOR_BOX, (GLint *)di->orig_sc); glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *)di->orig_projmat); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)di->orig_viewmat); di->screen_rect = *screen_rect; if (world_rect) { di->world_rect = *world_rect; } else { di->world_rect.xmin = di->screen_rect.xmin; di->world_rect.ymin = di->screen_rect.ymin; di->world_rect.xmax = di->screen_rect.xmax; di->world_rect.ymax = di->screen_rect.ymax; } sc_w = BLI_rcti_size_x(&di->screen_rect); sc_h = BLI_rcti_size_y(&di->screen_rect); wo_w = BLI_rcti_size_x(&di->world_rect); wo_h = BLI_rcti_size_y(&di->world_rect); di->wo_to_sc[0] = sc_w / wo_w; di->wo_to_sc[1] = sc_h / wo_h; glaDefine2DArea(&di->screen_rect); return di; }
void UI_fontstyle_draw_ex( const uiFontStyle *fs, const rcti *rect, const char *str, size_t len, float *r_xofs, float *r_yofs) { int xofs = 0, yofs; int font_flag = BLF_CLIPPING; UI_fontstyle_set(fs); /* set the flag */ if (fs->shadow) { font_flag |= BLF_SHADOW; const float shadow_color[4] = {fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha}; BLF_shadow(fs->uifont_id, fs->shadow, shadow_color); BLF_shadow_offset(fs->uifont_id, fs->shadx, fs->shady); } if (fs->kerning == 1) { font_flag |= BLF_KERNING_DEFAULT; } if (fs->word_wrap == 1) { font_flag |= BLF_WORD_WRAP; } BLF_enable(fs->uifont_id, font_flag); if (fs->word_wrap == 1) { /* draw from boundbox top */ yofs = BLI_rcti_size_y(rect) - BLF_height_max(fs->uifont_id); } else { /* draw from boundbox center */ yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - BLF_ascender(fs->uifont_id))); } if (fs->align == UI_STYLE_TEXT_CENTER) { xofs = floor(0.5f * (BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len))); /* don't center text if it chops off the start of the text, 2 gives some margin */ if (xofs < 2) { xofs = 2; } } else if (fs->align == UI_STYLE_TEXT_RIGHT) { xofs = BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len) - 0.1f * U.widget_unit; } /* clip is very strict, so we give it some space */ BLF_clipping(fs->uifont_id, rect->xmin - 2, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4); BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f); BLF_draw(fs->uifont_id, str, len); BLF_disable(fs->uifont_id, font_flag); *r_xofs = xofs; *r_yofs = yofs; }
/* drawn same as above, but at 90 degree angle */ void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const char *str) { float height; int xofs, yofs; float angle; rcti txtrect; UI_fontstyle_set(fs); height = BLF_ascender(fs->uifont_id); /* becomes x-offset when rotated */ xofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height)); /* ignore UI_STYLE, always aligned to top */ /* rotate counter-clockwise for now (assumes left-to-right language)*/ xofs += height; yofs = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX) + 5; angle = M_PI_2; /* translate rect to vertical */ txtrect.xmin = rect->xmin - BLI_rcti_size_y(rect); txtrect.ymin = rect->ymin - BLI_rcti_size_x(rect); txtrect.xmax = rect->xmin; txtrect.ymax = rect->ymin; /* clip is very strict, so we give it some space */ /* clipping is done without rotation, so make rect big enough to contain both positions */ BLF_clipping(fs->uifont_id, txtrect.xmin - 1, txtrect.ymin - yofs - xofs - 4, rect->xmax + 1, rect->ymax + 4); BLF_enable(fs->uifont_id, BLF_CLIPPING); BLF_position(fs->uifont_id, txtrect.xmin + xofs, txtrect.ymax - yofs, 0.0f); BLF_enable(fs->uifont_id, BLF_ROTATION); BLF_rotation(fs->uifont_id, angle); if (fs->shadow) { BLF_enable(fs->uifont_id, BLF_SHADOW); const float shadow_color[4] = {fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha}; BLF_shadow(fs->uifont_id, fs->shadow, shadow_color); BLF_shadow_offset(fs->uifont_id, fs->shadx, fs->shady); } if (fs->kerning == 1) BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT); BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); BLF_disable(fs->uifont_id, BLF_ROTATION); BLF_disable(fs->uifont_id, BLF_CLIPPING); if (fs->shadow) BLF_disable(fs->uifont_id, BLF_SHADOW); if (fs->kerning == 1) BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT); }
void gla2DSetMap(gla2DDrawInfo *di, rctf *rect) { int sc_w, sc_h; float wo_w, wo_h; di->world_rect = *rect; sc_w = BLI_rcti_size_x(&di->screen_rect); sc_h = BLI_rcti_size_y(&di->screen_rect); wo_w = BLI_rcti_size_x(&di->world_rect); wo_h = BLI_rcti_size_y(&di->world_rect); di->wo_to_sc[0] = sc_w / wo_w; di->wo_to_sc[1] = sc_h / wo_h; }
/* Draw Scene-Markers in time window */ void ED_markers_draw(const bContext *C, int flag) { ListBase *markers = ED_context_get_markers(C); View2D *v2d; TimeMarker *marker; Scene *scene; int select_pass; int v2d_clip_range_x[2]; float font_width_max; /* cache values */ float ypixels, xscale, yscale; if (markers == NULL || BLI_listbase_is_empty(markers)) { return; } scene = CTX_data_scene(C); v2d = UI_view2d_fromcontext(C); if (flag & DRAW_MARKERS_MARGIN) { const unsigned char shade[4] = {0, 0, 0, 16}; glColor4ubv(shade); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glRectf(v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y); glDisable(GL_BLEND); } /* no time correction for framelen! space is drawn with old values */ ypixels = BLI_rcti_size_y(&v2d->mask); UI_view2d_scale_get(v2d, &xscale, &yscale); glScalef(1.0f / xscale, 1.0f, 1.0f); /* x-bounds with offset for text (adjust for long string, avoid checking string width) */ font_width_max = (10 * UI_DPI_FAC) / xscale; v2d_clip_range_x[0] = v2d->cur.xmin - (sizeof(marker->name) * font_width_max); v2d_clip_range_x[1] = v2d->cur.xmax + font_width_max; /* loop [unselected, selected] */ for (select_pass = 0; select_pass <= SELECT; select_pass += SELECT) { /* unselected markers are drawn at the first time */ for (marker = markers->first; marker; marker = marker->next) { if ((marker->flag & SELECT) == select_pass) { /* bounds check */ if ((marker->frame >= v2d_clip_range_x[0]) && (marker->frame <= v2d_clip_range_x[1])) { draw_marker(v2d, marker, scene->r.cfra, flag, ypixels, xscale, yscale); } } } } glScalef(xscale, 1.0f, 1.0f); }
static void sclip_zoom_set(const bContext *C, float zoom, float location[2]) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); float oldzoom = sc->zoom; int width, height; sc->zoom = zoom; if (sc->zoom < 0.1f || sc->zoom > 4.0f) { /* check zoom limits */ ED_space_clip_get_size(sc, &width, &height); width *= sc->zoom; height *= sc->zoom; if ((width < 4) && (height < 4)) sc->zoom = oldzoom; else if (BLI_rcti_size_x(&ar->winrct) <= sc->zoom) sc->zoom = oldzoom; else if (BLI_rcti_size_y(&ar->winrct) <= sc->zoom) sc->zoom = oldzoom; } if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) { ED_space_clip_get_size(sc, &width, &height); sc->xof += ((location[0] - 0.5f) * width - sc->xof) * (sc->zoom - oldzoom) / sc->zoom; sc->yof += ((location[1] - 0.5f) * height - sc->yof) * (sc->zoom - oldzoom) / sc->zoom; } }
/* tweak and line gestures */ int wm_gesture_evaluate(wmGesture *gesture) { if (gesture->type == WM_GESTURE_TWEAK) { rcti *rect = gesture->customdata; int dx = BLI_rcti_size_x(rect); int dy = BLI_rcti_size_y(rect); if (ABS(dx) + ABS(dy) > U.tweak_threshold) { int theta = (int)floor(4.0f * atan2f((float)dy, (float)dx) / (float)M_PI + 0.5f); int val = EVT_GESTURE_W; if (theta == 0) val = EVT_GESTURE_E; else if (theta == 1) val = EVT_GESTURE_NE; else if (theta == 2) val = EVT_GESTURE_N; else if (theta == 3) val = EVT_GESTURE_NW; else if (theta == -1) val = EVT_GESTURE_SE; else if (theta == -2) val = EVT_GESTURE_S; else if (theta == -3) val = EVT_GESTURE_SW; #if 0 /* debug */ if (val == 1) printf("tweak north\n"); if (val == 2) printf("tweak north-east\n"); if (val == 3) printf("tweak east\n"); if (val == 4) printf("tweak south-east\n"); if (val == 5) printf("tweak south\n"); if (val == 6) printf("tweak south-west\n"); if (val == 7) printf("tweak west\n"); if (val == 8) printf("tweak north-west\n"); #endif return val; } } return 0; }
/* uses UI_BTYPE_ROUNDBOX button in block to get the rect */ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect) { Render *re; RenderResult rres; char name[32]; int offx = 0; int newx = BLI_rcti_size_x(rect); int newy = BLI_rcti_size_y(rect); bool ok = false; if (!split || first) sprintf(name, "Preview %p", (void *)sa); else sprintf(name, "SecondPreview %p", (void *)sa); if (split) { if (first) { offx = 0; newx = newx / 2; } else { offx = newx / 2; newx = newx - newx / 2; } } /* test if something rendered ok */ re = RE_GetRender(name); /* material preview only needs monoscopy (view 0) */ RE_AcquireResultImage(re, &rres, 0); if (rres.rectf) { if (ABS(rres.rectx - newx) < 2 && ABS(rres.recty - newy) < 2) { newrect->xmax = max_ii(newrect->xmax, rect->xmin + rres.rectx + offx); newrect->ymax = max_ii(newrect->ymax, rect->ymin + rres.recty); if (rres.rectx && rres.recty) { unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect"); float fx = rect->xmin + offx; float fy = rect->ymin; /* material preview only needs monoscopy (view 0) */ if (re) RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte, 0); glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte); MEM_freeN(rect_byte); ok = 1; } } } RE_ReleaseResultImage(re); return ok; }
/* tweak and line gestures */ int wm_gesture_evaluate(wmGesture *gesture, const wmEvent *event) { if (gesture->type == WM_GESTURE_TWEAK) { rcti *rect = gesture->customdata; const int delta[2] = { BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), }; if (WM_event_drag_test_with_delta(event, delta)) { int theta = round_fl_to_int(4.0f * atan2f((float)delta[1], (float)delta[0]) / (float)M_PI); int val = EVT_GESTURE_W; if (theta == 0) { val = EVT_GESTURE_E; } else if (theta == 1) { val = EVT_GESTURE_NE; } else if (theta == 2) { val = EVT_GESTURE_N; } else if (theta == 3) { val = EVT_GESTURE_NW; } else if (theta == -1) { val = EVT_GESTURE_SE; } else if (theta == -2) { val = EVT_GESTURE_S; } else if (theta == -3) { val = EVT_GESTURE_SW; } #if 0 /* debug */ if (val == 1) printf("tweak north\n"); if (val == 2) printf("tweak north-east\n"); if (val == 3) printf("tweak east\n"); if (val == 4) printf("tweak south-east\n"); if (val == 5) printf("tweak south\n"); if (val == 6) printf("tweak south-west\n"); if (val == 7) printf("tweak west\n"); if (val == 8) printf("tweak north-west\n"); #endif return val; } } return 0; }
/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; int depth_test_enabled; if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } GPU_matrix_push(); if (t->spacetype == SPACE_VIEW3D) { /* pass */ } else if (t->spacetype == SPACE_IMAGE) { GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]); } else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) { /* only scale y */ rcti *mask = &t->ar->v2d.mask; rctf *datamask = &t->ar->v2d.cur; float xsize = BLI_rctf_size_x(datamask); float ysize = BLI_rctf_size_y(datamask); float xmask = BLI_rcti_size_x(mask); float ymask = BLI_rcti_size_y(mask); GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask)); } depth_test_enabled = GPU_depth_test_enabled(); if (depth_test_enabled) { GPU_depth_test(false); } uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor(TH_GRID); set_inverted_drawing(1); imm_drawcircball(t->center_global, t->prop_size, imat, pos); set_inverted_drawing(0); immUnbindProgram(); if (depth_test_enabled) { GPU_depth_test(true); } GPU_matrix_pop(); } }
void ED_space_clip_get_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy) { int width, height; ED_space_clip_get_size(sc, &width, &height); *zoomx = (float)(BLI_rcti_size_x(&ar->winrct) + 1) / (BLI_rctf_size_x(&ar->v2d.cur) * width); *zoomy = (float)(BLI_rcti_size_y(&ar->winrct) + 1) / (BLI_rctf_size_y(&ar->v2d.cur) * height); }
static int graphkeys_borderselect_exec(bContext *C, wmOperator *op) { bAnimContext ac; rcti rect; rctf rect_fl; short mode = 0, selectmode = 0; bool incl_handles; bool extend; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; /* clear all selection if not extending selection */ extend = RNA_boolean_get(op->ptr, "extend"); if (!extend) deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true); /* get select mode * - 'gesture_mode' from the operator specifies how to select * - 'include_handles' from the operator specifies whether to include handles in the selection */ if (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT) selectmode = SELECT_ADD; else selectmode = SELECT_SUBTRACT; incl_handles = RNA_boolean_get(op->ptr, "include_handles"); /* get settings from operator */ WM_operator_properties_border_to_rcti(op, &rect); /* selection 'mode' depends on whether borderselect region only matters on one axis */ if (RNA_boolean_get(op->ptr, "axis_range")) { /* mode depends on which axis of the range is larger to determine which axis to use * - checking this in region-space is fine, as it's fundamentally still going to be a different rect size * - the frame-range select option is favored over the channel one (x over y), as frame-range one is often * used for tweaking timing when "blocking", while channels is not that useful... */ if ((BLI_rcti_size_x(&rect)) >= (BLI_rcti_size_y(&rect))) mode = BEZT_OK_FRAMERANGE; else mode = BEZT_OK_VALUERANGE; } else mode = BEZT_OK_REGION; BLI_rctf_rcti_copy(&rect_fl, &rect); /* apply borderselect action */ borderselect_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL); /* send notifier that keyframe selection has changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); return OPERATOR_FINISHED; }
void ED_space_image_get_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy) { int width, height; ED_space_image_get_size(sima, &width, &height); *zoomx = (float)(BLI_rcti_size_x(&ar->winrct) + 1) / (float)(BLI_rctf_size_x(&ar->v2d.cur) * width); *zoomy = (float)(BLI_rcti_size_y(&ar->winrct) + 1) / (float)(BLI_rctf_size_y(&ar->v2d.cur) * height); }
void wmViewport(const rcti *winrct) { int width = BLI_rcti_size_x(winrct) + 1; int height = BLI_rcti_size_y(winrct) + 1; glViewport(winrct->xmin, winrct->ymin, width, height); glScissor(winrct->xmin, winrct->ymin, width, height); wmOrtho2_pixelspace(width, height); GPU_matrix_identity_set(); }
void BLI_rcti_scale(rcti *rect, const float scale) { const int cent_x = BLI_rcti_cent_x(rect); const int cent_y = BLI_rcti_cent_y(rect); const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f); const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f); rect->xmin = cent_x - size_x_half; rect->ymin = cent_y - size_y_half; rect->xmax = cent_x + size_x_half; rect->ymax = cent_y + size_y_half; }
static int actkeys_viewall(bContext *C, const bool only_sel) { bAnimContext ac; View2D *v2d; float extra, min, max; bool found; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; v2d = &ac.ar->v2d; /* set the horizontal range, with an extra offset so that the extreme keys will be in view */ found = get_keyframe_extents(&ac, &min, &max, only_sel); if (only_sel && (found == false)) return OPERATOR_CANCELLED; v2d->cur.xmin = min; v2d->cur.xmax = max; extra = 0.1f * BLI_rctf_size_x(&v2d->cur); v2d->cur.xmin -= extra; v2d->cur.xmax += extra; /* set vertical range */ if (only_sel == false) { /* view all -> the summary channel is usually the shows everything, and resides right at the top... */ v2d->cur.ymax = 0.0f; v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask); } else { /* locate first selected channel (or the active one), and frame those */ float ymin = v2d->cur.ymin; float ymax = v2d->cur.ymax; if (actkeys_channels_get_selected_extents(&ac, &ymin, &ymax)) { /* recenter the view so that this range is in the middle */ float ymid = (ymax - ymin) / 2.0f + ymin; float x_center; UI_view2d_center_get(v2d, &x_center, NULL); UI_view2d_center_set(v2d, x_center, ymid); } } /* do View2D syncing */ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); /* just redraw this view */ ED_area_tag_redraw(CTX_wm_area(C)); return OPERATOR_FINISHED; }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ static int mat_livedb_scroll_page_down_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); int dy = -BLI_rcti_size_y(&ar->v2d.mask); ar->v2d.cur.ymin += dy; ar->v2d.cur.ymax += dy; ED_region_tag_redraw(ar); return OPERATOR_FINISHED; } /* mat_livedb_scroll_page_down_exec() */
void wmGetProjectionMatrix(float mat[4][4], const rcti *winrct) { int width = BLI_rcti_size_x(winrct) + 1; int height = BLI_rcti_size_y(winrct) + 1; orthographic_m4(mat, -GLA_PIXEL_OFS, (float)width - GLA_PIXEL_OFS, -GLA_PIXEL_OFS, (float)height - GLA_PIXEL_OFS, -100, 100); }
/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; int depth_test_enabled; UI_ThemeColor(TH_GRID); if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } glPushMatrix(); if (t->spacetype == SPACE_VIEW3D) { /* pass */ } else if (t->spacetype == SPACE_IMAGE) { glScalef(1.0f / t->aspect[0], 1.0f / t->aspect[1], 1.0f); } else if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) { /* only scale y */ rcti *mask = &t->ar->v2d.mask; rctf *datamask = &t->ar->v2d.cur; float xsize = BLI_rctf_size_x(datamask); float ysize = BLI_rctf_size_y(datamask); float xmask = BLI_rcti_size_x(mask); float ymask = BLI_rcti_size_y(mask); glScalef(1.0f, (ysize / xsize) * (xmask / ymask), 1.0f); } depth_test_enabled = glIsEnabled(GL_DEPTH_TEST); if (depth_test_enabled) glDisable(GL_DEPTH_TEST); set_inverted_drawing(1); drawcircball(GL_LINE_LOOP, t->center_global, t->prop_size, imat); set_inverted_drawing(0); if (depth_test_enabled) glEnable(GL_DEPTH_TEST); glPopMatrix(); } }
/* Part of the solution copied from `rect_subregion_stride_calc`. */ void GPU_select_buffer_stride_realign(const rcti *src, const rcti *dst, uint *r_buf) { const int x = dst->xmin - src->xmin; const int y = dst->ymin - src->ymin; BLI_assert(src->xmin <= dst->xmin && src->ymin <= dst->ymin && src->xmax >= dst->xmax && src->ymax >= dst->ymax); BLI_assert(x >= 0 && y >= 0); const int src_x = BLI_rcti_size_x(src); const int src_y = BLI_rcti_size_y(src); const int dst_x = BLI_rcti_size_x(dst); const int dst_y = BLI_rcti_size_y(dst); int last_px_id = src_x * (y + dst_y - 1) + (x + dst_x - 1); memset(&r_buf[last_px_id + 1], 0, (src_x * src_y - (last_px_id + 1)) * sizeof(*r_buf)); if (last_px_id < 0) { /* Nothing to write. */ BLI_assert(last_px_id == -1); return; } int last_px_written = dst_x * dst_y - 1; const int skip = src_x - dst_x; while (true) { for (int i = dst_x; i--;) { r_buf[last_px_id--] = r_buf[last_px_written--]; } if (last_px_written < 0) { break; } last_px_id -= skip; memset(&r_buf[last_px_id + 1], 0, skip * sizeof(*r_buf)); } memset(r_buf, 0, (last_px_id + 1) * sizeof(*r_buf)); }
void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct) { /* Setup part of the viewport for partial redraw. */ bool scissor_pad; if (partialrct->xmin == partialrct->xmax) { /* Full region. */ *drawrct = *winrct; scissor_pad = true; } else { /* Partial redraw, clipped to region. */ BLI_rcti_isect(winrct, partialrct, drawrct); scissor_pad = false; } int x = drawrct->xmin - winrct->xmin; int y = drawrct->ymin - winrct->ymin; int width = BLI_rcti_size_x(winrct) + 1; int height = BLI_rcti_size_y(winrct) + 1; int scissor_width = BLI_rcti_size_x(drawrct); int scissor_height = BLI_rcti_size_y(drawrct); /* Partial redraw rect uses different convention than region rect, * so compensate for that here. One pixel offset is noticeable with * viewport border render. */ if (scissor_pad) { scissor_width += 1; scissor_height += 1; } glViewport(0, 0, width, height); glScissor(x, y, scissor_width, scissor_height); wmOrtho2_pixelspace(width, height); GPU_matrix_identity_set(); }
static int actkeys_borderselect_exec(bContext *C, wmOperator *op) { bAnimContext ac; rcti rect; short mode = 0, selectmode = 0; const bool select = !RNA_boolean_get(op->ptr, "deselect"); const bool extend = RNA_boolean_get(op->ptr, "extend"); /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; /* clear all selection if not extending selection */ if (!extend) { deselect_action_keys(&ac, 1, SELECT_SUBTRACT); } /* get settings from operator */ WM_operator_properties_border_to_rcti(op, &rect); if (select) { selectmode = SELECT_ADD; } else { selectmode = SELECT_SUBTRACT; } /* selection 'mode' depends on whether borderselect region only matters on one axis */ if (RNA_boolean_get(op->ptr, "axis_range")) { /* mode depends on which axis of the range is larger to determine which axis to use * - checking this in region-space is fine, as it's fundamentally still going to be a different rect size * - the frame-range select option is favored over the channel one (x over y), as frame-range one is often * used for tweaking timing when "blocking", while channels is not that useful... */ if (BLI_rcti_size_x(&rect) >= BLI_rcti_size_y(&rect)) mode = ACTKEYS_BORDERSEL_FRAMERANGE; else mode = ACTKEYS_BORDERSEL_CHANNELS; } else mode = ACTKEYS_BORDERSEL_ALLKEYS; /* apply borderselect action */ borderselect_action(&ac, rect, mode, selectmode); /* set notifier that keyframe selection have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); return OPERATOR_FINISHED; }
static int view_all_exec(bContext *C, wmOperator *op) { SpaceClip *sc; ARegion *ar; int w, h, width, height; float aspx, aspy; int fit_view = RNA_boolean_get(op->ptr, "fit_view"); float zoomx, zoomy; /* retrieve state */ sc = CTX_wm_space_clip(C); ar = CTX_wm_region(C); ED_space_clip_get_size(sc, &w, &h); ED_space_clip_get_aspect(sc, &aspx, &aspy); w = w * aspx; h = h * aspy; /* check if the image will fit in the image with zoom == 1 */ width = BLI_rcti_size_x(&ar->winrct) + 1; height = BLI_rcti_size_y(&ar->winrct) + 1; if (fit_view) { const int margin = 5; /* margin from border */ zoomx = (float) width / (w + 2 * margin); zoomy = (float) height / (h + 2 * margin); sclip_zoom_set(C, min_ff(zoomx, zoomy), NULL); } else { if ((w >= width || h >= height) && (width > 0 && height > 0)) { zoomx = (float) width / w; zoomy = (float) height / h; /* find the zoom value that will fit the image in the image space */ sclip_zoom_set(C, 1.0f / power_of_2(1.0f / min_ff(zoomx, zoomy)), NULL); } else sclip_zoom_set(C, 1.0f, NULL); } sc->xof = sc->yof = 0.0f; ED_region_tag_redraw(CTX_wm_region(C)); return OPERATOR_FINISHED; }
/* area-rip calls this */ wmWindow *WM_window_open(bContext *C, const rcti *rect) { wmWindow *win = wm_window_new(C); win->posx = rect->xmin; win->posy = rect->ymin; win->sizex = BLI_rcti_size_x(rect); win->sizey = BLI_rcti_size_y(rect); win->drawmethod = U.wmdrawmethod; WM_check(C); return win; }
uint *ED_view3d_select_id_read_rect(const rcti *clip, uint *r_buf_len) { uint width = BLI_rcti_size_x(clip); uint height = BLI_rcti_size_y(clip); uint buf_len = width * height; uint *buf = MEM_mallocN(buf_len * sizeof(*buf), __func__); DRW_framebuffer_select_id_read(clip, buf); if (r_buf_len) { *r_buf_len = buf_len; } return buf; }
inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const { const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); if (this->m_singleThreaded) { BLI_rcti_init(rect, this->m_viewerBorder.xmin, border_width, this->m_viewerBorder.ymin, border_height); } else { const unsigned int minx = xChunk * this->m_chunkSize + this->m_viewerBorder.xmin; const unsigned int miny = yChunk * this->m_chunkSize + this->m_viewerBorder.ymin; const unsigned int width = min((unsigned int) this->m_viewerBorder.xmax, this->m_width); const unsigned int height = min((unsigned int) this->m_viewerBorder.ymax, this->m_height); BLI_rcti_init(rect, min(minx, this->m_width), min(minx + this->m_chunkSize, width), min(miny, this->m_height), min(miny + this->m_chunkSize, height)); } }
void ExecutionGroup::determineNumberOfChunks() { if (this->m_singleThreaded) { this->m_numberOfXChunks = 1; this->m_numberOfYChunks = 1; this->m_numberOfChunks = 1; } else { const float chunkSizef = this->m_chunkSize; const int border_width = BLI_rcti_size_x(&this->m_viewerBorder); const int border_height = BLI_rcti_size_y(&this->m_viewerBorder); this->m_numberOfXChunks = ceil(border_width / chunkSizef); this->m_numberOfYChunks = ceil(border_height / chunkSizef); this->m_numberOfChunks = this->m_numberOfXChunks * this->m_numberOfYChunks; } }
static void screenshot_crop(ImBuf *ibuf, rcti crop) { unsigned int *to = ibuf->rect; unsigned int *from = ibuf->rect + crop.ymin * ibuf->x + crop.xmin; int crop_x = BLI_rcti_size_x(&crop); int crop_y = BLI_rcti_size_y(&crop); int y; if (crop_x > 0 && crop_y > 0) { for (y = 0; y < crop_y; y++, to += crop_x, from += ibuf->x) memmove(to, from, sizeof(unsigned int) * crop_x); ibuf->x = crop_x; ibuf->y = crop_y; } }
void UI_fontstyle_draw_ex( const uiFontStyle *fs, const rcti *rect, const char *str, size_t len, float *r_xofs, float *r_yofs) { float height; int xofs = 0, yofs; UI_fontstyle_set(fs); height = BLF_ascender(fs->uifont_id); yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height)); if (fs->align == UI_STYLE_TEXT_CENTER) { xofs = floor(0.5f * (BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len))); /* don't center text if it chops off the start of the text, 2 gives some margin */ if (xofs < 2) { xofs = 2; } } else if (fs->align == UI_STYLE_TEXT_RIGHT) { xofs = BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len) - 0.1f * U.widget_unit; } /* clip is very strict, so we give it some space */ BLF_clipping(fs->uifont_id, rect->xmin - 2, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4); BLF_enable(fs->uifont_id, BLF_CLIPPING); BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f); if (fs->shadow) { BLF_enable(fs->uifont_id, BLF_SHADOW); BLF_shadow(fs->uifont_id, fs->shadow, fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha); BLF_shadow_offset(fs->uifont_id, fs->shadx, fs->shady); } if (fs->kerning == 1) BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT); BLF_draw(fs->uifont_id, str, len); BLF_disable(fs->uifont_id, BLF_CLIPPING); if (fs->shadow) BLF_disable(fs->uifont_id, BLF_SHADOW); if (fs->kerning == 1) BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT); *r_xofs = xofs; *r_yofs = yofs; }
static void sclip_zoom_set(const bContext *C, float zoom, float location[2]) { SpaceClip *sc = CTX_wm_space_clip(C); ARegion *ar = CTX_wm_region(C); float oldzoom = sc->zoom; int width, height; sc->zoom = zoom; if (sc->zoom < 0.1f || sc->zoom > 4.0f) { /* check zoom limits */ ED_space_clip_get_size(sc, &width, &height); width *= sc->zoom; height *= sc->zoom; if ((width < 4) && (height < 4) && sc->zoom < oldzoom) sc->zoom = oldzoom; else if (BLI_rcti_size_x(&ar->winrct) <= sc->zoom) sc->zoom = oldzoom; else if (BLI_rcti_size_y(&ar->winrct) <= sc->zoom) sc->zoom = oldzoom; } if ((U.uiflag & USER_ZOOM_TO_MOUSEPOS) && location) { float aspx, aspy, w, h, dx, dy; ED_space_clip_get_size(sc, &width, &height); ED_space_clip_get_aspect(sc, &aspx, &aspy); w = width * aspx; h = height * aspy; dx = ((location[0] - 0.5f) * w - sc->xof) * (sc->zoom - oldzoom) / sc->zoom; dy = ((location[1] - 0.5f) * h - sc->yof) * (sc->zoom - oldzoom) / sc->zoom; if (sc->flag & SC_LOCK_SELECTION) { sc->xlockof += dx; sc->ylockof += dy; } else { sc->xof += dx; sc->yof += dy; } } }