Fix incorrect location from SpaceText.region_location_from_cursor
The resulting location was incorrect because the offset didn't account for multi-byte characters and the logic had not been updated to use the TXT_LINE_HEIGHT macro. Also removes use of `goto` in favor of early return. Ref !126720.
This commit is contained in:
committed by
Campbell Barton
parent
e0733e0bca
commit
db5cd39a67
@@ -1790,33 +1790,34 @@ bool ED_space_text_region_location_from_cursor(const SpaceText *st,
|
||||
const int cursor_co[2],
|
||||
int r_pixel_co[2])
|
||||
{
|
||||
TextLine *line = nullptr;
|
||||
Text *text = st->text;
|
||||
|
||||
if (!st->text) {
|
||||
goto error;
|
||||
if (!text) {
|
||||
return false;
|
||||
}
|
||||
TextLine *line = static_cast<TextLine *>(BLI_findlink(&text->lines, cursor_co[0]));
|
||||
if (!line) {
|
||||
return false;
|
||||
}
|
||||
|
||||
line = static_cast<TextLine *>(BLI_findlink(&st->text->lines, cursor_co[0]));
|
||||
if (!line || (cursor_co[1] < 0) || (cursor_co[1] > line->len)) {
|
||||
goto error;
|
||||
/* Convert character index to char byte offset. */
|
||||
const int char_ofs = BLI_str_utf8_offset_from_index(line->line, line->len, cursor_co[1]);
|
||||
if (char_ofs < 0 || char_ofs > line->len) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
int offl, offc;
|
||||
int linenr_offset = TXT_BODY_LEFT(st);
|
||||
/* handle tabs as well! */
|
||||
int char_pos = space_text_get_char_pos(st, line->line, cursor_co[1]);
|
||||
|
||||
space_text_wrap_offset(st, region, line, cursor_co[1], &offl, &offc);
|
||||
r_pixel_co[0] = (char_pos + offc - st->left) * st->runtime->cwidth_px + linenr_offset;
|
||||
r_pixel_co[1] = (cursor_co[0] + offl - st->top) * TXT_LINE_HEIGHT(st);
|
||||
r_pixel_co[1] = (region->winy - (r_pixel_co[1] + (TXT_BODY_LPAD * st->runtime->cwidth_px))) -
|
||||
st->runtime->lheight_px;
|
||||
}
|
||||
/* All values are in-range, calculate the pixel offset.
|
||||
* Note that !126720 provides a useful interactive test-case for this logic. */
|
||||
const int lheight = TXT_LINE_HEIGHT(st);
|
||||
const int linenr_offset = TXT_BODY_LEFT(st);
|
||||
/* Handle tabs as well! */
|
||||
const int char_pos = space_text_get_char_pos(st, line->line, char_ofs);
|
||||
|
||||
int offl, offc;
|
||||
space_text_wrap_offset(st, region, line, char_ofs, &offl, &offc);
|
||||
r_pixel_co[0] = (char_pos + offc - st->left) * st->runtime->cwidth_px + linenr_offset;
|
||||
r_pixel_co[1] = (region->winy - ((cursor_co[0] + offl - st->top) * lheight)) - lheight;
|
||||
return true;
|
||||
|
||||
error:
|
||||
r_pixel_co[0] = r_pixel_co[1] = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -71,7 +71,9 @@ static void rna_SpaceTextEditor_region_location_from_cursor(
|
||||
if (area) {
|
||||
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
|
||||
const int cursor_co[2] = {line, column};
|
||||
ED_space_text_region_location_from_cursor(st, region, cursor_co, r_pixel_pos);
|
||||
if (!ED_space_text_region_location_from_cursor(st, region, cursor_co, r_pixel_pos)) {
|
||||
r_pixel_pos[0] = r_pixel_pos[1] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user