Home | History | Annotate | Download | only in test
      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:
     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 
     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:
     97     CV_DrawingTest_CPP() {}
     98 protected:
     99     virtual void draw( Mat& img );
    100     virtual int checkLineIterator( Mat& img);
    101 };
    102 
    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 
    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:
    246     CV_DrawingTest_C() {}
    247 protected:
    248     virtual void draw( Mat& img );
    249     virtual int checkLineIterator( Mat& img);
    250 };
    251 
    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 
    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
    414 TEST(Imgcodecs_Drawing,    cpp_regression) { CV_DrawingTest_CPP test; test.safe_run(); }
    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:
    421     CV_FillConvexPolyTest() {}
    422     ~CV_FillConvexPolyTest() {}
    423 protected:
    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 
    450 TEST(Imgcodecs_Drawing, fillconvexpoly_clipping) { CV_FillConvexPolyTest test; test.safe_run(); }
    451 
    452 class CV_DrawingTest_UTF8 : public cvtest::BaseTest
    453 {
    454 public:
    455     CV_DrawingTest_UTF8() {}
    456     ~CV_DrawingTest_UTF8() {}
    457 protected:
    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 
    528 TEST(Highgui_Drawing, utf8_support) { CV_DrawingTest_UTF8 test; test.safe_run(); }
    529