Render avatar to image surface
This commit is contained in:
parent
baa3f99ed7
commit
ea7efd6399
|
@ -18,6 +18,8 @@ public class AvatarImage : Misc {
|
|||
private bool gray;
|
||||
private Jid[] current_jids;
|
||||
private Gdk.Pixbuf[] current_avatars;
|
||||
private Cairo.ImageSurface? cached_surface;
|
||||
private static int8 use_image_surface = -1;
|
||||
|
||||
public AvatarImage() {
|
||||
can_focus = false;
|
||||
|
@ -78,9 +80,30 @@ public class AvatarImage : Misc {
|
|||
hex_color.length > 6 ? (double) hex_color.substring(6, 2).to_long(null, 16) / 255 : 1);
|
||||
}
|
||||
|
||||
public override bool draw(Cairo.Context ctx) {
|
||||
public override bool draw(Cairo.Context ctx_in) {
|
||||
if (text_only == null && (current_jids == null || current_avatars == null || current_jids.length == 0)) return false;
|
||||
double radius = 3;
|
||||
|
||||
Cairo.Context ctx = ctx_in;
|
||||
int width = this.width, height = this.height, base_factor = 1;
|
||||
if (use_image_surface == -1) {
|
||||
// TODO: detect if we have to buffer in image surface
|
||||
use_image_surface = 1;
|
||||
}
|
||||
if (use_image_surface == 1) {
|
||||
ctx_in.scale(1f/scale_factor, 1f/scale_factor);
|
||||
if (cached_surface != null) {
|
||||
ctx_in.set_source_surface(cached_surface, 0, 0);
|
||||
ctx_in.paint();
|
||||
return true;
|
||||
}
|
||||
width *= scale_factor;
|
||||
height *= scale_factor;
|
||||
base_factor *= scale_factor;
|
||||
cached_surface = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);
|
||||
ctx = new Cairo.Context(cached_surface);
|
||||
}
|
||||
|
||||
double radius = 3 * base_factor;
|
||||
double degrees = Math.PI / 180.0;
|
||||
ctx.new_sub_path();
|
||||
ctx.arc(width - radius, radius, radius, -90 * degrees, 0 * degrees);
|
||||
|
@ -91,23 +114,23 @@ public class AvatarImage : Misc {
|
|||
ctx.clip();
|
||||
|
||||
if (text_only != null) {
|
||||
ctx.set_source_surface(sub_surface(ctx, -1, width, height), 0, 0);
|
||||
ctx.set_source_surface(sub_surface(ctx, -1, width, height, base_factor), 0, 0);
|
||||
ctx.paint();
|
||||
} else if (current_jids.length == 4 || with_plus) {
|
||||
Cairo.Surface buffer = new Cairo.Surface.similar(ctx.get_target(), Cairo.Content.COLOR_ALPHA, width, height);
|
||||
Cairo.Context bufctx = new Cairo.Context(buffer);
|
||||
bufctx.scale(0.5, 0.5);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 0, width - 1, height - 1, 2), 0, 0);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 0, width - 1, height - 1, 2 * base_factor), 0, 0);
|
||||
bufctx.paint();
|
||||
bufctx.set_source_surface(sub_surface(ctx, 1, width - 1, height - 1, 2), width + 1, 0);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 1, width - 1, height - 1, 2 * base_factor), width + 1, 0);
|
||||
bufctx.paint();
|
||||
bufctx.set_source_surface(sub_surface(ctx, 2, width - 1, height - 1, 2), 0, height + 1);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 2, width - 1, height - 1, 2 * base_factor), 0, height + 1);
|
||||
bufctx.paint();
|
||||
if (with_plus) {
|
||||
bufctx.set_source_surface(sub_surface(ctx, -1, width - 1, height - 1, 2), width + 1, height + 1);
|
||||
bufctx.set_source_surface(sub_surface(ctx, -1, width - 1, height - 1, 2 * base_factor), width + 1, height + 1);
|
||||
bufctx.paint();
|
||||
} else {
|
||||
bufctx.set_source_surface(sub_surface(ctx, 3, width - 1, height - 1, 2), width + 1, height + 1);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 3, width - 1, height - 1, 2 * base_factor), width + 1, height + 1);
|
||||
bufctx.paint();
|
||||
}
|
||||
|
||||
|
@ -117,11 +140,11 @@ public class AvatarImage : Misc {
|
|||
Cairo.Surface buffer = new Cairo.Surface.similar(ctx.get_target(), Cairo.Content.COLOR_ALPHA, width, height);
|
||||
Cairo.Context bufctx = new Cairo.Context(buffer);
|
||||
bufctx.scale(0.5, 0.5);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 0, width - 1, height - 1, 2), 0, 0);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 0, width - 1, height - 1, 2 * base_factor), 0, 0);
|
||||
bufctx.paint();
|
||||
bufctx.set_source_surface(sub_surface(ctx, 1, width - 1, height * 2, 2), width + 1, 0);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 1, width - 1, height * 2, 2 * base_factor), width + 1, 0);
|
||||
bufctx.paint();
|
||||
bufctx.set_source_surface(sub_surface(ctx, 2, width - 1 , height - 1, 2), 0, height + 1);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 2, width - 1 , height - 1, 2 * base_factor), 0, height + 1);
|
||||
bufctx.paint();
|
||||
|
||||
ctx.set_source_surface(buffer, 0, 0);
|
||||
|
@ -130,15 +153,15 @@ public class AvatarImage : Misc {
|
|||
Cairo.Surface buffer = new Cairo.Surface.similar(ctx.get_target(), Cairo.Content.COLOR_ALPHA, width, height);
|
||||
Cairo.Context bufctx = new Cairo.Context(buffer);
|
||||
bufctx.scale(0.5, 0.5);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 0, width - 1, height * 2, 2), 0, 0);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 0, width - 1, height * 2, 2 * base_factor), 0, 0);
|
||||
bufctx.paint();
|
||||
bufctx.set_source_surface(sub_surface(ctx, 1, width - 1, height * 2, 2), width + 1, 0);
|
||||
bufctx.set_source_surface(sub_surface(ctx, 1, width - 1, height * 2, 2 * base_factor), width + 1, 0);
|
||||
bufctx.paint();
|
||||
|
||||
ctx.set_source_surface(buffer, 0, 0);
|
||||
ctx.paint();
|
||||
} else if (current_jids.length == 1) {
|
||||
ctx.set_source_surface(sub_surface(ctx, 0, width, height), 0, 0);
|
||||
ctx.set_source_surface(sub_surface(ctx, 0, width, height, base_factor), 0, 0);
|
||||
ctx.paint();
|
||||
} else {
|
||||
assert_not_reached();
|
||||
|
@ -157,6 +180,11 @@ public class AvatarImage : Misc {
|
|||
ctx.fill();
|
||||
}
|
||||
|
||||
if (use_image_surface == 1) {
|
||||
ctx_in.set_source_surface(ctx.get_target(), 0, 0);
|
||||
ctx_in.paint();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -276,6 +304,7 @@ public class AvatarImage : Misc {
|
|||
assert(jids.length > 0);
|
||||
assert(jids.length < 5);
|
||||
assert(!with_plus || jids.length == 3);
|
||||
this.cached_surface = null;
|
||||
this.text_only = null;
|
||||
this.gray = gray && allow_gray;
|
||||
this.with_plus = with_plus;
|
||||
|
|
Loading…
Reference in a new issue