1 /* base class for drawing operations
2  *
3  * 27/9/10
4  *	- from im_draw_circle()
5  * 17/11/10
6  * 	- oops, scanline clipping was off by 1
7  */
8 
9 /*
10 
11     This file is part of VIPS.
12 
13     VIPS is free software; you can redistribute it and/or modify
14     it under the terms of the GNU Lesser General Public License as published by
15     the Free Software Foundation; either version 2 of the License, or
16     (at your option) any later version.
17 
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU Lesser General Public License for more details.
22 
23     You should have received a copy of the GNU Lesser General Public License
24     along with this program; if not, write to the Free Software
25     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26     02110-1301  USA
27 
28  */
29 
30 /*
31 
32     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
33 
34  */
35 
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif /*HAVE_CONFIG_H*/
39 #include <vips/intl.h>
40 
41 #include <string.h>
42 
43 #include <vips/vips.h>
44 #include <vips/internal.h>
45 
46 #include "pdraw.h"
47 
48 /**
49  * SECTION: draw
50  * @short_description: drawing operations: flood, paste, line, circle
51  * @stability: Stable
52  * @include: vips/vips.h
53  *
54  * These operations directly modify the image. They do not thread, on 32-bit
55  * machines they will be limited to 2GB images, and a little care needs to be
56  * taken if you use them as part of an image pipeline.
57  * They are mostly supposed to be useful for paintbox-style programs.
58  *
59  * libvips operations are all functional: they take zero or more existing input
60  * images and generate zero or more new output images. Images are
61  * never altered, you always create new images. This means libvips can cache
62  * and thread very agressively.
63  *
64  * The downside is that creating entirely fresh images each time can be very
65  * slow. libvips has a range of tricks to avoid these problems, but there are
66  * still times when you really have to be able to modify an image. An example
67  * might be drawing a curved line from a set of straight line segments: if you
68  * need to draw 1,000 straight lines, a 1,000 operation-deep pipeline is going
69  * to be a slow way to do it. This is where the draw operations come in.
70  *
71  * To use these operations, use vips_copy() to make a copy of the image you
72  * want to modify to ensure that no one else is using it, then call a
73  * series of draw operations.
74  * Once you are done drawing, return to normal use of vips operations. Any time
75  * you want to start drawing again, you'll need to copy again.
76  */
77 
78 /**
79  * VipsCombineMode:
80  * @VIPS_COMBINE_MODE_SET: set pixels to the new value
81  * @VIPS_COMBINE_MODE_ADD: add pixels
82  *
83  * See vips_draw_image() and so on.
84  *
85  * Operations like vips_draw_image() need to be told how to combine images
86  * from two sources.
87  *
88  * See also: vips_join().
89  */
90 
91 G_DEFINE_ABSTRACT_TYPE( VipsDraw, vips_draw, VIPS_TYPE_OPERATION );
92 
93 static int
vips_draw_build(VipsObject * object)94 vips_draw_build( VipsObject *object )
95 {
96 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
97 	VipsDraw *draw = VIPS_DRAW( object );
98 
99 #ifdef DEBUG
100 	printf( "vips_draw_build: " );
101 	vips_object_print_name( object );
102 	printf( "\n" );
103 #endif /*DEBUG*/
104 
105 	if( VIPS_OBJECT_CLASS( vips_draw_parent_class )->build( object ) )
106 		return( -1 );
107 
108 	if( vips_check_coding_known( class->nickname, draw->image ) ||
109 		vips_image_inplace( draw->image ) )
110 		return( -1 );
111 
112 	draw->lsize = VIPS_IMAGE_SIZEOF_LINE( draw->image );
113 	draw->psize = VIPS_IMAGE_SIZEOF_PEL( draw->image );
114 	draw->noclip = FALSE;
115 
116 	return( 0 );
117 }
118 
119 static void
vips_draw_class_init(VipsDrawClass * class)120 vips_draw_class_init( VipsDrawClass *class )
121 {
122 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
123 	VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
124 
125 	gobject_class->set_property = vips_object_set_property;
126 	gobject_class->get_property = vips_object_get_property;
127 
128 	vobject_class->nickname = "draw";
129 	vobject_class->description = _( "draw operations" );
130 	vobject_class->build = vips_draw_build;
131 
132 	VIPS_ARG_IMAGE( class, "image", 1,
133 		_( "Image" ),
134 		_( "Image to draw on" ),
135 		VIPS_ARGUMENT_REQUIRED_INPUT | VIPS_ARGUMENT_MODIFY,
136 		G_STRUCT_OFFSET( VipsDraw, image ) );
137 
138 }
139 
140 static void
vips_draw_init(VipsDraw * draw)141 vips_draw_init( VipsDraw *draw )
142 {
143 }
144 
145 void
vips_draw_operation_init(void)146 vips_draw_operation_init( void )
147 {
148 	extern GType vips_draw_rect_get_type( void );
149 	extern GType vips_draw_image_get_type( void );
150 	extern GType vips_draw_mask_get_type( void );
151 	extern GType vips_draw_line_get_type( void );
152 	extern GType vips_draw_circle_get_type( void );
153 	extern GType vips_draw_flood_get_type( void );
154 	extern GType vips_draw_smudge_get_type( void );
155 
156 	vips_draw_rect_get_type();
157 	vips_draw_image_get_type();
158 	vips_draw_mask_get_type();
159 	vips_draw_line_get_type();
160 	vips_draw_circle_get_type();
161 	vips_draw_flood_get_type();
162 	vips_draw_smudge_get_type();
163 }
164 
165