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.
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 int right = img_size.width-1, bottom = img_size.height-1;
84 CV_Assert( img_size.width > 0 && img_size.height > 0 );
86 x1 = pt1.x; y1 = pt1.y; x2 = pt2.x; y2 = pt2.y;
87 c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8;
88 c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8;
90 if( (c1 & c2) == 0 && (c1 | c2) != 0 )
95 a = c1 < 8 ? 0 : bottom;
96 x1 += (int) (((int64) (a - y1)) * (x2 - x1) / (y2 - y1));
98 c1 = (x1 < 0) + (x1 > right) * 2;
102 a = c2 < 8 ? 0 : bottom;
103 x2 += (int) (((int64) (a - y2)) * (x2 - x1) / (y2 - y1));
105 c2 = (x2 < 0) + (x2 > right) * 2;
107 if( (c1 & c2) == 0 && (c1 | c2) != 0 )
111 a = c1 == 1 ? 0 : right;
112 y1 += (int) (((int64) (a - x1)) * (y2 - y1) / (x2 - x1));
118 a = c2 == 1 ? 0 : right;
119 y2 += (int) (((int64) (a - x2)) * (y2 - y1) / (x2 - x1));
125 assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 );
133 return (c1 | c2) == 0;
136 bool clipLine( Rect img_rect, Point& pt1, Point& pt2 )
138 Point tl = img_rect.tl();
139 pt1 -= tl; pt2 -= tl;
140 bool inside = clipLine(img_rect.size(), pt1, pt2);
141 pt1 += tl; pt2 += tl;
147 Initializes line iterator.
148 Returns number of points on the line or negative number if error.
150 LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
151 int connectivity, bool left_to_right)
155 CV_Assert( connectivity == 8 || connectivity == 4 );
157 if( (unsigned)pt1.x >= (unsigned)(img.cols) ||
158 (unsigned)pt2.x >= (unsigned)(img.cols) ||
159 (unsigned)pt1.y >= (unsigned)(img.rows) ||
160 (unsigned)pt2.y >= (unsigned)(img.rows) )
162 if( !clipLine( img.size(), pt1, pt2 ) )
165 err = plusDelta = minusDelta = plusStep = minusStep = count = 0;
170 int bt_pix0 = (int)img.elemSize(), bt_pix = bt_pix0;
171 size_t step = img.step;
173 int dx = pt2.x - pt1.x;
174 int dy = pt2.y - pt1.y;
175 int s = dx < 0 ? -1 : 0;
181 pt1.x ^= (pt1.x ^ pt2.x) & s;
182 pt1.y ^= (pt1.y ^ pt2.y) & s;
187 bt_pix = (bt_pix ^ s) - s;
190 ptr = (uchar*)(img.data + pt1.y * step + pt1.x * bt_pix0);
194 step = (step ^ s) - s;
196 s = dy > dx ? -1 : 0;
198 /* conditional swaps */
207 if( connectivity == 8 )
209 assert( dx >= 0 && dy >= 0 );
211 err = dx - (dy + dy);
213 minusDelta = -(dy + dy);
214 plusStep = (int)step;
218 else /* connectivity == 4 */
220 assert( dx >= 0 && dy >= 0 );
223 plusDelta = (dx + dx) + (dy + dy);
224 minusDelta = -(dy + dy);
225 plusStep = (int)step - bt_pix;
232 Line( Mat& img, Point pt1, Point pt2,
233 const void* color, int connectivity = 8 )
235 if( connectivity == 0 )
237 if( connectivity == 1 )
240 LineIterator iterator(img, pt1, pt2, connectivity, true);
241 int i, count = iterator.count;
242 int pix_size = (int)img.elemSize();
244 for( i = 0; i < count; i++, ++iterator )
246 CV_MEMCPY_AUTO( *iterator, color, pix_size );
251 /* Correction table depent on the slope */
252 static const uchar SlopeCorrTable[] = {
253 181, 181, 181, 182, 182, 183, 184, 185, 187, 188, 190, 192, 194, 196, 198, 201,
254 203, 206, 209, 211, 214, 218, 221, 224, 227, 231, 235, 238, 242, 246, 250, 254
257 /* Gaussian for antialiasing filter */
258 static const int FilterTable[] = {
259 168, 177, 185, 194, 202, 210, 218, 224, 231, 236, 241, 246, 249, 252, 254, 254,
260 254, 254, 252, 249, 246, 241, 236, 231, 224, 218, 210, 202, 194, 185, 177, 168,
261 158, 149, 140, 131, 122, 114, 105, 97, 89, 82, 75, 68, 62, 56, 50, 45,
262 40, 36, 32, 28, 25, 22, 19, 16, 14, 12, 11, 9, 8, 7, 5, 5
266 LineAA( Mat& img, Point pt1, Point pt2, const void* color )
269 int ecount, scount = 0;
275 int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2];
277 int nch = img.channels();
278 uchar* ptr = img.data;
279 size_t step = img.step;
280 Size size = img.size();
282 if( !((nch == 1 || nch == 3) && img.depth() == CV_8U) )
284 Line(img, pt1, pt2, color);
292 ptr += img.step*2 + 2*nch;
294 size.width = ((size.width - 5) << XY_SHIFT) + 1;
295 size.height = ((size.height - 5) << XY_SHIFT) + 1;
297 if( !clipLine( size, pt1, pt2 ))
320 y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
322 ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT);
323 j = -(pt1.x & (XY_ONE - 1));
324 pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
325 slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;
326 slope ^= (y_step < 0 ? 0x3f : 0);
328 /* Get 4-bit fractions for end-point adjustments */
329 i = (pt1.x >> (XY_SHIFT - 7)) & 0x78;
330 j = (pt2.x >> (XY_SHIFT - 7)) & 0x78;
343 x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
346 ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT);
347 j = -(pt1.y & (XY_ONE - 1));
348 pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
349 slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;
350 slope ^= (x_step < 0 ? 0x3f : 0);
352 /* Get 4-bit fractions for end-point adjustments */
353 i = (pt1.y >> (XY_SHIFT - 7)) & 0x78;
354 j = (pt2.y >> (XY_SHIFT - 7)) & 0x78;
357 slope = (slope & 0x20) ? 0x100 : SlopeCorrTable[slope];
359 /* Calc end point correction table */
362 int t1 = ((0x78 - i) | 4) * slope;
363 int t2 = (j | 4) * slope;
367 ep_table[1] = ep_table[3] = ((((j - i) & 0x78) | 4) * slope >> 8) & 0x1ff;
368 ep_table[2] = (t1 >> 8) & 0x1ff;
369 ep_table[4] = ((((j - i) + 0x80) | 4) * slope >> 8) & 0x1ff;
370 ep_table[5] = ((t1 + t0) >> 8) & 0x1ff;
371 ep_table[6] = (t2 >> 8) & 0x1ff;
372 ep_table[7] = ((t2 + t0) >> 8) & 0x1ff;
377 #define ICV_PUT_POINT() \
380 _cb += ((cb - _cb)*a + 127)>> 8;\
382 _cg += ((cg - _cg)*a + 127)>> 8;\
384 _cr += ((cr - _cr)*a + 127)>> 8;\
385 tptr[0] = (uchar)_cb; \
386 tptr[1] = (uchar)_cg; \
387 tptr[2] = (uchar)_cr; \
391 ptr += (pt1.x >> XY_SHIFT) * 3;
395 uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
397 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
398 (((ecount >= 2) + 1) & (ecount | 2))];
399 int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
401 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
406 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
411 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
423 ptr += (pt1.y >> XY_SHIFT) * step;
427 uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3;
429 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
430 (((ecount >= 2) + 1) & (ecount | 2))];
431 int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
433 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
438 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
443 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
457 #define ICV_PUT_POINT() \
460 _cb += ((cb - _cb)*a + 127)>> 8;\
461 tptr[0] = (uchar)_cb; \
466 ptr += (pt1.x >> XY_SHIFT);
470 uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
472 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
473 (((ecount >= 2) + 1) & (ecount | 2))];
474 int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
476 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
481 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
486 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
498 ptr += (pt1.y >> XY_SHIFT) * step;
502 uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1);
504 int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
505 (((ecount >= 2) + 1) & (ecount | 2))];
506 int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
508 a = (ep_corr * FilterTable[dist + 32] >> 8) & 0xff;
513 a = (ep_corr * FilterTable[dist] >> 8) & 0xff;
518 a = (ep_corr * FilterTable[63 - dist] >> 8) & 0xff;
534 Line2( Mat& img, Point pt1, Point pt2, const void* color )
541 int cb = ((uchar*)color)[0];
542 int cg = ((uchar*)color)[1];
543 int cr = ((uchar*)color)[2];
544 int pix_size = (int)img.elemSize();
545 uchar *ptr = img.data, *tptr;
546 size_t step = img.step;
547 Size size = img.size();
549 //assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U );
555 ptr += img.step*2 + 2*pix_size;
557 size.width = ((size.width - 5) << XY_SHIFT) + 1;
558 size.height = ((size.height - 5) << XY_SHIFT) + 1;
560 if( !clipLine( size, pt1, pt2 ))
583 y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
584 ecount = (pt2.x - pt1.x) >> XY_SHIFT;
597 x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
599 ecount = (pt2.y - pt1.y) >> XY_SHIFT;
602 pt1.x += (XY_ONE >> 1);
603 pt1.y += (XY_ONE >> 1);
607 #define ICV_PUT_POINT() \
609 tptr[0] = (uchar)cb; \
610 tptr[1] = (uchar)cg; \
611 tptr[2] = (uchar)cr; \
614 tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT)*3 +
615 ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;
620 ptr += (pt1.x >> XY_SHIFT) * 3;
624 tptr = ptr + (pt1.y >> XY_SHIFT) * step;
633 ptr += (pt1.y >> XY_SHIFT) * step;
637 tptr = ptr + (pt1.x >> XY_SHIFT) * 3;
647 else if( pix_size == 1 )
649 #define ICV_PUT_POINT() \
651 tptr[0] = (uchar)cb; \
654 tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT) +
655 ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;
660 ptr += (pt1.x >> XY_SHIFT);
664 tptr = ptr + (pt1.y >> XY_SHIFT) * step;
673 ptr += (pt1.y >> XY_SHIFT) * step;
677 tptr = ptr + (pt1.x >> XY_SHIFT);
688 #define ICV_PUT_POINT() \
689 for( j = 0; j < pix_size; j++ ) \
690 tptr[j] = ((uchar*)color)[j];
692 tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT)*pix_size +
693 ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;
698 ptr += (pt1.x >> XY_SHIFT) * pix_size;
702 tptr = ptr + (pt1.y >> XY_SHIFT) * step;
711 ptr += (pt1.y >> XY_SHIFT) * step;
715 tptr = ptr + (pt1.x >> XY_SHIFT) * pix_size;
728 /****************************************************************************************\
729 * Antialiazed Elliptic Arcs via Antialiazed Lines *
730 \****************************************************************************************/
732 static const float SinTable[] =
733 { 0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
734 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
735 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
736 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
737 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
738 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
739 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
740 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
741 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
742 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
743 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
744 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
745 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
746 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
747 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
748 1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f,
749 0.9945219f, 0.9925462f, 0.9902681f, 0.9876883f, 0.9848078f, 0.9816272f,
750 0.9781476f, 0.9743701f, 0.9702957f, 0.9659258f, 0.9612617f, 0.9563048f,
751 0.9510565f, 0.9455186f, 0.9396926f, 0.9335804f, 0.9271839f, 0.9205049f,
752 0.9135455f, 0.9063078f, 0.8987940f, 0.8910065f, 0.8829476f, 0.8746197f,
753 0.8660254f, 0.8571673f, 0.8480481f, 0.8386706f, 0.8290376f, 0.8191520f,
754 0.8090170f, 0.7986355f, 0.7880108f, 0.7771460f, 0.7660444f, 0.7547096f,
755 0.7431448f, 0.7313537f, 0.7193398f, 0.7071068f, 0.6946584f, 0.6819984f,
756 0.6691306f, 0.6560590f, 0.6427876f, 0.6293204f, 0.6156615f, 0.6018150f,
757 0.5877853f, 0.5735764f, 0.5591929f, 0.5446390f, 0.5299193f, 0.5150381f,
758 0.5000000f, 0.4848096f, 0.4694716f, 0.4539905f, 0.4383711f, 0.4226183f,
759 0.4067366f, 0.3907311f, 0.3746066f, 0.3583679f, 0.3420201f, 0.3255682f,
760 0.3090170f, 0.2923717f, 0.2756374f, 0.2588190f, 0.2419219f, 0.2249511f,
761 0.2079117f, 0.1908090f, 0.1736482f, 0.1564345f, 0.1391731f, 0.1218693f,
762 0.1045285f, 0.0871557f, 0.0697565f, 0.0523360f, 0.0348995f, 0.0174524f,
763 0.0000000f, -0.0174524f, -0.0348995f, -0.0523360f, -0.0697565f, -0.0871557f,
764 -0.1045285f, -0.1218693f, -0.1391731f, -0.1564345f, -0.1736482f, -0.1908090f,
765 -0.2079117f, -0.2249511f, -0.2419219f, -0.2588190f, -0.2756374f, -0.2923717f,
766 -0.3090170f, -0.3255682f, -0.3420201f, -0.3583679f, -0.3746066f, -0.3907311f,
767 -0.4067366f, -0.4226183f, -0.4383711f, -0.4539905f, -0.4694716f, -0.4848096f,
768 -0.5000000f, -0.5150381f, -0.5299193f, -0.5446390f, -0.5591929f, -0.5735764f,
769 -0.5877853f, -0.6018150f, -0.6156615f, -0.6293204f, -0.6427876f, -0.6560590f,
770 -0.6691306f, -0.6819984f, -0.6946584f, -0.7071068f, -0.7193398f, -0.7313537f,
771 -0.7431448f, -0.7547096f, -0.7660444f, -0.7771460f, -0.7880108f, -0.7986355f,
772 -0.8090170f, -0.8191520f, -0.8290376f, -0.8386706f, -0.8480481f, -0.8571673f,
773 -0.8660254f, -0.8746197f, -0.8829476f, -0.8910065f, -0.8987940f, -0.9063078f,
774 -0.9135455f, -0.9205049f, -0.9271839f, -0.9335804f, -0.9396926f, -0.9455186f,
775 -0.9510565f, -0.9563048f, -0.9612617f, -0.9659258f, -0.9702957f, -0.9743701f,
776 -0.9781476f, -0.9816272f, -0.9848078f, -0.9876883f, -0.9902681f, -0.9925462f,
777 -0.9945219f, -0.9961947f, -0.9975641f, -0.9986295f, -0.9993908f, -0.9998477f,
778 -1.0000000f, -0.9998477f, -0.9993908f, -0.9986295f, -0.9975641f, -0.9961947f,
779 -0.9945219f, -0.9925462f, -0.9902681f, -0.9876883f, -0.9848078f, -0.9816272f,
780 -0.9781476f, -0.9743701f, -0.9702957f, -0.9659258f, -0.9612617f, -0.9563048f,
781 -0.9510565f, -0.9455186f, -0.9396926f, -0.9335804f, -0.9271839f, -0.9205049f,
782 -0.9135455f, -0.9063078f, -0.8987940f, -0.8910065f, -0.8829476f, -0.8746197f,
783 -0.8660254f, -0.8571673f, -0.8480481f, -0.8386706f, -0.8290376f, -0.8191520f,
784 -0.8090170f, -0.7986355f, -0.7880108f, -0.7771460f, -0.7660444f, -0.7547096f,
785 -0.7431448f, -0.7313537f, -0.7193398f, -0.7071068f, -0.6946584f, -0.6819984f,
786 -0.6691306f, -0.6560590f, -0.6427876f, -0.6293204f, -0.6156615f, -0.6018150f,
787 -0.5877853f, -0.5735764f, -0.5591929f, -0.5446390f, -0.5299193f, -0.5150381f,
788 -0.5000000f, -0.4848096f, -0.4694716f, -0.4539905f, -0.4383711f, -0.4226183f,
789 -0.4067366f, -0.3907311f, -0.3746066f, -0.3583679f, -0.3420201f, -0.3255682f,
790 -0.3090170f, -0.2923717f, -0.2756374f, -0.2588190f, -0.2419219f, -0.2249511f,
791 -0.2079117f, -0.1908090f, -0.1736482f, -0.1564345f, -0.1391731f, -0.1218693f,
792 -0.1045285f, -0.0871557f, -0.0697565f, -0.0523360f, -0.0348995f, -0.0174524f,
793 -0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
794 0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
795 0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
796 0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
797 0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
798 0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
799 0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
800 0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
801 0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
802 0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
803 0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
804 0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
805 0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
806 0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
807 0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
813 sincos( int angle, float& cosval, float& sinval )
815 angle += (angle < 0 ? 360 : 0);
816 sinval = SinTable[angle];
817 cosval = SinTable[450 - angle];
821 constructs polygon that represents elliptic arc.
823 void ellipse2Poly( Point center, Size axes, int angle,
824 int arc_start, int arc_end,
825 int delta, vector<Point>& pts )
828 double size_a = axes.width, size_b = axes.height;
829 double cx = center.x, cy = center.y;
830 Point prevPt(INT_MIN,INT_MIN);
838 if( arc_start > arc_end )
844 while( arc_start < 0 )
849 while( arc_end > 360 )
854 if( arc_end - arc_start > 360 )
859 sincos( angle, alpha, beta );
862 for( i = arc_start; i < arc_end + delta; i += delta )
866 if( angle > arc_end )
871 x = size_a * SinTable[450-angle];
872 y = size_b * SinTable[angle];
874 pt.x = cvRound( cx + x * alpha - y * beta );
875 pt.y = cvRound( cy - x * beta - y * alpha );
881 pts.push_back(pts[0]);
886 EllipseEx( Mat& img, Point center, Size axes,
887 int angle, int arc_start, int arc_end,
888 const void* color, int thickness, int line_type )
890 CV_Assert( axes.width >= 0 && axes.height >= 0 );
891 int delta = (std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT;
892 delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5;
895 ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, v );
898 PolyLine( img, &v[0], (int)v.size(), false, color, thickness, line_type, XY_SHIFT );
899 else if( arc_end - arc_start >= 360 )
900 FillConvexPoly( img, &v[0], (int)v.size(), color, line_type, XY_SHIFT );
904 vector<PolyEdge> edges;
905 CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT );
906 FillEdgeCollection( img, edges, color );
911 /****************************************************************************************\
913 \****************************************************************************************/
915 /* helper macros: filling horizontal row */
916 #define ICV_HLINE( ptr, xl, xr, color, pix_size ) \
918 uchar* hline_ptr = (uchar*)(ptr) + (xl)*(pix_size); \
919 uchar* hline_max_ptr = (uchar*)(ptr) + (xr)*(pix_size); \
921 for( ; hline_ptr <= hline_max_ptr; hline_ptr += (pix_size))\
924 for( hline_j = 0; hline_j < (pix_size); hline_j++ ) \
926 hline_ptr[hline_j] = ((uchar*)color)[hline_j]; \
932 /* filling convex polygon. v - array of vertices, ntps - number of points */
934 FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_type, int shift )
943 int delta = shift ? 1 << (shift - 1) : 0;
944 int i, y, imin = 0, left = 0, right = 1, x1, x2;
946 int xmin, xmax, ymin, ymax;
947 uchar* ptr = img.data;
948 Size size = img.size();
949 int pix_size = (int)img.elemSize();
953 if( line_type < CV_AA )
954 delta1 = delta2 = XY_ONE >> 1;
956 delta1 = XY_ONE - 1, delta2 = 0;
959 p0.x <<= XY_SHIFT - shift;
960 p0.y <<= XY_SHIFT - shift;
962 assert( 0 <= shift && shift <= XY_SHIFT );
963 xmin = xmax = v[0].x;
964 ymin = ymax = v[0].y;
966 for( i = 0; i < npts; i++ )
975 ymax = std::max( ymax, p.y );
976 xmax = std::max( xmax, p.x );
977 xmin = MIN( xmin, p.x );
979 p.x <<= XY_SHIFT - shift;
980 p.y <<= XY_SHIFT - shift;
987 pt0.x = p0.x >> XY_SHIFT;
988 pt0.y = p0.y >> XY_SHIFT;
989 pt1.x = p.x >> XY_SHIFT;
990 pt1.y = p.y >> XY_SHIFT;
991 Line( img, pt0, pt1, color, line_type );
994 Line2( img, p0, p, color );
997 LineAA( img, p0, p, color );
1001 xmin = (xmin + delta) >> shift;
1002 xmax = (xmax + delta) >> shift;
1003 ymin = (ymin + delta) >> shift;
1004 ymax = (ymax + delta) >> shift;
1006 if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height )
1009 ymax = MIN( ymax, size.height - 1 );
1010 edge[0].idx = edge[1].idx = imin;
1012 edge[0].ye = edge[1].ye = y = ymin;
1014 edge[1].di = npts - 1;
1020 if( line_type < CV_AA || y < ymax || y == ymin )
1022 for( i = 0; i < 2; i++ )
1024 if( y >= edge[i].ye )
1026 int idx = edge[i].idx, di = edge[i].di;
1027 int xs = 0, xe, ye, ty = 0;
1031 ty = (v[idx].y + delta) >> shift;
1032 if( ty > y || edges == 0 )
1036 idx -= ((idx < npts) - 1) & npts; /* idx -= idx >= npts ? npts : 0 */
1041 xs <<= XY_SHIFT - shift;
1042 xe = v[idx].x << (XY_SHIFT - shift);
1049 edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y));
1056 if( edge[left].x > edge[right].x )
1067 int xx1 = (x1 + delta1) >> XY_SHIFT;
1068 int xx2 = (x2 + delta2) >> XY_SHIFT;
1070 if( xx2 >= 0 && xx1 < size.width )
1074 if( xx2 >= size.width )
1075 xx2 = size.width - 1;
1076 ICV_HLINE( ptr, xx1, xx2, color, pix_size );
1080 x1 += edge[left].dx;
1081 x2 += edge[right].dx;
1087 while( ++y <= ymax );
1091 /******** Arbitrary polygon **********/
1094 CollectPolyEdges( Mat& img, const Point* v, int count, vector<PolyEdge>& edges,
1095 const void* color, int line_type, int shift, Point offset )
1097 int i, delta = offset.y + (shift ? 1 << (shift - 1) : 0);
1098 Point pt0 = v[count-1], pt1;
1099 pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift);
1100 pt0.y = (pt0.y + delta) >> shift;
1102 edges.reserve( edges.size() + count );
1104 for( i = 0; i < count; i++, pt0 = pt1 )
1110 pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift);
1111 pt1.y = (pt1.y + delta) >> shift;
1113 if( line_type < CV_AA )
1115 t0.y = pt0.y; t1.y = pt1.y;
1116 t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT;
1117 t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT;
1118 Line( img, t0, t1, color, line_type );
1122 t0.x = pt0.x; t1.x = pt1.x;
1123 t0.y = pt0.y << XY_SHIFT;
1124 t1.y = pt1.y << XY_SHIFT;
1125 LineAA( img, t0, t1, color );
1128 if( pt0.y == pt1.y )
1143 edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
1144 edges.push_back(edge);
1150 bool operator ()(const PolyEdge& e1, const PolyEdge& e2)
1152 return e1.y0 - e2.y0 ? e1.y0 < e2.y0 :
1153 e1.x - e2.x ? e1.x < e2.x : e1.dx < e2.dx;
1157 /**************** helper macros and functions for sequence/contour processing ***********/
1160 FillEdgeCollection( Mat& img, vector<PolyEdge>& edges, const void* color )
1163 int i, y, total = (int)edges.size();
1164 Size size = img.size();
1166 int y_max = INT_MIN, x_max = INT_MIN, y_min = INT_MAX, x_min = INT_MAX;
1167 int pix_size = (int)img.elemSize();
1172 for( i = 0; i < total; i++ )
1174 PolyEdge& e1 = edges[i];
1175 assert( e1.y0 < e1.y1 );
1176 y_min = std::min( y_min, e1.y0 );
1177 y_max = std::max( y_max, e1.y1 );
1178 x_min = std::min( x_min, e1.x );
1179 x_max = std::max( x_max, e1.x );
1182 if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= (size.width<<XY_SHIFT) )
1185 std::sort( edges.begin(), edges.end(), CmpEdges() );
1189 edges.push_back(tmp); // after this point we do not add
1190 // any elements to edges, thus we can use pointers
1194 y_max = MIN( y_max, size.height );
1196 for( y = e->y0; y < y_max; y++ )
1198 PolyEdge *last, *prelast, *keep_prelast;
1201 int clipline = y < 0;
1205 while( last || e->y0 == y )
1207 if( last && last->y1 == y )
1209 // exclude edge if y reachs its lower point
1210 prelast->next = last->next;
1214 keep_prelast = prelast;
1215 if( last && (e->y0 > y || last->x < e->x) )
1217 // go to the next edge in active list
1221 else if( i < total )
1223 // insert new edge into active list if y reachs its upper point
1236 // convert x's from fixed-point to image coordinates
1237 uchar *timg = img.data + y * img.step;
1238 int x1 = keep_prelast->x;
1239 int x2 = prelast->x;
1249 x1 = (x1 + XY_ONE - 1) >> XY_SHIFT;
1250 x2 = x2 >> XY_SHIFT;
1252 // clip and draw the line
1253 if( x1 < size.width && x2 >= 0 )
1257 if( x2 >= size.width )
1258 x2 = size.width - 1;
1259 ICV_HLINE( timg, x1, x2, color, pix_size );
1262 keep_prelast->x += keep_prelast->dx;
1263 prelast->x += prelast->dx;
1268 // sort edges (using bubble sort)
1276 while( last != keep_prelast && last->next != 0 )
1278 PolyEdge *te = last->next;
1281 if( last->x > te->x )
1284 last->next = te->next;
1295 keep_prelast = prelast;
1297 while( sort_flag && keep_prelast != tmp.next && keep_prelast != &tmp );
1302 /* draws simple or filled circle */
1304 Circle( Mat& img, Point center, int radius, const void* color, int fill )
1306 Size size = img.size();
1307 size_t step = img.step;
1308 int pix_size = (int)img.elemSize();
1309 uchar* ptr = img.data;
1310 int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
1311 int inside = center.x >= radius && center.x < size.width - radius &&
1312 center.y >= radius && center.y < size.height - radius;
1314 #define ICV_PUT_POINT( ptr, x ) \
1315 CV_MEMCPY_CHAR( ptr + (x)*pix_size, color, pix_size );
1320 int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
1321 int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
1325 uchar *tptr0 = ptr + y11 * step;
1326 uchar *tptr1 = ptr + y12 * step;
1330 ICV_PUT_POINT( tptr0, x11 );
1331 ICV_PUT_POINT( tptr1, x11 );
1332 ICV_PUT_POINT( tptr0, x12 );
1333 ICV_PUT_POINT( tptr1, x12 );
1337 ICV_HLINE( tptr0, x11, x12, color, pix_size );
1338 ICV_HLINE( tptr1, x11, x12, color, pix_size );
1341 tptr0 = ptr + y21 * step;
1342 tptr1 = ptr + y22 * step;
1346 ICV_PUT_POINT( tptr0, x21 );
1347 ICV_PUT_POINT( tptr1, x21 );
1348 ICV_PUT_POINT( tptr0, x22 );
1349 ICV_PUT_POINT( tptr1, x22 );
1353 ICV_HLINE( tptr0, x21, x22, color, pix_size );
1354 ICV_HLINE( tptr1, x21, x22, color, pix_size );
1357 else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
1361 x11 = std::max( x11, 0 );
1362 x12 = MIN( x12, size.width - 1 );
1365 if( (unsigned)y11 < (unsigned)size.height )
1367 uchar *tptr = ptr + y11 * step;
1372 ICV_PUT_POINT( tptr, x11 );
1373 if( x12 < size.width )
1374 ICV_PUT_POINT( tptr, x12 );
1377 ICV_HLINE( tptr, x11, x12, color, pix_size );
1380 if( (unsigned)y12 < (unsigned)size.height )
1382 uchar *tptr = ptr + y12 * 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( x21 < size.width && x22 >= 0 )
1399 x21 = std::max( x21, 0 );
1400 x22 = MIN( x22, size.width - 1 );
1403 if( (unsigned)y21 < (unsigned)size.height )
1405 uchar *tptr = ptr + y21 * step;
1410 ICV_PUT_POINT( tptr, x21 );
1411 if( x22 < size.width )
1412 ICV_PUT_POINT( tptr, x22 );
1415 ICV_HLINE( tptr, x21, x22, color, pix_size );
1418 if( (unsigned)y22 < (unsigned)size.height )
1420 uchar *tptr = ptr + y22 * 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 );
1438 mask = (err <= 0) - 1;
1440 err -= minus & mask;
1445 #undef ICV_PUT_POINT
1450 ThickLine( Mat& img, Point p0, Point p1, const void* color,
1451 int thickness, int line_type, int flags, int shift )
1453 static const double INV_XY_ONE = 1./XY_ONE;
1455 p0.x <<= XY_SHIFT - shift;
1456 p0.y <<= XY_SHIFT - shift;
1457 p1.x <<= XY_SHIFT - shift;
1458 p1.y <<= XY_SHIFT - shift;
1460 if( thickness <= 1 )
1462 if( line_type < CV_AA )
1464 if( line_type == 1 || line_type == 4 || shift == 0 )
1466 p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
1467 p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
1468 p1.x = (p1.x + (XY_ONE>>1)) >> XY_SHIFT;
1469 p1.y = (p1.y + (XY_ONE>>1)) >> XY_SHIFT;
1470 Line( img, p0, p1, color, line_type );
1473 Line2( img, p0, p1, color );
1476 LineAA( img, p0, p1, color );
1480 Point pt[4], dp = Point(0,0);
1481 double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE;
1482 double r = dx * dx + dy * dy;
1483 int i, oddThickness = thickness & 1;
1484 thickness <<= XY_SHIFT - 1;
1486 if( fabs(r) > DBL_EPSILON )
1488 r = (thickness + oddThickness*XY_ONE*0.5)/std::sqrt(r);
1489 dp.x = cvRound( dy * r );
1490 dp.y = cvRound( dx * r );
1492 pt[0].x = p0.x + dp.x;
1493 pt[0].y = p0.y + dp.y;
1494 pt[1].x = p0.x - dp.x;
1495 pt[1].y = p0.y - dp.y;
1496 pt[2].x = p1.x - dp.x;
1497 pt[2].y = p1.y - dp.y;
1498 pt[3].x = p1.x + dp.x;
1499 pt[3].y = p1.y + dp.y;
1501 FillConvexPoly( img, pt, 4, color, line_type, XY_SHIFT );
1504 for( i = 0; i < 2; i++ )
1508 if( line_type < CV_AA )
1511 center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
1512 center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
1513 Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 );
1517 EllipseEx( img, p0, cvSize(thickness, thickness),
1518 0, 0, 360, color, -1, line_type );
1528 PolyLine( Mat& img, const Point* v, int count, bool is_closed,
1529 const void* color, int thickness,
1530 int line_type, int shift )
1532 if( !v || count <= 0 )
1535 int i = is_closed ? count - 1 : 0;
1536 int flags = 2 + !is_closed;
1538 CV_Assert( 0 <= shift && shift <= XY_SHIFT && thickness >= 0 );
1541 for( i = !is_closed; i < count; i++ )
1544 ThickLine( img, p0, p, color, thickness, line_type, flags, shift );
1550 /****************************************************************************************\
1551 * External functions *
1552 \****************************************************************************************/
1554 void line( Mat& img, Point pt1, Point pt2, const Scalar& color,
1555 int thickness, int line_type, int shift )
1557 if( line_type == CV_AA && img.depth() != CV_8U )
1560 CV_Assert( 0 <= thickness && thickness <= 255 );
1561 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1564 scalarToRawData( color, buf, img.type(), 0 );
1565 ThickLine( img, pt1, pt2, buf, thickness, line_type, 3, shift );
1568 void rectangle( Mat& img, Point pt1, Point pt2,
1569 const Scalar& color, int thickness,
1570 int line_type, int shift )
1572 if( line_type == CV_AA && img.depth() != CV_8U )
1575 CV_Assert( thickness <= 255 );
1576 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1579 scalarToRawData(color, buf, img.type(), 0);
1590 if( thickness >= 0 )
1591 PolyLine( img, pt, 4, true, buf, thickness, line_type, shift );
1593 FillConvexPoly( img, pt, 4, buf, line_type, shift );
1597 void circle( Mat& img, Point center, int radius,
1598 const Scalar& color, int thickness, int line_type, int shift )
1600 if( line_type == CV_AA && img.depth() != CV_8U )
1603 CV_Assert( radius >= 0 && thickness <= 255 &&
1604 0 <= shift && shift <= XY_SHIFT );
1607 scalarToRawData(color, buf, img.type(), 0);
1609 if( thickness > 1 || line_type >= CV_AA )
1611 center.x <<= XY_SHIFT - shift;
1612 center.y <<= XY_SHIFT - shift;
1613 radius <<= XY_SHIFT - shift;
1614 EllipseEx( img, center, Size(radius, radius),
1615 0, 0, 360, buf, thickness, line_type );
1618 Circle( img, center, radius, buf, thickness < 0 );
1622 void ellipse( Mat& img, Point center, Size axes,
1623 double angle, double start_angle, double end_angle,
1624 const Scalar& color, int thickness, int line_type, int shift )
1626 if( line_type == CV_AA && img.depth() != CV_8U )
1629 CV_Assert( axes.width >= 0 && axes.height >= 0 &&
1630 thickness <= 255 && 0 <= shift && shift <= XY_SHIFT );
1633 scalarToRawData(color, buf, img.type(), 0);
1635 int _angle = cvRound(angle);
1636 int _start_angle = cvRound(start_angle);
1637 int _end_angle = cvRound(end_angle);
1638 center.x <<= XY_SHIFT - shift;
1639 center.y <<= XY_SHIFT - shift;
1640 axes.width <<= XY_SHIFT - shift;
1641 axes.height <<= XY_SHIFT - shift;
1643 EllipseEx( img, center, axes, _angle, _start_angle,
1644 _end_angle, buf, thickness, line_type );
1647 void ellipse(Mat& img, const RotatedRect& box, const Scalar& color,
1648 int thickness, int lineType)
1650 if( lineType == CV_AA && img.depth() != CV_8U )
1653 CV_Assert( box.size.width >= 0 && box.size.height >= 0 &&
1657 scalarToRawData(color, buf, img.type(), 0);
1659 int _angle = cvRound(box.angle);
1660 Point center(cvRound(box.center.x*(1 << XY_SHIFT)),
1661 cvRound(box.center.y*(1 << XY_SHIFT)));
1662 Size axes(cvRound(box.size.width*(1 << (XY_SHIFT - 1))),
1663 cvRound(box.size.height*(1 << (XY_SHIFT - 1))));
1664 EllipseEx( img, center, axes, _angle, 0, 360, buf, thickness, lineType );
1667 void fillConvexPoly( Mat& img, const Point* pts, int npts,
1668 const Scalar& color, int line_type, int shift )
1670 if( !pts || npts <= 0 )
1673 if( line_type == CV_AA && img.depth() != CV_8U )
1677 CV_Assert( 0 <= shift && shift <= XY_SHIFT );
1678 scalarToRawData(color, buf, img.type(), 0);
1679 FillConvexPoly( img, pts, npts, buf, line_type, shift );
1683 void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours,
1684 const Scalar& color, int line_type,
1685 int shift, Point offset )
1687 if( line_type == CV_AA && img.depth() != CV_8U )
1690 CV_Assert( pts && npts && ncontours >= 0 && 0 <= shift && shift <= XY_SHIFT );
1693 scalarToRawData(color, buf, img.type(), 0);
1695 vector<PolyEdge> edges;
1698 for( i = 0; i < ncontours; i++ )
1701 edges.reserve( total + 1 );
1702 for( i = 0; i < ncontours; i++ )
1703 CollectPolyEdges( img, pts[i], npts[i], edges, buf, line_type, shift, offset );
1705 FillEdgeCollection(img, edges, buf);
1709 void polylines( Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed,
1710 const Scalar& color, int thickness, int line_type, int shift )
1712 if( line_type == CV_AA && img.depth() != CV_8U )
1715 CV_Assert( pts && npts && ncontours >= 0 &&
1716 0 <= thickness && thickness <= 255 &&
1717 0 <= shift && shift <= XY_SHIFT );
1720 scalarToRawData( color, buf, img.type(), 0 );
1722 for( int i = 0; i < ncontours; i++ )
1723 PolyLine( img, pts[i], npts[i], isClosed, buf, thickness, line_type, shift );
1727 enum { FONT_SIZE_SHIFT=8, FONT_ITALIC_ALPHA=(1 << 8),
1728 FONT_ITALIC_DIGIT=(2 << 8), FONT_ITALIC_PUNCT=(4 << 8),
1729 FONT_ITALIC_BRACES=(8 << 8), FONT_HAVE_GREEK=(16 << 8),
1730 FONT_HAVE_CYRILLIC=(32 << 8) };
1732 static const int HersheyPlain[] = {
1733 (5 + 4*16) + FONT_HAVE_GREEK,
1734 199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
1735 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
1736 215, 190, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1737 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 193, 84,
1738 194, 85, 86, 87, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1739 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
1740 195, 223, 196, 88 };
1742 static const int HersheyPlainItalic[] = {
1743 (5 + 4*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1744 199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
1745 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
1746 215, 190, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1747 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 193, 84,
1748 194, 85, 86, 87, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
1749 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
1750 195, 223, 196, 88 };
1752 static const int HersheyComplexSmall[] = {
1753 (6 + 7*16) + FONT_HAVE_GREEK,
1754 1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
1755 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 2213, 1241, 1238, 1242,
1756 1215, 1273, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013,
1757 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1223, 1084,
1758 1224, 1247, 586, 1249, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,
1759 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126,
1760 1225, 1229, 1226, 1246 };
1762 static const int HersheyComplexSmallItalic[] = {
1763 (6 + 7*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1764 1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
1765 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 1213, 1241, 1238, 1242,
1766 1215, 1273, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
1767 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1223, 1084,
1768 1224, 1247, 586, 1249, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161,
1769 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176,
1770 1225, 1229, 1226, 1246 };
1772 static const int HersheySimplex[] = {
1773 (9 + 12*16) + FONT_HAVE_GREEK,
1774 2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
1775 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
1776 715, 690, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513,
1777 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 693, 584,
1778 694, 2247, 586, 2249, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611,
1779 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626,
1780 695, 723, 696, 2246 };
1782 static const int HersheyDuplex[] = {
1783 (9 + 12*16) + FONT_HAVE_GREEK,
1784 2199, 2714, 2728, 2732, 2719, 2733, 2718, 2727, 2721, 2722, 2723, 2725, 2711, 2724, 2710, 2720,
1785 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2712, 2713, 2730, 2726, 2731,
1786 2715, 2734, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513,
1787 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2223, 2084,
1788 2224, 2247, 587, 2249, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611,
1789 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626,
1790 2225, 2229, 2226, 2246 };
1792 static const int HersheyComplex[] = {
1793 (9 + 12*16) + FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
1794 2199, 2214, 2217, 2275, 2274, 2271, 2272, 2216, 2221, 2222, 2219, 2232, 2211, 2231, 2210, 2220,
1795 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2212, 2213, 2241, 2238, 2242,
1796 2215, 2273, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
1797 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2223, 2084,
1798 2224, 2247, 587, 2249, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111,
1799 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126,
1800 2225, 2229, 2226, 2246 };
1802 static const int HersheyComplexItalic[] = {
1803 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT +
1804 FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
1805 2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
1806 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
1807 2765, 2273, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063,
1808 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2223, 2084,
1809 2224, 2247, 587, 2249, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161,
1810 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176,
1811 2225, 2229, 2226, 2246 };
1813 static const int HersheyTriplex[] = {
1814 (9 + 12*16) + FONT_HAVE_GREEK,
1815 2199, 3214, 3228, 3232, 3219, 3233, 3218, 3227, 3221, 3222, 3223, 3225, 3211, 3224, 3210, 3220,
1816 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3212, 3213, 3230, 3226, 3231,
1817 3215, 3234, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013,
1818 2014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 2223, 2084,
1819 2224, 2247, 587, 2249, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111,
1820 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126,
1821 2225, 2229, 2226, 2246 };
1823 static const int HersheyTriplexItalic[] = {
1824 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT +
1825 FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
1826 2199, 3264, 3278, 3282, 3269, 3233, 3268, 3277, 3271, 3272, 3223, 3225, 3261, 3224, 3260, 3270,
1827 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3262, 3263, 3230, 3226, 3231,
1828 3265, 3234, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063,
1829 2064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 2223, 2084,
1830 2224, 2247, 587, 2249, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161,
1831 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176,
1832 2225, 2229, 2226, 2246 };
1834 static const int HersheyScriptSimplex[] = {
1835 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
1836 2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
1837 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
1838 715, 690, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
1839 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 693, 584,
1840 694, 2247, 586, 2249, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661,
1841 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676,
1842 695, 723, 696, 2246 };
1844 static const int HersheyScriptComplex[] = {
1845 (9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
1846 2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
1847 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
1848 2215, 2273, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563,
1849 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2223, 2084,
1850 2224, 2247, 586, 2249, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661,
1851 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676,
1852 2225, 2229, 2226, 2246 };
1855 static const int* getFontData(int fontFace)
1857 bool isItalic = (fontFace & FONT_ITALIC) != 0;
1858 const int* ascii = 0;
1860 switch( fontFace & 15 )
1862 case FONT_HERSHEY_SIMPLEX:
1863 ascii = HersheySimplex;
1865 case FONT_HERSHEY_PLAIN:
1866 ascii = !isItalic ? HersheyPlain : HersheyPlainItalic;
1868 case FONT_HERSHEY_DUPLEX:
1869 ascii = HersheyDuplex;
1871 case FONT_HERSHEY_COMPLEX:
1872 ascii = !isItalic ? HersheyComplex : HersheyComplexItalic;
1874 case FONT_HERSHEY_TRIPLEX:
1875 ascii = !isItalic ? HersheyTriplex : HersheyTriplexItalic;
1877 case FONT_HERSHEY_COMPLEX_SMALL:
1878 ascii = !isItalic ? HersheyComplexSmall : HersheyComplexSmallItalic;
1880 case FONT_HERSHEY_SCRIPT_SIMPLEX:
1881 ascii = HersheyScriptSimplex;
1883 case FONT_HERSHEY_SCRIPT_COMPLEX:
1884 ascii = HersheyScriptComplex;
1887 CV_Error( CV_StsOutOfRange, "Unknown font type" );
1893 void putText( Mat& img, const string& text, Point org,
1894 int fontFace, double fontScale, Scalar color,
1895 int thickness, int line_type, bool bottomLeftOrigin )
1898 const int* ascii = getFontData(fontFace);
1901 scalarToRawData(color, buf, img.type(), 0);
1903 int base_line = -(ascii[0] & 15);
1904 int hscale = cvRound(fontScale*XY_ONE), vscale = hscale;
1906 if( line_type == CV_AA && img.type() != CV_8U )
1909 if( bottomLeftOrigin )
1912 int view_x = org.x << XY_SHIFT;
1913 int view_y = (org.y << XY_SHIFT) + base_line*vscale;
1915 pts.reserve(1 << 10);
1916 const char **faces = cv::g_HersheyGlyphs;
1918 for( int i = 0; text[i] != '\0'; i++ )
1920 int c = (uchar)text[i];
1923 if( c >= 127 || c < ' ' )
1926 const char* ptr = faces[ascii[(c-' ')+1]];
1927 p.x = (uchar)ptr[0] - 'R';
1928 p.y = (uchar)ptr[1] - 'R';
1929 int dx = p.y*hscale;
1930 view_x -= p.x*hscale;
1935 if( *ptr == ' ' || !*ptr )
1937 if( pts.size() > 1 )
1938 PolyLine( img, &pts[0], (int)pts.size(), false, buf, thickness, line_type, XY_SHIFT );
1945 p.x = (uchar)ptr[0] - 'R';
1946 p.y = (uchar)ptr[1] - 'R';
1948 pts.push_back(Point(p.x*hscale + view_x, p.y*vscale + view_y));
1955 Size getTextSize( const string& text, int fontFace, double fontScale, int thickness, int* _base_line)
1959 const char **faces = cv::g_HersheyGlyphs;
1960 const int* ascii = getFontData(fontFace);
1962 int base_line = (ascii[0] & 15);
1963 int cap_line = (ascii[0] >> 4) & 15;
1964 size.height = cvRound((cap_line + base_line)*fontScale + (thickness+1)/2);
1966 for( int i = 0; text[i] != '\0'; i++ )
1968 int c = (uchar)text[i];
1971 if( c >= 127 || c < ' ' )
1974 const char* ptr = faces[ascii[(c-' ')+1]];
1975 p.x = (uchar)ptr[0] - 'R';
1976 p.y = (uchar)ptr[1] - 'R';
1977 view_x += (p.y - p.x)*fontScale;
1980 size.width = cvRound(view_x + thickness);
1982 *_base_line = cvRound(base_line*fontScale + thickness*0.5);
1988 static const int CodeDeltas[8][2] =
1989 { {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
1991 #define CV_ADJUST_EDGE_COUNT( count, seq ) \
1992 ((count) -= ((count) == (seq)->total && !CV_IS_SEQ_CLOSED(seq)))
1995 cvDrawContours( void* _img, CvSeq* contour,
1996 CvScalar _externalColor, CvScalar _holeColor,
1997 int maxLevel, int thickness,
1998 int line_type, CvPoint _offset )
2000 CvSeq *contour0 = contour, *h_next = 0;
2001 CvTreeNodeIterator iterator;
2002 cv::vector<cv::PolyEdge> edges;
2003 cv::vector<cv::Point> pts;
2004 cv::Scalar externalColor = _externalColor, holeColor = _holeColor;
2005 cv::Mat img = cv::cvarrToMat(_img);
2006 cv::Point offset = _offset;
2007 double ext_buf[4], hole_buf[4];
2009 if( line_type == CV_AA && img.depth() != CV_8U )
2015 CV_Assert( thickness <= 255 );
2017 scalarToRawData( externalColor, ext_buf, img.type(), 0 );
2018 scalarToRawData( holeColor, hole_buf, img.type(), 0 );
2022 h_next = contour->h_next;
2023 contour->h_next = 0;
2024 maxLevel = -maxLevel+1;
2027 cvInitTreeNodeIterator( &iterator, contour, maxLevel );
2028 while( (contour = (CvSeq*)cvNextTreeNode( &iterator )) != 0 )
2031 int i, count = contour->total;
2032 int elem_type = CV_MAT_TYPE(contour->flags);
2033 void* clr = (contour->flags & CV_SEQ_FLAG_HOLE) == 0 ? ext_buf : hole_buf;
2035 cvStartReadSeq( contour, &reader, 0 );
2039 if( CV_IS_SEQ_CHAIN_CONTOUR( contour ))
2041 cv::Point pt = ((CvChain*)contour)->origin;
2042 cv::Point prev_pt = pt;
2043 char prev_code = reader.ptr ? reader.ptr[0] : '\0';
2047 for( i = 0; i < count; i++ )
2050 CV_READ_SEQ_ELEM( code, reader );
2052 assert( (code & ~7) == 0 );
2054 if( code != prev_code )
2057 if( thickness >= 0 )
2058 cv::ThickLine( img, prev_pt, pt, clr, thickness, line_type, 2, 0 );
2064 pt.x += CodeDeltas[(int)code][0];
2065 pt.y += CodeDeltas[(int)code][1];
2068 if( thickness >= 0 )
2069 cv::ThickLine( img, prev_pt,
2070 cv::Point(((CvChain*)contour)->origin) + offset,
2071 clr, thickness, line_type, 2, 0 );
2073 cv::CollectPolyEdges(img, &pts[0], (int)pts.size(),
2074 edges, ext_buf, line_type, 0, offset);
2076 else if( CV_IS_SEQ_POLYLINE( contour ))
2078 CV_Assert( elem_type == CV_32SC2 );
2082 count -= !CV_IS_SEQ_CLOSED(contour);
2083 CV_READ_SEQ_ELEM( pt1, reader );
2088 for( i = 0; i < count; i++ )
2090 CV_READ_SEQ_ELEM( pt2, reader );
2092 if( thickness >= 0 )
2093 cv::ThickLine( img, pt1, pt2, clr, thickness, line_type, 2, shift );
2099 cv::CollectPolyEdges( img, &pts[0], (int)pts.size(),
2100 edges, ext_buf, line_type, 0, cv::Point() );
2105 cv::FillEdgeCollection( img, edges, ext_buf );
2107 if( h_next && contour0 )
2108 contour0->h_next = h_next;
2112 cvClipLine( CvSize size, CvPoint* pt1, CvPoint* pt2 )
2114 CV_Assert( pt1 && pt2 );
2115 return cv::clipLine( size, *(cv::Point*)pt1, *(cv::Point*)pt2 );
2120 cvEllipse2Poly( CvPoint center, CvSize axes, int angle,
2121 int arc_start, int arc_end, CvPoint* _pts, int delta )
2123 cv::vector<cv::Point> pts;
2124 cv::ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, pts );
2125 memcpy( _pts, &pts[0], pts.size()*sizeof(_pts[0]) );
2126 return (int)pts.size();
2130 cvColorToScalar( double packed_color, int type )
2134 if( CV_MAT_DEPTH( type ) == CV_8U )
2136 int icolor = cvRound( packed_color );
2137 if( CV_MAT_CN( type ) > 1 )
2139 scalar.val[0] = icolor & 255;
2140 scalar.val[1] = (icolor >> 8) & 255;
2141 scalar.val[2] = (icolor >> 16) & 255;
2142 scalar.val[3] = (icolor >> 24) & 255;
2146 scalar.val[0] = CV_CAST_8U( icolor );
2147 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2150 else if( CV_MAT_DEPTH( type ) == CV_8S )
2152 int icolor = cvRound( packed_color );
2153 if( CV_MAT_CN( type ) > 1 )
2155 scalar.val[0] = (char)icolor;
2156 scalar.val[1] = (char)(icolor >> 8);
2157 scalar.val[2] = (char)(icolor >> 16);
2158 scalar.val[3] = (char)(icolor >> 24);
2162 scalar.val[0] = CV_CAST_8S( icolor );
2163 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2168 int cn = CV_MAT_CN( type );
2172 scalar.val[0] = packed_color;
2173 scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
2176 scalar.val[0] = scalar.val[1] = packed_color;
2177 scalar.val[2] = scalar.val[3] = 0;
2180 scalar.val[0] = scalar.val[1] = scalar.val[2] = packed_color;
2184 scalar.val[0] = scalar.val[1] =
2185 scalar.val[2] = scalar.val[3] = packed_color;
2194 cvInitLineIterator( const CvArr* img, CvPoint pt1, CvPoint pt2,
2195 CvLineIterator* iterator, int connectivity,
2198 CV_Assert( iterator != 0 );
2199 cv::LineIterator li(cv::cvarrToMat(img), pt1, pt2, connectivity, left_to_right!=0);
2201 iterator->err = li.err;
2202 iterator->minus_delta = li.minusDelta;
2203 iterator->plus_delta = li.plusDelta;
2204 iterator->minus_step = li.minusStep;
2205 iterator->plus_step = li.plusStep;
2206 iterator->ptr = li.ptr;
2212 cvLine( CvArr* _img, CvPoint pt1, CvPoint pt2, CvScalar color,
2213 int thickness, int line_type, int shift )
2215 cv::Mat img = cv::cvarrToMat(_img);
2216 cv::line( img, pt1, pt2, color, thickness, line_type, shift );
2220 cvRectangle( CvArr* _img, CvPoint pt1, CvPoint pt2,
2221 CvScalar color, int thickness,
2222 int line_type, int shift )
2224 cv::Mat img = cv::cvarrToMat(_img);
2225 cv::rectangle( img, pt1, pt2, color, thickness, line_type, shift );
2229 cvCircle( CvArr* _img, CvPoint center, int radius,
2230 CvScalar color, int thickness, int line_type, int shift )
2232 cv::Mat img = cv::cvarrToMat(_img);
2233 cv::circle( img, center, radius, color, thickness, line_type, shift );
2237 cvEllipse( CvArr* _img, CvPoint center, CvSize axes,
2238 double angle, double start_angle, double end_angle,
2239 CvScalar color, int thickness, int line_type, int shift )
2241 cv::Mat img = cv::cvarrToMat(_img);
2242 cv::ellipse( img, center, axes, angle, start_angle, end_angle,
2243 color, thickness, line_type, shift );
2247 cvFillConvexPoly( CvArr* _img, const CvPoint *pts, int npts,
2248 CvScalar color, int line_type, int shift )
2250 cv::Mat img = cv::cvarrToMat(_img);
2251 cv::fillConvexPoly( img, (const cv::Point*)pts, npts,
2252 color, line_type, shift );
2256 cvFillPoly( CvArr* _img, CvPoint **pts, const int *npts, int ncontours,
2257 CvScalar color, int line_type, int shift )
2259 cv::Mat img = cv::cvarrToMat(_img);
2261 cv::fillPoly( img, (const cv::Point**)pts, npts, ncontours, color, line_type, shift );
2265 cvPolyLine( CvArr* _img, CvPoint **pts, const int *npts,
2266 int ncontours, int closed, CvScalar color,
2267 int thickness, int line_type, int shift )
2269 cv::Mat img = cv::cvarrToMat(_img);
2271 cv::polylines( img, (const cv::Point**)pts, npts, ncontours,
2272 closed != 0, color, thickness, line_type, shift );
2276 cvPutText( CvArr* _img, const char *text, CvPoint org, const CvFont *_font, CvScalar color )
2278 cv::Mat img = cv::cvarrToMat(_img);
2279 CV_Assert( text != 0 && _font != 0);
2280 cv::putText( img, text, org, _font->font_face, (_font->hscale+_font->vscale)*0.5,
2281 color, _font->thickness, _font->line_type,
2282 CV_IS_IMAGE(_img) && ((IplImage*)_img)->origin != 0 );
2287 cvInitFont( CvFont *font, int font_face, double hscale, double vscale,
2288 double shear, int thickness, int line_type )
2290 CV_Assert( font != 0 && hscale > 0 && vscale > 0 && thickness >= 0 );
2292 font->ascii = cv::getFontData(font_face);
2293 font->font_face = font_face;
2294 font->hscale = (float)hscale;
2295 font->vscale = (float)vscale;
2296 font->thickness = thickness;
2297 font->shear = (float)shear;
2298 font->greek = font->cyrillic = 0;
2299 font->line_type = line_type;
2303 cvGetTextSize( const char *text, const CvFont *_font, CvSize *_size, int *_base_line )
2305 CV_Assert(text != 0 && _font != 0);
2306 cv::Size size = cv::getTextSize( text, _font->font_face, (_font->hscale + _font->vscale)*0.5,
2307 _font->thickness, _base_line );