mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 11:02:05 +00:00
random commit to help rejig stuff around
This commit is contained in:
parent
f016f09792
commit
69e830eea4
2
Makefile
2
Makefile
@ -6,6 +6,7 @@ CFLAGS=`pkg-config --cflags pangoft2 pango glib-2.0 gthread-2.0`
|
||||
|
||||
OBJS=cltr.o pixbuf.o util.o fonts.o \
|
||||
cltr-core.o \
|
||||
cltr-glu.o \
|
||||
cltr-texture.o \
|
||||
cltr-widget.o \
|
||||
cltr-events.o \
|
||||
@ -22,6 +23,7 @@ clutter: $(OBJS)
|
||||
$(OBJS): pixbuf.h util.h fonts.h \
|
||||
cltr.h \
|
||||
cltr-private.h \
|
||||
cltr-glu.h \
|
||||
cltr-events.h \
|
||||
cltr-texture.h \
|
||||
cltr-widget.h \
|
||||
|
16
cltr-core.c
16
cltr-core.c
@ -42,3 +42,19 @@ cltr_init(int *argc, char ***argv)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
cltr_display_width(void)
|
||||
{
|
||||
ClutterMainContext *ctx = CLTR_CONTEXT();
|
||||
|
||||
return DisplayWidth(ctx->xdpy, ctx->xscreen);
|
||||
}
|
||||
|
||||
int
|
||||
cltr_display_height(void)
|
||||
{
|
||||
ClutterMainContext *ctx = CLTR_CONTEXT();
|
||||
|
||||
return DisplayHeight(ctx->xdpy, ctx->xscreen);
|
||||
}
|
||||
|
@ -6,4 +6,10 @@
|
||||
int
|
||||
cltr_init(int *argc, char ***argv);
|
||||
|
||||
int
|
||||
cltr_display_height(void);
|
||||
|
||||
int
|
||||
cltr_display_width(void);
|
||||
|
||||
#endif
|
||||
|
@ -157,7 +157,6 @@ cltr_main_loop()
|
||||
{
|
||||
if (!g_queue_is_empty (ctx->internal_event_q))
|
||||
{
|
||||
CltrWidget *widget = NULL;
|
||||
CltrWindow *win = CLTR_WINDOW(ctx->window);
|
||||
|
||||
/* Empty the queue */
|
||||
|
133
cltr-glu.c
Normal file
133
cltr-glu.c
Normal file
@ -0,0 +1,133 @@
|
||||
#include "cltr-glu.h"
|
||||
#include "cltr-private.h"
|
||||
|
||||
/* Clutter GL Utility routines */
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
void
|
||||
cltr_glu_set_color(PixbufPixel *p)
|
||||
{
|
||||
glColor4ub(p->r, p->b, p->g, p->a);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
DrawRoundedSquare(float LineWidth,
|
||||
float x,
|
||||
float y,
|
||||
float radius,
|
||||
float width,
|
||||
float height,
|
||||
float r,
|
||||
float b,
|
||||
float g)
|
||||
{
|
||||
double ang=0;
|
||||
|
||||
glColor3f(r, b, g);
|
||||
glLineWidth(LineWidth);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(x, y + radius);
|
||||
glVertex2f(x, y + height - radius); /* Left Line */
|
||||
|
||||
glVertex2f(x + radius, y);
|
||||
glVertex2f(x + width - radius, y); /* Top Line */
|
||||
|
||||
glVertex2f(x + width, y + radius);
|
||||
glVertex2f(x + width, y + height - radius); /* Right Line */
|
||||
|
||||
glVertex2f(x + radius, y + height);
|
||||
glVertex2f(x + width - radius, y + height);//Bottom Line
|
||||
glEnd();
|
||||
|
||||
float cX= x+radius, cY = y+radius;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for(ang = PI; ang <= (1.5*PI); ang = ang + 0.05)
|
||||
{
|
||||
glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); //Top Left
|
||||
}
|
||||
cX = x+width-radius;
|
||||
glEnd();
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for(ang = (1.5*PI); ang <= (2 * PI); ang = ang + 0.05)
|
||||
{
|
||||
glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); //Top Right
|
||||
}
|
||||
glEnd();
|
||||
glBegin(GL_LINE_STRIP);
|
||||
cY = y+height-radius;
|
||||
for(ang = 0; ang <= (0.5*PI); ang = ang + 0.05)
|
||||
{
|
||||
glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY); //Bottom Right
|
||||
}
|
||||
glEnd();
|
||||
glBegin(GL_LINE_STRIP);
|
||||
cX = x+radius;
|
||||
for(ang = (0.5*PI); ang <= PI; ang = ang + 0.05)
|
||||
{
|
||||
glVertex2d(radius* cos(ang) + cX, radius * sin(ang) + cY);//Bottom Left
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
cltr_glu_rounded_rect(int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
int radius,
|
||||
PixbufPixel *col)
|
||||
{
|
||||
double i = 0;
|
||||
double gap = 0.05;
|
||||
float cX = x1 + radius, cY = y1 + radius;
|
||||
|
||||
if (col)
|
||||
cltr_glu_set_color(col);
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
|
||||
/* Left Line */
|
||||
glVertex2f(x1, y2 - radius);
|
||||
glVertex2f(x1, y1 + radius);
|
||||
|
||||
/* Top Left */
|
||||
for(i = PI; i <= (1.5*PI); i += gap)
|
||||
glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
|
||||
|
||||
/* Top Line */
|
||||
glVertex2f(x1 + radius, y1);
|
||||
glVertex2f(x2 - radius, y1);
|
||||
|
||||
cX = x2 - radius;
|
||||
|
||||
/* Top Right */
|
||||
for(i = (1.5*PI); i <= (2 * PI); i += gap)
|
||||
glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
|
||||
|
||||
glVertex2f(x2, y1 + radius);
|
||||
|
||||
/* Right Line */
|
||||
glVertex2f(x2, y2 - radius);
|
||||
|
||||
cY = y2 - radius;
|
||||
|
||||
/* Bottom Right */
|
||||
for(i = 0; i <= (0.5*PI); i+=gap)
|
||||
glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
|
||||
|
||||
/* Bottom Line */
|
||||
glVertex2f(x1 + radius, y2);
|
||||
glVertex2f(x2 - radius, y2);
|
||||
|
||||
/* Bottom Left */
|
||||
cX = x1 + radius;
|
||||
for(i = (0.5*PI); i <= PI; i += gap)
|
||||
glVertex2d(radius* cos(i) + cX, radius * sin(i) + cY);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
17
cltr-glu.h
Normal file
17
cltr-glu.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _HAVE_CLTR_GLU_H
|
||||
#define _HAVE_CLTR_GLU_H
|
||||
|
||||
#include "cltr.h"
|
||||
|
||||
void
|
||||
cltr_glu_set_color(PixbufPixel *p);
|
||||
|
||||
void
|
||||
cltr_glu_rounded_rect(int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
int radius,
|
||||
PixbufPixel *col);
|
||||
|
||||
#endif
|
@ -48,7 +48,7 @@ cltr_list_cell_new(CltrList *list)
|
||||
CltrListCell *cell = NULL;
|
||||
ClutterFont *font;
|
||||
gchar buf[24];
|
||||
PixbufPixel pixel = { 255, 20, 20, 255 };
|
||||
PixbufPixel pixel = { 255, 20, 20, 255 }, font_pixel = { 255, 255, 255, 200 };
|
||||
|
||||
font = font_new ("Sans Bold 96");
|
||||
|
||||
@ -60,7 +60,9 @@ cltr_list_cell_new(CltrList *list)
|
||||
|
||||
g_snprintf(&buf[0], 24, "%i %i %i", rand()%10, rand()%10, rand()%10);
|
||||
|
||||
font_draw(font, cell->pixb, buf, 10, 10);
|
||||
|
||||
|
||||
font_draw(font, cell->pixb, buf, 10, 10, &font_pixel);
|
||||
|
||||
cell->texture = cltr_texture_new(cell->pixb);
|
||||
|
||||
|
@ -393,6 +393,7 @@ cltr_photo_grid_populate(gpointer data)
|
||||
gchar *fullpath = NULL;
|
||||
int n_pixb = 0, i =0;
|
||||
ClutterFont *font = NULL;
|
||||
PixbufPixel font_col = { 255, 255, 255, 255 };
|
||||
|
||||
font = font_new("Sans Bold 96");
|
||||
|
||||
@ -430,7 +431,7 @@ cltr_photo_grid_populate(gpointer data)
|
||||
cell = cltr_photo_grid_cell_new(grid, pixb, entry);
|
||||
|
||||
g_snprintf(&buf[0], 24, "%i", i);
|
||||
font_draw(font, cell->pixb, buf, 10, 10);
|
||||
font_draw(font, cell->pixb, buf, 10, 10, &font_col);
|
||||
|
||||
g_mutex_lock(Mutex_GRID);
|
||||
|
||||
@ -721,6 +722,7 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
|
||||
if (cell_item == grid->cell_active
|
||||
&& grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
@ -729,8 +731,24 @@ cltr_photo_grid_paint(CltrWidget *widget)
|
||||
|
||||
/* Draw with origin in center of photo */
|
||||
|
||||
/*
|
||||
glRecti(-(thumb_w/2)-4, -(thumb_h/2)-4,
|
||||
(thumb_w/2)+4, (thumb_h/2)+ns_border);
|
||||
*/
|
||||
|
||||
cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4,
|
||||
(thumb_w/2)+4, (thumb_h/2)+ns_border,
|
||||
thumb_w/40,
|
||||
NULL);
|
||||
|
||||
glColor4f(0.1, 0.1, 0.1, 0.5);
|
||||
|
||||
cltr_glu_rounded_rect(-(thumb_w/2)-4, -(thumb_h/2)-4+1,
|
||||
(thumb_w/2)+4, (thumb_h/2)+ns_border+1,
|
||||
thumb_w/40,
|
||||
NULL);
|
||||
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
|
@ -11,6 +11,18 @@ cltr_widget_new(void)
|
||||
return w;
|
||||
}
|
||||
|
||||
int
|
||||
cltr_widget_width(CltrWidget *widget)
|
||||
{
|
||||
return widget->width;
|
||||
}
|
||||
|
||||
int
|
||||
cltr_widget_height(CltrWidget *widget)
|
||||
{
|
||||
return widget->width;
|
||||
}
|
||||
|
||||
void
|
||||
cltr_widget_show(CltrWidget *widget)
|
||||
{
|
||||
|
@ -7,22 +7,24 @@ typedef struct CltrWidget CltrWidget;
|
||||
|
||||
#define CLTR_WIDGET(w) ((CltrWidget*)(w))
|
||||
|
||||
|
||||
CltrWidget*
|
||||
cltr_widget_new(void);
|
||||
|
||||
int
|
||||
cltr_widget_width(CltrWidget *widget);
|
||||
|
||||
int
|
||||
cltr_widget_height(CltrWidget *widget);
|
||||
|
||||
void
|
||||
cltr_widget_show(CltrWidget *widget);
|
||||
|
||||
void
|
||||
cltr_widget_paint(CltrWidget *widget);
|
||||
|
||||
|
||||
gboolean
|
||||
cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev);
|
||||
|
||||
|
||||
|
||||
void
|
||||
cltr_widget_show_all(CltrWidget *widget);
|
||||
|
||||
@ -32,5 +34,4 @@ cltr_widget_queue_paint(CltrWidget *widget);
|
||||
void
|
||||
cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -17,6 +17,19 @@ struct CltrWindow
|
||||
CltrWidget *focused_child;
|
||||
};
|
||||
|
||||
void
|
||||
clrt_window_set_gl_viewport(CltrWindow *win)
|
||||
{
|
||||
CltrWidget *widget = CLTR_WIDGET(win);
|
||||
|
||||
glViewport (0, 0, widget->width, widget->height);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, widget->width, widget->height, 0, -1, 1); /* 2d */
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
}
|
||||
|
||||
CltrWidget*
|
||||
cltr_window_new(int width, int height)
|
||||
{
|
||||
@ -46,16 +59,10 @@ cltr_window_new(int width, int height)
|
||||
|
||||
/* All likely better somewhere else */
|
||||
|
||||
/* view port */
|
||||
glViewport (0, 0, width, height);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
glOrtho (0, width, height, 0, -1, 1); /* 2d */
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
|
||||
ctx->window = CLTR_WIDGET(win);
|
||||
|
||||
clrt_window_set_gl_viewport(win);
|
||||
|
||||
return CLTR_WIDGET(win);
|
||||
}
|
||||
|
||||
@ -83,6 +90,17 @@ cltr_window_paint(CltrWidget *widget)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_window_handle_xconfigure(CltrWindow *win, XConfigureEvent *cxev)
|
||||
{
|
||||
|
||||
/*
|
||||
widget.width = cxev->width;
|
||||
widget.height = cxev->height;
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev)
|
||||
{
|
||||
@ -95,6 +113,11 @@ cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev)
|
||||
cltr_widget_queue_paint(widget);
|
||||
}
|
||||
|
||||
/*
|
||||
case ConfigureNotify:
|
||||
wm_handle_configure_request(w, &ev.xconfigure); break;
|
||||
*/
|
||||
|
||||
/* XXX Very basic - assumes we are only interested in mouse clicks */
|
||||
if (win->focused_child)
|
||||
return cltr_widget_handle_xevent(win->focused_child, xev);
|
||||
@ -110,6 +133,25 @@ cltr_window_xwin(CltrWindow *win)
|
||||
return win->xwin;
|
||||
}
|
||||
|
||||
void
|
||||
cltr_window_set_fullscreen(CltrWindow *win)
|
||||
{
|
||||
ClutterMainContext *ctx = CLTR_CONTEXT();
|
||||
|
||||
Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN;
|
||||
|
||||
atom_WINDOW_STATE
|
||||
= XInternAtom(ctx->xdpy, "_NET_WM_STATE", False);
|
||||
atom_WINDOW_STATE_FULLSCREEN
|
||||
= XInternAtom(ctx->xdpy, "_NET_WM_STATE_FULLSCREEN",False);
|
||||
|
||||
XChangeProperty(ctx->xdpy, win->xwin,
|
||||
atom_WINDOW_STATE, XA_ATOM, 32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
|
||||
}
|
||||
|
||||
|
||||
Window
|
||||
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
|
||||
{
|
||||
@ -118,6 +160,7 @@ cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget)
|
||||
ClutterMainContext *ctx = CLTR_CONTEXT();
|
||||
|
||||
win->focused_child = widget;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,6 +21,9 @@ cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
|
||||
Window
|
||||
cltr_window_xwin(CltrWindow *win);
|
||||
|
||||
void
|
||||
cltr_window_set_fullscreen(CltrWindow *win);
|
||||
|
||||
Window
|
||||
cltr_window_focus_widget(CltrWindow *win, CltrWidget *widget);
|
||||
|
||||
|
75
cltr.c
75
cltr.c
@ -1,41 +1,84 @@
|
||||
#include "cltr.h"
|
||||
|
||||
int
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf(stderr, "Usage ... check source for now\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL;
|
||||
CltrWidget *list;
|
||||
int i;
|
||||
CltrWidget *win = NULL, *grid = NULL, *test = NULL, *test2 = NULL;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
g_printerr("usage: '%s' <path to not too heavily populated image dir>\n"
|
||||
, argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
gchar *img_path = NULL;
|
||||
gboolean want_fullscreen = FALSE;
|
||||
gint cols = 3;
|
||||
|
||||
cltr_init(&argc, &argv);
|
||||
|
||||
win = cltr_window_new(640, 480);
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (!strcmp ("--image-path", argv[i]) || !strcmp ("-i", argv[i]))
|
||||
{
|
||||
if (++i>=argc) usage (argv[0]);
|
||||
img_path = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (!strcmp ("--cols", argv[i]) || !strcmp ("-c", argv[i]))
|
||||
{
|
||||
if (++i>=argc) usage (argv[0]);
|
||||
cols = atoi(argv[i]);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp ("-fs", argv[i]) || !strcmp ("--fullscreen", argv[i]))
|
||||
{
|
||||
want_fullscreen = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i]))
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
grid = cltr_photo_grid_new(640, 480, 4, 4, argv[1]);
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
test = cltr_scratch_new(100, 100);
|
||||
test2 = cltr_scratch_new(150, 150);
|
||||
win = cltr_window_new(800, 600);
|
||||
|
||||
if (want_fullscreen)
|
||||
cltr_window_set_fullscreen(CLTR_WINDOW(win));
|
||||
|
||||
|
||||
grid = cltr_photo_grid_new(800, 600, cols, cols, img_path);
|
||||
|
||||
cltr_window_focus_widget(CLTR_WINDOW(win), grid);
|
||||
|
||||
cltr_widget_add_child(win, grid, 0, 0);
|
||||
|
||||
|
||||
/*
|
||||
test = cltr_scratch_new(300, 100);
|
||||
test2 = cltr_scratch_new(150, 150);
|
||||
|
||||
cltr_widget_add_child(win, test, 400, 240);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
cltr_widget_add_child(win, test, 320, 240);
|
||||
cltr_widget_add_child(win, test2, 400, 300);
|
||||
|
||||
cltr_window_focus_widget(CLTR_WINDOW(win), grid);
|
||||
*/
|
||||
|
||||
list = cltr_list_new(640,480,640, 160);
|
||||
|
||||
cltr_widget_add_child(win, list, 0, 0);
|
||||
|
||||
*/
|
||||
|
||||
|
||||
cltr_widget_show_all(win);
|
||||
|
||||
cltr_main_loop();
|
||||
|
2
cltr.h
2
cltr.h
@ -8,6 +8,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include <GL/glx.h>
|
||||
@ -43,6 +44,7 @@ CltrRect;
|
||||
/* ******************* */
|
||||
|
||||
#include "cltr-core.h"
|
||||
#include "cltr-glu.h"
|
||||
#include "cltr-texture.h"
|
||||
#include "cltr-events.h"
|
||||
#include "cltr-widget.h"
|
||||
|
6
fonts.c
6
fonts.c
@ -146,11 +146,11 @@ font_draw(ClutterFont *font,
|
||||
Pixbuf *pixb,
|
||||
const char *text,
|
||||
int x,
|
||||
int y)
|
||||
int y,
|
||||
PixbufPixel *p)
|
||||
{
|
||||
int layout_width, layout_height;
|
||||
PangoLayout *layout;
|
||||
PixbufPixel p = { 0xff,0xff,0xff,0x80 };
|
||||
|
||||
layout = pango_layout_new (font->context);
|
||||
|
||||
@ -161,7 +161,7 @@ font_draw(ClutterFont *font,
|
||||
|
||||
/* cant rely on just clip - need to set layout width too */
|
||||
|
||||
draw_layout_on_pixbuf (layout, pixb, &p, x, y,
|
||||
draw_layout_on_pixbuf (layout, pixb, p, x, y,
|
||||
x,
|
||||
y,
|
||||
pixb->width - x,
|
||||
|
3
fonts.h
3
fonts.h
@ -25,7 +25,8 @@ font_draw(ClutterFont *font,
|
||||
Pixbuf *pixb,
|
||||
const char *text,
|
||||
int x,
|
||||
int y);
|
||||
int y,
|
||||
PixbufPixel *p);
|
||||
|
||||
|
||||
#endif
|
||||
|
259
pixbuf.c
259
pixbuf.c
@ -458,7 +458,7 @@ pixbuf_new(int width, int height)
|
||||
pixb->bytes_per_line = pixb->bytes_per_pixel * pixb->width;
|
||||
pixb->data = malloc(pixb->bytes_per_line * pixb->height);
|
||||
|
||||
/* memset ? */
|
||||
memset(pixb->data, 0, pixb->bytes_per_line * pixb->height);
|
||||
|
||||
return pixb;
|
||||
}
|
||||
@ -671,3 +671,260 @@ pixbuf_scale_down(Pixbuf *pixb,
|
||||
|
||||
return pixb_scaled;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% %
|
||||
% %
|
||||
% C o n v o l v e I m a g e %
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Method ConvolveImage applies a general image convolution kernel to an
|
||||
% image returns the results. ConvolveImage allocates the memory necessary for
|
||||
% the new Image structure and returns a pointer to the new image.
|
||||
%
|
||||
% The format of the ConvolveImage method is:
|
||||
%
|
||||
% Image *ConvolveImage(Image *image,const unsigned int order,
|
||||
% const double *kernel,ExceptionInfo *exception)
|
||||
%
|
||||
% A description of each parameter follows:
|
||||
%
|
||||
% o convolve_image: Method ConvolveImage returns a pointer to the image
|
||||
% after it is convolved. A null image is returned if there is a memory
|
||||
% shortage.
|
||||
%
|
||||
% o image: The address of a structure of type Image; returned from
|
||||
% ReadImage.
|
||||
%
|
||||
% o order: The number of columns and rows in the filter kernel.
|
||||
%
|
||||
% o kernel: An array of double representing the convolution kernel.
|
||||
%
|
||||
% o exception: return any errors or warnings in this structure.
|
||||
%
|
||||
%
|
||||
*/
|
||||
MagickExport Image *ConvolveImage(Image *image,
|
||||
const unsigned int order,
|
||||
const double *kernel,
|
||||
ExceptionInfo *exception)
|
||||
{
|
||||
#define ConvolveImageText " Convolving image... "
|
||||
#define Cx(x) \
|
||||
(x) < 0 ? (x)+image->columns : (x) >= image->columns ? (x)-image->columns : x
|
||||
#define Cy(y) \
|
||||
(y) < 0 ? (y)+image->rows : (y) >= image->rows ? (y)-image->rows : y
|
||||
|
||||
double
|
||||
blue,
|
||||
green,
|
||||
normalize,
|
||||
opacity,
|
||||
red;
|
||||
|
||||
Image
|
||||
*convolve_image;
|
||||
|
||||
int
|
||||
i,
|
||||
width,
|
||||
y;
|
||||
|
||||
PixelPacket
|
||||
*p,
|
||||
pixel;
|
||||
|
||||
register const double
|
||||
*k;
|
||||
|
||||
register int
|
||||
u,
|
||||
v,
|
||||
x;
|
||||
|
||||
register PixelPacket
|
||||
*q,
|
||||
*s;
|
||||
|
||||
/*
|
||||
Initialize convolved image attributes.
|
||||
*/
|
||||
assert(image != (Image *) NULL);
|
||||
assert(image->signature == MagickSignature);
|
||||
assert(exception != (ExceptionInfo *) NULL);
|
||||
assert(exception->signature == MagickSignature);
|
||||
width=order;
|
||||
if ((width % 2) == 0)
|
||||
ThrowImageException(OptionWarning,"Unable to convolve image",
|
||||
"kernel width must be an odd number");
|
||||
if ((image->columns < width) || (image->rows < width))
|
||||
ThrowImageException(OptionWarning,"Unable to convolve image",
|
||||
"image smaller than kernel width");
|
||||
convolve_image=CloneImage(image,image->columns,image->rows,False,exception);
|
||||
if (convolve_image == (Image *) NULL)
|
||||
return((Image *) NULL);
|
||||
convolve_image->storage_class=DirectClass;
|
||||
/*
|
||||
Convolve image.
|
||||
*/
|
||||
normalize=0.0;
|
||||
for (i=0; i < (width*width); i++)
|
||||
normalize+=kernel[i];
|
||||
for (y=0; y < (int) convolve_image->rows; y++)
|
||||
{
|
||||
p=(PixelPacket *) NULL;
|
||||
q=SetImagePixels(convolve_image,0,y,convolve_image->columns,1);
|
||||
if (q == (PixelPacket *) NULL)
|
||||
break;
|
||||
for (x=0; x < (int) convolve_image->columns; x++)
|
||||
{
|
||||
red=0.0;
|
||||
green=0.0;
|
||||
blue=0.0;
|
||||
opacity=0.0;
|
||||
k=kernel;
|
||||
if ((x < (width/2)) || (x >= (int) (image->columns-width/2)) ||
|
||||
(y < (width/2)) || (y >= (int) (image->rows-width/2)))
|
||||
{
|
||||
for (v=(-width/2); v <= (width/2); v++)
|
||||
{
|
||||
for (u=(-width/2); u <= (width/2); u++)
|
||||
{
|
||||
pixel=GetOnePixel(image,Cx(x+u),Cy(y+v));
|
||||
red+=(*k)*pixel.red;
|
||||
green+=(*k)*pixel.green;
|
||||
blue+=(*k)*pixel.blue;
|
||||
opacity+=(*k)*pixel.opacity;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p == (PixelPacket *) NULL)
|
||||
{
|
||||
p=GetImagePixels(image,0,y-width/2,image->columns,width);
|
||||
if (p == (PixelPacket *) NULL)
|
||||
break;
|
||||
}
|
||||
s=p+x;
|
||||
for (v=(-width/2); v <= (width/2); v++)
|
||||
{
|
||||
for (u=(-width/2); u <= (width/2); u++)
|
||||
{
|
||||
red+=(*k)*s[u].red;
|
||||
green+=(*k)*s[u].green;
|
||||
blue+=(*k)*s[u].blue;
|
||||
opacity+=(*k)*s[u].opacity;
|
||||
k++;
|
||||
}
|
||||
s+=image->columns;
|
||||
}
|
||||
}
|
||||
if ((normalize != 0.0) && (normalize != 1.0))
|
||||
{
|
||||
red/=normalize;
|
||||
green/=normalize;
|
||||
blue/=normalize;
|
||||
opacity/=normalize;
|
||||
}
|
||||
q->red=(Quantum) ((red < 0) ? 0 : (red > MaxRGB) ? MaxRGB : red+0.5);
|
||||
q->green=(Quantum)
|
||||
((green < 0) ? 0 : (green > MaxRGB) ? MaxRGB : green+0.5);
|
||||
q->blue=(Quantum) ((blue < 0) ? 0 : (blue > MaxRGB) ? MaxRGB : blue+0.5);
|
||||
q->opacity=(Quantum)
|
||||
((opacity < 0) ? 0 : (opacity > MaxRGB) ? MaxRGB : opacity+0.5);
|
||||
q++;
|
||||
}
|
||||
if (!SyncImagePixels(convolve_image))
|
||||
break;
|
||||
if (QuantumTick(y,convolve_image->rows))
|
||||
MagickMonitor(ConvolveImageText,y,convolve_image->rows);
|
||||
}
|
||||
return(convolve_image);
|
||||
}
|
||||
|
||||
/*
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% %
|
||||
% %
|
||||
% G a u s s i a n B l u r I m a g e %
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% Method GaussianBlurImage creates a new image that is a copy of an existing
|
||||
% one with the pixels blur. It allocates the memory necessary for the
|
||||
% new Image structure and returns a pointer to the new image.
|
||||
%
|
||||
% The format of the BlurImage method is:
|
||||
%
|
||||
% Image *GaussianBlurImage(Image *image,const double radius,
|
||||
% const double sigma,ExceptionInfo *exception)
|
||||
%
|
||||
% A description of each parameter follows:
|
||||
%
|
||||
% o blur_image: Method GaussianBlurImage returns a pointer to the image
|
||||
% after it is blur. A null image is returned if there is a memory
|
||||
% shortage.
|
||||
%
|
||||
% o radius: the radius of the Gaussian, in pixels, not counting the center
|
||||
% pixel.
|
||||
%
|
||||
% o sigma: the standard deviation of the Gaussian, in pixels.
|
||||
%
|
||||
% o exception: return any errors or warnings in this structure.
|
||||
%
|
||||
%
|
||||
*/
|
||||
MagickExport Image *GaussianBlurImage(Image *image,const double radius,
|
||||
const double sigma,ExceptionInfo *exception)
|
||||
{
|
||||
double
|
||||
*kernel;
|
||||
|
||||
Image
|
||||
*blur_image;
|
||||
|
||||
int
|
||||
width;
|
||||
|
||||
register int
|
||||
i,
|
||||
u,
|
||||
v;
|
||||
|
||||
assert(image != (Image *) NULL);
|
||||
assert(image->signature == MagickSignature);
|
||||
assert(exception != (ExceptionInfo *) NULL);
|
||||
assert(exception->signature == MagickSignature);
|
||||
width=GetOptimalKernelWidth2D(radius,sigma);
|
||||
if ((image->columns < width) || (image->rows < width))
|
||||
ThrowImageException(OptionWarning,"Unable to Gaussian blur image",
|
||||
"image is smaller than radius");
|
||||
kernel=(double *) AcquireMemory(width*width*sizeof(double));
|
||||
if (kernel == (double *) NULL)
|
||||
ThrowImageException(ResourceLimitWarning,"Unable to Gaussian blur image",
|
||||
"Memory allocation failed");
|
||||
i=0;
|
||||
for (v=(-width/2); v <= (width/2); v++)
|
||||
{
|
||||
for (u=(-width/2); u <= (width/2); u++)
|
||||
{
|
||||
kernel[i]=exp((double) -(u*u+v*v)/(sigma*sigma));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
blur_image=ConvolveImage(image,width,kernel,exception);
|
||||
LiberateMemory((void **) &kernel);
|
||||
return(blur_image);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user