summaryrefslogtreecommitdiff
path: root/src/faces/FaceShape.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/faces/FaceShape.vala')
-rw-r--r--src/faces/FaceShape.vala120
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;
}
}