/** 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; }
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; }
/* 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; }
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; } }
static int node_circleselect_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); ARegion *ar = CTX_wm_region(C); bNode *node; int x, y, radius, gesture_mode; float offset[2]; float zoom = (float)(BLI_rcti_size_x(&ar->winrct)) / (float)(BLI_rctf_size_x(&ar->v2d.cur)); gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); /* get operator properties */ x = RNA_int_get(op->ptr, "x"); y = RNA_int_get(op->ptr, "y"); radius = RNA_int_get(op->ptr, "radius"); UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]); for (node = snode->edittree->nodes.first; node; node = node->next) { if (BLI_rctf_isect_circle(&node->totr, offset, radius / zoom)) { nodeSetSelected(node, (gesture_mode == GESTURE_MODAL_SELECT)); } } WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); return OPERATOR_FINISHED; }
void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *data) { const float distance = this->m_distance; const float mindist = distance * distance; MemoryBuffer *inputBuffer = (MemoryBuffer *)data; float *buffer = inputBuffer->getBuffer(); rcti *rect = inputBuffer->getRect(); const int minx = max(x - this->m_scope, rect->xmin); const int miny = max(y - this->m_scope, rect->ymin); const int maxx = min(x + this->m_scope, rect->xmax); const int maxy = min(y + this->m_scope, rect->ymax); const int bufferWidth = BLI_rcti_size_x(rect); int offset; float value = 1.0f; for (int yi = miny; yi < maxy; yi++) { const float dy = yi - y; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; for (int xi = minx; xi < maxx; xi++) { const float dx = xi - x; const float dis = dx * dx + dy * dy; if (dis <= mindist) { value = min(buffer[offset], value); } offset += 4; } } output[0] = value; }
/* draw the contents of the sequencer strips view */ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar) { Scene *scene = CTX_data_scene(C); View2D *v2d = &ar->v2d; Sequence *last_seq = BKE_sequencer_active_get(scene); int sel = 0, j; float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); /* loop through twice, first unselected, then selected */ for (j = 0; j < 2; j++) { Sequence *seq; int outline_tint = (j) ? -60 : -150; /* highlighting around strip edges indicating selection */ /* loop through strips, checking for those that are visible */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { /* boundbox and selection tests for NOT drawing the strip... */ if ((seq->flag & SELECT) != sel) continue; else if (seq == last_seq) continue; else if (min_ii(seq->startdisp, seq->start) > v2d->cur.xmax) continue; else if (max_ii(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) continue; else if (seq->machine + 1.0f < v2d->cur.ymin) continue; else if (seq->machine > v2d->cur.ymax) continue; /* strip passed all tests unscathed... so draw it now */ draw_seq_strip(scene, ar, seq, outline_tint, pixelx); } /* draw selected next time round */ sel = SELECT; } /* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */ if (last_seq) draw_seq_strip(scene, ar, last_seq, 120, pixelx); }
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; }
/* 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; }
/* 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; }
/* 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(); } }
/* nothing drawn here, we use it to store values */ static void preview_cb(ScrArea *sa, struct uiBlock *block) { SpaceImage *sima = sa->spacedata.first; rctf dispf; rcti *disprect = &G.scene->r.disprect; int winx = (G.scene->r.size * G.scene->r.xsch) / 100; int winy = (G.scene->r.size * G.scene->r.ysch) / 100; int mval[2]; if (G.scene->r.mode & R_BORDER) { winx *= BLI_rcti_size_x(&G.scene->r.border); winy *= BLI_rctf_size_y(&G.scene->r.border); } /* while dragging we need to update the rects, otherwise it doesn't end with correct one */ BLI_rctf_init(&dispf, 15.0f, BLI_rcti_size_x(&block->rect) - 15.0f, 15.0f, (BLI_rctf_size_y(&block->rect)) - 15.0f); ui_graphics_to_window_rct(sa->win, &dispf, disprect); /* correction for gla draw */ BLI_rcti_translate(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); calc_image_view(sima, 'p'); // printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax); /* map to image space coordinates */ mval[0] = disprect->xmin; mval[1] = disprect->ymin; areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin); mval[0] = disprect->xmax; mval[1] = disprect->ymax; areamouseco_to_ipoco(v2d, mval, &dispf.xmax, &dispf.ymax); /* map to render coordinates */ disprect->xmin = dispf.xmin; disprect->xmax = dispf.xmax; disprect->ymin = dispf.ymin; disprect->ymax = dispf.ymax; CLAMP(disprect->xmin, 0, winx); CLAMP(disprect->xmax, 0, winx); CLAMP(disprect->ymin, 0, winy); CLAMP(disprect->ymax, 0, winy); // printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin, disprect->xmax, disprect->ymax); }
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); }
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_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); }
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; }
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(); }
/* 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 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(); } }
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(); }
/* 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)); }
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; }
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; } }
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)); } }
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; } }