diff --git a/app/src/main/cpp/CvText.cpp b/app/src/main/cpp/CvText.cpp index d1c0c7e9..8689f7de 100644 --- a/app/src/main/cpp/CvText.cpp +++ b/app/src/main/cpp/CvText.cpp @@ -397,13 +397,14 @@ namespace cv { int offsetY = 0; int imgHeight = mat.rows; // Initilize currentPosition ( in FreeType coordinates) - FT_Vector currentPos = { 0,0 }; + FT_Vector currentPos = { 0, 0 }; currentPos.x = _org.x * 64; currentPos.y = _org.y * 64; // Update currentPosition with bottomLeftOrigin ( in FreeType coordinates) - if (_bottomLeftOrigin != true) { - currentPos.y += _fontHeight * 64; + if (_bottomLeftOrigin != true) + { + currentPos.y += _fontHeight * 64; currentPos.y = imgHeight * 64 - currentPos.y; } @@ -469,10 +470,8 @@ namespace cv { #else for (unsigned int i = 0; i < wstr.size(); i++) { - // if (_bottomLeftOrigin != true) - { - FT_Set_Transform(mFace, 0, ¤tPos); - } + FT_Set_Transform(mFace, 0, ¤tPos); + CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), FT_LOAD_NO_BITMAP)); #endif FT_GlyphSlot slot = mFace->glyph; @@ -531,8 +530,8 @@ namespace cv { } float bearingX = slot->metrics.horiBearingX >> 6; - float bearingY = slot->metrics.horiBearingY >> 6; - float advance = slot->advance.x >> 6; + // float bearingY = slot->metrics.horiBearingY >> 6; + // float advance = slot->advance.x >> 6; // Allocate data for our image and clear it out to transparent. // Pixel32 *pxl = new Pixel32[imgSize]; @@ -544,13 +543,17 @@ namespace cv { // image. for (Spans::iterator s = outlineSpans.begin(); s != outlineSpans.end(); ++s) { + // int row = (imgHeight - 1 - (s->y - rect.ymin)) - imgHeight + (rect.ymax - rect.ymin); + // int row = (imgHeight - 1 - (s->y - rect.ymin)); + int row = (bbox.yMax - bbox.yMin) - (s->y - rect.ymin) + _org.y - offsetY; + if (row < 0 || row >= imgHeight) + { + continue; + } for (int w = 0; w < s->width; ++w) { - // int row = (imgHeight - 1 - (s->y - rect.ymin)) - imgHeight + (rect.ymax - rect.ymin); - // int row = (imgHeight - 1 - (s->y - rect.ymin)); - int row = (bbox.yMax - bbox.yMin) - (s->y - rect.ymin) + _org.y - offsetY; int col = s->x - rect.xmin + w + _org.x + bearingX; - if (row < 0 || col < 0 || row >= imgHeight || col >= imgWidth) + if (col < 0 || col >= imgWidth) { continue; } @@ -572,17 +575,22 @@ namespace cv { // the image. for (Spans::iterator s = spans.begin(); s != spans.end(); ++s) { + // int row = (imgHeight - 1 - (s->y - rect.ymin)) - imgHeight + (rect.ymax - rect.ymin); + int row = (bbox.yMax - bbox.yMin) - (s->y - rect.ymin) + _org.y - offsetY; + if (row < 0 || row >= imgHeight) + { + continue; + } for (int w = 0; w < s->width; ++w) { - // int row = (imgHeight - 1 - (s->y - rect.ymin)) - imgHeight + (rect.ymax - rect.ymin); - int row = (bbox.yMax - bbox.yMin) - (s->y - rect.ymin) + _org.y - offsetY; - int col = s->x - rect.xmin + w + _org.x + bearingX; - if (row < 0 || col < 0 || row >= imgHeight || col >= imgWidth) + // int col = s->x - rect.xmin + w + _org.x + bearingX; + int col = s->x - rect.xmin + w + _org.x + bearingX; + if (col < 0 || col >= imgWidth) { continue; } // int row = ((bbox.yMax - bbox.yMin) - (glyph_bbox.yMax - glyph_bbox.yMin)) / 2 - (s->y - rect.ymin) + _org.y; - mat.at(row, s->x - rect.xmin + w + _org.x + bearingX) = fontColor; + mat.at(row, col) = fontColor; // mat.at(-(s->y - rect.ymin), s->x - rect.xmin + w) = fontColor; #if 0 Pixel32 &dst = @@ -612,15 +620,15 @@ namespace cv { // Update current position ( in FreeType coordinates ) float advance = mFace->glyph->advance.x >> 6; - currentPos.x += mFace->glyph->advance.x >> 6; - currentPos.y += mFace->glyph->advance.y >> 6; + currentPos.x += mFace->glyph->advance.x + mFace->glyph->bitmap_left; + currentPos.y += mFace->glyph->advance.y; // currentPos.x += mFace->glyph->metrics.horiBearingX >> 6; // currentPos.y += mFace->glyph->metrics.horiBearingY >> 6; // currentPos.x += mFace->glyph->metrics.horiBearingX; // currentPos.y += mFace->glyph->metrics.horiBearingY; // break; - _org.x += mFace->glyph->advance.x >> 6; + _org.x += (mFace->glyph->advance.x + mFace->glyph->bitmap_left) >> 6; _org.y += mFace->glyph->advance.y >> 6; } @@ -628,7 +636,125 @@ namespace cv { #if defined(USING_HB) hb_buffer_destroy(hb_buffer); #endif 0 - } + } + + Size FreeType2Impl::getTextSize( + const String& _text, + int _fontHeight, + int _thickness, + CV_OUT int* _baseLine) + { + if (_text.empty()) + { + return Size(0, 0); + } + + CV_Assert(_fontHeight >= 0); + if (_fontHeight == 0) + { + return Size(0, 0); + } + + CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight)); + + FT_Vector currentPos = { 0,0 }; + FT_Set_Transform(mFace, 0, ¤tPos); +#if defined(USING_HB) + hb_buffer_t *hb_buffer = hb_buffer_create(); + CV_Assert(hb_buffer != NULL); + + hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1); + hb_buffer_guess_segment_properties(hb_buffer); + hb_shape(mHb_font, hb_buffer, NULL, 0); + + unsigned int textLen = 0; + hb_glyph_info_t *info = + hb_buffer_get_glyph_infos(hb_buffer, &textLen); + CV_Assert(info != NULL); +#else + std::wstring_convert> converter; + wstring wstr = converter.from_bytes(_text); +#endif + // Initilize BoundaryBox ( in OpenCV coordinates ) + int xMin = INT_MAX, yMin = INT_MAX; + int xMax = INT_MIN, yMax = INT_MIN; + +#if defined(USING_HB) + for (unsigned int i = 0; i < textLen; i++) { + CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0)); +#else + for (unsigned int i = 0; i < wstr.size(); i++) { + if (wstr[i] == '\r' || wstr[i] == '\n') + { + // xMin = cv::min(xMin, ftd(bbox.xMin)); + // xMax = cv::max(xMax, ftd(bbox.xMax)); + // yMin = cv::min(yMin, ftd(bbox.yMin)); + // yMax = cv::max(yMax, currentPos.y + (mFace->glyph->advance.y)); + continue; + } + CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0)); +#endif + FT_GlyphSlot slot = mFace->glyph; + FT_Outline outline = slot->outline; + FT_BBox bbox; + + // Flip ( in FreeType coordinates ) + FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) }; + FT_Outline_Transform(&outline, &mtx); + + // Move to current position ( in FreeType coordinates ) + FT_Outline_Translate(&outline, currentPos.x, currentPos.y); + + // Get BoundaryBox ( in FreeType coordinatrs ) + CV_Assert(!FT_Outline_Get_BBox(&outline, &bbox)); + + // If codepoint is space(0x20), it has no glyph. + // A dummy boundary box is needed when last code is space. + if ( + (bbox.xMin == 0) && (bbox.xMax == 0) && + (bbox.yMin == 0) && (bbox.yMax == 0) + ) + { + bbox.xMin = currentPos.x; + bbox.xMax = currentPos.x + (mFace->glyph->advance.x); + bbox.yMin = yMin; + bbox.yMax = yMax; + } + + // Update current position ( in FreeType coordinates ) + currentPos.x += mFace->glyph->advance.x + mFace->glyph->bitmap_left; + currentPos.y += mFace->glyph->advance.y; + + // Update BoundaryBox ( in OpenCV coordinates ) + xMin = cv::min(xMin, ftd(bbox.xMin)); + xMax = cv::max(xMax, ftd(bbox.xMax)); + yMin = cv::min(yMin, ftd(bbox.yMin)); + yMax = cv::max(yMax, ftd(bbox.yMax)); + } + +#if defined(USING_HB) + hb_buffer_destroy(hb_buffer); +#endif + + // Calcurate width/height/baseline ( in OpenCV coordinates ) + int width = xMax - xMin; + int height = -yMin; + + if (_thickness > 0) { + width = cvRound(width + _thickness * 2); + height = cvRound(height + _thickness * 1); + } + else { + width = cvRound(width + 1); + height = cvRound(height + 1); + } + + if (_baseLine) { + *_baseLine = yMax; + } + + return Size(width, height); + } void FreeType2Impl::putPixel_8UC1_mono(Mat& _dst, const int _py, const int _px, const uint8_t *_col) { @@ -910,125 +1036,7 @@ namespace cv { #if defined(USING_HB) hb_buffer_destroy(hb_buffer); #endif - } - - Size FreeType2Impl::getTextSize( - const String& _text, - int _fontHeight, - int _thickness, - CV_OUT int* _baseLine) - { - if (_text.empty()) - { - return Size(0, 0); - } - - CV_Assert(_fontHeight >= 0); - if (_fontHeight == 0) - { - return Size(0, 0); - } - - CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight)); - - FT_Vector currentPos = { 0,0 }; - FT_Set_Transform(mFace, 0, ¤tPos); -#if defined(USING_HB) - hb_buffer_t *hb_buffer = hb_buffer_create(); - CV_Assert(hb_buffer != NULL); - - hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1); - hb_buffer_guess_segment_properties(hb_buffer); - hb_shape(mHb_font, hb_buffer, NULL, 0); - - unsigned int textLen = 0; - hb_glyph_info_t *info = - hb_buffer_get_glyph_infos(hb_buffer, &textLen); - CV_Assert(info != NULL); -#else - std::wstring_convert> converter; - wstring wstr = converter.from_bytes(_text); -#endif - // Initilize BoundaryBox ( in OpenCV coordinates ) - int xMin = INT_MAX, yMin = INT_MAX; - int xMax = INT_MIN, yMax = INT_MIN; - -#if defined(USING_HB) - for (unsigned int i = 0; i < textLen; i++) { - CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0)); -#else - for (unsigned int i = 0; i < wstr.size(); i++) { - if (wstr[i] == '\r' || wstr[i] == '\n') - { - // xMin = cv::min(xMin, ftd(bbox.xMin)); - // xMax = cv::max(xMax, ftd(bbox.xMax)); - // yMin = cv::min(yMin, ftd(bbox.yMin)); - // yMax = cv::max(yMax, currentPos.y + (mFace->glyph->advance.y)); - continue; - } - CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0)); -#endif - FT_GlyphSlot slot = mFace->glyph; - FT_Outline outline = slot->outline; - FT_BBox bbox; - - // Flip ( in FreeType coordinates ) - FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) }; - FT_Outline_Transform(&outline, &mtx); - - // Move to current position ( in FreeType coordinates ) - FT_Outline_Translate(&outline, currentPos.x, currentPos.y); - - // Get BoundaryBox ( in FreeType coordinatrs ) - CV_Assert(!FT_Outline_Get_BBox(&outline, &bbox)); - - // If codepoint is space(0x20), it has no glyph. - // A dummy boundary box is needed when last code is space. - if ( - (bbox.xMin == 0) && (bbox.xMax == 0) && - (bbox.yMin == 0) && (bbox.yMax == 0) - ) - { - bbox.xMin = currentPos.x; - bbox.xMax = currentPos.x + (mFace->glyph->advance.x); - bbox.yMin = yMin; - bbox.yMax = yMax; - } - - // Update current position ( in FreeType coordinates ) - currentPos.x += mFace->glyph->advance.x; - currentPos.y += mFace->glyph->advance.y; - - // Update BoundaryBox ( in OpenCV coordinates ) - xMin = cv::min(xMin, ftd(bbox.xMin)); - xMax = cv::max(xMax, ftd(bbox.xMax)); - yMin = cv::min(yMin, ftd(bbox.yMin)); - yMax = cv::max(yMax, ftd(bbox.yMax)); - } - -#if defined(USING_HB) - hb_buffer_destroy(hb_buffer); -#endif - - // Calcurate width/height/baseline ( in OpenCV coordinates ) - int width = xMax - xMin; - int height = -yMin; - - if (_thickness > 0) { - width = cvRound(width + _thickness * 2); - height = cvRound(height + _thickness * 1); - } - else { - width = cvRound(width + 1); - height = cvRound(height + 1); - } - - if (_baseLine) { - *_baseLine = yMax; - } - - return Size(width, height); - } + } int FreeType2Impl::mvFn(const FT_Vector *to, void * user) {