diff options
author | Jörg Frings-Fürst <debian@jff.email> | 2023-06-14 20:36:37 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff.email> | 2023-06-14 20:36:37 +0200 |
commit | bb80d3feebdc9acc52e3f4ad24084d8425f043a2 (patch) | |
tree | 2084a84c39f159c6aea254775dc0880d52579d45 /src/faces/FaceShape.vala | |
parent | b26ff0798252a1a8072dd2c7a67f6205de9fde11 (diff) | |
parent | 31804433d72460cbe0a39f9f8ea5e76058d84cda (diff) |
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'src/faces/FaceShape.vala')
-rw-r--r-- | src/faces/FaceShape.vala | 120 |
1 files changed, 86 insertions, 34 deletions
diff --git a/src/faces/FaceShape.vala b/src/faces/FaceShape.vala index 1ff01fd..f90f254 100644 --- a/src/faces/FaceShape.vala +++ b/src/faces/FaceShape.vala @@ -18,14 +18,16 @@ public abstract class FaceShape : Object { protected Gdk.CursorType current_cursor_type = Gdk.CursorType.BOTTOM_RIGHT_CORNER; protected EditingTools.PhotoCanvas canvas; protected string serialized = null; + protected double[] face_vec; private bool editable = true; private bool visible = true; private bool known = true; + private double guess = 0.0; private weak FacesTool.FaceWidget face_widget = null; - protected FaceShape(EditingTools.PhotoCanvas canvas) { + protected FaceShape(EditingTools.PhotoCanvas canvas, double[] vec) { this.canvas = canvas; this.canvas.new_surface.connect(prepare_ctx); @@ -37,19 +39,21 @@ public abstract class FaceShape : Object { face_window.show_all(); face_window.hide(); - this.canvas.get_drawing_window().set_cursor(new Gdk.Cursor(current_cursor_type)); + this.face_vec = vec; + this.canvas.set_cursor(current_cursor_type); } ~FaceShape() { - if (visible) + if (visible) { erase(); + } face_window.destroy(); canvas.new_surface.disconnect(prepare_ctx); // make sure the cursor isn't set to a modify indicator - canvas.get_drawing_window().set_cursor(new Gdk.Cursor(Gdk.CursorType.LEFT_PTR)); + canvas.set_cursor(Gdk.CursorType.LEFT_PTR); } public static FaceShape from_serialized(EditingTools.PhotoCanvas canvas, string serialized) @@ -88,7 +92,15 @@ public abstract class FaceShape : Object { public bool get_known() { return known; } + + public void set_guess(double guess) { + this.guess = guess; + } + public double get_guess() { + return guess; + } + public void set_widget(FacesTool.FaceWidget face_widget) { this.face_widget = face_widget; } @@ -107,7 +119,7 @@ public abstract class FaceShape : Object { face_window.hide(); // make sure the cursor isn't set to a modify indicator - canvas.get_drawing_window().set_cursor(new Gdk.Cursor(Gdk.CursorType.LEFT_PTR)); + canvas.set_cursor(Gdk.CursorType.LEFT_PTR); } public void show() { @@ -160,7 +172,7 @@ public abstract class FaceShape : Object { return true; } - public abstract string serialize(); + public abstract string serialize(bool geometry_only = false); public abstract void update_face_window_position(); public abstract void prepare_ctx(Cairo.Context ctx, Dimensions dim); public abstract void on_resized_pixbuf(Dimensions old_dim, Gdk.Pixbuf scaled); @@ -170,6 +182,7 @@ public abstract class FaceShape : Object { public abstract bool cursor_is_over(int x, int y); public abstract bool equals(FaceShape face_shape); public abstract double get_distance(int x, int y); + public abstract double[] get_face_vec(); protected abstract void paint(); protected abstract void erase(); @@ -186,13 +199,17 @@ public class FaceRectangle : FaceShape { private BoxLocation in_manipulation = BoxLocation.OUTSIDE; private Cairo.Context wide_black_ctx = null; private Cairo.Context wide_white_ctx = null; - private Cairo.Context thin_white_ctx = null; private int last_grab_x = -1; private int last_grab_y = -1; public FaceRectangle(EditingTools.PhotoCanvas canvas, int x, int y, - int half_width = NULL_SIZE, int half_height = NULL_SIZE) { - base(canvas); + int half_width = NULL_SIZE, int half_height = NULL_SIZE, double[] vec = {}) { + double[] int_vec; + if (vec.length == 0) + int_vec = create_empty_vec(); + else + int_vec = vec; + base(canvas, int_vec); Gdk.Rectangle scaled_pixbuf_pos = canvas.get_scaled_pixbuf_position(); x -= scaled_pixbuf_pos.x; @@ -219,6 +236,14 @@ public class FaceRectangle : FaceShape { if (!is_editable()) erase_label(); } + + public static double[] create_empty_vec() { + double[] empty_vec = new double[128]; + for (int i = 0; i < 128; i++) { + empty_vec[i] = 0; + } + return empty_vec; + } public static new FaceRectangle from_serialized(EditingTools.PhotoCanvas canvas, string[] args) throws FaceShapeError { @@ -226,7 +251,9 @@ public class FaceRectangle : FaceShape { Photo photo = canvas.get_photo(); Dimensions raw_dim = photo.get_raw_dimensions(); - + + // 1, 2 is the center of the rectangle, 3, 4 is the half width / height of the rectangle, + // normalized int x = (int) (raw_dim.width * double.parse(args[1])); int y = (int) (raw_dim.height * double.parse(args[2])); int half_width = (int) (raw_dim.width * double.parse(args[3])); @@ -265,9 +292,21 @@ public class FaceRectangle : FaceShape { if (half_width < FACE_MIN_SIZE || half_height < FACE_MIN_SIZE) throw new FaceShapeError.CANT_CREATE("FaceShape is out of cropped photo area"); - + + string[] vec_str; + if (args.length == 6) + vec_str = args[5].split(","); + else + vec_str = {}; + double[] vec = new double[128]; + for (int i = 0; i < 128; i++) { + if (vec_str.length > i) + vec[i] = double.parse(vec_str[i]); + else + vec[i] = 0; + } return new FaceRectangle(canvas, box.left + half_width, box.top + half_height, - half_width, half_height); + half_width, half_height, vec); } public override void update_face_window_position() { @@ -283,32 +322,35 @@ public class FaceRectangle : FaceShape { face_window.get_allocation(out face_window_alloc); - x += scaled_pixbuf_pos.x + box.left + ((box.get_width() - face_window_alloc.width) >> 1); - y += scaled_pixbuf_pos.y + box.bottom + FACE_WINDOW_MARGIN; + var scale = Application.get_scale(); + var left = (int)Math.lround((scaled_pixbuf_pos.x + box.left) / scale); + var width = (int)Math.lround(box.get_width() / scale); + var top = (int)Math.lround((scaled_pixbuf_pos.y + box.bottom) / scale); + x += (left + ((width - face_window_alloc.width) >> 1)); + y += top + FACE_WINDOW_MARGIN; face_window.move(x, y); } protected override void paint() { + // The box is in image coordinates. Need to scale down to device coordinates canvas.draw_box(wide_black_ctx, box); canvas.draw_box(wide_white_ctx, box.get_reduced(1)); canvas.draw_box(wide_white_ctx, box.get_reduced(2)); - canvas.invalidate_area(box); + //canvas.invalidate_area(box); if (!is_editable()) paint_label(); } protected override void erase() { - canvas.erase_box(box); - canvas.erase_box(box.get_reduced(1)); - canvas.erase_box(box.get_reduced(2)); - canvas.invalidate_area(box); if (!is_editable()) erase_label(); + +// canvas.repaint(); } private void paint_label() { @@ -317,6 +359,9 @@ public class FaceRectangle : FaceShape { ctx.save(); + ctx.select_font_face("Sans", Cairo.FontSlant.NORMAL, Cairo.FontWeight.NORMAL); + ctx.set_font_size(10.0 * Application.get_scale()); + Cairo.TextExtents text_extents = Cairo.TextExtents(); ctx.text_extents(get_name(), out text_extents); @@ -368,7 +413,7 @@ public class FaceRectangle : FaceShape { ctx.restore(); } - public override string serialize() { + public override string serialize(bool geometry_only = false) { if (serialized != null) return serialized; @@ -378,10 +423,15 @@ public class FaceRectangle : FaceShape { double half_height; get_geometry(out x, out y, out half_width, out half_height); - - serialized = "%s;%s;%s;%s;%s".printf(SHAPE_TYPE, x.to_string(), + serialized = "%s;%s;%s;%s;%s;".printf(SHAPE_TYPE, x.to_string(), y.to_string(), half_width.to_string(), half_height.to_string()); - + if (!geometry_only) { + string face_vec_str = ""; + foreach (var d in face_vec[0:-2]) + face_vec_str += d.to_string() + ","; + face_vec_str += face_vec[-1].to_string(); + serialized += face_vec_str; + } return serialized; } @@ -425,23 +475,23 @@ public class FaceRectangle : FaceShape { half_width = (width_right_end - width_left_end) / 2; half_height = (height_bottom_end - height_top_end) / 2; } + + public override double[] get_face_vec() { + return face_vec; + } public override bool equals(FaceShape face_shape) { - return serialize() == face_shape.serialize(); + return serialize(true) == face_shape.serialize(true); } public override void prepare_ctx(Cairo.Context ctx, Dimensions dim) { wide_black_ctx = new Cairo.Context(ctx.get_target()); set_source_color_from_string(wide_black_ctx, "#000"); - wide_black_ctx.set_line_width(1); + wide_black_ctx.set_line_width(1 * Application.get_scale()); wide_white_ctx = new Cairo.Context(ctx.get_target()); - set_source_color_from_string(wide_black_ctx, "#FFF"); - wide_white_ctx.set_line_width(1); - - thin_white_ctx = new Cairo.Context(ctx.get_target()); - set_source_color_from_string(wide_black_ctx, "#FFF"); - thin_white_ctx.set_line_width(0.5); + set_source_color_from_string(wide_white_ctx, "#FFF"); + wide_white_ctx.set_line_width(1 * Application.get_scale()); } private bool on_canvas_manipulation(int x, int y) { @@ -620,17 +670,20 @@ public class FaceRectangle : FaceShape { Box new_box = Box(left, top, right, bottom); if (!box.equals(new_box)) { - erase(); + canvas.invalidate_area(box); if (in_manipulation != BoxLocation.INSIDE) check_resized_box(new_box); box = new_box; paint(); + canvas.invalidate_area(new_box); } if (is_editable()) update_face_window_position(); + + canvas.repaint(); serialized = null; @@ -698,8 +751,7 @@ public class FaceRectangle : FaceShape { } if (cursor_type != current_cursor_type) { - Gdk.Cursor cursor = new Gdk.Cursor(cursor_type); - canvas.get_drawing_window().set_cursor(cursor); + canvas.set_cursor(cursor_type); current_cursor_type = cursor_type; } } |