Commit a2d6d96e authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #7161 from terfendail:shortline_fix

parents 67c40463 1d045f27
...@@ -177,6 +177,7 @@ public: ...@@ -177,6 +177,7 @@ public:
}; };
typedef Point_<int> Point2i; typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;
typedef Point_<float> Point2f; typedef Point_<float> Point2f;
typedef Point_<double> Point2d; typedef Point_<double> Point2d;
typedef Point2i Point; typedef Point2i Point;
...@@ -308,6 +309,7 @@ public: ...@@ -308,6 +309,7 @@ public:
}; };
typedef Size_<int> Size2i; typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f; typedef Size_<float> Size2f;
typedef Size_<double> Size2d; typedef Size_<double> Size2d;
typedef Size2i Size; typedef Size2i Size;
......
...@@ -410,9 +410,143 @@ int CV_DrawingTest_C::checkLineIterator( Mat& _img ) ...@@ -410,9 +410,143 @@ int CV_DrawingTest_C::checkLineIterator( Mat& _img )
return 0; return 0;
} }
class CV_DrawingTest_Far : public CV_DrawingTest_CPP
{
public:
CV_DrawingTest_Far() {}
protected:
virtual void draw(Mat& img);
};
void CV_DrawingTest_Far::draw(Mat& img)
{
Size imgSize(32768 + 600, 400);
img.create(imgSize, CV_8UC3);
vector<Point> polyline(4);
polyline[0] = Point(32768 + 0, 0);
polyline[1] = Point(imgSize.width, 0);
polyline[2] = Point(imgSize.width, imgSize.height);
polyline[3] = Point(32768 + 0, imgSize.height);
const Point* pts = &polyline[0];
int n = (int)polyline.size();
fillPoly(img, &pts, &n, 1, Scalar::all(255));
Point p1(32768 + 1, 1), p2(32768 + 3, 3);
if (clipLine(Rect(32768 + 0, 0, imgSize.width, imgSize.height), p1, p2) && clipLine(imgSize, p1, p2))
circle(img, Point(32768 + 300, 100), 40, Scalar(0, 0, 255), 3); // draw
p2 = Point(32768 + 3, imgSize.height + 1000);
if (clipLine(Rect(32768 + 0, 0, imgSize.width, imgSize.height), p1, p2) && clipLine(imgSize, p1, p2))
circle(img, Point(65536 + 500, 300), 50, cvColorToScalar(255, CV_8UC3), 5, 8, 1); // draw
p1 = Point(imgSize.width, 1), p2 = Point(imgSize.width, 3);
if (clipLine(Rect(32768 + 0, 0, imgSize.width, imgSize.height), p1, p2) && clipLine(imgSize, p1, p2))
circle(img, Point(32768 + 390, 100), 10, Scalar(0, 0, 255), 3); // not draw
p1 = Point(imgSize.width - 1, 1), p2 = Point(imgSize.width, 3);
if (clipLine(Rect(32768 + 0, 0, imgSize.width, imgSize.height), p1, p2) && clipLine(imgSize, p1, p2))
ellipse(img, Point(32768 + 390, 100), Size(20, 30), 60, 0, 220.0, Scalar(0, 200, 0), 4); //draw
ellipse(img, RotatedRect(Point(32768 + 100, 200), Size(200, 100), 160), Scalar(200, 200, 255), 5);
polyline.clear();
ellipse2Poly(Point(32768 + 430, 180), Size(100, 150), 30, 0, 150, 20, polyline);
pts = &polyline[0];
n = (int)polyline.size();
polylines(img, &pts, &n, 1, false, Scalar(0, 0, 150), 4, CV_AA);
n = 0;
for (vector<Point>::const_iterator it = polyline.begin(); n < (int)polyline.size() - 1; ++it, n++)
{
line(img, *it, *(it + 1), Scalar(50, 250, 100));
}
polyline.clear();
ellipse2Poly(Point(32768 + 500, 300), Size(50, 80), 0, 0, 180, 10, polyline);
pts = &polyline[0];
n = (int)polyline.size();
polylines(img, &pts, &n, 1, true, Scalar(100, 200, 100), 20);
fillConvexPoly(img, pts, n, Scalar(0, 80, 0));
polyline.resize(8);
// external rectengular
polyline[0] = Point(32768 + 0, 0);
polyline[1] = Point(32768 + 80, 0);
polyline[2] = Point(32768 + 80, 80);
polyline[3] = Point(32768 + 0, 80);
// internal rectangular
polyline[4] = Point(32768 + 20, 20);
polyline[5] = Point(32768 + 60, 20);
polyline[6] = Point(32768 + 60, 60);
polyline[7] = Point(32768 + 20, 60);
const Point* ppts[] = { &polyline[0], &polyline[0] + 4 };
int pn[] = { 4, 4 };
fillPoly(img, ppts, pn, 2, Scalar(100, 100, 0), 8, 0, Point(500, 20));
rectangle(img, Point(32768 + 0, 300), Point(32768 + 50, 398), Scalar(0, 0, 255));
string text1 = "OpenCV";
int baseline = 0, thickness = 3, fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
float fontScale = 2;
Size textSize = getTextSize(text1, fontFace, fontScale, thickness, &baseline);
baseline += thickness;
Point textOrg((32768 + img.cols - textSize.width) / 2, (img.rows + textSize.height) / 2);
rectangle(img, textOrg + Point(0, baseline), textOrg + Point(textSize.width, -textSize.height), Scalar(0, 0, 255));
line(img, textOrg + Point(0, thickness), textOrg + Point(textSize.width, thickness), Scalar(0, 0, 255));
putText(img, text1, textOrg, fontFace, fontScale, Scalar(150, 0, 150), thickness, 8);
string text2 = "abcdefghijklmnopqrstuvwxyz1234567890";
Scalar color(200, 0, 0);
fontScale = 0.5, thickness = 1;
int dist = 5;
textSize = getTextSize(text2, FONT_HERSHEY_SIMPLEX, fontScale, thickness, &baseline);
textOrg = Point(32768 + 5, 5) + Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_SIMPLEX, fontScale, color, thickness, CV_AA);
fontScale = 1;
textSize = getTextSize(text2, FONT_HERSHEY_PLAIN, fontScale, thickness, &baseline);
textOrg += Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_PLAIN, fontScale, color, thickness, CV_AA);
fontScale = 0.5;
textSize = getTextSize(text2, FONT_HERSHEY_DUPLEX, fontScale, thickness, &baseline);
textOrg += Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_DUPLEX, fontScale, color, thickness, CV_AA);
textSize = getTextSize(text2, FONT_HERSHEY_COMPLEX, fontScale, thickness, &baseline);
textOrg += Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_COMPLEX, fontScale, color, thickness, CV_AA);
textSize = getTextSize(text2, FONT_HERSHEY_TRIPLEX, fontScale, thickness, &baseline);
textOrg += Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_TRIPLEX, fontScale, color, thickness, CV_AA);
fontScale = 1;
textSize = getTextSize(text2, FONT_HERSHEY_COMPLEX_SMALL, fontScale, thickness, &baseline);
textOrg += Point(0, 180) + Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_COMPLEX_SMALL, fontScale, color, thickness, CV_AA);
textSize = getTextSize(text2, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, &baseline);
textOrg += Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, color, thickness, CV_AA);
textSize = getTextSize(text2, FONT_HERSHEY_SCRIPT_COMPLEX, fontScale, thickness, &baseline);
textOrg += Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_HERSHEY_SCRIPT_COMPLEX, fontScale, color, thickness, CV_AA);
dist = 15, fontScale = 0.5;
textSize = getTextSize(text2, FONT_ITALIC, fontScale, thickness, &baseline);
textOrg += Point(0, textSize.height + dist);
putText(img, text2, textOrg, FONT_ITALIC, fontScale, color, thickness, CV_AA);
img = img(Rect(32768, 0, 600, 400)).clone();
}
#ifdef HAVE_JPEG #ifdef HAVE_JPEG
TEST(Imgcodecs_Drawing, cpp_regression) { CV_DrawingTest_CPP test; test.safe_run(); } TEST(Imgcodecs_Drawing, cpp_regression) { CV_DrawingTest_CPP test; test.safe_run(); }
TEST(Imgcodecs_Drawing, c_regression) { CV_DrawingTest_C test; test.safe_run(); } TEST(Imgcodecs_Drawing, c_regression) { CV_DrawingTest_C test; test.safe_run(); }
TEST(Imgcodecs_Drawing, far_regression) { CV_DrawingTest_Far test; test.safe_run(); }
#endif #endif
class CV_FillConvexPolyTest : public cvtest::BaseTest class CV_FillConvexPolyTest : public cvtest::BaseTest
......
...@@ -4414,6 +4414,13 @@ it returns true . ...@@ -4414,6 +4414,13 @@ it returns true .
*/ */
CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2); CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2);
/** @overload
@param imgSize Image size. The image rectangle is Rect(0, 0, imgSize.width, imgSize.height) .
@param pt1 First line point.
@param pt2 Second line point.
*/
CV_EXPORTS bool clipLine(Size2l imgSize, CV_IN_OUT Point2l& pt1, CV_IN_OUT Point2l& pt2);
/** @overload /** @overload
@param imgRect Image rectangle. @param imgRect Image rectangle.
@param pt1 First line point. @param pt1 First line point.
...@@ -4439,6 +4446,20 @@ CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle, ...@@ -4439,6 +4446,20 @@ CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle,
int arcStart, int arcEnd, int delta, int arcStart, int arcEnd, int delta,
CV_OUT std::vector<Point>& pts ); CV_OUT std::vector<Point>& pts );
/** @overload
@param center Center of the arc.
@param axes Half of the size of the ellipse main axes. See the ellipse for details.
@param angle Rotation angle of the ellipse in degrees. See the ellipse for details.
@param arcStart Starting angle of the elliptic arc in degrees.
@param arcEnd Ending angle of the elliptic arc in degrees.
@param delta Angle between the subsequent polyline vertices. It defines the approximation
accuracy.
@param pts Output vector of polyline vertices.
*/
CV_EXPORTS void ellipse2Poly(Point2d center, Size2d axes, int angle,
int arcStart, int arcEnd, int delta,
CV_OUT std::vector<Point2d>& pts);
/** @brief Draws a text string. /** @brief Draws a text string.
The function putText renders the specified text string in the image. Symbols that cannot be rendered The function putText renders the specified text string in the image. Symbols that cannot be rendered
......
...@@ -53,12 +53,12 @@ struct PolyEdge ...@@ -53,12 +53,12 @@ struct PolyEdge
//PolyEdge(int _y0, int _y1, int _x, int _dx) : y0(_y0), y1(_y1), x(_x), dx(_dx) {} //PolyEdge(int _y0, int _y1, int _x, int _dx) : y0(_y0), y1(_y1), x(_x), dx(_dx) {}
int y0, y1; int y0, y1;
int x, dx; int64 x, dx;
PolyEdge *next; PolyEdge *next;
}; };
static void static void
CollectPolyEdges( Mat& img, const Point* v, int npts, CollectPolyEdges( Mat& img, const Point2l* v, int npts,
std::vector<PolyEdge>& edges, const void* color, int line_type, std::vector<PolyEdge>& edges, const void* color, int line_type,
int shift, Point offset=Point() ); int shift, Point offset=Point() );
...@@ -66,11 +66,11 @@ static void ...@@ -66,11 +66,11 @@ static void
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color ); FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color );
static void static void
PolyLine( Mat& img, const Point* v, int npts, bool closed, PolyLine( Mat& img, const Point2l* v, int npts, bool closed,
const void* color, int thickness, int line_type, int shift ); const void* color, int thickness, int line_type, int shift );
static void static void
FillConvexPoly( Mat& img, const Point* v, int npts, FillConvexPoly( Mat& img, const Point2l* v, int npts,
const void* color, int line_type, int shift ); const void* color, int line_type, int shift );
/****************************************************************************************\ /****************************************************************************************\
...@@ -78,17 +78,28 @@ FillConvexPoly( Mat& img, const Point* v, int npts, ...@@ -78,17 +78,28 @@ FillConvexPoly( Mat& img, const Point* v, int npts,
\****************************************************************************************/ \****************************************************************************************/
bool clipLine( Size img_size, Point& pt1, Point& pt2 ) bool clipLine( Size img_size, Point& pt1, Point& pt2 )
{
Point2l p1(pt1);
Point2l p2(pt2);
bool inside = clipLine(Size2l(img_size.width, img_size.height), p1, p2);
pt1.x = (int)p1.x;
pt1.y = (int)p1.y;
pt2.x = (int)p2.x;
pt2.y = (int)p2.y;
return inside;
}
bool clipLine( Size2l img_size, Point2l& pt1, Point2l& pt2 )
{ {
CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION()
int64 x1, y1, x2, y2;
int c1, c2; int c1, c2;
int64 right = img_size.width-1, bottom = img_size.height-1; int64 right = img_size.width-1, bottom = img_size.height-1;
if( img_size.width <= 0 || img_size.height <= 0 ) if( img_size.width <= 0 || img_size.height <= 0 )
return false; return false;
x1 = pt1.x; y1 = pt1.y; x2 = pt2.x; y2 = pt2.y; int64 &x1 = pt1.x, &y1 = pt1.y, &x2 = pt2.x, &y2 = pt2.y;
c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8; c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8;
c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8; c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8;
...@@ -128,11 +139,6 @@ bool clipLine( Size img_size, Point& pt1, Point& pt2 ) ...@@ -128,11 +139,6 @@ bool clipLine( Size img_size, Point& pt1, Point& pt2 )
} }
assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 ); assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 );
pt1.x = (int)x1;
pt1.y = (int)y1;
pt2.x = (int)x2;
pt2.y = (int)y2;
} }
return (c1 | c2) == 0; return (c1 | c2) == 0;
...@@ -285,25 +291,25 @@ static const int FilterTable[] = { ...@@ -285,25 +291,25 @@ static const int FilterTable[] = {
}; };
static void static void
LineAA( Mat& img, Point pt1, Point pt2, const void* color ) LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color )
{ {
int dx, dy; int64 dx, dy;
int ecount, scount = 0; int ecount, scount = 0;
int slope; int slope;
int ax, ay; int64 ax, ay;
int x_step, y_step; int64 x_step, y_step;
int i, j; int64 i, j;
int ep_table[9]; int ep_table[9];
int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2], ca = ((uchar*)color)[3]; int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2], ca = ((uchar*)color)[3];
int _cb, _cg, _cr, _ca; int _cb, _cg, _cr, _ca;
int nch = img.channels(); int nch = img.channels();
uchar* ptr = img.ptr(); uchar* ptr = img.ptr();
size_t step = img.step; size_t step = img.step;
Size size = img.size(); Size2l size(img.size());
if( !((nch == 1 || nch == 3 || nch == 4) && img.depth() == CV_8U) ) if( !((nch == 1 || nch == 3 || nch == 4) && img.depth() == CV_8U) )
{ {
Line(img, pt1, pt2, color); Line(img, Point((int)(pt1.x<<XY_SHIFT), (int)(pt1.y<<XY_SHIFT)), Point((int)(pt2.x<<XY_SHIFT), (int)(pt2.y<<XY_SHIFT)), color);
return; return;
} }
...@@ -339,11 +345,11 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -339,11 +345,11 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
pt1.y ^= pt2.y & j; pt1.y ^= pt2.y & j;
x_step = XY_ONE; x_step = XY_ONE;
y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1)); y_step = (dy << XY_SHIFT) / (ax | 1);
pt2.x += XY_ONE; pt2.x += XY_ONE;
ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT); ecount = (int)((pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT));
j = -(pt1.x & (XY_ONE - 1)); j = -(pt1.x & (XY_ONE - 1));
pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1); pt1.y += ((y_step * j) >> XY_SHIFT) + (XY_ONE >> 1);
slope = (y_step >> (XY_SHIFT - 5)) & 0x3f; slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;
slope ^= (y_step < 0 ? 0x3f : 0); slope ^= (y_step < 0 ? 0x3f : 0);
...@@ -362,12 +368,12 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -362,12 +368,12 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
pt2.y ^= pt1.y & i; pt2.y ^= pt1.y & i;
pt1.y ^= pt2.y & i; pt1.y ^= pt2.y & i;
x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1)); x_step = (dx << XY_SHIFT) / (ay | 1);
y_step = XY_ONE; y_step = XY_ONE;
pt2.y += XY_ONE; pt2.y += XY_ONE;
ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT); ecount = (int)((pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT));
j = -(pt1.y & (XY_ONE - 1)); j = -(pt1.y & (XY_ONE - 1));
pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1); pt1.x += ((x_step * j) >> XY_SHIFT) + (XY_ONE >> 1);
slope = (x_step >> (XY_SHIFT - 5)) & 0x3f; slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;
slope ^= (x_step < 0 ? 0x3f : 0); slope ^= (x_step < 0 ? 0x3f : 0);
...@@ -381,8 +387,8 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -381,8 +387,8 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
/* Calc end point correction table */ /* Calc end point correction table */
{ {
int t0 = slope << 7; int t0 = slope << 7;
int t1 = ((0x78 - i) | 4) * slope; int t1 = ((0x78 - (int)i) | 4) * slope;
int t2 = (j | 4) * slope; int t2 = ((int)j | 4) * slope;
ep_table[0] = 0; ep_table[0] = 0;
ep_table[8] = slope; ep_table[8] = slope;
...@@ -636,23 +642,25 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -636,23 +642,25 @@ LineAA( Mat& img, Point pt1, Point pt2, const void* color )
static void static void
Line2( Mat& img, Point pt1, Point pt2, const void* color ) Line2( Mat& img, Point2l pt1, Point2l pt2, const void* color)
{ {
int dx, dy; int64 dx, dy;
int ecount; int ecount;
int ax, ay; int64 ax, ay;
int i, j, x, y; int64 i, j;
int x_step, y_step; int x, y;
int64 x_step, y_step;
int cb = ((uchar*)color)[0]; int cb = ((uchar*)color)[0];
int cg = ((uchar*)color)[1]; int cg = ((uchar*)color)[1];
int cr = ((uchar*)color)[2]; int cr = ((uchar*)color)[2];
int pix_size = (int)img.elemSize(); int pix_size = (int)img.elemSize();
uchar *ptr = img.ptr(), *tptr; uchar *ptr = img.ptr(), *tptr;
size_t step = img.step; size_t step = img.step;
Size size = img.size(), sizeScaled(size.width*XY_ONE, size.height*XY_ONE); Size size = img.size();
//assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U ); //assert( img && (nch == 1 || nch == 3) && img.depth() == CV_8U );
Size2l sizeScaled(((int64)size.width) << XY_SHIFT, ((int64)size.height) << XY_SHIFT);
if( !clipLine( sizeScaled, pt1, pt2 )) if( !clipLine( sizeScaled, pt1, pt2 ))
return; return;
...@@ -676,8 +684,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -676,8 +684,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
pt1.y ^= pt2.y & j; pt1.y ^= pt2.y & j;
x_step = XY_ONE; x_step = XY_ONE;
y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1)); y_step = (dy << XY_SHIFT) / (ax | 1);
ecount = (pt2.x - pt1.x) >> XY_SHIFT; ecount = (int)((pt2.x - pt1.x) >> XY_SHIFT);
} }
else else
{ {
...@@ -690,9 +698,9 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -690,9 +698,9 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
pt2.y ^= pt1.y & i; pt2.y ^= pt1.y & i;
pt1.y ^= pt2.y & i; pt1.y ^= pt2.y & i;
x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1)); x_step = (dx << XY_SHIFT) / (ay | 1);
y_step = XY_ONE; y_step = XY_ONE;
ecount = (pt2.y - pt1.y) >> XY_SHIFT; ecount = (int)((pt2.y - pt1.y) >> XY_SHIFT);
} }
pt1.x += (XY_ONE >> 1); pt1.x += (XY_ONE >> 1);
...@@ -711,8 +719,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -711,8 +719,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
tptr[2] = (uchar)cr; \ tptr[2] = (uchar)cr; \
} }
ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT, ICV_PUT_POINT((int)((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT),
(pt2.y + (XY_ONE >> 1)) >> XY_SHIFT); (int)((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT));
if( ax > ay ) if( ax > ay )
{ {
...@@ -720,7 +728,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -720,7 +728,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
while( ecount >= 0 ) while( ecount >= 0 )
{ {
ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT); ICV_PUT_POINT((int)(pt1.x), (int)(pt1.y >> XY_SHIFT));
pt1.x++; pt1.x++;
pt1.y += y_step; pt1.y += y_step;
ecount--; ecount--;
...@@ -732,7 +740,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -732,7 +740,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
while( ecount >= 0 ) while( ecount >= 0 )
{ {
ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y); ICV_PUT_POINT((int)(pt1.x >> XY_SHIFT), (int)(pt1.y));
pt1.x += x_step; pt1.x += x_step;
pt1.y++; pt1.y++;
ecount--; ecount--;
...@@ -752,8 +760,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -752,8 +760,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
tptr[0] = (uchar)cb; \ tptr[0] = (uchar)cb; \
} }
ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT, ICV_PUT_POINT((int)((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT),
(pt2.y + (XY_ONE >> 1)) >> XY_SHIFT); (int)((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT));
if( ax > ay ) if( ax > ay )
{ {
...@@ -761,7 +769,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -761,7 +769,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
while( ecount >= 0 ) while( ecount >= 0 )
{ {
ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT); ICV_PUT_POINT((int)(pt1.x), (int)(pt1.y >> XY_SHIFT));
pt1.x++; pt1.x++;
pt1.y += y_step; pt1.y += y_step;
ecount--; ecount--;
...@@ -773,7 +781,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -773,7 +781,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
while( ecount >= 0 ) while( ecount >= 0 )
{ {
ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y); ICV_PUT_POINT((int)(pt1.x >> XY_SHIFT), (int)(pt1.y));
pt1.x += x_step; pt1.x += x_step;
pt1.y++; pt1.y++;
ecount--; ecount--;
...@@ -794,8 +802,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -794,8 +802,8 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
tptr[j] = ((uchar*)color)[j]; \ tptr[j] = ((uchar*)color)[j]; \
} }
ICV_PUT_POINT((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT, ICV_PUT_POINT((int)((pt2.x + (XY_ONE >> 1)) >> XY_SHIFT),
(pt2.y + (XY_ONE >> 1)) >> XY_SHIFT); (int)((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT));
if( ax > ay ) if( ax > ay )
{ {
...@@ -803,7 +811,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -803,7 +811,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
while( ecount >= 0 ) while( ecount >= 0 )
{ {
ICV_PUT_POINT(pt1.x, pt1.y >> XY_SHIFT); ICV_PUT_POINT((int)(pt1.x), (int)(pt1.y >> XY_SHIFT));
pt1.x++; pt1.x++;
pt1.y += y_step; pt1.y += y_step;
ecount--; ecount--;
...@@ -815,7 +823,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color ) ...@@ -815,7 +823,7 @@ Line2( Mat& img, Point pt1, Point pt2, const void* color )
while( ecount >= 0 ) while( ecount >= 0 )
{ {
ICV_PUT_POINT(pt1.x >> XY_SHIFT, pt1.y); ICV_PUT_POINT((int)(pt1.x >> XY_SHIFT), (int)(pt1.y));
pt1.x += x_step; pt1.x += x_step;
pt1.y++; pt1.y++;
ecount--; ecount--;
...@@ -923,15 +931,38 @@ sincos( int angle, float& cosval, float& sinval ) ...@@ -923,15 +931,38 @@ sincos( int angle, float& cosval, float& sinval )
constructs polygon that represents elliptic arc. constructs polygon that represents elliptic arc.
*/ */
void ellipse2Poly( Point center, Size axes, int angle, void ellipse2Poly( Point center, Size axes, int angle,
int arcStart, int arcEnd,
int delta, CV_OUT std::vector<Point>& pts )
{
std::vector<Point2d> _pts;
ellipse2Poly(Point2d(center.x, center.y), Size2d(axes.width, axes.height), angle,
arcStart, arcEnd, delta, _pts);
Point prevPt(INT_MIN, INT_MIN);
pts.resize(0);
for (unsigned int i = 0; i < _pts.size(); ++i)
{
Point pt;
pt.x = cvRound(_pts[i].x);
pt.y = cvRound(_pts[i].y);
if (pt != prevPt) {
pts.push_back(pt);
prevPt = pt;
}
}
// If there are no points, it's a zero-size polygon
if (pts.size() == 1) {
pts.assign(2, center);
}
}
void ellipse2Poly( Point2d center, Size2d axes, int angle,
int arc_start, int arc_end, int arc_start, int arc_end,
int delta, std::vector<Point>& pts ) int delta, std::vector<Point2d>& pts )
{ {
CV_INSTRUMENT_REGION() CV_INSTRUMENT_REGION()
float alpha, beta; float alpha, beta;
double size_a = axes.width, size_b = axes.height;
double cx = center.x, cy = center.y;
Point prevPt(INT_MIN,INT_MIN);
int i; int i;
while( angle < 0 ) while( angle < 0 )
...@@ -972,15 +1003,12 @@ void ellipse2Poly( Point center, Size axes, int angle, ...@@ -972,15 +1003,12 @@ void ellipse2Poly( Point center, Size axes, int angle,
if( angle < 0 ) if( angle < 0 )
angle += 360; angle += 360;
x = size_a * SinTable[450-angle]; x = axes.width * SinTable[450-angle];
y = size_b * SinTable[angle]; y = axes.height * SinTable[angle];
Point pt; Point2d pt;
pt.x = cvRound( cx + x * alpha - y * beta ); pt.x = center.x + x * alpha - y * beta;
pt.y = cvRound( cy + x * beta + y * alpha ); pt.y = center.y + x * beta + y * alpha;
if( pt != prevPt ){ pts.push_back(pt);
pts.push_back(pt);
prevPt = pt;
}
} }
// If there are no points, it's a zero-size polygon // If there are no points, it's a zero-size polygon
...@@ -991,16 +1019,37 @@ void ellipse2Poly( Point center, Size axes, int angle, ...@@ -991,16 +1019,37 @@ void ellipse2Poly( Point center, Size axes, int angle,
static void static void
EllipseEx( Mat& img, Point center, Size axes, EllipseEx( Mat& img, Point2l center, Size2l axes,
int angle, int arc_start, int arc_end, int angle, int arc_start, int arc_end,
const void* color, int thickness, int line_type ) const void* color, int thickness, int line_type )
{ {
axes.width = std::abs(axes.width), axes.height = std::abs(axes.height); axes.width = std::abs(axes.width), axes.height = std::abs(axes.height);
int delta = (std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT; int delta = (int)((std::max(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT);
delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5; delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5;
std::vector<Point> v; std::vector<Point2d> _v;
ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, v ); ellipse2Poly( Point2d((double)center.x, (double)center.y), Size2d((double)axes.width, (double)axes.height), angle, arc_start, arc_end, delta, _v );
std::vector<Point2l> v;
Point2l prevPt(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
v.resize(0);
for (unsigned int i = 0; i < _v.size(); ++i)
{
Point2l pt;
pt.x = (int64)cvRound(_v[i].x / XY_ONE) << XY_SHIFT;
pt.y = (int64)cvRound(_v[i].y / XY_ONE) << XY_SHIFT;
pt.x += cvRound(_v[i].x - pt.x);
pt.y += cvRound(_v[i].y - pt.y);
if (pt != prevPt) {
v.push_back(pt);
prevPt = pt;
}
}
// If there are no points, it's a zero-size polygon
if (v.size() == 1) {
v.assign(2, center);
}
if( thickness >= 0 ) if( thickness >= 0 )
PolyLine( img, &v[0], (int)v.size(), false, color, thickness, line_type, XY_SHIFT ); PolyLine( img, &v[0], (int)v.size(), false, color, thickness, line_type, XY_SHIFT );
...@@ -1039,23 +1088,24 @@ EllipseEx( Mat& img, Point center, Size axes, ...@@ -1039,23 +1088,24 @@ EllipseEx( Mat& img, Point center, Size axes,
/* filling convex polygon. v - array of vertices, ntps - number of points */ /* filling convex polygon. v - array of vertices, ntps - number of points */
static void static void
FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_type, int shift ) FillConvexPoly( Mat& img, const Point2l* v, int npts, const void* color, int line_type, int shift )
{ {
struct struct
{ {
int idx, di; int idx, di;
int x, dx, ye; int64 x, dx;
int ye;
} }
edge[2]; edge[2];
int delta = shift ? 1 << (shift - 1) : 0; int delta = 1 << shift >> 1;
int i, y, imin = 0, left = 0, right = 1, x1, x2; int i, y, imin = 0, left = 0, right = 1;
int edges = npts; int edges = npts;
int xmin, xmax, ymin, ymax; int64 xmin, xmax, ymin, ymax;
uchar* ptr = img.ptr(); uchar* ptr = img.ptr();
Size size = img.size(); Size size = img.size();
int pix_size = (int)img.elemSize(); int pix_size = (int)img.elemSize();
Point p0; Point2l p0;
int delta1, delta2; int delta1, delta2;
if( line_type < CV_AA ) if( line_type < CV_AA )
...@@ -1073,7 +1123,7 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_ ...@@ -1073,7 +1123,7 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
for( i = 0; i < npts; i++ ) for( i = 0; i < npts; i++ )
{ {
Point p = v[i]; Point2l p = v[i];
if( p.y < ymin ) if( p.y < ymin )
{ {
ymin = p.y; ymin = p.y;
...@@ -1092,10 +1142,10 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_ ...@@ -1092,10 +1142,10 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
if( shift == 0 ) if( shift == 0 )
{ {
Point pt0, pt1; Point pt0, pt1;
pt0.x = p0.x >> XY_SHIFT; pt0.x = (int)(p0.x >> XY_SHIFT);
pt0.y = p0.y >> XY_SHIFT; pt0.y = (int)(p0.y >> XY_SHIFT);
pt1.x = p.x >> XY_SHIFT; pt1.x = (int)(p.x >> XY_SHIFT);
pt1.y = p.y >> XY_SHIFT; pt1.y = (int)(p.y >> XY_SHIFT);
Line( img, pt0, pt1, color, line_type ); Line( img, pt0, pt1, color, line_type );
} }
else else
...@@ -1111,13 +1161,13 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_ ...@@ -1111,13 +1161,13 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
ymin = (ymin + delta) >> shift; ymin = (ymin + delta) >> shift;
ymax = (ymax + delta) >> shift; ymax = (ymax + delta) >> shift;
if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height ) if( npts < 3 || (int)xmax < 0 || (int)ymax < 0 || (int)xmin >= size.width || (int)ymin >= size.height )
return; return;
ymax = MIN( ymax, size.height - 1 ); ymax = MIN( ymax, size.height - 1 );
edge[0].idx = edge[1].idx = imin; edge[0].idx = edge[1].idx = imin;
edge[0].ye = edge[1].ye = y = ymin; edge[0].ye = edge[1].ye = y = (int)ymin;
edge[0].di = 1; edge[0].di = 1;
edge[1].di = npts - 1; edge[1].di = npts - 1;
...@@ -1125,18 +1175,19 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_ ...@@ -1125,18 +1175,19 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
do do
{ {
if( line_type < CV_AA || y < ymax || y == ymin ) if( line_type < CV_AA || y < (int)ymax || y == (int)ymin )
{ {
for( i = 0; i < 2; i++ ) for( i = 0; i < 2; i++ )
{ {
if( y >= edge[i].ye ) if( y >= edge[i].ye )
{ {
int idx = edge[i].idx, di = edge[i].di; int idx = edge[i].idx, di = edge[i].di;
int xs = 0, xe, ye, ty = 0; int64 xs = 0, xe;
int ty = 0;
for(;;) for(;;)
{ {
ty = (v[idx].y + delta) >> shift; ty = (int)((v[idx].y + delta) >> shift);
if( ty > y || edges == 0 ) if( ty > y || edges == 0 )
break; break;
xs = v[idx].x; xs = v[idx].x;
...@@ -1145,16 +1196,15 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_ ...@@ -1145,16 +1196,15 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
edges--; edges--;
} }
ye = ty;
xs <<= XY_SHIFT - shift; xs <<= XY_SHIFT - shift;
xe = v[idx].x << (XY_SHIFT - shift); xe = v[idx].x << (XY_SHIFT - shift);
/* no more edges */ /* no more edges */
if( y >= ye ) if( y >= ty)
return; return;
edge[i].ye = ye; edge[i].ye = ty;
edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y)); edge[i].dx = ((xe - xs)*2 + (ty - y)) / (2 * (ty - y));
edge[i].x = xs; edge[i].x = xs;
edge[i].idx = idx; edge[i].idx = idx;
} }
...@@ -1167,13 +1217,10 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_ ...@@ -1167,13 +1217,10 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
right ^= 1; right ^= 1;
} }
x1 = edge[left].x;
x2 = edge[right].x;
if( y >= 0 ) if( y >= 0 )
{ {
int xx1 = (x1 + delta1) >> XY_SHIFT; int xx1 = (int)((edge[left].x + delta1) >> XY_SHIFT);
int xx2 = (x2 + delta2) >> XY_SHIFT; int xx2 = (int)((edge[right].x + delta2) >> XY_SHIFT);
if( xx2 >= 0 && xx1 < size.width ) if( xx2 >= 0 && xx1 < size.width )
{ {
...@@ -1185,25 +1232,22 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_ ...@@ -1185,25 +1232,22 @@ FillConvexPoly( Mat& img, const Point* v, int npts, const void* color, int line_
} }
} }
x1 += edge[left].dx; edge[left].x += edge[left].dx;
x2 += edge[right].dx; edge[right].x += edge[right].dx;
edge[left].x = x1;
edge[right].x = x2;
ptr += img.step; ptr += img.step;
} }
while( ++y <= ymax ); while( ++y <= (int)ymax );
} }
/******** Arbitrary polygon **********/ /******** Arbitrary polygon **********/
static void static void
CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& edges, CollectPolyEdges( Mat& img, const Point2l* v, int count, std::vector<PolyEdge>& edges,
const void* color, int line_type, int shift, Point offset ) const void* color, int line_type, int shift, Point offset )
{ {
int i, delta = offset.y + (shift ? 1 << (shift - 1) : 0); int i, delta = offset.y + ((1 << shift) >> 1);
Point pt0 = v[count-1], pt1; Point2l pt0 = v[count-1], pt1;
pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift); pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift);
pt0.y = (pt0.y + delta) >> shift; pt0.y = (pt0.y + delta) >> shift;
...@@ -1211,7 +1255,7 @@ CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& ed ...@@ -1211,7 +1255,7 @@ CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& ed
for( i = 0; i < count; i++, pt0 = pt1 ) for( i = 0; i < count; i++, pt0 = pt1 )
{ {
Point t0, t1; Point2l t0, t1;
PolyEdge edge; PolyEdge edge;
pt1 = v[i]; pt1 = v[i];
...@@ -1238,14 +1282,14 @@ CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& ed ...@@ -1238,14 +1282,14 @@ CollectPolyEdges( Mat& img, const Point* v, int count, std::vector<PolyEdge>& ed
if( pt0.y < pt1.y ) if( pt0.y < pt1.y )
{ {
edge.y0 = pt0.y; edge.y0 = (int)(pt0.y);
edge.y1 = pt1.y; edge.y1 = (int)(pt1.y);
edge.x = pt0.x; edge.x = pt0.x;
} }
else else
{ {
edge.y0 = pt1.y; edge.y0 = (int)(pt1.y);
edge.y1 = pt0.y; edge.y1 = (int)(pt0.y);
edge.x = pt1.x; edge.x = pt1.x;
} }
edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y); edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
...@@ -1271,7 +1315,8 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color ) ...@@ -1271,7 +1315,8 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
int i, y, total = (int)edges.size(); int i, y, total = (int)edges.size();
Size size = img.size(); Size size = img.size();
PolyEdge* e; PolyEdge* e;
int y_max = INT_MIN, x_max = INT_MIN, y_min = INT_MAX, x_min = INT_MAX; int y_max = INT_MIN, y_min = INT_MAX;
int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF;
int pix_size = (int)img.elemSize(); int pix_size = (int)img.elemSize();
if( total < 2 ) if( total < 2 )
...@@ -1283,7 +1328,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color ) ...@@ -1283,7 +1328,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
assert( e1.y0 < e1.y1 ); assert( e1.y0 < e1.y1 );
// Determine x-coordinate of the end of the edge. // Determine x-coordinate of the end of the edge.
// (This is not necessary x-coordinate of any vertex in the array.) // (This is not necessary x-coordinate of any vertex in the array.)
int x1 = e1.x + (e1.y1 - e1.y0) * e1.dx; int64 x1 = e1.x + (e1.y1 - e1.y0) * e1.dx;
y_min = std::min( y_min, e1.y0 ); y_min = std::min( y_min, e1.y0 );
y_max = std::max( y_max, e1.y1 ); y_max = std::max( y_max, e1.y1 );
x_min = std::min( x_min, e1.x ); x_min = std::min( x_min, e1.x );
...@@ -1292,7 +1337,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color ) ...@@ -1292,7 +1337,7 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
x_max = std::max( x_max, x1 ); x_max = std::max( x_max, x1 );
} }
if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= (size.width<<XY_SHIFT) ) if( y_max < 0 || y_min >= size.height || x_max < 0 || x_min >= ((int64)size.width<<XY_SHIFT) )
return; return;
std::sort( edges.begin(), edges.end(), CmpEdges() ); std::sort( edges.begin(), edges.end(), CmpEdges() );
...@@ -1348,19 +1393,18 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color ) ...@@ -1348,19 +1393,18 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
{ {
// convert x's from fixed-point to image coordinates // convert x's from fixed-point to image coordinates
uchar *timg = img.ptr(y); uchar *timg = img.ptr(y);
int x1 = keep_prelast->x; int x1, x2;
int x2 = prelast->x;
if( x1 > x2 ) if (keep_prelast->x > prelast->x)
{ {
int t = x1; x1 = (int)((prelast->x + XY_ONE - 1) >> XY_SHIFT);
x2 = (int)(keep_prelast->x >> XY_SHIFT);
x1 = x2; }
x2 = t; else
{
x1 = (int)((keep_prelast->x + XY_ONE - 1) >> XY_SHIFT);
x2 = (int)(prelast->x >> XY_SHIFT);
} }
x1 = (x1 + XY_ONE - 1) >> XY_SHIFT;
x2 = x2 >> XY_SHIFT;
// clip and draw the line // clip and draw the line
if( x1 < size.width && x2 >= 0 ) if( x1 < size.width && x2 >= 0 )
...@@ -1560,7 +1604,7 @@ Circle( Mat& img, Point center, int radius, const void* color, int fill ) ...@@ -1560,7 +1604,7 @@ Circle( Mat& img, Point center, int radius, const void* color, int fill )
static void static void
ThickLine( Mat& img, Point p0, Point p1, const void* color, ThickLine( Mat& img, Point2l p0, Point2l p1, const void* color,
int thickness, int line_type, int flags, int shift ) int thickness, int line_type, int flags, int shift )
{ {
static const double INV_XY_ONE = 1./XY_ONE; static const double INV_XY_ONE = 1./XY_ONE;
...@@ -1590,7 +1634,7 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color, ...@@ -1590,7 +1634,7 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color,
} }
else else
{ {
Point pt[4], dp = Point(0,0); Point2l pt[4], dp = Point2l(0,0);
double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE; double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE;
double r = dx * dx + dy * dy; double r = dx * dx + dy * dy;
int i, oddThickness = thickness & 1; int i, oddThickness = thickness & 1;
...@@ -1621,13 +1665,13 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color, ...@@ -1621,13 +1665,13 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color,
if( line_type < CV_AA ) if( line_type < CV_AA )
{ {
Point center; Point center;
center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT; center.x = (int)((p0.x + (XY_ONE>>1)) >> XY_SHIFT);
center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT; center.y = (int)((p0.y + (XY_ONE>>1)) >> XY_SHIFT);
Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 ); Circle( img, center, (thickness + (XY_ONE>>1)) >> XY_SHIFT, color, 1 );
} }
else else
{ {
EllipseEx( img, p0, cvSize(thickness, thickness), EllipseEx( img, p0, Size2l(thickness, thickness),
0, 0, 360, color, -1, line_type ); 0, 0, 360, color, -1, line_type );
} }
} }
...@@ -1638,7 +1682,7 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color, ...@@ -1638,7 +1682,7 @@ ThickLine( Mat& img, Point p0, Point p1, const void* color,
static void static void
PolyLine( Mat& img, const Point* v, int count, bool is_closed, PolyLine( Mat& img, const Point2l* v, int count, bool is_closed,
const void* color, int thickness, const void* color, int thickness,
int line_type, int shift ) int line_type, int shift )
{ {
...@@ -1647,13 +1691,13 @@ PolyLine( Mat& img, const Point* v, int count, bool is_closed, ...@@ -1647,13 +1691,13 @@ PolyLine( Mat& img, const Point* v, int count, bool is_closed,
int i = is_closed ? count - 1 : 0; int i = is_closed ? count - 1 : 0;
int flags = 2 + !is_closed; int flags = 2 + !is_closed;
Point p0; Point2l p0;
CV_Assert( 0 <= shift && shift <= XY_SHIFT && thickness >= 0 ); CV_Assert( 0 <= shift && shift <= XY_SHIFT && thickness >= 0 );
p0 = v[i]; p0 = v[i];
for( i = !is_closed; i < count; i++ ) for( i = !is_closed; i < count; i++ )
{ {
Point p = v[i]; Point2l p = v[i];
ThickLine( img, p0, p, color, thickness, line_type, flags, shift ); ThickLine( img, p0, p, color, thickness, line_type, flags, shift );
p0 = p; p0 = p;
flags = 2; flags = 2;
...@@ -1784,7 +1828,7 @@ void rectangle( InputOutputArray _img, Point pt1, Point pt2, ...@@ -1784,7 +1828,7 @@ void rectangle( InputOutputArray _img, Point pt1, Point pt2,
double buf[4]; double buf[4];
scalarToRawData(color, buf, img.type(), 0); scalarToRawData(color, buf, img.type(), 0);
Point pt[4]; Point2l pt[4];
pt[0] = pt1; pt[0] = pt1;
pt[1].x = pt2.x; pt[1].x = pt2.x;
...@@ -1831,10 +1875,12 @@ void circle( InputOutputArray _img, Point center, int radius, ...@@ -1831,10 +1875,12 @@ void circle( InputOutputArray _img, Point center, int radius,
if( thickness > 1 || line_type != LINE_8 || shift > 0 ) if( thickness > 1 || line_type != LINE_8 || shift > 0 )
{ {
center.x <<= XY_SHIFT - shift; Point2l _center(center);
center.y <<= XY_SHIFT - shift; int64 _radius(radius);
radius <<= XY_SHIFT - shift; _center.x <<= XY_SHIFT - shift;
EllipseEx( img, center, Size(radius, radius), _center.y <<= XY_SHIFT - shift;
_radius <<= XY_SHIFT - shift;
EllipseEx( img, _center, Size2l(_radius, _radius),
0, 0, 360, buf, thickness, line_type ); 0, 0, 360, buf, thickness, line_type );
} }
else else
...@@ -1862,12 +1908,14 @@ void ellipse( InputOutputArray _img, Point center, Size axes, ...@@ -1862,12 +1908,14 @@ void ellipse( InputOutputArray _img, Point center, Size axes,
int _angle = cvRound(angle); int _angle = cvRound(angle);
int _start_angle = cvRound(start_angle); int _start_angle = cvRound(start_angle);
int _end_angle = cvRound(end_angle); int _end_angle = cvRound(end_angle);
center.x <<= XY_SHIFT - shift; Point2l _center(center);
center.y <<= XY_SHIFT - shift; Size2l _axes(axes);
axes.width <<= XY_SHIFT - shift; _center.x <<= XY_SHIFT - shift;
axes.height <<= XY_SHIFT - shift; _center.y <<= XY_SHIFT - shift;
_axes.width <<= XY_SHIFT - shift;
EllipseEx( img, center, axes, _angle, _start_angle, _axes.height <<= XY_SHIFT - shift;
EllipseEx( img, _center, _axes, _angle, _start_angle,
_end_angle, buf, thickness, line_type ); _end_angle, buf, thickness, line_type );
} }
...@@ -1888,10 +1936,14 @@ void ellipse(InputOutputArray _img, const RotatedRect& box, const Scalar& color, ...@@ -1888,10 +1936,14 @@ void ellipse(InputOutputArray _img, const RotatedRect& box, const Scalar& color,
scalarToRawData(color, buf, img.type(), 0); scalarToRawData(color, buf, img.type(), 0);
int _angle = cvRound(box.angle); int _angle = cvRound(box.angle);
Point center(cvRound(box.center.x*(1 << XY_SHIFT)), Point2l center(cvRound(box.center.x),
cvRound(box.center.y*(1 << XY_SHIFT))); cvRound(box.center.y));
Size axes(cvRound(box.size.width*(1 << (XY_SHIFT - 1))), center.x = (center.x << XY_SHIFT) + cvRound((box.center.x - center.x)*XY_ONE);
cvRound(box.size.height*(1 << (XY_SHIFT - 1)))); center.y = (center.y << XY_SHIFT) + cvRound((box.center.y - center.y)*XY_ONE);
Size2l axes(cvRound(box.size.width),
cvRound(box.size.height));
axes.width = (axes.width << (XY_SHIFT - 1)) + cvRound((box.size.width - axes.width)*(XY_ONE>>1));
axes.height = (axes.height << (XY_SHIFT - 1)) + cvRound((box.size.height - axes.height)*(XY_ONE>>1));
EllipseEx( img, center, axes, _angle, 0, 360, buf, thickness, lineType ); EllipseEx( img, center, axes, _angle, 0, 360, buf, thickness, lineType );
} }
...@@ -1909,7 +1961,8 @@ void fillConvexPoly( Mat& img, const Point* pts, int npts, ...@@ -1909,7 +1961,8 @@ void fillConvexPoly( Mat& img, const Point* pts, int npts,
double buf[4]; double buf[4];
CV_Assert( 0 <= shift && shift <= XY_SHIFT ); CV_Assert( 0 <= shift && shift <= XY_SHIFT );
scalarToRawData(color, buf, img.type(), 0); scalarToRawData(color, buf, img.type(), 0);
FillConvexPoly( img, pts, npts, buf, line_type, shift ); std::vector<Point2l> _pts(pts, pts + npts);
FillConvexPoly( img, _pts.data(), npts, buf, line_type, shift );
} }
...@@ -1934,8 +1987,11 @@ void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours, ...@@ -1934,8 +1987,11 @@ void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours,
total += npts[i]; total += npts[i];
edges.reserve( total + 1 ); edges.reserve( total + 1 );
for( i = 0; i < ncontours; i++ ) for (i = 0; i < ncontours; i++)
CollectPolyEdges( img, pts[i], npts[i], edges, buf, line_type, shift, offset ); {
std::vector<Point2l> _pts(pts[i], pts[i] + npts[i]);
CollectPolyEdges(img, _pts.data(), npts[i], edges, buf, line_type, shift, offset);
}
FillEdgeCollection(img, edges, buf); FillEdgeCollection(img, edges, buf);
} }
...@@ -1957,7 +2013,10 @@ void polylines( Mat& img, const Point* const* pts, const int* npts, int ncontour ...@@ -1957,7 +2013,10 @@ void polylines( Mat& img, const Point* const* pts, const int* npts, int ncontour
scalarToRawData( color, buf, img.type(), 0 ); scalarToRawData( color, buf, img.type(), 0 );
for( int i = 0; i < ncontours; i++ ) for( int i = 0; i < ncontours; i++ )
PolyLine( img, pts[i], npts[i], isClosed, buf, thickness, line_type, shift ); {
std::vector<Point2l> _pts(pts[i], pts[i]+npts[i]);
PolyLine( img, _pts.data(), npts[i], isClosed, buf, thickness, line_type, shift );
}
} }
...@@ -2202,23 +2261,23 @@ void putText( InputOutputArray _img, const String& text, Point org, ...@@ -2202,23 +2261,23 @@ void putText( InputOutputArray _img, const String& text, Point org,
if( bottomLeftOrigin ) if( bottomLeftOrigin )
vscale = -vscale; vscale = -vscale;
int view_x = org.x << XY_SHIFT; int64 view_x = (int64)org.x << XY_SHIFT;
int view_y = (org.y << XY_SHIFT) + base_line*vscale; int64 view_y = ((int64)org.y << XY_SHIFT) + base_line*vscale;
std::vector<Point> pts; std::vector<Point2l> pts;
pts.reserve(1 << 10); pts.reserve(1 << 10);
const char **faces = cv::g_HersheyGlyphs; const char **faces = cv::g_HersheyGlyphs;
for( int i = 0; i < (int)text.size(); i++ ) for( int i = 0; i < (int)text.size(); i++ )
{ {
int c = (uchar)text[i]; int c = (uchar)text[i];
Point p; Point2l p;
readCheck(c, i, text, fontFace); readCheck(c, i, text, fontFace);
const char* ptr = faces[ascii[(c-' ')+1]]; const char* ptr = faces[ascii[(c-' ')+1]];
p.x = (uchar)ptr[0] - 'R'; p.x = (uchar)ptr[0] - 'R';
p.y = (uchar)ptr[1] - 'R'; p.y = (uchar)ptr[1] - 'R';
int dx = p.y*hscale; int64 dx = p.y*hscale;
view_x -= p.x*hscale; view_x -= p.x*hscale;
pts.resize(0); pts.resize(0);
...@@ -2237,7 +2296,7 @@ void putText( InputOutputArray _img, const String& text, Point org, ...@@ -2237,7 +2296,7 @@ void putText( InputOutputArray _img, const String& text, Point org,
p.x = (uchar)ptr[0] - 'R'; p.x = (uchar)ptr[0] - 'R';
p.y = (uchar)ptr[1] - 'R'; p.y = (uchar)ptr[1] - 'R';
ptr += 2; ptr += 2;
pts.push_back(Point(p.x*hscale + view_x, p.y*vscale + view_y)); pts.push_back(Point2l(p.x*hscale + view_x, p.y*vscale + view_y));
} }
} }
view_x += dx; view_x += dx;
...@@ -2474,7 +2533,7 @@ cvDrawContours( void* _img, CvSeq* contour, ...@@ -2474,7 +2533,7 @@ cvDrawContours( void* _img, CvSeq* contour,
CvSeq *contour0 = contour, *h_next = 0; CvSeq *contour0 = contour, *h_next = 0;
CvTreeNodeIterator iterator; CvTreeNodeIterator iterator;
std::vector<cv::PolyEdge> edges; std::vector<cv::PolyEdge> edges;
std::vector<cv::Point> pts; std::vector<cv::Point2l> pts;
cv::Scalar externalColor = _externalColor, holeColor = _holeColor; cv::Scalar externalColor = _externalColor, holeColor = _holeColor;
cv::Mat img = cv::cvarrToMat(_img); cv::Mat img = cv::cvarrToMat(_img);
cv::Point offset = _offset; cv::Point offset = _offset;
...@@ -2598,7 +2657,7 @@ cvEllipse2Poly( CvPoint center, CvSize axes, int angle, ...@@ -2598,7 +2657,7 @@ cvEllipse2Poly( CvPoint center, CvSize axes, int angle,
int arc_start, int arc_end, CvPoint* _pts, int delta ) int arc_start, int arc_end, CvPoint* _pts, int delta )
{ {
std::vector<cv::Point> pts; std::vector<cv::Point> pts;
cv::ellipse2Poly( center, axes, angle, arc_start, arc_end, delta, pts ); cv::ellipse2Poly( Point(center), Size(axes), angle, arc_start, arc_end, delta, pts );
memcpy( _pts, &pts[0], pts.size()*sizeof(_pts[0]) ); memcpy( _pts, &pts[0], pts.size()*sizeof(_pts[0]) );
return (int)pts.size(); return (int)pts.size();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment