1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
41 #include "precomp.hpp"
46 enum { XY_SHIFT = 16, XY_ONE = 1 << XY_SHIFT, DRAWING_STORAGE_BLOCK = (1<<12) - 256 };
50 PolyEdge() : y0(0), y1(0), x(0), dx(0), next(0) {}
51 //PolyEdge(int _y0, int _y1, int _x, int _dx) : y0(_y0), y1(_y1), x(_x), dx(_dx) {}
59 CollectPolyEdges( Mat& img, const Point* v, int npts,
60 vector<PolyEdge>& edges, const void* color, int line_type,
61 int shift, Point offset=Point() );
64 FillEdgeCollection( Mat& img, vector<PolyEdge>& edges, const void* color );
67 PolyLine( Mat& img, const Point* v, int npts, bool closed,
68 const void* color, int thickness, int line_type, int shift );
71 FillConvexPoly( Mat& img, const Point* v, int npts,
72 const void* color, int line_type, int shift );
74 /****************************************************************************************\
76 \****************************************************************************************/
78 bool clipLine( Size img_size, Point& pt1, Point& pt2 )
82 int64 right = img_size.width-1, bottom = img_size.height-1;
84 if( img_size.width <= 0 || img_size.height <= 0 )
87 x1 = pt1.x; y1 = pt1.y; x2 = pt2.x; y2 = pt2.y;
88 c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8;
89 c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8;
91 if( (c1 & c2) == 0 && (c1 | c2) != 0 )
96 a = c1 < 8 ? 0 : bottom;
97 x1 += (a - y1) * (x2 - x1) / (y2 - y1);
99 c1 = (x1 < 0) + (x1 > right) * 2;
103 a = c2 < 8 ? 0 : bottom;
104 x2 += (a - y2) * (x2 - x1) / (y2 - y1);
106 c2 = (x2 < 0) + (x2 > right) * 2;
108 if( (c1 & c2) == 0 && (c1 | c2) != 0 )
112 a = c1 == 1 ? 0 : right;
113 y1 += (a - x1) * (y2 - y1) / (x2 - x1);
119 a = c2 == 1 ? 0 : right;
120 y2 += (a - x2) * (y2 - y1) / (x2 - x1);
126 assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 );
134 return (c1 | c2) == 0;
137 bool clipLine( Rect img_rect, Point& pt1, Point& pt2 )
139 Point tl = img_rect.tl();
140 pt1 -= tl; pt2 -= tl;
141 bool inside = clipLine(img_rect.size(), pt1, pt2);
142 pt1 += tl; pt2 += tl;
148 Initializes line iterator.
149 Returns number of points on the line or negative number if error.
151 LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
152 int connectivity, bool left_to_right)
156 CV_Assert( connectivity == 8 || connectivity == 4 );
158 if( (unsigned)pt1.x >= (unsigned)(img.cols) ||
159 (unsigned)pt2.x >= (unsigned)(img.cols) ||
160 (unsigned)pt1.y >= (unsigned)(img.rows) ||
161 (unsigned)pt2.y >= (unsigned)(img.rows) )
163 if( !clipLine( img.size(), pt1, pt2 ) )
166 err = plusDelta = minusDelta = plusStep = minusStep = count = 0;
171 int bt_pix0 = (int)img.elemSize(), bt_pix = bt_pix0;
172 size_t istep = img.step;
174 int dx = pt2.x - pt1.x;
175 int dy = pt2.y - pt1.y;
176 int s = dx < 0 ? -1 : 0;
182 pt1.x ^= (pt1.x ^ pt2.x) & s;
183 pt1.y ^= (pt1.y ^ pt2.y) & s;
188 bt_pix = (bt_pix ^ s) - s;
191 ptr = (uchar*)(img.data + pt1.y * istep + pt1.x * bt_pix0);
195 istep = (istep ^ s) - s;
197 s = dy > dx ? -1 : 0;
199 /* conditional swaps */
208 if( connectivity == 8 )
210 assert( dx >= 0 && dy >= 0 );
212 err = dx - (dy + dy);
214 minusDelta = -(dy + dy);
215 plusStep = (int)istep;
219 else /* connectivity == 4 */
221 assert( dx >= 0 && dy >= 0 );
224 plusDelta = (dx + dx) + (dy + dy);
225 minusDelta = -(dy + dy);
226 plusStep = (int)istep - bt_pix;
231 this->ptr0 = img.data;
232 this->step = (int)img.step;
233 this->elemSize = bt_pix0;
237 Line( Mat& img, Point pt1, Point pt2,
238 const void* _color, int connectivity = 8 )
240 if( connectivity == 0 )
242 if( connectivity == 1 )
245 LineIterator iterator(img, pt1, pt2, connectivity, true);
246 int i, count = iterator.count;
247 int pix_size = (int)img.elemSize();
248 const uchar* color = (const uchar*)_color;
250 for( i = 0; i < count; i++, ++iterator )
252 uchar* ptr = *iterator;
255 else if( pix_size == 3 )
262 memcpy( *iterator, color, pix_size );
267 /* Correction table depent on the slope */
268 static const uchar SlopeCorrTable[] = {
269 181, 181, 181, 182, 182, 183, 184, 185, 187, 188, 190, 192, 194, 196, 198, 201,
270 203, 206, 209, 211, 214, 218, 221, 224, 227, 231, 235, 238, 242, 246, 250, 254
273 /* Gaussian for antialiasing filter */
274 static const int FilterTable[] = {
275 168, 177, 185, 194, 202, 210, 218, 224, 231, 236, 241, 246, 249, 252, 254, 254,
276 254, 254, 252, 249, 246, 241, 236, 231, 224, 218, 210, 202, 194, 185, 177, 168,
277 158, 149, 140, 131, 122, 114, 105, 97, 89, 82, 75, 68, 62, 56, 50, 45,
278 40, 36, 32, 28, 25, 22, 19, 16, 14, 12, 11, 9, 8, 7, 5, 5
282 LineAA( Mat& img, Point pt1, Point pt2, const void* color )
285 int ecount, scount = 0;
291 int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2];
293 int nch = img.channels();
294 uchar* ptr = img.data;
295 size_t step = img.step;
296 Size size = img.size();
298 if( !((nch == 1 || nch == 3) && img.depth() == CV_8U) )
300 Line(img, pt1, pt2, color);
308 ptr += img.step*2 + 2*nch;
310 size.width = ((size.width - 5) << XY_SHIFT) + 1;
311 size.height = ((size.height - 5) << XY_SHIFT) + 1;
313 if( !clipLine( size, pt1, pt2 ))
336 y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
338 ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT);
339 j = -(pt1.x & (XY_ONE - 1));
340 pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
341 slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;
342 slope ^= (y_step < 0 ? 0x3f : 0);
344 /* Get 4-bit fractions for end-point adjustments */
345 i = (pt1.x >> (XY_SHIFT - 7)) & 0x78;
346 j = (pt2.x >> (XY_SHIFT - 7)) & 0x78;
359 x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
362 ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT);
363 j = -(pt1.y & (XY_ONE - 1));
364 pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
365 slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;
366 slope ^= (x_step < 0 ? 0x3f : 0);
368 /* Get 4-bit fractions for end-point adjustments */
369 i = (pt1.y >> (XY_SHIFT - 7)) & 0x78;
370 j = (pt2.y >> (XY_SHIFT - 7)) & 0x78;
373 slope = (slope & 0x20) ? 0x100 : SlopeCorrTable[slope];
375 /* Calc end point correction table */
378 int t1 = ((0x78 - i) | 4) * slope;
379 int t2 = (j | 4) * slope;
383 ep_table[1] = ep_table[3] = ((((j - i) & 0x78) | 4) * slope >> 8) & 0x1ff;
384 ep_table[2] = (t1 >> 8) & 0x1ff;
385 ep_table[4] = ((((j - i) + 0x80) | 4) * slope >> 8) & 0x1ff;
386 ep_table[5] = ((t1 + t0) >> 8) & 0x1ff;
387 ep_table[6] = (t2 >> 8) & 0x1ff;
388 ep_table[7] = ((t2 + t0) >> 8) & 0x1ff;
393 #define ICV_PUT_POINT() \
396 _cb += ((cb - _cb)*a + 127)>> 8;\
398 _cg += ((cg - _cg)*a + 127)>> 8;\
400 _cr += ((cr - _cr)*a + 127)>> 8;\
401 tptr[0] = (uchar)_cb; \
402 tptr[1] = (uchar)_cg; \
403 tptr[2] = (uchar)_cr; \
407 ptr += (pt1.x >> XY_SHIFT) * 3;
411 uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
413 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
414 (((ecount >= 2) + 1) & (ecount | 2))];
415 int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
417 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
422 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
427 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
439 ptr += (pt1.y >> XY_SHIFT) * step;
443 uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3;
445 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
446 (((ecount >= 2) + 1) & (ecount | 2))];
447 int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
449 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
454 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
459 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
473 #define ICV_PUT_POINT() \
476 _cb += ((cb - _cb)*a + 127)>> 8;\
477 tptr[0] = (uchar)_cb; \
482 ptr += (pt1.x >> XY_SHIFT);
486 uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
488 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
489 (((ecount >= 2) + 1) & (ecount | 2))];
490 int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
492 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
497 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
502 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
514 ptr += (pt1.y >> XY_SHIFT) * step;
518 uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1);
520 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
521 (((ecount >= 2) + 1) & (ecount | 2))];
522 int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
524 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
529 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
534 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
550 Line2( Mat& img, Point pt1, Point pt2, const void* color )
557 int cb = ((uchar*)color)[0];
558 int cg = ((uchar*)color)[1];
559 int cr = ((uchar*)color)[2];
560 int pix_size = (int)img.elemSize();
561 uchar *ptr = img.data, *tptr;
562 size_t step = img.step;
563 Size size = img.size(), sizeScaled(size.width*XY_ONE, size.height*XY_ONE);
565 //assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U );
567 if( !clipLine( sizeScaled, pt1, pt2 ))
590 y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
591 ecount = (pt2.x - pt1.x) >> XY_SHIFT;
604 x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
606 ecount = (pt2.y - pt1.y) >> XY_SHIFT;
609 pt1.x += (XY_ONE >> 1);
610 pt1.y += (XY_ONE >> 1);
614 #define ICV_PUT_POINT(_x,_y) \
615 x = (_x); y = (_y); \
616 if( 0 <= x && x < size.width && \
617 0 <= y && y < size.height ) \
619 tptr = ptr + y*step + x*3; \
620 tptr[0] = (uchar)cb; \
621 tptr[1] = (uchar)cg; \
622 tptr[2] = (uchar)cr; \
625 ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
626 (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
634 ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
646 ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
655 else if( pix_size == 1 )
657 #define ICV_PUT_POINT(_x,_y) \
658 x = (_x); y = (_y); \
659 if( 0 <= x && x < size.width && \
660 0 <= y && y < size.height ) \
662 tptr = ptr + y*step + x;\
663 tptr[0] = (uchar)cb; \
666 ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
667 (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
675 ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
687 ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
698 #define ICV_PUT_POINT(_x,_y) \
699 x = (_x); y = (_y); \
700 if( 0 <= x && x < size.width && \
701 0 <= y && y < size.height ) \
703 tptr = ptr + y*step + x*pix_size;\
704 for( j = 0; j < pix_size; j++ ) \
705 tptr[j] = ((uchar*)color)[j]; \
708 ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT,
709 (pt2.y + (XY_ONE >> 1)) >> XY_SHIFT);
717 ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT);
729 ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y);
741 /****************************************************************************************\
742 * Antialiazed Elliptic Arcs via Antialiazed Lines *
743 \****************************************************************************************/
745 static const float SinTable[] =
746 { 0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
747 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
748 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
749 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
750 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
751 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
752 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
753 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
754 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
755 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
756 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
757 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
758 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
759 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
760 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
761 1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f,
762 0.9945219f, 0.9925462f, 0.9902681f, 0.9876883f, 0.9848078f, 0.9816272f,
763 0.9781476f, 0.9743701f, 0.9702957f, 0.9659258f, 0.9612617f, 0.9563048f,
764 0.9510565f, 0.9455186f, 0.9396926f, 0.9335804f, 0.9271839f, 0.9205049f,
765 0.9135455f, 0.9063078f, 0.8987940f, 0.8910065f, 0.8829476f, 0.8746197f,
766 0.8660254f, 0.8571673f, 0.8480481f, 0.8386706f, 0.8290376f, 0.8191520f,
767 0.8090170f, 0.7986355f, 0.7880108f, 0.7771460f, 0.7660444f, 0.7547096f,
768 0.7431448f, 0.7313537f, 0.7193398f, 0.7071068f, 0.6946584f, 0.6819984f,
769 0.6691306f, 0.6560590f, 0.6427876f, 0.6293204f, 0.6156615f, 0.6018150f,
770 0.5877853f, 0.5735764f, 0.5591929f, 0.5446390f, 0.5299193f, 0.5150381f,
771 0.5000000f, 0.4848096f, 0.4694716f, 0.4539905f, 0.4383711f, 0.4226183f,
772 0.4067366f, 0.3907311f, 0.3746066f, 0.3583679f, 0.3420201f, 0.3255682f,
773 0.3090170f, 0.2923717f, 0.2756374f, 0.2588190f, 0.2419219f, 0.2249511f,
774 0.2079117f, 0.1908090f, 0.1736482f, 0.1564345f, 0.1391731f, 0.1218693f,
775 0.1045285f, 0.0871557f, 0.0697565f, 0.0523360f, 0.0348995f, 0.0174524f,
776 0.0000000f, -0.0174524f, -0.0348995f, -0.0523360f, -0.0697565f, -0.0871557f,
777 -0.1045285f, -0.1218693f, -0.1391731f, -0.1564345f, -0.1736482f, -0.1908090f,
778 -0.2079117f, -0.2249511f, -0.2419219f, -0.2588190f, -0.2756374f, -0.2923717f,
779 -0.3090170f, -0.3255682f, -0.3420201f, -0.3583679f, -0.3746066f, -0.3907311f,
780 -0.4067366f, -0.4226183f, -0.4383711f, -0.4539905f, -0.4694716f, -0.4848096f,
781 -0.5000000f, -0.5150381f, -0.5299193f, -0.5446390f, -0.5591929f, -0.5735764f,
782 -0.5877853f, -0.6018150f, -0.6156615f, -0.6293204f, -0.6427876f, -0.6560590f,
783 -0.6691306f, -0.6819984f, -0.6946584f, -0.7071068f, -0.7193398f, -0.7313537f,
784 -0.7431448f, -0.7547096f, -0.7660444f, -0.7771460f, -0.7880108f, -0.7986355f,
785 -0.8090170f, -0.8191520f, -0.8290376f, -0.8386706f, -0.8480481f, -0.8571673f,
786 -0.8660254f, -0.8746197f, -0.8829476f, -0.8910065f, -0.8987940f, -0.9063078f,
787 -0.9135455f, -0.9205049f, -0.9271839f, -0.9335804f, -0.9396926f, -0.9455186f,
788 -0.9510565f, -0.9563048f, -0.9612617f, -0.9659258f, -0.9702957f, -0.9743701f,
789 -0.9781476f, -0.9816272f, -0.9848078f, -0.9876883f, -0.9902681f, -0.9925462f,
790 -0.9945219f, -0.9961947f, -0.9975641f, -0.9986295f, -0.9993908f, -0.9998477f,
791 -1.0000000f, -0.9998477f, -0.9993908f, -0.9986295f, -0.9975641f, -0.9961947f,
792 -0.9945219f, -0.9925462f, -0.9902681f, -0.9876883f, -0.9848078f, -0.9816272f,
793 -0.9781476f, -0.9743701f, -0.9702957f, -0.9659258f, -0.9612617f, -0.9563048f,
794 -0.9510565f, -0.9455186f, -0.9396926f, -0.9335804f, -0.9271839f, -0.9205049f,
795 -0.9135455f, -0.9063078f, -0.8987940f, -0.8910065f, -0.8829476f, -0.8746197f,
796 -0.8660254f, -0.8571673f, -0.8480481f, -0.8386706f, -0.8290376f, -0.8191520f,
797 -0.8090170f, -0.7986355f, -0.7880108f, -0.7771460f, -0.7660444f, -0.7547096f,
798 -0.7431448f, -0.7313537f, -0.7193398f, -0.7071068f, -0.6946584f, -0.6819984f,
799 -0.6691306f, -0.6560590f, -0.6427876f, -0.6293204f, -0.6156615f, -0.6018150f,
800 -0.5877853f, -0.5735764f, -0.5591929f, -0.5446390f, -0.5299193f, -0.5150381f,
801 -0.5000000f, -0.4848096f, -0.4694716f, -0.4539905f, -0.4383711f, -0.4226183f,
802 -0.4067366f, -0.3907311f, -0.3746066f, -0.3583679f, -0.3420201f, -0.3255682f,
803 -0.3090170f, -0.2923717f, -0.2756374f, -0.2588190f, -0.2419219f, -0.2249511f,
804 -0.2079117f, -0.1908090f, -0.1736482f, -0.1564345f, -0.1391731f, -0.1218693f,
805 -0.1045285f, -0.0871557f, -0.0697565f, -0.0523360f, -0.0348995f, -0.0174524f,
806 -0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
807 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
808 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
809 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
810 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
811 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
812 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
813 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
814 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
815 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
816 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
817 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
818 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
819 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
820 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
826 sincos( int angle, float& cosval, float& sinval )
828 angle += (angle < 0 ? 360 : 0);
829 sinval = SinTable[angle];
830 cosval = SinTable[450 - angle];
834 constructs polygon that represents elliptic arc.
836 void ellipse2Poly( Point center, Size axes, int angle,
837 int arc_start, int arc_end,
838 int delta, vector<Point>& pts )
841 double size_a = axes.width, size_b = axes.height;
842 double cx = center.x, cy = center.y;
843 Point prevPt(INT_MIN,INT_MIN);
851 if( arc_start > arc_end )
857 while( arc_start < 0 )
862 while( arc_end > 360 )
867 if( arc_end - arc_start > 360 )
872 sincos( angle, alpha, beta );
875 for( i = arc_start; i < arc_end + delta; i += delta )
879 if( angle > arc_end )
884 x = size_a * SinTable[450-angle];
885 y = size_b * SinTable[angle];
887 pt.x = cvRound( cx + x * alpha - y * beta );
888 pt.y = cvRound( cy + x * beta + y * alpha );
895 if( pts.size() == 1 )
896 pts.push_back(pts[0]);
901 EllipseEx( Mat& img, Point center, Size axes,
902 int angle, int arc_start, int arc_end,
903 const void* color, int thickness, int line_type )
905 axes.width = std::abs(axes.width), axes.height = std::abs(axes.height);
906 int delta = (std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT;
907 delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5;
910 ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, v );
913 PolyLine( img, &v[0], (int)v.size(), false, color, thickness, line_type, XY_SHIFT );
914 else if( arc_end - arc_start >= 360 )
915 FillConvexPoly( img, &v[0], (int)v.size(), color, line_type, XY_SHIFT );
919 vector<PolyEdge> edges;
920 CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT );
921 FillEdgeCollection( img, edges, color );
926 /****************************************************************************************\
928 \****************************************************************************************/
930 /* helper macros: filling horizontal row */
931 #define ICV_HLINE( ptr, xl, xr, color, pix_size ) \
933 uchar* hline_ptr = (uchar*)(ptr) + (xl)*(pix_size); \
934 uchar* hline_max_ptr = (uchar*)(ptr) + (xr)*(pix_size); \
936 for( ; hline_ptr <= hline_max_ptr; hline_ptr += (pix_size))\
939 for( hline_j = 0; hline_j < (pix_size); hline_j++ ) \
941 hline_ptr[hline_j] = ((uchar*)color)[hline_j]; \
947 /* filling convex polygon. v - array of vertices, ntps - number of points */
949 FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_type, int shift )
958 int delta = shift ? 1 << (shift - 1) : 0;
959 int i, y, imin = 0, left = 0, right = 1, x1, x2;
961 int xmin, xmax, ymin, ymax;
962 uchar* ptr = img.data;
963 Size size = img.size();
964 int pix_size = (int)img.elemSize();
968 if( line_type < CV_AA )
969 delta1 = delta2 = XY_ONE >> 1;
971 delta1 = XY_ONE - 1, delta2 = 0;
974 p0.x <<= XY_SHIFT - shift;
975 p0.y <<= XY_SHIFT - shift;
977 assert( 0 <= shift && shift <= XY_SHIFT );
978 xmin = xmax = v[0].x;
979 ymin = ymax = v[0].y;
981 for( i = 0; i < npts; i++ )
990 ymax = std::max( ymax, p.y );
991 xmax = std::max( xmax, p.x );
992 xmin = MIN( xmin, p.x );
994 p.x <<= XY_SHIFT - shift;
995 p.y <<= XY_SHIFT - shift;
1002 pt0.x = p0.x >> XY_SHIFT;
1003 pt0.y = p0.y >> XY_SHIFT;
1004 pt1.x = p.x >> XY_SHIFT;
1005 pt1.y = p.y >> XY_SHIFT;
1006 Line( img, pt0, pt1, color, line_type );
1009 Line2( img, p0, p, color );
1012 LineAA( img, p0, p, color );
1016 xmin = (xmin + delta) >> shift;
1017 xmax = (xmax + delta) >> shift;
1018 ymin = (ymin + delta) >> shift;
1019 ymax = (ymax + delta) >> shift;
1021 if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height )
1024 ymax = MIN( ymax, size.height - 1 );
1025 edge[0].idx = edge[1].idx = imin;
1027 edge[0].ye = edge[1].ye = y = ymin;
1029 edge[1].di = npts - 1;
1035 if( line_type < CV_AA || y < ymax || y == ymin )
1037 for( i = 0; i < 2; i++ )
1039 if( y >= edge[i].ye )
1041 int idx = edge[i].idx, di = edge[i].di;
1042 int xs = 0, xe, ye, ty = 0;
1046 ty = (v[idx].y + delta) >> shift;
1047 if( ty > y || edges == 0 )
1051 idx -= ((idx < npts) - 1) & npts; /* idx -= idx >= npts ? npts : 0 */
1056 xs <<= XY_SHIFT - shift;
1057 xe = v[idx].x << (XY_SHIFT - shift);
1064 edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y));
1071 if( edge[left].x > edge[right].x )
1082 int xx1 = (x1 + delta1) >> XY_SHIFT;
1083 int xx2 = (x2 + delta2) >> XY_SHIFT;
1085 if( xx2 >= 0 && xx1 < size.width )
1089 if( xx2 >= size.width )
1090 xx2 = size.width - 1;
1091 ICV_HLINE( ptr, xx1, xx2, color, pix_size );
1095 x1 += edge[left].dx;
1096 x2 += edge[right].dx;
1102 while( ++y <= ymax );
1106 /******** Arbitrary polygon **********/
1109 CollectPolyEdges( Mat& img, const Point* v, int count, vector<PolyEdge>& edges,
1110 const void* color, int line_type, int shift, Point offset )
1112 int i, delta = offset.y + (shift ? 1 << (shift - 1) : 0);
1113 Point pt0 = v[count-1], pt1;
1114 pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift);
1115 pt0.y = (pt0.y + delta) >> shift;
1117 edges.reserve( edges.size() + count );
1119 for( i = 0; i < count; i++, pt0 = pt1 )
1125 pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift);
1126 pt1.y = (pt1.y + delta) >> shift;
1128 if( line_type < CV_AA )
1130 t0.y = pt0.y; t1.y = pt1.y;
1131 t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT;
1132 t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT;
1133 Line( img, t0, t1, color, line_type );
1137 t0.x = pt0.x; t1.x = pt1.x;
1138 t0.y = pt0.y << XY_SHIFT;
1139 t1.y = pt1.y << XY_SHIFT;
1140 LineAA( img, t0, t1, color );
1143 if( pt0.y == pt1.y )
1158 edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
1159 edges.push_back(edge);
1165 bool operator ()(const PolyEdge& e1, const PolyEdge& e2)
1167 return e1.y0 - e2.y0 ? e1.y0 < e2.y0 :
1168 e1.x - e2.x ? e1.x < e2.x : e1.dx < e2.dx;
1172 /**************** helper macros and functions for sequence/contour processing ***********/
1175 FillEdgeCollection( Mat& img, vector<PolyEdge>& edges, const void* color )
1178 int i, y, total = (int)edges.size();
1179 Size size = img.size();
1181 int y_max = INT_MIN, x_max = INT_MIN, y_min = INT_MAX, x_min = INT_MAX;
1182 int pix_size = (int)img.elemSize();
1187 for( i = 0; i < total; i++ )
1189 PolyEdge& e1 = edges[i];
1190 assert( e1.y0 < e1.y1 );
1191 y_min = std::min( y_min, e1.y0 );
1192 y_max = std::max( y_max, e1.y1 );
1193 x_min = std::min( x_min, e1.x );
1194 x_max = std::max( x_max, e1.x );
1197 if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= (size.width<<XY_SHIFT) )
1200 std::sort( edges.begin(), edges.end(), CmpEdges() );
1204 edges.push_back(tmp); // after this point we do not add
1205 // any elements to edges, thus we can use pointers
1209 y_max = MIN( y_max, size.height );
1211 for( y = e->y0; y < y_max; y++ )
1213 PolyEdge *last, *prelast, *keep_prelast;
1216 int clipline = y < 0;
1220 while( last || e->y0 == y )
1222 if( last && last->y1 == y )
1224 // exclude edge if y reachs its lower point
1225 prelast->next = last->next;
1229 keep_prelast = prelast;
1230 if( last && (e->y0 > y || last->x < e->x) )
1232 // go to the next edge in active list
1236 else if( i < total )
1238 // insert new edge into active list if y reachs its upper point
1251 // convert x's from fixed-point to image coordinates
1252 uchar *timg = img.data + y * img.step;
1253 int x1 = keep_prelast->x;
1254 int x2 = prelast->x;
1264 x1 = (x1 + XY_ONE - 1) >> XY_SHIFT;
1265 x2 = x2 >> XY_SHIFT;
1267 // clip and draw the line
1268 if( x1 < size.width && x2 >= 0 )
1272 if( x2 >= size.width )
1273 x2 = size.width - 1;
1274 ICV_HLINE( timg, x1, x2, color, pix_size );
1277 keep_prelast->x += keep_prelast->dx;
1278 prelast->x += prelast->dx;
1283 // sort edges (using bubble sort)
1291 while( last != keep_prelast && last->next != 0 )
1293 PolyEdge *te = last->next;
1296 if( last->x > te->x )
1299 last->next = te->next;
1310 keep_prelast = prelast;
1312 while( sort_flag && keep_prelast != tmp.next && keep_prelast != &tmp );
1317 /* draws simple or filled circle */
1319 Circle( Mat& img, Point center, int radius, const void* color, int fill )
1321 Size size = img.size();
1322 size_t step = img.step;
1323 int pix_size = (int)img.elemSize();
1324 uchar* ptr = img.data;
1325 int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
1326 int inside = center.x >= radius && center.x < size.width - radius &&
1327 center.y >= radius && center.y < size.height - radius;
1329 #define ICV_PUT_POINT( ptr, x ) \
1330 memcpy( ptr + (x)*pix_size, color, pix_size );
1335 int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
1336 int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
1340 uchar *tptr0 = ptr + y11 * step;
1341 uchar *tptr1 = ptr + y12 * step;
1345 ICV_PUT_POINT( tptr0, x11 );
1346 ICV_PUT_POINT( tptr1, x11 );
1347 ICV_PUT_POINT( tptr0, x12 );
1348 ICV_PUT_POINT( tptr1, x12 );
1352 ICV_HLINE( tptr0, x11, x12, color, pix_size );
1353 ICV_HLINE( tptr1, x11, x12, color, pix_size );
1356 tptr0 = ptr + y21 * step;
1357 tptr1 = ptr + y22 * step;
1361 ICV_PUT_POINT( tptr0, x21 );
1362 ICV_PUT_POINT( tptr1, x21 );
1363 ICV_PUT_POINT( tptr0, x22 );
1364 ICV_PUT_POINT( tptr1, x22 );
1368 ICV_HLINE( tptr0, x21, x22, color, pix_size );
1369 ICV_HLINE( tptr1, x21, x22, color, pix_size );
1372 else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
1376 x11 = std::max( x11, 0 );
1377 x12 = MIN( x12, size.width - 1 );
1380 if( (unsigned)y11 < (unsigned)size.height )
1382 uchar *tptr = ptr + y11 * step;
1387 ICV_PUT_POINT( tptr, x11 );
1388 if( x12 < size.width )
1389 ICV_PUT_POINT( tptr, x12 );
1392 ICV_HLINE( tptr, x11, x12, color, pix_size );
1395 if( (unsigned)y12 < (unsigned)size.height )
1397 uchar *tptr = ptr + y12 * step;
1402 ICV_PUT_POINT( tptr, x11 );
1403 if( x12 < size.width )
1404 ICV_PUT_POINT( tptr, x12 );
1407 ICV_HLINE( tptr, x11, x12, color, pix_size );
1410 if( x21 < size.width && x22 >= 0 )
1414 x21 = std::max( x21, 0 );
1415 x22 = MIN( x22, size.width - 1 );
1418 if( (unsigned)y21 < (unsigned)size.height )
1420 uchar *tptr = ptr + y21 * step;
1425 ICV_PUT_POINT( tptr, x21 );
1426 if( x22 < size.width )
1427 ICV_PUT_POINT( tptr, x22 );
1430 ICV_HLINE( tptr, x21, x22, color, pix_size );
1433 if( (unsigned)y22 < (unsigned)size.height )
1435 uchar *tptr = ptr + y22 * step;
1440 ICV_PUT_POINT( tptr, x21 );
1441 if( x22 < size.width )
1442 ICV_PUT_POINT( tptr, x22 );
1445 ICV_HLINE( tptr, x21, x22, color, pix_size );
1453 mask = (err <= 0) - 1;
1455 err -= minus & mask;
1460 #undef ICV_PUT_POINT
1465 ThickLine( Mat& img, Point p0, Point p1, const void* color,
1466 int thickness, int line_type, int flags, int shift )
1468 static const double INV_XY_ONE = 1./XY_ONE;
1470 p0.x <<= XY_SHIFT - shift;
1471 p0.y <<= XY_SHIFT - shift;
1472 p1.x <<= XY_SHIFT - shift;
1473 p1.y <<= XY_SHIFT - shift;
1475 if( thickness <= 1 )
1477 if( line_type < CV_AA )
1479 if( line_type == 1 || line_type == 4 || shift == 0 )
1481 p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
1482 p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
1483 p1.x = (p1.x + (XY_ONE>>1)) >> XY_SHIFT;
1484 p1.y = (p1.y + (XY_ONE>>1)) >> XY_SHIFT;
1485 Line( img, p0, p1, color, line_type );
1488 Line2( img, p0, p1, color );
1491 LineAA( img, p0, p1, color );
1495 Point pt[4], dp = Point(0,0);
1496 double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE;
1497 double r = dx * dx + dy * dy;
1498 int i, oddThickness = thickness & 1;
1499 thickness <<= XY_SHIFT - 1;
1501 if( fabs(r) > DBL_EPSILON )
1503 r = (thickness + oddThickness*XY_ONE*0.5)/std::sqrt(r);
1504 dp.x = cvRound( dy * r );
1505 dp.y = cvRound( dx * r );
1507 pt[0].x = p0.x + dp.x;
1508 pt[0].y = p0.y + dp.y;
1509 pt[1].x = p0.x - dp.x;
1510 pt[1].y = p0.y - dp.y;
1511 pt[2].x = p1.x - dp.x;
1512 pt[2].y = p1.y - dp.y;
1513 pt[3].x = p1.x + dp.x;
1514 pt[3].y = p1.y + dp.y;
1516 FillConvexPoly( img, pt, 4, color, line_type, XY_SHIFT );
1519 for( i = 0; i < 2; i++ )
1523 if( line_type < CV_AA )
1526 center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
1527 center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
1528 Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 );
1532 EllipseEx( img, p0, cvSize(thickness, thickness),
1533 0, 0, 360, color, -1, line_type );
1543 PolyLine( Mat& img, const Point* v, int count, bool is_closed,
1544 const void* color, int thickness,
1545 int line_type, int shift )
1547 if( !v || count <= 0 )
1550 int i = is_closed ? count - 1 : 0;
1551 int flags = 2 + !is_closed;
1553 CV_Assert( 0 <= shift && shift <= XY_SHIFT && thickness >= 0 );
1556 for( i = !is_closed; i < count; i++ )
1559 ThickLine( img, p0, p, color, thickness, line_type, flags, shift );
1565 /****************************************************************************************\
1566 * External functions *
1567 \****************************************************************************************/
1569 void line( Mat& img, Point pt1, Point pt2, const Scalar& color,
1570 int thickness, int line_type, int shift )
1572 if( line_type == CV_AA && img.depth() != CV_8U )
1575 CV_Assert( 0 <= thickness && thickness <= 255 );
1576 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1579 scalarToRawData( color, buf, img.type(), 0 );
1580 ThickLine( img, pt1, pt2, buf, thickness, line_type, 3, shift );
1583 void rectangle( Mat& img, Point pt1, Point pt2,
1584 const Scalar& color, int thickness,
1585 int lineType, int shift )
1587 if( lineType == CV_AA && img.depth() != CV_8U )
1590 CV_Assert( thickness <= 255 );
1591 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1594 scalarToRawData(color, buf, img.type(), 0);
1605 if( thickness >= 0 )
1606 PolyLine( img, pt, 4, true, buf, thickness, lineType, shift );
1608 FillConvexPoly( img, pt, 4, buf, lineType, shift );
1612 void rectangle( Mat& img, Rect rec,
1613 const Scalar& color, int thickness,
1614 int lineType, int shift )
1616 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1617 if( rec.area() > 0 )
1618 rectangle( img, rec.tl(), rec.br() - Point(1<<shift,1<<shift),
1619 color, thickness, lineType, shift );
1623 void circle( Mat& img, Point center, int radius,
1624 const Scalar& color, int thickness, int line_type, int shift )
1626 if( line_type == CV_AA && img.depth() != CV_8U )
1629 CV_Assert( radius >= 0 && thickness <= 255 &&
1630 0 <= shift && shift <= XY_SHIFT );
1633 scalarToRawData(color, buf, img.type(), 0);
1635 if( thickness > 1 || line_type >= CV_AA )
1637 center.x <<= XY_SHIFT - shift;
1638 center.y <<= XY_SHIFT - shift;
1639 radius <<= XY_SHIFT - shift;
1640 EllipseEx( img, center, Size(radius, radius),
1641 0, 0, 360, buf, thickness, line_type );
1644 Circle( img, center, radius, buf, thickness < 0 );
1648 void ellipse( Mat& img, Point center, Size axes,
1649 double angle, double start_angle, double end_angle,
1650 const Scalar& color, int thickness, int line_type, int shift )
1652 if( line_type == CV_AA && img.depth() != CV_8U )
1655 CV_Assert( axes.width >= 0 && axes.height >= 0 &&
1656 thickness <= 255 && 0 <= shift && shift <= XY_SHIFT );
1659 scalarToRawData(color, buf, img.type(), 0);
1661 int _angle = cvRound(angle);
1662 int _start_angle = cvRound(start_angle);
1663 int _end_angle = cvRound(end_angle);
1664 center.x <<= XY_SHIFT - shift;
1665 center.y <<= XY_SHIFT - shift;
1666 axes.width <<= XY_SHIFT - shift;
1667 axes.height <<= XY_SHIFT - shift;
1669 EllipseEx( img, center, axes, _angle, _start_angle,
1670 _end_angle, buf, thickness, line_type );
1673 void ellipse(Mat& img, const RotatedRect& box, const Scalar& color,
1674 int thickness, int lineType)
1676 if( lineType == CV_AA && img.depth() != CV_8U )
1679 CV_Assert( box.size.width >= 0 && box.size.height >= 0 &&
1683 scalarToRawData(color, buf, img.type(), 0);
1685 int _angle = cvRound(box.angle);
1686 Point center(cvRound(box.center.x*(1 << XY_SHIFT)),
1687 cvRound(box.center.y*(1 << XY_SHIFT)));
1688 Size axes(cvRound(box.size.width*(1 << (XY_SHIFT - 1))),
1689 cvRound(box.size.height*(1 << (XY_SHIFT - 1))));
1690 EllipseEx( img, center, axes, _angle, 0, 360, buf, thickness, lineType );
1693 void fillConvexPoly( Mat& img, const Point* pts, int npts,
1694 const Scalar& color, int line_type, int shift )
1696 if( !pts || npts <= 0 )
1699 if( line_type == CV_AA && img.depth() != CV_8U )
1703 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1704 scalarToRawData(color, buf, img.type(), 0);
1705 FillConvexPoly( img, pts, npts, buf, line_type, shift );
1709 void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours,
1710 const Scalar& color, int line_type,
1711 int shift, Point offset )
1713 if( line_type == CV_AA && img.depth() != CV_8U )
1716 CV_Assert( pts && npts && ncontours >= 0 && 0 <= shift && shift <= XY_SHIFT );
1719 scalarToRawData(color, buf, img.type(), 0);
1721 vector<PolyEdge> edges;
1724 for( i = 0; i < ncontours; i++ )
1727 edges.reserve( total + 1 );
1728 for( i = 0; i < ncontours; i++ )
1729 CollectPolyEdges( img, pts[i], npts[i], edges, buf, line_type, shift, offset );
1731 FillEdgeCollection(img, edges, buf);
1735 void polylines( Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed,
1736 const Scalar& color, int thickness, int line_type, int shift )
1738 if( line_type == CV_AA && img.depth() != CV_8U )
1741 CV_Assert( pts && npts && ncontours >= 0 &&
1742 0 <= thickness && thickness <= 255 &&
1743 0 <= shift && shift <= XY_SHIFT );
1746 scalarToRawData( color, buf, img.type(), 0 );
1748 for( int i = 0; i < ncontours; i++ )
1749 PolyLine( img, pts[i], npts[i], isClosed, buf, thickness, line_type, shift );
1753 enum { FONT_SIZE_SHIFT=8, FONT_ITALIC_ALPHA=(1 << 8),
1754 FONT_ITALIC_DIGIT=(2 << 8), FONT_ITALIC_PUNCT=(4 << 8),
1755 FONT_ITALIC_BRACES=(8 << 8), FONT_HAVE_GREEK=(16 << 8),
1756 FONT_HAVE_CYRILLIC=(32 << 8) };
1758 static const int HersheyPlain[] = {
1759 (5 + 4*16) + FONT_HAVE_GREEK,
1760 199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
1761 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
1762 215, 190, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1763 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 193, 84,
1764 194, 85, 86, 87, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1765 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
1766 195, 223, 196, 88 };
1768 static const int HersheyPlainItalic[] = {
1769 (5 + 4*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1770 199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
1771 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
1772 215, 190, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1773 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 193, 84,
1774 194, 85, 86, 87, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
1775 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
1776 195, 223, 196, 88 };
1778 static const int HersheyComplexSmall[] = {
1779 (6 + 7*16) + FONT_HAVE_GREEK,
1780 1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
1781 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 2213, 1241, 1238, 1242,
1782 1215, 1273, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013,
1783 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1223, 1084,
1784 1224, 1247, 586, 1249, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,
1785 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126,
1786 1225, 1229, 1226, 1246 };
1788 static const int HersheyComplexSmallItalic[] = {
1789 (6 + 7*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1790 1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
1791 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 1213, 1241, 1238, 1242,
1792 1215, 1273, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
1793 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1223, 1084,
1794 1224, 1247, 586, 1249, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161,
1795 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176,
1796 1225, 1229, 1226, 1246 };
1798 static const int HersheySimplex[] = {
1799 (9 + 12*16) + FONT_HAVE_GREEK,
1800 2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
1801 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
1802 715, 690, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513,
1803 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 693, 584,
1804 694, 2247, 586, 2249, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611,
1805 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626,
1806 695, 723, 696, 2246 };
1808 static const int HersheyDuplex[] = {
1809 (9 + 12*16) + FONT_HAVE_GREEK,
1810 2199, 2714, 2728, 2732, 2719, 2733, 2718, 2727, 2721, 2722, 2723, 2725, 2711, 2724, 2710, 2720,
1811 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2712, 2713, 2730, 2726, 2731,
1812 2715, 2734, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513,
1813 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2223, 2084,
1814 2224, 2247, 587, 2249, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611,
1815 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626,
1816 2225, 2229, 2226, 2246 };
1818 static const int HersheyComplex[] = {
1819 (9 + 12*16) + FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
1820 2199, 2214, 2217, 2275, 2274, 2271, 2272, 2216, 2221, 2222, 2219, 2232, 2211, 2231, 2210, 2220,
1821 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2212, 2213, 2241, 2238, 2242,
1822 2215, 2273, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
1823 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2223, 2084,
1824 2224, 2247, 587, 2249, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111,
1825 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126,
1826 2225, 2229, 2226, 2246 };
1828 static const int HersheyComplexItalic[] = {
1829 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT +
1830 FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
1831 2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
1832 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
1833 2765, 2273, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063,
1834 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2223, 2084,
1835 2224, 2247, 587, 2249, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161,
1836 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176,
1837 2225, 2229, 2226, 2246 };
1839 static const int HersheyTriplex[] = {
1840 (9 + 12*16) + FONT_HAVE_GREEK,
1841 2199, 3214, 3228, 3232, 3219, 3233, 3218, 3227, 3221, 3222, 3223, 3225, 3211, 3224, 3210, 3220,
1842 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3212, 3213, 3230, 3226, 3231,
1843 3215, 3234, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013,
1844 2014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 2223, 2084,
1845 2224, 2247, 587, 2249, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111,
1846 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126,
1847 2225, 2229, 2226, 2246 };
1849 static const int HersheyTriplexItalic[] = {
1850 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT +
1851 FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
1852 2199, 3264, 3278, 3282, 3269, 3233, 3268, 3277, 3271, 3272, 3223, 3225, 3261, 3224, 3260, 3270,
1853 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3262, 3263, 3230, 3226, 3231,
1854 3265, 3234, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063,
1855 2064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 2223, 2084,
1856 2224, 2247, 587, 2249, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161,
1857 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176,
1858 2225, 2229, 2226, 2246 };
1860 static const int HersheyScriptSimplex[] = {
1861 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1862 2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
1863 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
1864 715, 690, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
1865 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 693, 584,
1866 694, 2247, 586, 2249, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661,
1867 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676,
1868 695, 723, 696, 2246 };
1870 static const int HersheyScriptComplex[] = {
1871 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
1872 2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
1873 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
1874 2215, 2273, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563,
1875 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2223, 2084,
1876 2224, 2247, 586, 2249, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661,
1877 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676,
1878 2225, 2229, 2226, 2246 };
1881 static const int* getFontData(int fontFace)
1883 bool isItalic = (fontFace & FONT_ITALIC) != 0;
1884 const int* ascii = 0;
1886 switch( fontFace & 15 )
1888 case FONT_HERSHEY_SIMPLEX:
1889 ascii = HersheySimplex;
1891 case FONT_HERSHEY_PLAIN:
1892 ascii = !isItalic ? HersheyPlain : HersheyPlainItalic;
1894 case FONT_HERSHEY_DUPLEX:
1895 ascii = HersheyDuplex;
1897 case FONT_HERSHEY_COMPLEX:
1898 ascii = !isItalic ? HersheyComplex : HersheyComplexItalic;
1900 case FONT_HERSHEY_TRIPLEX:
1901 ascii = !isItalic ? HersheyTriplex : HersheyTriplexItalic;
1903 case FONT_HERSHEY_COMPLEX_SMALL:
1904 ascii = !isItalic ? HersheyComplexSmall : HersheyComplexSmallItalic;
1906 case FONT_HERSHEY_SCRIPT_SIMPLEX:
1907 ascii = HersheyScriptSimplex;
1909 case FONT_HERSHEY_SCRIPT_COMPLEX:
1910 ascii = HersheyScriptComplex;
1913 CV_Error( CV_StsOutOfRange, "Unknown font type" );
1919 void putText( Mat& img, const string& text, Point org,
1920 int fontFace, double fontScale, Scalar color,
1921 int thickness, int line_type, bool bottomLeftOrigin )
1924 const int* ascii = getFontData(fontFace);
1927 scalarToRawData(color, buf, img.type(), 0);
1929 int base_line = -(ascii[0] & 15);
1930 int hscale = cvRound(fontScale*XY_ONE), vscale = hscale;
1932 if( line_type == CV_AA && img.depth() != CV_8U )
1935 if( bottomLeftOrigin )
1938 int view_x = org.x << XY_SHIFT;
1939 int view_y = (org.y << XY_SHIFT) + base_line*vscale;
1941 pts.reserve(1 << 10);
1942 const char **faces = cv::g_HersheyGlyphs;
1944 for( int i = 0; text[i] != '\0'; i++ )
1946 int c = (uchar)text[i];
1949 if( c >= 127 || c < ' ' )
1952 const char* ptr = faces[ascii[(c-' ')+1]];
1953 p.x = (uchar)ptr[0] - 'R';
1954 p.y = (uchar)ptr[1] - 'R';
1955 int dx = p.y*hscale;
1956 view_x -= p.x*hscale;
1961 if( *ptr == ' ' || !*ptr )
1963 if( pts.size() > 1 )
1964 PolyLine( img, &pts[0], (int)pts.size(), false, buf, thickness, line_type, XY_SHIFT );
1971 p.x = (uchar)ptr[0] - 'R';
1972 p.y = (uchar)ptr[1] - 'R';
1974 pts.push_back(Point(p.x*hscale + view_x, p.y*vscale + view_y));
1981 Size getTextSize( const string& text, int fontFace, double fontScale, int thickness, int* _base_line)
1985 const char **faces = cv::g_HersheyGlyphs;
1986 const int* ascii = getFontData(fontFace);
1988 int base_line = (ascii[0] & 15);
1989 int cap_line = (ascii[0] >> 4) & 15;
1990 size.height = cvRound((cap_line + base_line)*fontScale + (thickness+1)/2);
1992 for( int i = 0; text[i] != '\0'; i++ )
1994 int c = (uchar)text[i];
1997 if( c >= 127 || c < ' ' )
2000 const char* ptr = faces[ascii[(c-' ')+1]];
2001 p.x = (uchar)ptr[0] - 'R';
2002 p.y = (uchar)ptr[1] - 'R';
2003 view_x += (p.y - p.x)*fontScale;
2006 size.width = cvRound(view_x + thickness);
2008 *_base_line = cvRound(base_line*fontScale + thickness*0.5);
2015 void cv::fillConvexPoly(InputOutputArray _img, InputArray _points,
2016 const Scalar& color, int lineType, int shift)
2018 Mat img = _img.getMat(), points = _points.getMat();
2019 CV_Assert(points.checkVector(2, CV_32S) >= 0);
2020 fillConvexPoly(img, (const Point*)points.data, points.rows*points.cols*points.channels()/2, color, lineType, shift);
2024 void cv::fillPoly(InputOutputArray _img, InputArrayOfArrays pts,
2025 const Scalar& color, int lineType, int shift, Point offset)
2027 Mat img = _img.getMat();
2028 int i, ncontours = (int)pts.total();
2029 if( ncontours == 0 )
2031 AutoBuffer<Point*> _ptsptr(ncontours);
2032 AutoBuffer<int> _npts(ncontours);
2033 Point** ptsptr = _ptsptr;
2036 for( i = 0; i < ncontours; i++ )
2038 Mat p = pts.getMat(i);
2039 CV_Assert(p.checkVector(2, CV_32S) >= 0);
2040 ptsptr[i] = (Point*)p.data;
2041 npts[i] = p.rows*p.cols*p.channels()/2;
2043 fillPoly(img, (const Point**)ptsptr, npts, (int)ncontours, color, lineType, shift, offset);
2047 void cv::polylines(InputOutputArray _img, InputArrayOfArrays pts,
2048 bool isClosed, const Scalar& color,
2049 int thickness, int lineType, int shift )
2051 Mat img = _img.getMat();
2052 bool manyContours = pts.kind() == _InputArray::STD_VECTOR_VECTOR ||
2053 pts.kind() == _InputArray::STD_VECTOR_MAT;
2054 int i, ncontours = manyContours ? (int)pts.total() : 1;
2055 if( ncontours == 0 )
2057 AutoBuffer<Point*> _ptsptr(ncontours);
2058 AutoBuffer<int> _npts(ncontours);
2059 Point** ptsptr = _ptsptr;
2062 for( i = 0; i < ncontours; i++ )
2064 Mat p = pts.getMat(manyContours ? i : -1);
2065 if( p.total() == 0 )
2067 CV_Assert(p.checkVector(2, CV_32S) >= 0);
2068 ptsptr[i] = (Point*)p.data;
2069 npts[i] = p.rows*p.cols*p.channels()/2;
2071 polylines(img, (const Point**)ptsptr, npts, (int)ncontours, isClosed, color, thickness, lineType, shift);
2075 static const int CodeDeltas[8][2] =
2076 { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
2078 #define CV_ADJUST_EDGE_COUNT( count, seq ) \
2079 ((count) -= ((count) == (seq)->total && !CV_IS_SEQ_CLOSED(seq)))
2082 cvDrawContours( void* _img, CvSeq* contour,
2083 CvScalar _externalColor, CvScalar _holeColor,
2084 int maxLevel, int thickness,
2085 int line_type, CvPoint _offset )
2087 CvSeq *contour0 = contour, *h_next = 0;
2088 CvTreeNodeIterator iterator;
2089 cv::vector<cv::PolyEdge> edges;
2090 cv::vector<cv::Point> pts;
2091 cv::Scalar externalColor = _externalColor, holeColor = _holeColor;
2092 cv::Mat img = cv::cvarrToMat(_img);
2093 cv::Point offset = _offset;
2094 double ext_buf[4], hole_buf[4];
2096 if( line_type == CV_AA && img.depth() != CV_8U )
2102 CV_Assert( thickness <= 255 );
2104 scalarToRawData( externalColor, ext_buf, img.type(), 0 );
2105 scalarToRawData( holeColor, hole_buf, img.type(), 0 );
2107 maxLevel = MAX(maxLevel, INT_MIN+2);
2108 maxLevel = MIN(maxLevel, INT_MAX-1);
2112 h_next = contour->h_next;
2113 contour->h_next = 0;
2114 maxLevel = -maxLevel+1;
2117 cvInitTreeNodeIterator( &iterator, contour, maxLevel );
2118 while( (contour = (CvSeq*)cvNextTreeNode( &iterator )) != 0 )
2121 int i, count = contour->total;
2122 int elem_type = CV_MAT_TYPE(contour->flags);
2123 void* clr = (contour->flags & CV_SEQ_FLAG_HOLE) == 0 ? ext_buf : hole_buf;
2125 cvStartReadSeq( contour, &reader, 0 );
2129 if( CV_IS_SEQ_CHAIN_CONTOUR( contour ))
2131 cv::Point pt = ((CvChain*)contour)->origin;
2132 cv::Point prev_pt = pt;
2133 char prev_code = reader.ptr ? reader.ptr[0] : '\0';
2137 for( i = 0; i < count; i++ )
2140 CV_READ_SEQ_ELEM( code, reader );
2142 assert( (code & ~7) == 0 );
2144 if( code != prev_code )
2147 if( thickness >= 0 )
2148 cv::ThickLine( img, prev_pt, pt, clr, thickness, line_type, 2, 0 );
2154 pt.x += CodeDeltas[(int)code][0];
2155 pt.y += CodeDeltas[(int)code][1];
2158 if( thickness >= 0 )
2159 cv::ThickLine( img, prev_pt,
2160 cv::Point(((CvChain*)contour)->origin) + offset,
2161 clr, thickness, line_type, 2, 0 );
2163 cv::CollectPolyEdges(img, &pts[0], (int)pts.size(),
2164 edges, ext_buf, line_type, 0, offset);
2166 else if( CV_IS_SEQ_POLYLINE( contour ))
2168 CV_Assert( elem_type == CV_32SC2 );
2172 count -= !CV_IS_SEQ_CLOSED(contour);
2173 CV_READ_SEQ_ELEM( pt1, reader );
2178 for( i = 0; i < count; i++ )
2180 CV_READ_SEQ_ELEM( pt2, reader );
2182 if( thickness >= 0 )
2183 cv::ThickLine( img, pt1, pt2, clr, thickness, line_type, 2, shift );
2189 cv::CollectPolyEdges( img, &pts[0], (int)pts.size(),
2190 edges, ext_buf, line_type, 0, cv::Point() );
2195 cv::FillEdgeCollection( img, edges, ext_buf );
2197 if( h_next && contour0 )
2198 contour0->h_next = h_next;
2202 cvClipLine( CvSize size, CvPoint* pt1, CvPoint* pt2 )
2204 CV_Assert( pt1 && pt2 );
2205 return cv::clipLine( size, *(cv::Point*)pt1, *(cv::Point*)pt2 );
2210 cvEllipse2Poly( CvPoint center, CvSize axes, int angle,
2211 int arc_start, int arc_end, CvPoint* _pts, int delta )
2213 cv::vector<cv::Point> pts;
2214 cv::ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, pts );
2215 memcpy( _pts, &pts[0], pts.size()*sizeof(_pts[0]) );
2216 return (int)pts.size();
2220 cvColorToScalar( double packed_color, int type )
2224 if( CV_MAT_DEPTH( type ) == CV_8U )
2226 int icolor = cvRound( packed_color );
2227 if( CV_MAT_CN( type ) > 1 )
2229 scalar.val[0] = icolor & 255;
2230 scalar.val[1] = (icolor >> 8) & 255;
2231 scalar.val[2] = (icolor >> 16) & 255;
2232 scalar.val[3] = (icolor >> 24) & 255;
2236 scalar.val[0] = CV_CAST_8U( icolor );
2237 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2240 else if( CV_MAT_DEPTH( type ) == CV_8S )
2242 int icolor = cvRound( packed_color );
2243 if( CV_MAT_CN( type ) > 1 )
2245 scalar.val[0] = (char)icolor;
2246 scalar.val[1] = (char)(icolor >> 8);
2247 scalar.val[2] = (char)(icolor >> 16);
2248 scalar.val[3] = (char)(icolor >> 24);
2252 scalar.val[0] = CV_CAST_8S( icolor );
2253 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2258 int cn = CV_MAT_CN( type );
2262 scalar.val[0] = packed_color;
2263 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2266 scalar.val[0] = scalar.val[1] = packed_color;
2267 scalar.val[2] = scalar.val[3] = 0;
2270 scalar.val[0] = scalar.val[1] = scalar.val[2] = packed_color;
2274 scalar.val[0] = scalar.val[1] =
2275 scalar.val[2] = scalar.val[3] = packed_color;
2284 cvInitLineIterator( const CvArr* img, CvPoint pt1, CvPoint pt2,
2285 CvLineIterator* iterator, int connectivity,
2288 CV_Assert( iterator != 0 );
2289 cv::LineIterator li(cv::cvarrToMat(img), pt1, pt2, connectivity, left_to_right!=0);
2291 iterator->err = li.err;
2292 iterator->minus_delta = li.minusDelta;
2293 iterator->plus_delta = li.plusDelta;
2294 iterator->minus_step = li.minusStep;
2295 iterator->plus_step = li.plusStep;
2296 iterator->ptr = li.ptr;
2302 cvLine( CvArr* _img, CvPoint pt1, CvPoint pt2, CvScalar color,
2303 int thickness, int line_type, int shift )
2305 cv::Mat img = cv::cvarrToMat(_img);
2306 cv::line( img, pt1, pt2, color, thickness, line_type, shift );
2310 cvRectangle( CvArr* _img, CvPoint pt1, CvPoint pt2,
2311 CvScalar color, int thickness,
2312 int line_type, int shift )
2314 cv::Mat img = cv::cvarrToMat(_img);
2315 cv::rectangle( img, pt1, pt2, color, thickness, line_type, shift );
2319 cvRectangleR( CvArr* _img, CvRect rec,
2320 CvScalar color, int thickness,
2321 int line_type, int shift )
2323 cv::Mat img = cv::cvarrToMat(_img);
2324 cv::rectangle( img, rec, color, thickness, line_type, shift );
2328 cvCircle( CvArr* _img, CvPoint center, int radius,
2329 CvScalar color, int thickness, int line_type, int shift )
2331 cv::Mat img = cv::cvarrToMat(_img);
2332 cv::circle( img, center, radius, color, thickness, line_type, shift );
2336 cvEllipse( CvArr* _img, CvPoint center, CvSize axes,
2337 double angle, double start_angle, double end_angle,
2338 CvScalar color, int thickness, int line_type, int shift )
2340 cv::Mat img = cv::cvarrToMat(_img);
2341 cv::ellipse( img, center, axes, angle, start_angle, end_angle,
2342 color, thickness, line_type, shift );
2346 cvFillConvexPoly( CvArr* _img, const CvPoint *pts, int npts,
2347 CvScalar color, int line_type, int shift )
2349 cv::Mat img = cv::cvarrToMat(_img);
2350 cv::fillConvexPoly( img, (const cv::Point*)pts, npts,
2351 color, line_type, shift );
2355 cvFillPoly( CvArr* _img, CvPoint **pts, const int *npts, int ncontours,
2356 CvScalar color, int line_type, int shift )
2358 cv::Mat img = cv::cvarrToMat(_img);
2360 cv::fillPoly( img, (const cv::Point**)pts, npts, ncontours, color, line_type, shift );
2364 cvPolyLine( CvArr* _img, CvPoint **pts, const int *npts,
2365 int ncontours, int closed, CvScalar color,
2366 int thickness, int line_type, int shift )
2368 cv::Mat img = cv::cvarrToMat(_img);
2370 cv::polylines( img, (const cv::Point**)pts, npts, ncontours,
2371 closed != 0, color, thickness, line_type, shift );
2375 cvPutText( CvArr* _img, const char *text, CvPoint org, const CvFont *_font, CvScalar color )
2377 cv::Mat img = cv::cvarrToMat(_img);
2378 CV_Assert( text != 0 && _font != 0);
2379 cv::putText( img, text, org, _font->font_face, (_font->hscale+_font->vscale)*0.5,
2380 color, _font->thickness, _font->line_type,
2381 CV_IS_IMAGE(_img) && ((IplImage*)_img)->origin != 0 );
2386 cvInitFont( CvFont *font, int font_face, double hscale, double vscale,
2387 double shear, int thickness, int line_type )
2389 CV_Assert( font != 0 && hscale > 0 && vscale > 0 && thickness >= 0 );
2391 font->ascii = cv::getFontData(font_face);
2392 font->font_face = font_face;
2393 font->hscale = (float)hscale;
2394 font->vscale = (float)vscale;
2395 font->thickness = thickness;
2396 font->shear = (float)shear;
2397 font->greek = font->cyrillic = 0;
2398 font->line_type = line_type;
2402 cvGetTextSize( const char *text, const CvFont *_font, CvSize *_size, int *_base_line )
2404 CV_Assert(text != 0 && _font != 0);
2405 cv::Size size = cv::getTextSize( text, _font->font_face, (_font->hscale + _font->vscale)*0.5,
2406 _font->thickness, _base_line );