mirror of
https://github.com/penpot/penpot.git
synced 2026-09-10 14:09:17 +00:00
Merge pull request #9059 from penpot/azazeln28-fix-caret-dimensions
🐛 Fix caret dimensions
This commit is contained in:
commit
04f29a0d72
@ -1,9 +1,17 @@
|
|||||||
|
use crate::render::options::RenderOptions;
|
||||||
use crate::shapes::{Shape, TextContent, Type, VerticalAlign};
|
use crate::shapes::{Shape, TextContent, Type, VerticalAlign};
|
||||||
use crate::state::{TextEditorState, TextSelection};
|
use crate::state::{TextEditorState, TextSelection};
|
||||||
|
use crate::view::Viewbox;
|
||||||
use skia_safe::textlayout::{RectHeightStyle, RectWidthStyle};
|
use skia_safe::textlayout::{RectHeightStyle, RectWidthStyle};
|
||||||
use skia_safe::{BlendMode, Canvas, Paint, Rect};
|
use skia_safe::{BlendMode, Canvas, Paint, Rect};
|
||||||
|
|
||||||
pub fn render_overlay(canvas: &Canvas, editor_state: &TextEditorState, shape: &Shape) {
|
pub fn render_overlay(
|
||||||
|
canvas: &Canvas,
|
||||||
|
viewbox: &Viewbox,
|
||||||
|
options: &RenderOptions,
|
||||||
|
editor_state: &TextEditorState,
|
||||||
|
shape: &Shape,
|
||||||
|
) {
|
||||||
if !editor_state.has_focus {
|
if !editor_state.has_focus {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -13,17 +21,24 @@ pub fn render_overlay(canvas: &Canvas, editor_state: &TextEditorState, shape: &S
|
|||||||
};
|
};
|
||||||
|
|
||||||
canvas.save();
|
canvas.save();
|
||||||
|
let zoom = viewbox.zoom * options.dpr();
|
||||||
|
canvas.scale((zoom, zoom));
|
||||||
|
canvas.translate((-viewbox.area.left, -viewbox.area.top));
|
||||||
|
|
||||||
if editor_state.selection.is_selection() {
|
if editor_state.selection.is_selection() {
|
||||||
render_selection(canvas, editor_state, text_content, shape);
|
render_selection(canvas, editor_state, text_content, shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
if editor_state.cursor_visible {
|
if editor_state.cursor_visible {
|
||||||
render_cursor(canvas, editor_state, text_content, shape);
|
render_cursor(canvas, zoom, editor_state, text_content, shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_cursor(
|
fn render_cursor(
|
||||||
canvas: &Canvas,
|
canvas: &Canvas,
|
||||||
|
zoom: f32,
|
||||||
editor_state: &TextEditorState,
|
editor_state: &TextEditorState,
|
||||||
text_content: &TextContent,
|
text_content: &TextContent,
|
||||||
shape: &Shape,
|
shape: &Shape,
|
||||||
@ -32,6 +47,9 @@ fn render_cursor(
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut cursor_rect = Rect::new_empty();
|
||||||
|
cursor_rect.set_xywh(rect.x(), rect.y(), 1.5 / zoom, rect.height());
|
||||||
|
|
||||||
let mut paint = Paint::default();
|
let mut paint = Paint::default();
|
||||||
paint.set_color(editor_state.theme.cursor_color);
|
paint.set_color(editor_state.theme.cursor_color);
|
||||||
paint.set_anti_alias(true);
|
paint.set_anti_alias(true);
|
||||||
@ -39,7 +57,7 @@ fn render_cursor(
|
|||||||
let shape_matrix = shape.get_matrix();
|
let shape_matrix = shape.get_matrix();
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.concat(&shape_matrix);
|
canvas.concat(&shape_matrix);
|
||||||
canvas.draw_rect(rect, &paint);
|
canvas.draw_rect(cursor_rect, &paint);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +178,7 @@ fn calculate_cursor_rect(
|
|||||||
return Some(Rect::from_xywh(
|
return Some(Rect::from_xywh(
|
||||||
cursor_x,
|
cursor_x,
|
||||||
y_offset + cursor_y,
|
y_offset + cursor_y,
|
||||||
editor_state.theme.cursor_width,
|
1.0, // cursor_width
|
||||||
cursor_height,
|
cursor_height,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,7 +100,6 @@ pub enum TextEditorEvent {
|
|||||||
|
|
||||||
/// FIXME: It should be better to get these constants from the frontend through the API.
|
/// FIXME: It should be better to get these constants from the frontend through the API.
|
||||||
const SELECTION_COLOR: Color = Color::from_argb(127, 0, 209, 184);
|
const SELECTION_COLOR: Color = Color::from_argb(127, 0, 209, 184);
|
||||||
const CURSOR_WIDTH: f32 = 1.5;
|
|
||||||
const CURSOR_COLOR: Color = Color::BLACK;
|
const CURSOR_COLOR: Color = Color::BLACK;
|
||||||
const CURSOR_BLINK_INTERVAL_MS: f64 = 530.0;
|
const CURSOR_BLINK_INTERVAL_MS: f64 = 530.0;
|
||||||
|
|
||||||
@ -257,7 +256,6 @@ impl TextEditorStyles {
|
|||||||
|
|
||||||
pub struct TextEditorTheme {
|
pub struct TextEditorTheme {
|
||||||
pub selection_color: Color,
|
pub selection_color: Color,
|
||||||
pub cursor_width: f32,
|
|
||||||
pub cursor_color: Color,
|
pub cursor_color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +338,6 @@ impl TextEditorState {
|
|||||||
Self {
|
Self {
|
||||||
theme: TextEditorTheme {
|
theme: TextEditorTheme {
|
||||||
selection_color: SELECTION_COLOR,
|
selection_color: SELECTION_COLOR,
|
||||||
cursor_width: CURSOR_WIDTH,
|
|
||||||
cursor_color: CURSOR_COLOR,
|
cursor_color: CURSOR_COLOR,
|
||||||
},
|
},
|
||||||
selection: TextSelection::new(),
|
selection: TextSelection::new(),
|
||||||
|
|||||||
@ -32,16 +32,11 @@ pub enum CursorDirection {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn text_editor_apply_theme(
|
pub extern "C" fn text_editor_apply_theme(selection_color: u32, cursor_color: u32) {
|
||||||
selection_color: u32,
|
|
||||||
cursor_width: f32,
|
|
||||||
cursor_color: u32,
|
|
||||||
) {
|
|
||||||
with_state_mut!(state, {
|
with_state_mut!(state, {
|
||||||
// NOTE: In the future could be interesting to fill al this data from
|
// NOTE: In the future could be interesting to fill al this data from
|
||||||
// a structure pointer.
|
// a structure pointer.
|
||||||
state.text_editor_state.theme.selection_color = Color::new(selection_color);
|
state.text_editor_state.theme.selection_color = Color::new(selection_color);
|
||||||
state.text_editor_state.theme.cursor_width = cursor_width;
|
|
||||||
state.text_editor_state.theme.cursor_color = Color::new(cursor_color);
|
state.text_editor_state.theme.cursor_color = Color::new(cursor_color);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -912,13 +907,14 @@ pub extern "C" fn text_editor_render_overlay() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let canvas = state.render_state.surfaces.canvas(SurfaceId::Target);
|
let canvas = state.render_state.surfaces.canvas(SurfaceId::Target);
|
||||||
canvas.save();
|
|
||||||
let viewbox = state.render_state.viewbox;
|
let viewbox = state.render_state.viewbox;
|
||||||
let zoom = viewbox.zoom * state.render_state.options.dpr();
|
text_editor_render::render_overlay(
|
||||||
canvas.scale((zoom, zoom));
|
canvas,
|
||||||
canvas.translate((-viewbox.area.left, -viewbox.area.top));
|
&viewbox,
|
||||||
text_editor_render::render_overlay(canvas, &state.text_editor_state, shape);
|
&state.render_state.options,
|
||||||
canvas.restore();
|
&state.text_editor_state,
|
||||||
|
shape,
|
||||||
|
);
|
||||||
state.render_state.flush_and_submit();
|
state.render_state.flush_and_submit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1103,12 +1099,11 @@ fn get_cursor_rect(
|
|||||||
(pos.position as f32, height)
|
(pos.position as f32, height)
|
||||||
};
|
};
|
||||||
|
|
||||||
let cursor_width = 2.0;
|
|
||||||
let selrect = shape.selrect();
|
let selrect = shape.selrect();
|
||||||
let base_x = selrect.x();
|
let base_x = selrect.x();
|
||||||
let base_y = selrect.y() + y_offset;
|
let base_y = selrect.y() + y_offset;
|
||||||
|
|
||||||
return Some(Rect::from_xywh(base_x + x, base_y, cursor_width, height));
|
return Some(Rect::from_xywh(base_x + x, base_y, 1.0, height));
|
||||||
}
|
}
|
||||||
y_offset += laid_out_para.height();
|
y_offset += laid_out_para.height();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user