优化代码格式(VS)

serial
BlueMatthew 1 year ago
parent 9e4e73a734
commit ab93ef9fc9

@ -14,7 +14,7 @@
#include <opencv2/imgproc.hpp> #include <opencv2/imgproc.hpp>
namespace cv { namespace cv {
namespace ft { namespace ft {
using namespace std; using namespace std;
@ -24,7 +24,7 @@ namespace ft {
FreeType2Impl(); FreeType2Impl();
~FreeType2Impl(); ~FreeType2Impl();
void loadFontData(String fontFileName, int idx); void loadFontData(String fontFileName, int idx);
void setSplitNumber( int num ); void setSplitNumber(int num);
void putText( void putText(
InputOutputArray img, const String& text, Point org, InputOutputArray img, const String& text, Point org,
int fontHeight, Scalar color, int fontHeight, Scalar color,
@ -61,22 +61,22 @@ namespace ft {
int thickness, int line_type, bool bottomLeftOrigin int thickness, int line_type, bool bottomLeftOrigin
); );
typedef void (putPixel_mono_fn)( Mat& _dst, const int _py, const int _px, const uint8_t *_col); typedef void (putPixel_mono_fn)(Mat& _dst, const int _py, const int _px, const uint8_t *_col);
putPixel_mono_fn putPixel_8UC1_mono; putPixel_mono_fn putPixel_8UC1_mono;
putPixel_mono_fn putPixel_8UC3_mono; putPixel_mono_fn putPixel_8UC3_mono;
putPixel_mono_fn putPixel_8UC4_mono; putPixel_mono_fn putPixel_8UC4_mono;
typedef void (putPixel_blend_fn)( Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha); typedef void (putPixel_blend_fn)(Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha);
putPixel_blend_fn putPixel_8UC1_blend; putPixel_blend_fn putPixel_8UC1_blend;
putPixel_blend_fn putPixel_8UC3_blend; putPixel_blend_fn putPixel_8UC3_blend;
putPixel_blend_fn putPixel_8UC4_blend; putPixel_blend_fn putPixel_8UC4_blend;
static int mvFn( const FT_Vector *to, void * user); static int mvFn(const FT_Vector *to, void * user);
static int lnFn( const FT_Vector *to, void * user); static int lnFn(const FT_Vector *to, void * user);
static int coFn( const FT_Vector *cnt, static int coFn(const FT_Vector *cnt,
const FT_Vector *to, const FT_Vector *to,
void * user); void * user);
static int cuFn( const FT_Vector *cnt1, static int cuFn(const FT_Vector *cnt1,
const FT_Vector *cnt2, const FT_Vector *cnt2,
const FT_Vector *to, const FT_Vector *to,
void * user); void * user);
@ -85,18 +85,19 @@ namespace ft {
* Convert from FT_F26Dot6 to int(coodinate of OpenCV) * Convert from FT_F26Dot6 to int(coodinate of OpenCV)
* (FT_F26Dot6 is signed 26.6 real) * (FT_F26Dot6 is signed 26.6 real)
*/ */
static int ftd(FT_F26Dot6 fixedInt){ static int ftd(FT_F26Dot6 fixedInt) {
if ( fixedInt > 0 ) { if (fixedInt > 0) {
return ( fixedInt + 32 ) / 64 ; return (fixedInt + 32) / 64;
}else{ }
return ( fixedInt - 32 ) / 64 ; else {
return (fixedInt - 32) / 64;
} }
} }
class PathUserData{ class PathUserData {
private: private:
public: public:
PathUserData( InputOutputArray _img) : mImg(_img) {}; PathUserData(InputOutputArray _img) : mImg(_img) {};
InputOutputArray mImg; InputOutputArray mImg;
Scalar mColor; Scalar mColor;
@ -110,7 +111,7 @@ namespace ft {
FreeType2Impl::FreeType2Impl() FreeType2Impl::FreeType2Impl()
{ {
FT_Init_FreeType(&(this->mLibrary) ); FT_Init_FreeType(&(this->mLibrary));
mCtoL = 16; mCtoL = 16;
mFn.shift = 0; mFn.shift = 0;
@ -125,10 +126,10 @@ namespace ft {
FreeType2Impl::~FreeType2Impl() FreeType2Impl::~FreeType2Impl()
{ {
if( mIsFaceAvailable == true ) if (mIsFaceAvailable == true)
{ {
#if 0 #if 0
hb_font_destroy (mHb_font); hb_font_destroy(mHb_font);
#endif #endif
CV_Assert(!FT_Done_Face(mFace)); CV_Assert(!FT_Done_Face(mFace));
mIsFaceAvailable = false; mIsFaceAvailable = false;
@ -138,32 +139,32 @@ namespace ft {
void FreeType2Impl::loadFontData(String fontFileName, int idx) void FreeType2Impl::loadFontData(String fontFileName, int idx)
{ {
CV_Assert( idx >= 0 ); CV_Assert(idx >= 0);
if( mIsFaceAvailable == true ) if (mIsFaceAvailable == true)
{ {
#if 0 #if 0
hb_font_destroy (mHb_font); hb_font_destroy(mHb_font);
#endif #endif
CV_Assert(!FT_Done_Face(mFace)); CV_Assert(!FT_Done_Face(mFace));
} }
mIsFaceAvailable = false; mIsFaceAvailable = false;
CV_Assert( !FT_New_Face( mLibrary, fontFileName.c_str(), static_cast<FT_Long>(idx), &(mFace) ) ); CV_Assert(!FT_New_Face(mLibrary, fontFileName.c_str(), static_cast<FT_Long>(idx), &(mFace)));
#if 0 #if 0
mHb_font = hb_ft_font_create (mFace, NULL); mHb_font = hb_ft_font_create(mFace, NULL);
if ( mHb_font == NULL ) if (mHb_font == NULL)
{ {
CV_Assert(!FT_Done_Face(mFace)); CV_Assert(!FT_Done_Face(mFace));
return; return;
} }
CV_Assert( mHb_font != NULL ); CV_Assert(mHb_font != NULL);
#endif #endif
mIsFaceAvailable = true; mIsFaceAvailable = true;
} }
void FreeType2Impl::setSplitNumber(int num ){ void FreeType2Impl::setSplitNumber(int num) {
CV_Assert( num > 0 ); CV_Assert(num > 0);
mCtoL = num; mCtoL = num;
} }
@ -173,88 +174,90 @@ namespace ft {
int _thickness, int _line_type, bool _bottomLeftOrigin int _thickness, int _line_type, bool _bottomLeftOrigin
) )
{ {
CV_Assert ( mIsFaceAvailable == true ); CV_Assert(mIsFaceAvailable == true);
CV_Assert ( _img.empty() == false ); CV_Assert(_img.empty() == false);
CV_Assert ( _img.isMat() == true ); CV_Assert(_img.isMat() == true);
CV_Assert ( _img.dims() == 2 ); CV_Assert(_img.dims() == 2);
CV_Assert( ( _img.type() == CV_8UC1 ) || CV_Assert((_img.type() == CV_8UC1) ||
( _img.type() == CV_8UC3 ) || (_img.type() == CV_8UC3) ||
( _img.type() == CV_8UC4 ) ); (_img.type() == CV_8UC4));
CV_Assert( ( _line_type == LINE_AA) || CV_Assert((_line_type == LINE_AA) ||
( _line_type == LINE_4 ) || (_line_type == LINE_4) ||
( _line_type == LINE_8 ) ); (_line_type == LINE_8));
CV_Assert ( _fontHeight >= 0 ); CV_Assert(_fontHeight >= 0);
if ( _text.empty() ) if (_text.empty())
{ {
return; return;
} }
if ( _fontHeight == 0 ) if (_fontHeight == 0)
{ {
return; return;
} }
CV_Assert(!FT_Set_Pixel_Sizes( mFace, _fontHeight, _fontHeight )); CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight));
if( _thickness < 0 ) // CV_FILLED if (_thickness < 0) // CV_FILLED
{ {
if ( _line_type == LINE_AA ) { if (_line_type == LINE_AA) {
putTextBitmapBlend( _img, _text, _org, _fontHeight, _color, putTextBitmapBlend(_img, _text, _org, _fontHeight, _color,
_thickness, _line_type, _bottomLeftOrigin ); _thickness, _line_type, _bottomLeftOrigin);
}else{ }
putTextBitmapMono( _img, _text, _org, _fontHeight, _color, else {
_thickness, _line_type, _bottomLeftOrigin ); putTextBitmapMono(_img, _text, _org, _fontHeight, _color,
_thickness, _line_type, _bottomLeftOrigin);
}
} }
}else{ else {
putTextOutline( _img, _text, _org, _fontHeight, _color, putTextOutline(_img, _text, _org, _fontHeight, _color,
_thickness, _line_type, _bottomLeftOrigin ); _thickness, _line_type, _bottomLeftOrigin);
} }
} }
void FreeType2Impl::putTextOutline( void FreeType2Impl::putTextOutline(
InputOutputArray _img, const String& _text, Point _org, InputOutputArray _img, const String& _text, Point _org,
int _fontHeight, Scalar _color, int _fontHeight, Scalar _color,
int _thickness, int _line_type, bool _bottomLeftOrigin ) int _thickness, int _line_type, bool _bottomLeftOrigin)
{ {
#if 0 #if 0
hb_buffer_t *hb_buffer = hb_buffer_create (); hb_buffer_t *hb_buffer = hb_buffer_create();
CV_Assert( hb_buffer != NULL ); CV_Assert(hb_buffer != NULL);
hb_buffer_add_utf8 (hb_buffer, _text.c_str(), -1, 0, -1); hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1);
hb_buffer_guess_segment_properties (hb_buffer); hb_buffer_guess_segment_properties(hb_buffer);
hb_shape (mHb_font, hb_buffer, NULL, 0); hb_shape(mHb_font, hb_buffer, NULL, 0);
unsigned int textLen = 0; unsigned int textLen = 0;
hb_glyph_info_t *info = hb_glyph_info_t *info =
hb_buffer_get_glyph_infos(hb_buffer,&textLen ); hb_buffer_get_glyph_infos(hb_buffer, &textLen);
CV_Assert( info != NULL ); CV_Assert(info != NULL);
#else #else
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
wstring wstr = converter.from_bytes(_text); wstring wstr = converter.from_bytes(_text);
#endif #endif
PathUserData *userData = new PathUserData( _img ); PathUserData *userData = new PathUserData(_img);
userData->mColor = _color; userData->mColor = _color;
userData->mCtoL = mCtoL; userData->mCtoL = mCtoL;
userData->mThickness = _thickness; userData->mThickness = _thickness;
userData->mLine_type = _line_type; userData->mLine_type = _line_type;
// Initilize currentPosition ( in FreeType coordinates) // Initilize currentPosition ( in FreeType coordinates)
FT_Vector currentPos = {0,0}; FT_Vector currentPos = { 0,0 };
currentPos.x = _org.x * 64; currentPos.x = _org.x * 64;
currentPos.y = _org.y * 64; currentPos.y = _org.y * 64;
// Update currentPosition with bottomLeftOrigin ( in FreeType coordinates) // Update currentPosition with bottomLeftOrigin ( in FreeType coordinates)
if( _bottomLeftOrigin != true ){ if (_bottomLeftOrigin != true) {
currentPos.y += _fontHeight * 64; currentPos.y += _fontHeight * 64;
} }
#if defined(USING_HB) #if defined(USING_HB)
for( unsigned int i = 0 ; i < textLen ; i ++ ){ for (unsigned int i = 0; i < textLen; i++) {
CV_Assert( !FT_Load_Glyph(mFace, info[i].codepoint, 0 ) ); CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0));
#else #else
for( unsigned int i = 0 ; i < wstr.size() ; i ++ ){ for (unsigned int i = 0; i < wstr.size(); i++) {
CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0 )); CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0));
#endif #endif
FT_GlyphSlot slot = mFace->glyph; FT_GlyphSlot slot = mFace->glyph;
FT_Outline outline = slot->outline; FT_Outline outline = slot->outline;
@ -269,10 +272,10 @@ namespace ft {
currentPos.y); currentPos.y);
// Draw ( in FreeType coordinates ) // Draw ( in FreeType coordinates )
CV_Assert( !FT_Outline_Decompose(&outline, &mFn, (void*)userData) ); CV_Assert(!FT_Outline_Decompose(&outline, &mFn, (void*)userData));
// Draw (Last Path) ( in FreeType coordinates ) // Draw (Last Path) ( in FreeType coordinates )
mvFn( NULL, (void*)userData ); mvFn(NULL, (void*)userData);
// Update current position ( in FreeType coordinates ) // Update current position ( in FreeType coordinates )
currentPos.x += mFace->glyph->advance.x; currentPos.x += mFace->glyph->advance.x;
@ -280,27 +283,27 @@ namespace ft {
} }
delete userData; delete userData;
#if defined(USING_HB) #if defined(USING_HB)
hb_buffer_destroy (hb_buffer); hb_buffer_destroy(hb_buffer);
#endif 0 #endif 0
} }
void FreeType2Impl::putPixel_8UC1_mono( Mat& _dst, const int _py, const int _px, const uint8_t *_col) void FreeType2Impl::putPixel_8UC1_mono(Mat& _dst, const int _py, const int _px, const uint8_t *_col)
{ {
uint8_t* ptr = _dst.ptr<uint8_t>( _py, _px ); uint8_t* ptr = _dst.ptr<uint8_t>(_py, _px);
(*ptr) = _col[0]; (*ptr) = _col[0];
} }
void FreeType2Impl::putPixel_8UC3_mono ( Mat& _dst, const int _py, const int _px, const uint8_t *_col) void FreeType2Impl::putPixel_8UC3_mono(Mat& _dst, const int _py, const int _px, const uint8_t *_col)
{ {
cv::Vec3b* ptr = _dst.ptr<cv::Vec3b>( _py, _px ); cv::Vec3b* ptr = _dst.ptr<cv::Vec3b>(_py, _px);
(*ptr)[0] = _col[0]; (*ptr)[0] = _col[0];
(*ptr)[1] = _col[1]; (*ptr)[1] = _col[1];
(*ptr)[2] = _col[2]; (*ptr)[2] = _col[2];
} }
void FreeType2Impl::putPixel_8UC4_mono( Mat& _dst, const int _py, const int _px, const uint8_t *_col) void FreeType2Impl::putPixel_8UC4_mono(Mat& _dst, const int _py, const int _px, const uint8_t *_col)
{ {
cv::Vec4b* ptr = _dst.ptr<cv::Vec4b>( _py, _px ); cv::Vec4b* ptr = _dst.ptr<cv::Vec4b>(_py, _px);
(*ptr)[0] = _col[0]; (*ptr)[0] = _col[0];
(*ptr)[1] = _col[1]; (*ptr)[1] = _col[1];
(*ptr)[2] = _col[2]; (*ptr)[2] = _col[2];
@ -310,31 +313,31 @@ namespace ft {
void FreeType2Impl::putTextBitmapMono( void FreeType2Impl::putTextBitmapMono(
InputOutputArray _img, const String& _text, Point _org, InputOutputArray _img, const String& _text, Point _org,
int _fontHeight, Scalar _color, int _fontHeight, Scalar _color,
int _thickness, int _line_type, bool _bottomLeftOrigin ) int _thickness, int _line_type, bool _bottomLeftOrigin)
{ {
CV_Assert( _thickness < 0 ); CV_Assert(_thickness < 0);
CV_Assert( _line_type == LINE_4 || _line_type == LINE_8); CV_Assert(_line_type == LINE_4 || _line_type == LINE_8);
Mat dst = _img.getMat(); Mat dst = _img.getMat();
#if defined(USING_HB) #if defined(USING_HB)
hb_buffer_t *hb_buffer = hb_buffer_create (); hb_buffer_t *hb_buffer = hb_buffer_create();
CV_Assert( hb_buffer != NULL ); CV_Assert(hb_buffer != NULL);
hb_buffer_add_utf8 (hb_buffer, _text.c_str(), -1, 0, -1); hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1);
hb_buffer_guess_segment_properties (hb_buffer); hb_buffer_guess_segment_properties(hb_buffer);
hb_shape (mHb_font, hb_buffer, NULL, 0); hb_shape(mHb_font, hb_buffer, NULL, 0);
unsigned int textLen = 0; unsigned int textLen = 0;
hb_glyph_info_t *info = hb_glyph_info_t *info =
hb_buffer_get_glyph_infos(hb_buffer,&textLen ); hb_buffer_get_glyph_infos(hb_buffer, &textLen);
CV_Assert( info != NULL ); CV_Assert(info != NULL);
#else #else
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
wstring wstr = converter.from_bytes(_text); wstring wstr = converter.from_bytes(_text);
#endif #endif
_org.y += _fontHeight; _org.y += _fontHeight;
if( _bottomLeftOrigin == true ){ if (_bottomLeftOrigin == true) {
_org.y -= _fontHeight; _org.y -= _fontHeight;
} }
@ -344,130 +347,130 @@ namespace ft {
static_cast<uint8_t>(_color[2]), static_cast<uint8_t>(_color[2]),
static_cast<uint8_t>(_color[3]) }; static_cast<uint8_t>(_color[3]) };
void (cv::ft::FreeType2Impl::*putPixel)( Mat&, const int, const int, const uint8_t*) = void (cv::ft::FreeType2Impl::*putPixel)(Mat&, const int, const int, const uint8_t*) =
(_img.type() == CV_8UC4)?(&FreeType2Impl::putPixel_8UC4_mono): (_img.type() == CV_8UC4) ? (&FreeType2Impl::putPixel_8UC4_mono) :
(_img.type() == CV_8UC3)?(&FreeType2Impl::putPixel_8UC3_mono): (_img.type() == CV_8UC3) ? (&FreeType2Impl::putPixel_8UC3_mono) :
(&FreeType2Impl::putPixel_8UC1_mono); (&FreeType2Impl::putPixel_8UC1_mono);
#if defined(USING_HB) #if defined(USING_HB)
for( unsigned int i = 0 ; i < textLen ; i ++ ){ for (unsigned int i = 0; i < textLen; i++) {
CV_Assert( !FT_Load_Glyph(mFace, info[i].codepoint, 0 ) ); CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0));
#else #else
for( unsigned int i = 0 ; i < wstr.size() ; i ++ ){ for (unsigned int i = 0; i < wstr.size(); i++) {
CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0 )); CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0));
#endif #endif
CV_Assert( !FT_Render_Glyph( mFace->glyph, FT_RENDER_MODE_MONO ) ); CV_Assert(!FT_Render_Glyph(mFace->glyph, FT_RENDER_MODE_MONO));
FT_Bitmap *bmp = &(mFace->glyph->bitmap); FT_Bitmap *bmp = &(mFace->glyph->bitmap);
Point gPos = _org; Point gPos = _org;
gPos.y -= ( mFace->glyph->metrics.horiBearingY >> 6) ; gPos.y -= (mFace->glyph->metrics.horiBearingY >> 6);
gPos.x += ( mFace->glyph->metrics.horiBearingX >> 6) ; gPos.x += (mFace->glyph->metrics.horiBearingX >> 6);
for (int row = 0; row < (int)bmp->rows; row ++) { for (int row = 0; row < (int)bmp->rows; row++) {
if( gPos.y + row < 0 ) { if (gPos.y + row < 0) {
continue; continue;
} }
if( gPos.y + row >= dst.rows ) { if (gPos.y + row >= dst.rows) {
break; break;
} }
for (int col = 0; col < bmp->pitch; col ++) { for (int col = 0; col < bmp->pitch; col++) {
int cl = bmp->buffer[ row * bmp->pitch + col ]; int cl = bmp->buffer[row * bmp->pitch + col];
if ( cl == 0 ) { if (cl == 0) {
continue; continue;
} }
for(int bit = 7; bit >= 0; bit -- ){ for (int bit = 7; bit >= 0; bit--) {
if( gPos.x + col * 8 + (7 - bit) < 0 ) if (gPos.x + col * 8 + (7 - bit) < 0)
{ {
continue; continue;
} }
if( gPos.x + col * 8 + (7 - bit) >= dst.cols ) if (gPos.x + col * 8 + (7 - bit) >= dst.cols)
{ {
break; break;
} }
if ( ( (cl >> bit) & 0x01 ) == 1 ) { if (((cl >> bit) & 0x01) == 1) {
(this->*putPixel)( dst, gPos.y + row, gPos.x + col * 8 + (7 - bit), _colorUC8n ); (this->*putPixel)(dst, gPos.y + row, gPos.x + col * 8 + (7 - bit), _colorUC8n);
} }
} }
} }
} }
_org.x += ( mFace->glyph->advance.x ) >> 6; _org.x += (mFace->glyph->advance.x) >> 6;
_org.y += ( mFace->glyph->advance.y ) >> 6; _org.y += (mFace->glyph->advance.y) >> 6;
} }
#if defined(USING_HB) #if defined(USING_HB)
hb_buffer_destroy (hb_buffer); hb_buffer_destroy(hb_buffer);
#endif #endif
} }
// Alpha composite algorithm is porting from imgproc. // Alpha composite algorithm is porting from imgproc.
// See https://github.com/opencv/opencv/blob/4.6.0/modules/imgproc/src/drawing.cpp // See https://github.com/opencv/opencv/blob/4.6.0/modules/imgproc/src/drawing.cpp
// static void LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color ) // static void LineAA( Mat& img, Point2l pt1, Point2l pt2, const void* color )
// ICV_PUT_POINT Macro. // ICV_PUT_POINT Macro.
void FreeType2Impl::putPixel_8UC1_blend( Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha) void FreeType2Impl::putPixel_8UC1_blend(Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha)
{ {
const int a = alpha; const int a = alpha;
const int cb = _col[0]; const int cb = _col[0];
uint8_t* tptr = _dst.ptr<uint8_t>( _py, _px ); uint8_t* tptr = _dst.ptr<uint8_t>(_py, _px);
int _cb = static_cast<int>(tptr[0]); int _cb = static_cast<int>(tptr[0]);
_cb += ((cb - _cb)*a + 127)>> 8; _cb += ((cb - _cb)*a + 127) >> 8;
_cb += ((cb - _cb)*a + 127)>> 8; _cb += ((cb - _cb)*a + 127) >> 8;
tptr[0] = static_cast<uint8_t>(_cb); tptr[0] = static_cast<uint8_t>(_cb);
} }
void FreeType2Impl::putPixel_8UC3_blend ( Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha) void FreeType2Impl::putPixel_8UC3_blend(Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha)
{ {
const int a = alpha; const int a = alpha;
const int cb = _col[0]; const int cb = _col[0];
const int cg = _col[1]; const int cg = _col[1];
const int cr = _col[2]; const int cr = _col[2];
uint8_t* tptr = _dst.ptr<uint8_t>( _py, _px ); uint8_t* tptr = _dst.ptr<uint8_t>(_py, _px);
int _cb = static_cast<int>(tptr[0]); int _cb = static_cast<int>(tptr[0]);
_cb += ((cb - _cb)*a + 127)>> 8; _cb += ((cb - _cb)*a + 127) >> 8;
_cb += ((cb - _cb)*a + 127)>> 8; _cb += ((cb - _cb)*a + 127) >> 8;
int _cg = static_cast<int>(tptr[1]); int _cg = static_cast<int>(tptr[1]);
_cg += ((cg - _cg)*a + 127)>> 8; _cg += ((cg - _cg)*a + 127) >> 8;
_cg += ((cg - _cg)*a + 127)>> 8; _cg += ((cg - _cg)*a + 127) >> 8;
int _cr = static_cast<int>(tptr[2]); int _cr = static_cast<int>(tptr[2]);
_cr += ((cr - _cr)*a + 127)>> 8; _cr += ((cr - _cr)*a + 127) >> 8;
_cr += ((cr - _cr)*a + 127)>> 8; _cr += ((cr - _cr)*a + 127) >> 8;
tptr[0] = static_cast<uint8_t>(_cb); tptr[0] = static_cast<uint8_t>(_cb);
tptr[1] = static_cast<uint8_t>(_cg); tptr[1] = static_cast<uint8_t>(_cg);
tptr[2] = static_cast<uint8_t>(_cr); tptr[2] = static_cast<uint8_t>(_cr);
} }
void FreeType2Impl::putPixel_8UC4_blend( Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha) void FreeType2Impl::putPixel_8UC4_blend(Mat& _dst, const int _py, const int _px, const uint8_t *_col, const uint8_t alpha)
{ {
const uint8_t a = alpha; const uint8_t a = alpha;
const int cb = _col[0]; const int cb = _col[0];
const int cg = _col[1]; const int cg = _col[1];
const int cr = _col[2]; const int cr = _col[2];
const int ca = _col[3]; const int ca = _col[3];
uint8_t* tptr = _dst.ptr<uint8_t>( _py, _px ); uint8_t* tptr = _dst.ptr<uint8_t>(_py, _px);
int _cb = static_cast<int>(tptr[0]); int _cb = static_cast<int>(tptr[0]);
_cb += ((cb - _cb)*a + 127)>> 8; _cb += ((cb - _cb)*a + 127) >> 8;
_cb += ((cb - _cb)*a + 127)>> 8; _cb += ((cb - _cb)*a + 127) >> 8;
int _cg = static_cast<int>(tptr[1]); int _cg = static_cast<int>(tptr[1]);
_cg += ((cg - _cg)*a + 127)>> 8; _cg += ((cg - _cg)*a + 127) >> 8;
_cg += ((cg - _cg)*a + 127)>> 8; _cg += ((cg - _cg)*a + 127) >> 8;
int _cr = static_cast<int>(tptr[2]); int _cr = static_cast<int>(tptr[2]);
_cr += ((cr - _cr)*a + 127)>> 8; _cr += ((cr - _cr)*a + 127) >> 8;
_cr += ((cr - _cr)*a + 127)>> 8; _cr += ((cr - _cr)*a + 127) >> 8;
int _ca = static_cast<int>(tptr[3]); int _ca = static_cast<int>(tptr[3]);
_ca += ((ca - _ca)*a + 127)>> 8; _ca += ((ca - _ca)*a + 127) >> 8;
_ca += ((ca - _ca)*a + 127)>> 8; _ca += ((ca - _ca)*a + 127) >> 8;
tptr[0] = static_cast<uint8_t>(_cb); tptr[0] = static_cast<uint8_t>(_cb);
tptr[1] = static_cast<uint8_t>(_cg); tptr[1] = static_cast<uint8_t>(_cg);
@ -478,32 +481,32 @@ namespace ft {
void FreeType2Impl::putTextBitmapBlend( void FreeType2Impl::putTextBitmapBlend(
InputOutputArray _img, const String& _text, Point _org, InputOutputArray _img, const String& _text, Point _org,
int _fontHeight, Scalar _color, int _fontHeight, Scalar _color,
int _thickness, int _line_type, bool _bottomLeftOrigin ) int _thickness, int _line_type, bool _bottomLeftOrigin)
{ {
CV_Assert( _thickness < 0 ); CV_Assert(_thickness < 0);
CV_Assert( _line_type == LINE_AA ); CV_Assert(_line_type == LINE_AA);
Mat dst = _img.getMat(); Mat dst = _img.getMat();
#if defined(USING_HB) #if defined(USING_HB)
hb_buffer_t *hb_buffer = hb_buffer_create (); hb_buffer_t *hb_buffer = hb_buffer_create();
CV_Assert( hb_buffer != NULL ); CV_Assert(hb_buffer != NULL);
hb_buffer_add_utf8 (hb_buffer, _text.c_str(), -1, 0, -1); hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1);
hb_buffer_guess_segment_properties (hb_buffer); hb_buffer_guess_segment_properties(hb_buffer);
hb_shape (mHb_font, hb_buffer, NULL, 0); hb_shape(mHb_font, hb_buffer, NULL, 0);
unsigned int textLen = 0; unsigned int textLen = 0;
hb_glyph_info_t *info = hb_glyph_info_t *info =
hb_buffer_get_glyph_infos(hb_buffer,&textLen ); hb_buffer_get_glyph_infos(hb_buffer, &textLen);
CV_Assert( info != NULL ); CV_Assert(info != NULL);
#else #else
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
wstring wstr = converter.from_bytes(_text); wstring wstr = converter.from_bytes(_text);
#endif #endif
_org.y += _fontHeight; _org.y += _fontHeight;
if( _bottomLeftOrigin == true ){ if (_bottomLeftOrigin == true) {
_org.y -= _fontHeight; _org.y -= _fontHeight;
} }
@ -513,56 +516,56 @@ namespace ft {
static_cast<uint8_t>(_color[2]), static_cast<uint8_t>(_color[2]),
static_cast<uint8_t>(_color[3]) }; static_cast<uint8_t>(_color[3]) };
void (cv::ft::FreeType2Impl::*putPixel)( Mat&, const int, const int, const uint8_t*, const uint8_t) = void (cv::ft::FreeType2Impl::*putPixel)(Mat&, const int, const int, const uint8_t*, const uint8_t) =
(_img.type() == CV_8UC4)?(&FreeType2Impl::putPixel_8UC4_blend): (_img.type() == CV_8UC4) ? (&FreeType2Impl::putPixel_8UC4_blend) :
(_img.type() == CV_8UC3)?(&FreeType2Impl::putPixel_8UC3_blend): (_img.type() == CV_8UC3) ? (&FreeType2Impl::putPixel_8UC3_blend) :
(&FreeType2Impl::putPixel_8UC1_blend); (&FreeType2Impl::putPixel_8UC1_blend);
#if defined(USING_HB) #if defined(USING_HB)
for( unsigned int i = 0 ; i < textLen ; i ++ ){ for (unsigned int i = 0; i < textLen; i++) {
CV_Assert( !FT_Load_Glyph(mFace, info[i].codepoint, 0 ) ); CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0));
#else #else
for( unsigned int i = 0 ; i < wstr.size() ; i ++ ){ for (unsigned int i = 0; i < wstr.size(); i++) {
CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0 )); CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0));
#endif #endif
CV_Assert( !FT_Render_Glyph( mFace->glyph, FT_RENDER_MODE_NORMAL ) ); CV_Assert(!FT_Render_Glyph(mFace->glyph, FT_RENDER_MODE_NORMAL));
FT_Bitmap *bmp = &(mFace->glyph->bitmap); FT_Bitmap *bmp = &(mFace->glyph->bitmap);
Point gPos = _org; Point gPos = _org;
gPos.y -= ( mFace->glyph->metrics.horiBearingY >> 6) ; gPos.y -= (mFace->glyph->metrics.horiBearingY >> 6);
gPos.x += ( mFace->glyph->metrics.horiBearingX >> 6) ; gPos.x += (mFace->glyph->metrics.horiBearingX >> 6);
for (int row = 0; row < (int)bmp->rows; row ++) { for (int row = 0; row < (int)bmp->rows; row++) {
if( gPos.y + row < 0 ) { if (gPos.y + row < 0) {
continue; continue;
} }
if( gPos.y + row >= dst.rows ) { if (gPos.y + row >= dst.rows) {
break; break;
} }
for (int col = 0; col < bmp->pitch; col ++) { for (int col = 0; col < bmp->pitch; col++) {
uint8_t cl = bmp->buffer[ row * bmp->pitch + col ]; uint8_t cl = bmp->buffer[row * bmp->pitch + col];
if ( cl == 0 ) { if (cl == 0) {
continue; continue;
} }
if( gPos.x + col < 0 ) if (gPos.x + col < 0)
{ {
continue; continue;
} }
if( gPos.x + col >= dst.cols ) if (gPos.x + col >= dst.cols)
{ {
break; break;
} }
(this->*putPixel)( dst, gPos.y + row, gPos.x + col, _colorUC8n, cl ); (this->*putPixel)(dst, gPos.y + row, gPos.x + col, _colorUC8n, cl);
} }
} }
_org.x += ( mFace->glyph->advance.x ) >> 6; _org.x += (mFace->glyph->advance.x) >> 6;
_org.y += ( mFace->glyph->advance.y ) >> 6; _org.y += (mFace->glyph->advance.y) >> 6;
} }
#if defined(USING_HB) #if defined(USING_HB)
hb_buffer_destroy (hb_buffer); hb_buffer_destroy(hb_buffer);
#endif #endif
} }
@ -572,32 +575,32 @@ namespace ft {
int _thickness, int _thickness,
CV_OUT int* _baseLine) CV_OUT int* _baseLine)
{ {
if ( _text.empty() ) if (_text.empty())
{ {
return Size(0,0); return Size(0, 0);
} }
CV_Assert( _fontHeight >= 0 ) ; CV_Assert(_fontHeight >= 0);
if ( _fontHeight == 0 ) if (_fontHeight == 0)
{ {
return Size(0,0); return Size(0, 0);
} }
CV_Assert(!FT_Set_Pixel_Sizes( mFace, _fontHeight, _fontHeight )); CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight));
FT_Vector currentPos = {0,0}; FT_Vector currentPos = { 0,0 };
#if defined(USING_HB) #if defined(USING_HB)
hb_buffer_t *hb_buffer = hb_buffer_create (); hb_buffer_t *hb_buffer = hb_buffer_create();
CV_Assert( hb_buffer != NULL ); CV_Assert(hb_buffer != NULL);
hb_buffer_add_utf8 (hb_buffer, _text.c_str(), -1, 0, -1); hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1);
hb_buffer_guess_segment_properties (hb_buffer); hb_buffer_guess_segment_properties(hb_buffer);
hb_shape (mHb_font, hb_buffer, NULL, 0); hb_shape(mHb_font, hb_buffer, NULL, 0);
unsigned int textLen = 0; unsigned int textLen = 0;
hb_glyph_info_t *info = hb_glyph_info_t *info =
hb_buffer_get_glyph_infos(hb_buffer,&textLen ); hb_buffer_get_glyph_infos(hb_buffer, &textLen);
CV_Assert( info != NULL ); CV_Assert(info != NULL);
#else #else
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
wstring wstr = converter.from_bytes(_text); wstring wstr = converter.from_bytes(_text);
@ -607,15 +610,15 @@ namespace ft {
int xMax = INT_MIN, yMax = INT_MIN; int xMax = INT_MIN, yMax = INT_MIN;
#if defined(USING_HB) #if defined(USING_HB)
for( unsigned int i = 0 ; i < textLen ; i ++ ){ for (unsigned int i = 0; i < textLen; i++) {
CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0 )); CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0));
#else #else
for( unsigned int i = 0 ; i < wstr.size() ; i ++ ){ for (unsigned int i = 0; i < wstr.size(); i++) {
CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0 )); CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0));
#endif #endif
FT_GlyphSlot slot = mFace->glyph; FT_GlyphSlot slot = mFace->glyph;
FT_Outline outline = slot->outline; FT_Outline outline = slot->outline;
FT_BBox bbox ; FT_BBox bbox;
// Flip ( in FreeType coordinates ) // Flip ( in FreeType coordinates )
FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) }; FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) };
@ -624,19 +627,19 @@ namespace ft {
// Move to current position ( in FreeType coordinates ) // Move to current position ( in FreeType coordinates )
FT_Outline_Translate(&outline, FT_Outline_Translate(&outline,
currentPos.x, currentPos.x,
currentPos.y ); currentPos.y);
// Get BoundaryBox ( in FreeType coordinatrs ) // Get BoundaryBox ( in FreeType coordinatrs )
CV_Assert( !FT_Outline_Get_BBox( &outline, &bbox ) ); CV_Assert(!FT_Outline_Get_BBox(&outline, &bbox));
// If codepoint is space(0x20), it has no glyph. // If codepoint is space(0x20), it has no glyph.
// A dummy boundary box is needed when last code is space. // A dummy boundary box is needed when last code is space.
if( if (
(bbox.xMin == 0 ) && (bbox.xMax == 0 ) && (bbox.xMin == 0) && (bbox.xMax == 0) &&
(bbox.yMin == 0 ) && (bbox.yMax == 0 ) (bbox.yMin == 0) && (bbox.yMax == 0)
){ ) {
bbox.xMin = currentPos.x ; bbox.xMin = currentPos.x;
bbox.xMax = currentPos.x + ( mFace->glyph->advance.x ); bbox.xMax = currentPos.x + (mFace->glyph->advance.x);
bbox.yMin = yMin; bbox.yMin = yMin;
bbox.yMax = yMax; bbox.yMax = yMax;
} }
@ -646,42 +649,43 @@ namespace ft {
currentPos.y += mFace->glyph->advance.y; currentPos.y += mFace->glyph->advance.y;
// Update BoundaryBox ( in OpenCV coordinates ) // Update BoundaryBox ( in OpenCV coordinates )
xMin = cv::min ( xMin, ftd(bbox.xMin) ); xMin = cv::min(xMin, ftd(bbox.xMin));
xMax = cv::max ( xMax, ftd(bbox.xMax) ); xMax = cv::max(xMax, ftd(bbox.xMax));
yMin = cv::min ( yMin, ftd(bbox.yMin) ); yMin = cv::min(yMin, ftd(bbox.yMin));
yMax = cv::max ( yMax, ftd(bbox.yMax) ); yMax = cv::max(yMax, ftd(bbox.yMax));
} }
#if defined(USING_HB) #if defined(USING_HB)
hb_buffer_destroy (hb_buffer); hb_buffer_destroy(hb_buffer);
#endif #endif
// Calcurate width/height/baseline ( in OpenCV coordinates ) // Calcurate width/height/baseline ( in OpenCV coordinates )
int width = xMax - xMin ; int width = xMax - xMin;
int height = -yMin ; int height = -yMin;
if ( _thickness > 0 ) { if (_thickness > 0) {
width = cvRound(width + _thickness * 2); width = cvRound(width + _thickness * 2);
height = cvRound(height + _thickness * 1); height = cvRound(height + _thickness * 1);
}else{ }
else {
width = cvRound(width + 1); width = cvRound(width + 1);
height = cvRound(height + 1); height = cvRound(height + 1);
} }
if ( _baseLine ) { if (_baseLine) {
*_baseLine = yMax; *_baseLine = yMax;
} }
return Size( width, height ); return Size(width, height);
} }
int FreeType2Impl::mvFn( const FT_Vector *to, void * user) int FreeType2Impl::mvFn(const FT_Vector *to, void * user)
{ {
if(user == NULL ) { return 1; } if (user == NULL) { return 1; }
PathUserData *p = (PathUserData*)user; PathUserData *p = (PathUserData*)user;
// Draw polylines( in OpenCV coordinates ). // Draw polylines( in OpenCV coordinates ).
if( p->mPts.size() > 0 ){ if (p->mPts.size() > 0) {
Mat dst = p->mImg.getMat(); Mat dst = p->mImg.getMat();
const Point *ptsList[] = { &(p->mPts[0]) }; const Point *ptsList[] = { &(p->mPts[0]) };
int npt[1]; npt[0] = p->mPts.size(); int npt[1]; npt[0] = p->mPts.size();
@ -700,41 +704,41 @@ namespace ft {
p->mPts.clear(); p->mPts.clear();
if( to == NULL ) { return 1; } if (to == NULL) { return 1; }
// Store points to draw( in OpenCV coordinates ). // Store points to draw( in OpenCV coordinates ).
p->mPts.push_back( Point ( ftd(to->x), ftd(to->y) ) ); p->mPts.push_back(Point(ftd(to->x), ftd(to->y)));
p->mOldP = *to; p->mOldP = *to;
return 0; return 0;
} }
int FreeType2Impl::lnFn( const FT_Vector *to, void * user) int FreeType2Impl::lnFn(const FT_Vector *to, void * user)
{ {
if(to == NULL ) { return 1; } if (to == NULL) { return 1; }
if(user == NULL ) { return 1; } if (user == NULL) { return 1; }
PathUserData *p = (PathUserData *)user; PathUserData *p = (PathUserData *)user;
// Store points to draw( in OpenCV coordinates ). // Store points to draw( in OpenCV coordinates ).
p->mPts.push_back( Point ( ftd(to->x), ftd(to->y) ) ); p->mPts.push_back(Point(ftd(to->x), ftd(to->y)));
p->mOldP = *to; p->mOldP = *to;
return 0; return 0;
} }
int FreeType2Impl::coFn( const FT_Vector *cnt, int FreeType2Impl::coFn(const FT_Vector *cnt,
const FT_Vector *to, const FT_Vector *to,
void * user) void * user)
{ {
if(cnt == NULL ) { return 1; } if (cnt == NULL) { return 1; }
if(to == NULL ) { return 1; } if (to == NULL) { return 1; }
if(user == NULL ) { return 1; } if (user == NULL) { return 1; }
PathUserData *p = (PathUserData *)user; PathUserData *p = (PathUserData *)user;
// Bezier to Line // Bezier to Line
for(int i = 0;i <= p->mCtoL; i++){ for (int i = 0; i <= p->mCtoL; i++) {
// Split Bezier to lines ( in FreeType coordinates ). // Split Bezier to lines ( in FreeType coordinates ).
double u = (double)i * 1.0 / (p->mCtoL) ; double u = (double)i * 1.0 / (p->mCtoL);
double nu = 1.0 - u; double nu = 1.0 - u;
double p0 = nu * nu; double p0 = nu * nu;
double p1 = 2.0 * u * nu; double p1 = 2.0 * u * nu;
@ -744,28 +748,28 @@ namespace ft {
double Y = (p->mOldP.y) * p0 + cnt->y * p1 + to->y * p2; double Y = (p->mOldP.y) * p0 + cnt->y * p1 + to->y * p2;
// Store points to draw( in OpenCV coordinates ). // Store points to draw( in OpenCV coordinates ).
p->mPts.push_back( Point ( ftd(X), ftd(Y) ) ); p->mPts.push_back(Point(ftd(X), ftd(Y)));
} }
p->mOldP = *to; p->mOldP = *to;
return 0; return 0;
} }
int FreeType2Impl::cuFn( const FT_Vector *cnt1, int FreeType2Impl::cuFn(const FT_Vector *cnt1,
const FT_Vector *cnt2, const FT_Vector *cnt2,
const FT_Vector *to, const FT_Vector *to,
void * user) void * user)
{ {
if(cnt1 == NULL ) { return 1; } if (cnt1 == NULL) { return 1; }
if(cnt2 == NULL ) { return 1; } if (cnt2 == NULL) { return 1; }
if(to == NULL ) { return 1; } if (to == NULL) { return 1; }
if(user == NULL ) { return 1; } if (user == NULL) { return 1; }
PathUserData *p = (PathUserData *)user; PathUserData *p = (PathUserData *)user;
// Bezier to Line // Bezier to Line
for(int i = 0; i <= p->mCtoL ;i++){ for (int i = 0; i <= p->mCtoL; i++) {
// Split Bezier to lines ( in FreeType coordinates ). // Split Bezier to lines ( in FreeType coordinates ).
double u = (double)i * 1.0 / (p->mCtoL) ; double u = (double)i * 1.0 / (p->mCtoL);
double nu = 1.0 - u; double nu = 1.0 - u;
double p0 = nu * nu * nu; double p0 = nu * nu * nu;
double p1 = 3.0 * u * nu * nu; double p1 = 3.0 * u * nu * nu;
@ -773,12 +777,12 @@ namespace ft {
double p3 = u * u * u; double p3 = u * u * u;
double X = (p->mOldP.x) * p0 + (cnt1->x) * p1 + double X = (p->mOldP.x) * p0 + (cnt1->x) * p1 +
(cnt2->x ) * p2 + (to->x ) * p3; (cnt2->x) * p2 + (to->x) * p3;
double Y = (p->mOldP.y) * p0 + (cnt1->y) * p1 + double Y = (p->mOldP.y) * p0 + (cnt1->y) * p1 +
(cnt2->y ) * p2 + (to->y ) * p3; (cnt2->y) * p2 + (to->y) * p3;
// Store points to draw( in OpenCV coordinates ). // Store points to draw( in OpenCV coordinates ).
p->mPts.push_back( Point ( ftd(X), ftd(Y) ) ); p->mPts.push_back(Point(ftd(X), ftd(Y)));
} }
p->mOldP = *to; p->mOldP = *to;
return 0; return 0;
@ -786,8 +790,9 @@ namespace ft {
CV_EXPORTS_W Ptr<FreeType2> createFreeType2() CV_EXPORTS_W Ptr<FreeType2> createFreeType2()
{ {
return Ptr<FreeType2Impl> (new FreeType2Impl () ); return Ptr<FreeType2Impl>(new FreeType2Impl());
} }
}} // namespace freetype2 }
} // namespace freetype2

Loading…
Cancel
Save