• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
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.
8 //
9 //
10 //                          License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42 
43 #include "test_precomp.hpp"
44 
45 using namespace std;
46 using namespace cv;
47 
48 //#define DRAW_TEST_IMAGE
49 
50 class CV_DrawingTest : public cvtest::BaseTest
51 {
52 public:
CV_DrawingTest()53     CV_DrawingTest(){}
54 protected:
55     void run( int );
56     virtual void draw( Mat& img ) = 0;
57     virtual int checkLineIterator( Mat& img) = 0;
58 };
59 
run(int)60 void CV_DrawingTest::run( int )
61 {
62     Mat testImg, valImg;
63     const string fname = "drawing/image.png";
64     string path = ts->get_data_path(), filename;
65     filename = path + fname;
66 
67     draw( testImg );
68 
69     valImg = imread( filename );
70     if( valImg.empty() )
71     {
72         imwrite( filename, testImg );
73         //ts->printf( ts->LOG, "test image can not be read");
74         //ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
75     }
76     else
77     {
78         // image should match exactly
79         float err = (float)cvtest::norm( testImg, valImg, NORM_L1 );
80         float Eps = 1;
81         if( err > Eps)
82         {
83             ts->printf( ts->LOG, "NORM_L1 between testImg and valImg is equal %f (larger than %f)\n", err, Eps );
84             ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
85         }
86         else
87         {
88             ts->set_failed_test_info(checkLineIterator( testImg ));
89         }
90     }
91     ts->set_failed_test_info(cvtest::TS::OK);
92 }
93 
94 class CV_DrawingTest_CPP : public CV_DrawingTest
95 {
96 public:
CV_DrawingTest_CPP()97     CV_DrawingTest_CPP() {}
98 protected:
99     virtual void draw( Mat& img );
100     virtual int checkLineIterator( Mat& img);
101 };
102 
draw(Mat & img)103 void CV_DrawingTest_CPP::draw( Mat& img )
104 {
105     Size imgSize( 600, 400 );
106     img.create( imgSize, CV_8UC3 );
107 
108     vector<Point> polyline(4);
109     polyline[0] = Point(0, 0);
110     polyline[1] = Point(imgSize.width, 0);
111     polyline[2] = Point(imgSize.width, imgSize.height);
112     polyline[3] = Point(0, imgSize.height);
113     const Point* pts = &polyline[0];
114     int n = (int)polyline.size();
115     fillPoly( img, &pts, &n, 1, Scalar::all(255) );
116 
117     Point p1(1,1), p2(3,3);
118     if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) )
119         circle( img, Point(300,100), 40, Scalar(0,0,255), 3 ); // draw
120 
121     p2 = Point(3,imgSize.height+1000);
122     if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) )
123         circle( img, Point(500,300), 50, cvColorToScalar(255,CV_8UC3), 5, 8, 1 ); // draw
124 
125     p1 = Point(imgSize.width,1), p2 = Point(imgSize.width,3);
126     if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) )
127         circle( img, Point(390,100), 10, Scalar(0,0,255), 3 ); // not draw
128 
129     p1 = Point(imgSize.width-1,1), p2 = Point(imgSize.width,3);
130     if( clipLine(Rect(0,0,imgSize.width,imgSize.height), p1, p2) && clipLine(imgSize, p1, p2) )
131         ellipse( img, Point(390,100), Size(20,30), 60, 0, 220.0, Scalar(0,200,0), 4 ); //draw
132 
133     ellipse( img, RotatedRect(Point(100,200),Size(200,100),160), Scalar(200,200,255), 5 );
134 
135     polyline.clear();
136     ellipse2Poly( Point(430,180), Size(100,150), 30, 0, 150, 20, polyline );
137     pts = &polyline[0];
138     n = (int)polyline.size();
139     polylines( img, &pts, &n, 1, false, Scalar(0,0,150), 4, CV_AA );
140     n = 0;
141     for( vector<Point>::const_iterator it = polyline.begin(); n < (int)polyline.size()-1; ++it, n++ )
142     {
143         line( img, *it, *(it+1), Scalar(50,250,100));
144     }
145 
146     polyline.clear();
147     ellipse2Poly( Point(500,300), Size(50,80), 0, 0, 180, 10, polyline );
148     pts = &polyline[0];
149     n = (int)polyline.size();
150     polylines( img, &pts, &n, 1, true, Scalar(100,200,100), 20 );
151     fillConvexPoly( img, pts, n, Scalar(0, 80, 0) );
152 
153     polyline.resize(8);
154     // external rectengular
155     polyline[0] = Point(0, 0);
156     polyline[1] = Point(80, 0);
157     polyline[2] = Point(80, 80);
158     polyline[3] = Point(0, 80);
159     // internal rectangular
160     polyline[4] = Point(20, 20);
161     polyline[5] = Point(60, 20);
162     polyline[6] = Point(60, 60);
163     polyline[7] = Point(20, 60);
164     const Point* ppts[] = {&polyline[0], &polyline[0]+4};
165     int pn[] = {4, 4};
166     fillPoly( img, ppts, pn, 2, Scalar(100, 100, 0), 8, 0, Point(500, 20) );
167 
168     rectangle( img, Point(0, 300), Point(50, 398), Scalar(0,0,255) );
169 
170     string text1 = "OpenCV";
171     int baseline = 0, thickness = 3, fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
172     float fontScale = 2;
173     Size textSize = getTextSize( text1, fontFace, fontScale, thickness, &baseline);
174     baseline += thickness;
175     Point textOrg((img.cols - textSize.width)/2, (img.rows + textSize.height)/2);
176     rectangle(img, textOrg + Point(0, baseline), textOrg + Point(textSize.width, -textSize.height), Scalar(0,0,255));
177     line(img, textOrg + Point(0, thickness), textOrg + Point(textSize.width, thickness), Scalar(0, 0, 255));
178     putText(img, text1, textOrg, fontFace, fontScale, Scalar(150,0,150), thickness, 8);
179 
180     string text2 = "abcdefghijklmnopqrstuvwxyz1234567890";
181     Scalar color(200,0,0);
182     fontScale = 0.5, thickness = 1;
183     int dist = 5;
184 
185     textSize = getTextSize( text2, FONT_HERSHEY_SIMPLEX, fontScale, thickness, &baseline);
186     textOrg = Point(5,5)+Point(0,textSize.height+dist);
187     putText(img, text2, textOrg, FONT_HERSHEY_SIMPLEX, fontScale, color, thickness, CV_AA);
188 
189     fontScale = 1;
190     textSize = getTextSize( text2, FONT_HERSHEY_PLAIN, fontScale, thickness, &baseline);
191     textOrg += Point(0,textSize.height+dist);
192     putText(img, text2, textOrg, FONT_HERSHEY_PLAIN, fontScale, color, thickness, CV_AA);
193 
194     fontScale = 0.5;
195     textSize = getTextSize( text2, FONT_HERSHEY_DUPLEX, fontScale, thickness, &baseline);
196     textOrg += Point(0,textSize.height+dist);
197     putText(img, text2, textOrg, FONT_HERSHEY_DUPLEX, fontScale, color, thickness, CV_AA);
198 
199     textSize = getTextSize( text2, FONT_HERSHEY_COMPLEX, fontScale, thickness, &baseline);
200     textOrg += Point(0,textSize.height+dist);
201     putText(img, text2, textOrg, FONT_HERSHEY_COMPLEX, fontScale, color, thickness, CV_AA);
202 
203     textSize = getTextSize( text2, FONT_HERSHEY_TRIPLEX, fontScale, thickness, &baseline);
204     textOrg += Point(0,textSize.height+dist);
205     putText(img, text2, textOrg, FONT_HERSHEY_TRIPLEX, fontScale, color, thickness, CV_AA);
206 
207     fontScale = 1;
208     textSize = getTextSize( text2, FONT_HERSHEY_COMPLEX_SMALL, fontScale, thickness, &baseline);
209     textOrg += Point(0,180) + Point(0,textSize.height+dist);
210     putText(img, text2, textOrg, FONT_HERSHEY_COMPLEX_SMALL, fontScale, color, thickness, CV_AA);
211 
212     textSize = getTextSize( text2, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, &baseline);
213     textOrg += Point(0,textSize.height+dist);
214     putText(img, text2, textOrg, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, color, thickness, CV_AA);
215 
216     textSize = getTextSize( text2, FONT_HERSHEY_SCRIPT_COMPLEX, fontScale, thickness, &baseline);
217     textOrg += Point(0,textSize.height+dist);
218     putText(img, text2, textOrg, FONT_HERSHEY_SCRIPT_COMPLEX, fontScale, color, thickness, CV_AA);
219 
220     dist = 15, fontScale = 0.5;
221     textSize = getTextSize( text2, FONT_ITALIC, fontScale, thickness, &baseline);
222     textOrg += Point(0,textSize.height+dist);
223     putText(img, text2, textOrg, FONT_ITALIC, fontScale, color, thickness, CV_AA);
224 }
225 
checkLineIterator(Mat & img)226 int CV_DrawingTest_CPP::checkLineIterator( Mat& img )
227 {
228     LineIterator it( img, Point(0,300), Point(1000, 300) );
229     for(int i = 0; i < it.count; ++it, i++ )
230     {
231         Vec3b v = (Vec3b)(*(*it)) - img.at<Vec3b>(300,i);
232         float err = (float)cvtest::norm( v, NORM_L2 );
233         if( err != 0 )
234         {
235             ts->printf( ts->LOG, "LineIterator works incorrect" );
236             ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
237         }
238     }
239     ts->set_failed_test_info(cvtest::TS::OK);
240     return 0;
241 }
242 
243 class CV_DrawingTest_C : public CV_DrawingTest
244 {
245 public:
CV_DrawingTest_C()246     CV_DrawingTest_C() {}
247 protected:
248     virtual void draw( Mat& img );
249     virtual int checkLineIterator( Mat& img);
250 };
251 
draw(Mat & _img)252 void CV_DrawingTest_C::draw( Mat& _img )
253 {
254     CvSize imgSize = cvSize(600, 400);
255     _img.create( imgSize, CV_8UC3 );
256     CvMat img = _img;
257 
258     vector<CvPoint> polyline(4);
259     polyline[0] = cvPoint(0, 0);
260     polyline[1] = cvPoint(imgSize.width, 0);
261     polyline[2] = cvPoint(imgSize.width, imgSize.height);
262     polyline[3] = cvPoint(0, imgSize.height);
263     CvPoint* pts = &polyline[0];
264     int n = (int)polyline.size();
265     int actualSize = 0;
266     cvFillPoly( &img, &pts, &n, 1, cvScalar(255,255,255) );
267 
268     CvPoint p1 = cvPoint(1,1), p2 = cvPoint(3,3);
269     if( cvClipLine(imgSize, &p1, &p2) )
270         cvCircle( &img, cvPoint(300,100), 40, cvScalar(0,0,255), 3 ); // draw
271 
272     p1 = cvPoint(1,1), p2 = cvPoint(3,imgSize.height+1000);
273     if( cvClipLine(imgSize, &p1, &p2) )
274         cvCircle( &img, cvPoint(500,300), 50, cvScalar(255,0,0), 5, 8, 1 ); // draw
275 
276     p1 = cvPoint(imgSize.width,1), p2 = cvPoint(imgSize.width,3);
277     if( cvClipLine(imgSize, &p1, &p2) )
278         cvCircle( &img, cvPoint(390,100), 10, cvScalar(0,0,255), 3 ); // not draw
279 
280     p1 = Point(imgSize.width-1,1), p2 = Point(imgSize.width,3);
281     if( cvClipLine(imgSize, &p1, &p2) )
282         cvEllipse( &img, cvPoint(390,100), cvSize(20,30), 60, 0, 220.0, cvScalar(0,200,0), 4 ); //draw
283 
284     CvBox2D box;
285     box.center.x = 100;
286     box.center.y = 200;
287     box.size.width = 200;
288     box.size.height = 100;
289     box.angle = 160;
290     cvEllipseBox( &img, box, Scalar(200,200,255), 5 );
291 
292     polyline.resize(9);
293     pts = &polyline[0];
294     n = (int)polyline.size();
295     actualSize = cvEllipse2Poly( cvPoint(430,180), cvSize(100,150), 30, 0, 150, &polyline[0], 20 );
296     CV_Assert(actualSize == n);
297     cvPolyLine( &img, &pts, &n, 1, false, cvScalar(0,0,150), 4, CV_AA );
298     n = 0;
299     for( vector<CvPoint>::const_iterator it = polyline.begin(); n < (int)polyline.size()-1; ++it, n++ )
300     {
301         cvLine( &img, *it, *(it+1), cvScalar(50,250,100) );
302     }
303 
304     polyline.resize(19);
305     pts = &polyline[0];
306     n = (int)polyline.size();
307     actualSize = cvEllipse2Poly( cvPoint(500,300), cvSize(50,80), 0, 0, 180, &polyline[0], 10 );
308     CV_Assert(actualSize == n);
309     cvPolyLine( &img, &pts, &n, 1, true, Scalar(100,200,100), 20 );
310     cvFillConvexPoly( &img, pts, n, cvScalar(0, 80, 0) );
311 
312     polyline.resize(8);
313     // external rectengular
314     polyline[0] = cvPoint(500, 20);
315     polyline[1] = cvPoint(580, 20);
316     polyline[2] = cvPoint(580, 100);
317     polyline[3] = cvPoint(500, 100);
318     // internal rectangular
319     polyline[4] = cvPoint(520, 40);
320     polyline[5] = cvPoint(560, 40);
321     polyline[6] = cvPoint(560, 80);
322     polyline[7] = cvPoint(520, 80);
323     CvPoint* ppts[] = {&polyline[0], &polyline[0]+4};
324     int pn[] = {4, 4};
325     cvFillPoly( &img, ppts, pn, 2, cvScalar(100, 100, 0), 8, 0 );
326 
327     cvRectangle( &img, cvPoint(0, 300), cvPoint(50, 398), cvScalar(0,0,255) );
328 
329     string text1 = "OpenCV";
330     CvFont font;
331     cvInitFont( &font, FONT_HERSHEY_SCRIPT_SIMPLEX, 2, 2, 0, 3 );
332     int baseline = 0;
333     CvSize textSize;
334     cvGetTextSize( text1.c_str(), &font, &textSize, &baseline );
335     baseline += font.thickness;
336     CvPoint textOrg = cvPoint((imgSize.width - textSize.width)/2, (imgSize.height + textSize.height)/2);
337     cvRectangle( &img, cvPoint( textOrg.x, textOrg.y + baseline),
338                  cvPoint(textOrg.x + textSize.width, textOrg.y - textSize.height), cvScalar(0,0,255));
339     cvLine( &img, cvPoint(textOrg.x, textOrg.y + font.thickness),
340             cvPoint(textOrg.x + textSize.width, textOrg.y + font.thickness), cvScalar(0, 0, 255));
341     cvPutText( &img, text1.c_str(), textOrg, &font, cvScalar(150,0,150) );
342 
343     int dist = 5;
344     string text2 = "abcdefghijklmnopqrstuvwxyz1234567890";
345     CvScalar color = cvScalar(200,0,0);
346     cvInitFont( &font, FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA );
347     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
348     textOrg = cvPoint(5, 5+textSize.height+dist);
349     cvPutText(&img, text2.c_str(), textOrg, &font, color );
350 
351     cvInitFont( &font, FONT_HERSHEY_PLAIN, 1, 1, 0, 1, CV_AA );
352     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
353     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist);
354     cvPutText(&img, text2.c_str(), textOrg, &font, color );
355 
356     cvInitFont( &font, FONT_HERSHEY_DUPLEX, 0.5, 0.5, 0, 1, CV_AA );
357     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
358     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist);
359     cvPutText(&img, text2.c_str(), textOrg, &font, color );
360 
361     cvInitFont( &font, FONT_HERSHEY_COMPLEX, 0.5, 0.5, 0, 1, CV_AA );
362     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
363     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist);
364     cvPutText(&img, text2.c_str(), textOrg, &font, color );
365 
366     cvInitFont( &font, FONT_HERSHEY_TRIPLEX, 0.5, 0.5, 0, 1, CV_AA );
367     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
368     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist);
369     cvPutText(&img, text2.c_str(), textOrg, &font, color );
370 
371     cvInitFont( &font, FONT_HERSHEY_COMPLEX_SMALL, 1, 1, 0, 1, CV_AA );
372     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
373     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist + 180);
374     cvPutText(&img, text2.c_str(), textOrg, &font, color );
375 
376     cvInitFont( &font, FONT_HERSHEY_SCRIPT_SIMPLEX, 1, 1, 0, 1, CV_AA );
377     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
378     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist);
379     cvPutText(&img, text2.c_str(), textOrg, &font, color );
380 
381     cvInitFont( &font, FONT_HERSHEY_SCRIPT_COMPLEX, 1, 1, 0, 1, CV_AA );
382     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
383     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist);
384     cvPutText(&img, text2.c_str(), textOrg, &font, color );
385 
386     dist = 15;
387     cvInitFont( &font, FONT_ITALIC, 0.5, 0.5, 0, 1, CV_AA );
388     cvGetTextSize( text2.c_str(), &font, &textSize, &baseline );
389     textOrg = cvPoint(textOrg.x,textOrg.y+textSize.height+dist);
390     cvPutText(&img, text2.c_str(), textOrg, &font, color );
391 }
392 
checkLineIterator(Mat & _img)393 int CV_DrawingTest_C::checkLineIterator( Mat& _img )
394 {
395     CvLineIterator it;
396     CvMat img = _img;
397     int count = cvInitLineIterator( &img, cvPoint(0,300), cvPoint(1000, 300), &it );
398     for(int i = 0; i < count; i++ )
399     {
400         Vec3b v = (Vec3b)(*(it.ptr)) - _img.at<Vec3b>(300,i);
401         float err = (float)cvtest::norm( v, NORM_L2 );
402         if( err != 0 )
403         {
404             ts->printf( ts->LOG, "CvLineIterator works incorrect" );
405             ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
406         }
407         CV_NEXT_LINE_POINT(it);
408     }
409     ts->set_failed_test_info(cvtest::TS::OK);
410     return 0;
411 }
412 
413 #ifdef HAVE_JPEG
TEST(Imgcodecs_Drawing,cpp_regression)414 TEST(Imgcodecs_Drawing,    cpp_regression) { CV_DrawingTest_CPP test; test.safe_run(); }
TEST(Imgcodecs_Drawing,c_regression)415 TEST(Imgcodecs_Drawing,      c_regression) { CV_DrawingTest_C   test; test.safe_run(); }
416 #endif
417 
418 class CV_FillConvexPolyTest : public cvtest::BaseTest
419 {
420 public:
CV_FillConvexPolyTest()421     CV_FillConvexPolyTest() {}
~CV_FillConvexPolyTest()422     ~CV_FillConvexPolyTest() {}
423 protected:
run(int)424     void run(int)
425     {
426         vector<Point> line1;
427         vector<Point> line2;
428 
429         line1.push_back(Point(1, 1));
430         line1.push_back(Point(5, 1));
431         line1.push_back(Point(5, 8));
432         line1.push_back(Point(1, 8));
433 
434         line2.push_back(Point(2, 2));
435         line2.push_back(Point(10, 2));
436         line2.push_back(Point(10, 16));
437         line2.push_back(Point(2, 16));
438 
439         Mat gray0(10,10,CV_8U, Scalar(0));
440         fillConvexPoly(gray0, line1, Scalar(255), 8, 0);
441         int nz1 = countNonZero(gray0);
442 
443         fillConvexPoly(gray0, line2, Scalar(0), 8, 1);
444         int nz2 = countNonZero(gray0)/255;
445 
446         CV_Assert( nz1 == 40 && nz2 == 0 );
447     }
448 };
449 
TEST(Imgcodecs_Drawing,fillconvexpoly_clipping)450 TEST(Imgcodecs_Drawing, fillconvexpoly_clipping) { CV_FillConvexPolyTest test; test.safe_run(); }
451 
452 class CV_DrawingTest_UTF8 : public cvtest::BaseTest
453 {
454 public:
CV_DrawingTest_UTF8()455     CV_DrawingTest_UTF8() {}
~CV_DrawingTest_UTF8()456     ~CV_DrawingTest_UTF8() {}
457 protected:
run(int)458     void run(int)
459     {
460         vector<string> lines;
461         lines.push_back("abcdefghijklmnopqrstuvwxyz1234567890");
462         // cyrillic letters small
463         lines.push_back("\xD0\xB0\xD0\xB1\xD0\xB2\xD0\xB3\xD0\xB4\xD0\xB5\xD1\x91\xD0\xB6\xD0\xB7"
464                         "\xD0\xB8\xD0\xB9\xD0\xBA\xD0\xBB\xD0\xBC\xD0\xBD\xD0\xBE\xD0\xBF\xD1\x80"
465                         "\xD1\x81\xD1\x82\xD1\x83\xD1\x84\xD1\x85\xD1\x86\xD1\x87\xD1\x88\xD1\x89"
466                         "\xD1\x8A\xD1\x8B\xD1\x8C\xD1\x8D\xD1\x8E\xD1\x8F");
467         // cyrillic letters capital
468         lines.push_back("\xD0\x90\xD0\x91\xD0\x92\xD0\x93\xD0\x94\xD0\x95\xD0\x81\xD0\x96\xD0\x97"
469                         "\xD0\x98\xD0\x99\xD0\x9A\xD0\x9B\xD0\x9C\xD0\x9D\xD0\x9E\xD0\x9F\xD0\xA0"
470                         "\xD0\xA1\xD0\xA2\xD0\xA3\xD0\xA4\xD0\xA5\xD0\xA6\xD0\xA7\xD0\xA8\xD0\xA9"
471                         "\xD0\xAA\xD0\xAB\xD0\xAC\xD0\xAD\xD0\xAE\xD0\xAF");
472         // bounds
473         lines.push_back("-\xD0\x80-\xD0\x8E-\xD0\x8F-");
474         lines.push_back("-\xD1\x90-\xD1\x91-\xD1\xBF-");
475         // bad utf8
476         lines.push_back("-\x81-\x82-\x83-");
477         lines.push_back("--\xF0--");
478         lines.push_back("-\xF0");
479 
480         vector<int> fonts;
481         fonts.push_back(FONT_HERSHEY_SIMPLEX);
482         fonts.push_back(FONT_HERSHEY_PLAIN);
483         fonts.push_back(FONT_HERSHEY_DUPLEX);
484         fonts.push_back(FONT_HERSHEY_COMPLEX);
485         fonts.push_back(FONT_HERSHEY_TRIPLEX);
486         fonts.push_back(FONT_HERSHEY_COMPLEX_SMALL);
487         fonts.push_back(FONT_HERSHEY_SCRIPT_SIMPLEX);
488         fonts.push_back(FONT_HERSHEY_SCRIPT_COMPLEX);
489 
490         vector<Mat> results;
491         Size bigSize(0, 0);
492         for (vector<int>::const_iterator font = fonts.begin(); font != fonts.end(); ++font)
493         {
494             for (int italic = 0; italic <= FONT_ITALIC; italic += FONT_ITALIC)
495             {
496                 for (vector<string>::const_iterator line = lines.begin(); line != lines.end(); ++line)
497                 {
498                     const float fontScale = 1;
499                     const int thickness = 1;
500                     const Scalar color(20,20,20);
501                     int baseline = 0;
502 
503                     Size textSize = getTextSize(*line, *font | italic, fontScale, thickness, &baseline);
504                     Point textOrg(0, textSize.height + 2);
505                     Mat img(textSize + Size(0, baseline), CV_8UC3, Scalar(255, 255, 255));
506                     putText(img, *line, textOrg, *font | italic, fontScale, color, thickness, CV_AA);
507 
508                     results.push_back(img);
509                     bigSize.width = max(bigSize.width, img.size().width);
510                     bigSize.height += img.size().height + 1;
511                 }
512             }
513         }
514 
515         int shift = 0;
516         Mat result(bigSize, CV_8UC3, Scalar(100, 100, 100));
517         for (vector<Mat>::const_iterator img = results.begin(); img != results.end(); ++img)
518         {
519             Rect roi(Point(0, shift), img->size());
520             Mat sub(result, roi);
521             img->copyTo(sub);
522             shift += img->size().height + 1;
523         }
524         imwrite("/tmp/all_fonts.png", result);
525     }
526 };
527 
TEST(Highgui_Drawing,utf8_support)528 TEST(Highgui_Drawing, utf8_support) { CV_DrawingTest_UTF8 test; test.safe_run(); }
529