From 6da3752815ae0393a0c9330988144f5a9eb0537c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 7 Feb 2014 17:42:11 +0000 Subject: [PATCH] im_draw_line() is a wrapper --- libvips/deprecated/vips7compat.c | 23 ++ libvips/draw/Makefile.am | 2 +- libvips/draw/draw.c | 2 + libvips/draw/im_draw_line.c | 376 ------------------------------- libvips/draw/linemask.c | 34 +-- 5 files changed, 31 insertions(+), 406 deletions(-) delete mode 100644 libvips/draw/im_draw_line.c diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 84a4a7c1..f84b8087 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -4537,6 +4537,29 @@ im_draw_circle( VipsImage *image, NULL ) ); } +int +im_draw_line( VipsImage *image, int x1, int y1, int x2, int y2, VipsPel *ink ) +{ + double *vec; + int n; + + if( !(vec = vips__ink_to_vector( "im_draw_line", image, ink, &n )) ) + return( -1 ); + + return( vips_line( image, vec, n, x1, y1, x2, y2, NULL ) ); +} + +int +im_draw_line_user( VipsImage *image, + int x1, int y1, int x2, int y2, + VipsPlotFn plot, void *a, void *b, void *c ) +{ + im_error( "im_draw_line_user", + "not supported ... use a VipsLine subclass instead, " + "or vips_line_mask()" ); + return( -1 ); +} + int im_draw_mask( VipsImage *image, VipsImage *mask_im, int x, int y, VipsPel *ink ) { diff --git a/libvips/draw/Makefile.am b/libvips/draw/Makefile.am index 91f6fb6d..ab5486bc 100644 --- a/libvips/draw/Makefile.am +++ b/libvips/draw/Makefile.am @@ -7,8 +7,8 @@ libdraw_la_SOURCES = \ draw.c \ flood.c \ paintmask.c \ + linemask.c \ im_draw_image.c \ - im_draw_line.c \ im_draw_point.c \ im_draw_rect.c \ im_draw_smudge.c \ diff --git a/libvips/draw/draw.c b/libvips/draw/draw.c index efa0ea38..76eb2ea7 100644 --- a/libvips/draw/draw.c +++ b/libvips/draw/draw.c @@ -131,11 +131,13 @@ vips_draw_operation_init( void ) { extern GType vips_paintmask_get_type( void ); extern GType vips_line_get_type( void ); + extern GType vips_line_mask_get_type( void ); extern GType vips_circle_get_type( void ); extern GType vips_flood_get_type( void ); vips_paintmask_get_type(); vips_line_get_type(); + vips_line_mask_get_type(); vips_circle_get_type(); vips_flood_get_type(); } diff --git a/libvips/draw/im_draw_line.c b/libvips/draw/im_draw_line.c deleted file mode 100644 index 359892bd..00000000 --- a/libvips/draw/im_draw_line.c +++ /dev/null @@ -1,376 +0,0 @@ -/* draw straight lines - * - * Copyright: J. Cupitt - * Written: 15/06/1992 - * Modified : 22/10/92 - clipping constraints changed - * 22/7/93 JC - * - im_incheck() added - * 16/8/94 JC - * - im_incheck() changed to im_makerw() - * 5/12/06 - * - im_invalidate() after paint - * 1/3/10 - * - oops, lineset needs to ask for WIO of mask and ink - * 6/3/10 - * - don't im_invalidate() after paint, this now needs to be at a higher - * level - * 27/9/10 - * - gtk-doc - * - use draw.c base class - * - do pointwise clipping - * - rename as im_draw_line() for consistency - * - cleanups! - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include - -#include - -#include "old_draw.h" - -typedef struct _Line { - Draw draw; - - int x1, y1; - int x2, y2; - - int dx; - int dy; - - VipsPlotFn plot; - void *a; - void *b; - void *c; -} Line; - -static void -line_free( Line *line ) -{ - im__draw_free( DRAW( line ) ); - im_free( line ); -} - -static Line * -line_new( VipsImage *im, int x1, int y1, int x2, int y2, VipsPel *ink ) -{ - Line *line; - - if( !(line = IM_NEW( NULL, Line )) ) - return( NULL ); - if( !im__draw_init( DRAW( line ), im, ink ) ) { - line_free( line ); - return( NULL ); - } - - /* Find offsets. - */ - line->dx = x2 - x1; - line->dy = y2 - y1; - - /* Swap endpoints to reduce number of cases. - */ - if( abs( line->dx ) >= abs( line->dy ) && line->dx < 0 ) { - /* Swap to get all x greater or equal cases going to the - * right. Do diagonals here .. just have up and right and down - * and right now. - */ - IM_SWAP( int, x1, x2 ); - IM_SWAP( int, y1, y2 ); - } - else if( abs( line->dx ) < abs( line->dy ) && line->dy < 0 ) { - /* Swap to get all y greater cases going down the screen. - */ - IM_SWAP( int, x1, x2 ); - IM_SWAP( int, y1, y2 ); - } - - /* Recalculate dx, dy. - */ - line->dx = x2 - x1; - line->dy = y2 - y1; - - line->x1 = x1; - line->y1 = y1; - line->x2 = x2; - line->y2 = y2; - - line->plot = NULL; - line->a = NULL; - line->b = NULL; - line->c = NULL; - - if( x1 < im->Xsize && x1 >= 0 && - x2 < im->Xsize && x2 >= 0 && - y1 < im->Ysize && y1 >= 0 && - y2 < im->Ysize && y2 >= 0 ) - DRAW( line )->noclip = TRUE; - - return( line ); -} - -static inline int -line_plot( Line *line, int x, int y ) -{ - return( line->plot( DRAW( line )->im, x, y, - line->a, line->b, line->c ) ); -} - -static int -line_draw( Line *line ) -{ - int x, y, err; - - /* Start point and offset. - */ - x = line->x1; - y = line->y1; - - /* Special case: zero width and height is single point. - */ - if( line->dx == 0 && line->dy == 0 ) { - if( line_plot( line, x, y ) ) - return( -1 ); - } - /* Special case vertical and horizontal lines for speed. - */ - else if( line->dx == 0 ) { - /* Vertical line going down. - */ - for( ; y <= line->y2; y++ ) { - if( line_plot( line, x, y ) ) - return( -1 ); - } - } - else if( line->dy == 0 ) { - /* Horizontal line to the right. - */ - for( ; x <= line->x2; x++ ) { - if( line_plot( line, x, y ) ) - return( -1 ); - } - } - /* Special case diagonal lines. - */ - else if( abs( line->dy ) == abs( line->dx ) && line->dy > 0 ) { - /* Diagonal line going down and right. - */ - for( ; x <= line->x2; x++, y++ ) { - if( line_plot( line, x, y ) ) - return( -1 ); - } - } - else if( abs( line->dy ) == abs( line->dx ) && line->dy < 0 ) { - /* Diagonal line going up and right. - */ - for( ; x <= line->x2; x++, y-- ) { - if( line_plot( line, x, y ) ) - return( -1 ); - } - } - else if( abs( line->dy ) < abs( line->dx ) && line->dy > 0 ) { - /* Between -45 and 0 degrees. - */ - for( err = 0; x <= line->x2; x++ ) { - if( line_plot( line, x, y ) ) - return( -1 ); - - err += line->dy; - if( err >= line->dx ) { - err -= line->dx; - y++; - } - } - } - else if( abs( line->dy ) < abs( line->dx ) && line->dy < 0 ) { - /* Between 0 and 45 degrees. - */ - for( err = 0; x <= line->x2; x++ ) { - if( line_plot( line, x, y ) ) - return( -1 ); - - err -= line->dy; - if( err >= line->dx ) { - err -= line->dx; - y--; - } - } - } - else if( abs( line->dy ) > abs( line->dx ) && line->dx > 0 ) { - /* Between -45 and -90 degrees. - */ - for( err = 0; y <= line->y2; y++ ) { - if( line_plot( line, x, y ) ) - return( -1 ); - - err += line->dx; - if( err >= line->dy ) { - err -= line->dy; - x++; - } - } - } - else if( abs( line->dy ) > abs( line->dx ) && line->dx < 0 ) { - /* Between -90 and -135 degrees. - */ - for( err = 0; y <= line->y2; y++ ) { - if( line_plot( line, x, y ) ) - return( -1 ); - - err -= line->dx; - if( err >= line->dy ) { - err -= line->dy; - x--; - } - } - } - else - g_assert( 0 ); - - return( 0 ); -} - -/** - * VipsPlotFn: - * @image: image to draw on - * @x: position to draw at - * @y: position to draw at - * @a: user data - * @b: user data - * @c: user data - * - * A plot function, as used by im_draw_line_user() to draw on an image. - */ - -/** - * im_draw_line_user: - * @image: image to draw on - * @x1: start point - * @y1: start point - * @x2: end point - * @y2: end point - * @plot: draw operation - * @a: draw operation parameter - * @b: draw operation parameter - * @c: draw operation parameter - * - * Calls @plot for every point on the line connecting @x1, @y1 and @x2, @y2. - * If you pass im_draw_mask() as the plot operation, you can draw wide lines - * or lines with various brushes. - * - * See also: im_draw_mask(), im_draw_line(), im_draw_circle(). - * - * Returns: 0 on success, or -1 on error. - */ -int -im_draw_line_user( VipsImage *image, - int x1, int y1, int x2, int y2, - VipsPlotFn plot, void *a, void *b, void *c ) -{ - Line *line; - - if( im_check_coding_known( "im_draw_line_user", image ) || - !(line = line_new( image, x1, y1, x2, y2, NULL )) ) - return( -1 ); - - line->plot = plot; - line->a = a; - line->b = b; - line->c = c; - - if( line_draw( line ) ) { - line_free( line ); - return( -1 ); - } - line_free( line ); - - return( 0 ); -} - -static int -line_plot_point( VipsImage *im, int x, int y, - void *a, void *b, void *c ) -{ - Draw *draw = (Draw *) a; - - if( draw->noclip ) - im__draw_pel( draw, IM_IMAGE_ADDR( draw->im, x, y ) ); - else - im__draw_pel_clip( draw, x, y ); - - return( 0 ); -} - -/** - * im_draw_line: - * @image: image to draw on - * @x1: start point - * @y1: start point - * @x2: end point - * @y2: end point - * @ink: value to draw - * - * Draws a 1-pixel-wide line on an image. - * - * @ink is an array of bytes - * containing a valid pixel for the image's format. - * It must have at least IM_IMAGE_SIZEOF_PEL( @image ) bytes. - * - * See also: im_draw_circle(). - * - * Returns: 0 on success, or -1 on error. - */ -int -im_draw_line( VipsImage *image, int x1, int y1, int x2, int y2, VipsPel *ink ) -{ - Line *line; - - if( im_check_coding_known( "im_draw_line", image ) || - !(line = line_new( image, x1, y1, x2, y2, ink )) ) - return( -1 ); - - line->plot = line_plot_point; - line->a = line; - - if( line_draw( line ) ) { - line_free( line ); - return( 0 ); - } - - line_free( line ); - - return( 0 ); -} - diff --git a/libvips/draw/linemask.c b/libvips/draw/linemask.c index dfa36b52..844c57c8 100644 --- a/libvips/draw/linemask.c +++ b/libvips/draw/linemask.c @@ -74,41 +74,18 @@ typedef VipsLineClass VipsLineMaskClass; G_DEFINE_TYPE( VipsLineMask, vips_line_mask, VIPS_TYPE_LINE ); -static int -vips_line_mask_build( VipsObject *object ) -{ - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); - VipsDraw *draw = VIPS_DRAW( object ); - VipsLine *line = (VipsLine *) object; - - if( VIPS_OBJECT_CLASS( vips_line_mask_parent_class )->build( object ) ) - return( -1 ); - - if( vips_check_coding_noneorlabq( class->nickname, draw->image ) || - im_incheck( mask_im ) || - vips_check_mono( class->nickname, mask_im ) || - vips_check_uncoded( class->nickname, mask_im ) || - vips_check_format( class->nickname, mask_im, VIPS_FORMAT_UCHAR ) || - return( NULL ); - - return( 0 ); -} - static int vips_line_mask_plot_point( VipsLine *line, int x, int y ) { VipsDraw *draw = (VipsDraw *) line; + VipsLineMask *line_mask = (VipsLineMask *) line; - if( draw->noclip ) - vips__draw_pel( draw, VIPS_IMAGE_ADDR( draw->image, x, y ) ); - else - vips__draw_pel_clip( draw, x, y ); - - return( 0 ); + return( vips_paintmask( draw->image, + draw->ink->data, draw->ink->n, line_mask->mask, x, y, NULL ) ); } static void -vips_line_mask_class_init( VipsLineClass *class ) +vips_line_mask_class_init( VipsLineMaskClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); @@ -118,7 +95,6 @@ vips_line_mask_class_init( VipsLineClass *class ) vobject_class->nickname = "line_mask"; vobject_class->description = _( "draw a mask along a line" ); - vobject_class->build = vips_line_mask_build; class->plot_point = vips_line_mask_plot_point; @@ -131,7 +107,7 @@ vips_line_mask_class_init( VipsLineClass *class ) } static void -vips_line_mask_init( VipsLine *line ) +vips_line_mask_init( VipsLineMask *line_mask ) { }