pull/3585/merge
Kumataro 1 month ago committed by GitHub
commit 6fa0de5fb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 97
      modules/freetype/src/freetype.cpp
  2. 117
      modules/freetype/test/test_basic.cpp

@ -762,20 +762,45 @@ int FreeType2Impl::coFn( const FT_Vector *cnt,
PathUserData *p = (PathUserData *)user;
// Calicurate upper limit of CtoL.
// It is same as total length of polylines{ mOldP, cnt, to }.
const double dx1 = p->mOldP.x - cnt->x;
const double dy1 = p->mOldP.y - cnt->y;
const double dx2 = cnt->x - to->x;
const double dy2 = cnt->y - to->y;
const int maxL = static_cast<int>(
std::sqrt( dx1 * dx1 + dy1 * dy1 ) +
std::sqrt( dx2 * dx2 + dy2 * dy2 )
);
// iCtoL should be less than INT_MAX to avoid overflowing for int i.
// iCtoL should not be 0 to avoid dividing 0 for double u.
const int iCtoL = std::max( 1, std::min( { maxL, p->mCtoL, INT_MAX - 1 } ) );
// Avoid to push_back() same as previous points.
Point prevPt(INT_MIN, INT_MIN);
// Bezier to Line
for(int i = 0;i <= p->mCtoL; i++){
for(int i = 0;i <= iCtoL; i++){
// Split Bezier to lines ( in FreeType coordinates ).
double u = (double)i * 1.0 / (p->mCtoL) ;
double nu = 1.0 - u;
double p0 = nu * nu;
double p1 = 2.0 * u * nu;
double p2 = u * u;
const double u = static_cast<double>(i) / iCtoL;
const double nu = 1.0 - u;
const double p0 = nu * nu;
const double p1 = 2.0 * u * nu;
const double p2 = u * u;
double X = (p->mOldP.x) * p0 + cnt->x * p1 + to->x * p2;
double Y = (p->mOldP.y) * p0 + cnt->y * p1 + to->y * p2;
const double X = (p->mOldP.x) * p0 + cnt->x * p1 + to->x * p2;
const double Y = (p->mOldP.y) * p0 + cnt->y * p1 + to->y * p2;
// Store points to draw( in OpenCV coordinates ).
p->mPts.push_back( Point ( ftd(X), ftd(Y) ) );
const Point pt( ftd(X), ftd(Y) );
if ( pt != prevPt )
{
p->mPts.push_back( pt );
prevPt = pt;
}
}
p->mOldP = *to;
return 0;
@ -793,23 +818,51 @@ int FreeType2Impl::cuFn( const FT_Vector *cnt1,
PathUserData *p = (PathUserData *)user;
// Calicurate upper limit of CtoL.
// It is same as total length of polylines{ mOldP, cnt1, cnt2, to }.
const double dx1 = p->mOldP.x - cnt1->x;
const double dy1 = p->mOldP.y - cnt1->y;
const double dx2 = cnt1->x - cnt2->x;
const double dy2 = cnt1->y - cnt2->y;
const double dx3 = cnt2->x - to->x;
const double dy3 = cnt2->y - to->y;
const int maxL = static_cast<int>(
std::sqrt( dx1 * dx1 + dy1 * dy1 ) +
std::sqrt( dx2 * dx2 + dy2 * dy2 ) +
std::sqrt( dx3 * dx3 + dy3 * dy3 )
);
// iCtoL should be less than INT_MAX to avoid overflowing for int i.
// iCtoL should not be 0 to avoid dividing 0 for double u.
const int iCtoL = std::max( 1, std::min( { maxL, p->mCtoL, INT_MAX - 1 } ) );
// Avoid to push_back() same as previous points.
Point prevPt(INT_MIN, INT_MIN);
// Bezier to Line
for(int i = 0; i <= p->mCtoL ;i++){
for(int i = 0; i <= iCtoL ;i++){
// Split Bezier to lines ( in FreeType coordinates ).
double u = (double)i * 1.0 / (p->mCtoL) ;
double nu = 1.0 - u;
double p0 = nu * nu * nu;
double p1 = 3.0 * u * nu * nu;
double p2 = 3.0 * u * u * nu;
double p3 = u * u * u;
double X = (p->mOldP.x) * p0 + (cnt1->x) * p1 +
(cnt2->x ) * p2 + (to->x ) * p3;
double Y = (p->mOldP.y) * p0 + (cnt1->y) * p1 +
(cnt2->y ) * p2 + (to->y ) * p3;
const double u = static_cast<double>(i) / iCtoL;
const double nu = 1.0 - u;
const double p0 = nu * nu * nu;
const double p1 = 3.0 * u * nu * nu;
const double p2 = 3.0 * u * u * nu;
const double p3 = u * u * u;
const double X = (p->mOldP.x) * p0 + (cnt1->x) * p1 +
(cnt2->x ) * p2 + (to->x ) * p3;
const double Y = (p->mOldP.y) * p0 + (cnt1->y) * p1 +
(cnt2->y ) * p2 + (to->y ) * p3;
// Store points to draw( in OpenCV coordinates ).
p->mPts.push_back( Point ( ftd(X), ftd(Y) ) );
const Point pt( ftd(X), ftd(Y) );
if ( pt != prevPt )
{
p->mPts.push_back( pt );
prevPt = pt;
}
}
p->mOldP = *to;
return 0;

@ -12,15 +12,59 @@ struct MattypeParams
bool expect_success;
};
::std::ostream& operator<<(::std::ostream& os, const MattypeParams& prm) {
return os << prm.title;
::std::ostream& operator<<(::std::ostream& os, const MattypeParams& prm)
{
os << "title = " << prm.title << " ";
os << "mattype = ";
switch( CV_MAT_DEPTH( prm.mattype ) )
{
case CV_8U: os << "CV_8U" ; break;
case CV_8S: os << "CV_8S" ; break;
case CV_16U: os << "CV_16U"; break;
case CV_16S: os << "CV_16S"; break;
case CV_32S: os << "CV_32S"; break;
case CV_32F: os << "CV_32F"; break;
case CV_64F: os << "CV_64F"; break;
case CV_16F: os << "CV_16F"; break;
// OpenCV5
#ifdef CV_16BF
case CV_16BF: os << "CV_16BF"; break;
#endif
#ifdef CV_Bool
case CV_Bool: os << "CV_Bool"; break;
#endif
#ifdef CV_64U
case CV_64U: os << "CV_64U"; break;
#endif
#ifdef CV_64S
case CV_64S: os << "CV_64S"; break;
#endif
#ifdef CV_32U
case CV_32U: os << "CV_32U"; break;
#endif
default: os << "CV UNKNOWN_DEPTH(" << CV_MAT_DEPTH( prm.mattype ) << ")" ; break;
}
switch( CV_MAT_CN( prm.mattype ) )
{
case 1: os << "C1" ; break;
case 2: os << "C2" ; break;
case 3: os << "C3" ; break;
case 4: os << "C4" ; break;
default: os << "UNKNOWN_CN" << CV_MAT_CN( prm.mattype ) << ")" ; break;
}
os << " expected = " << (prm.expect_success? "true": "false") ;
return os;
}
const MattypeParams mattype_list[] =
{
{ "CV_8UC1", CV_8UC1, true}, { "CV_8UC2", CV_8UC2, false},
{ "CV_8UC3", CV_8UC3, true}, { "CV_8UC4", CV_8UC4, true},
{ "CV_8SC1", CV_8SC1, false}, { "CV_8SC2", CV_8SC2, false},
{ "CV_8SC3", CV_8SC3, false}, { "CV_8SC4", CV_8SC4, false},
{ "CV_16UC1", CV_16UC1, false}, { "CV_16UC2", CV_16UC2, false},
@ -34,7 +78,35 @@ const MattypeParams mattype_list[] =
{ "CV_64FC1", CV_64FC1, false}, { "CV_64FC2", CV_64FC2, false},
{ "CV_64FC3", CV_64FC3, false}, { "CV_64FC4", CV_64FC4, false},
{ "CV_16FC1", CV_16FC1, false}, { "CV_16FC2", CV_16FC2, false},
{ "CV_16FC3", CV_16FC3, false}, { "CV_16FC4", CV_16FC4, false},
{ "CV_16FC3", CV_16FC3, false}, { "CV_16FC4", CV_16FC4, false}
// OpenCV5
#ifdef CV_16BF
,
{ "CV_16BFC1", CV_16BFC1, false}, { "CV_16FC2", CV_16BFC2, false},
{ "CV_16BFC3", CV_16BFC3, false}, { "CV_16FC4", CV_16BFC4, false}
#endif
#ifdef CV_Bool
,
{ "CV_BoolC1", CV_BoolC1, false}, { "CV_BoolC2", CV_BoolC2, false},
{ "CV_BoolC3", CV_BoolC3, false}, { "CV_BoolC4", CV_BoolC4, false}
#endif
#ifdef CV_64U
,
{ "CV_64UC1", CV_64UC1, false}, { "CV_64UC2", CV_64UC2, false},
{ "CV_64UC3", CV_64UC3, false}, { "CV_64UC4", CV_64UC4, false}
#endif
#ifdef CV_64S
,
{ "CV_64SC1", CV_64SC1, false}, { "CV_64SC2", CV_64SC2, false},
{ "CV_64SC3", CV_64SC3, false}, { "CV_64SC4", CV_64SC4, false}
#endif
#ifdef CV_32U
,
{ "CV_32UC1", CV_32UC1, false}, { "CV_32UC2", CV_32UC2, false},
{ "CV_32UC3", CV_32UC3, false}, { "CV_32UC4", CV_32UC4, false}
#endif
};
/******************
@ -209,26 +281,53 @@ TEST_P(ctol_range, success)
const string root = cvtest::TS::ptr()->get_data_path();
const string fontdata = root + "freetype/mplus/Mplus1-Regular.ttf";
EXPECT_NO_THROW( ft2->loadFontData( fontdata, 0 ) );
EXPECT_NO_THROW( ft2->setSplitNumber(GetParam()) );
int ctol = GetParam();
if ( ctol < 1 )
{
EXPECT_THROW( ft2->setSplitNumber(GetParam()), cv::Exception );
}
else
{
EXPECT_NO_THROW( ft2->setSplitNumber(GetParam()) );
}
Mat dst(600,600, CV_8UC3, Scalar::all(255) );
Scalar col(128,64,255,192);
EXPECT_NO_THROW( ft2->putText(dst, "CtoL", Point( 0, 50), 50, col, 1, LINE_4, true ) );
EXPECT_NO_THROW( ft2->putText(dst, "LINE_4: oOpPqQ", Point( 40, 100), 50, col, 1, LINE_4, true ) );
EXPECT_NO_THROW( ft2->putText(dst, "LINE_8: oOpPqQ", Point( 40, 150), 50, col, 1, LINE_8, true ) );
EXPECT_NO_THROW( ft2->putText(dst, "LINE_AA:oOpPqQ", Point( 40, 150), 50, col, 1, LINE_AA, true ) );
EXPECT_NO_THROW( ft2->putText(dst, "LINE_AA:oOpPqQ", Point( 40, 200), 50, col, 1, LINE_AA, true ) );
if (cvtest::debugLevel > 0 )
{
imwrite( cv::format("CtoL%d-MatType.png", GetParam()) , dst );
}
}
const int ctol_list[] =
{
1,
INT_MIN, // invalid min
INT_MIN + 1,
-1,
0, // invalid max
1, // valid min
2,
4,
8,
16,
32,
64,
128,
// INT_MAX -1, // Hang-up
// INT_MAX // Hang-up
256,
512,
1024,
2048,
4096,
8192,
INT_MAX -1,
INT_MAX // valid max
};
INSTANTIATE_TEST_CASE_P(Freetype_setSplitNumber, ctol_range,

Loading…
Cancel
Save