diff --git a/app/src/main/cpp/CvText.cpp b/app/src/main/cpp/CvText.cpp index 8689f7de..5746bb8d 100644 --- a/app/src/main/cpp/CvText.cpp +++ b/app/src/main/cpp/CvText.cpp @@ -620,7 +620,7 @@ namespace cv { // Update current position ( in FreeType coordinates ) float advance = mFace->glyph->advance.x >> 6; - currentPos.x += mFace->glyph->advance.x + mFace->glyph->bitmap_left; + currentPos.x += mFace->glyph->advance.x + mFace->glyph->metrics.horiBearingX; currentPos.y += mFace->glyph->advance.y; // currentPos.x += mFace->glyph->metrics.horiBearingX >> 6; // currentPos.y += mFace->glyph->metrics.horiBearingY >> 6; @@ -628,7 +628,7 @@ namespace cv { // currentPos.x += mFace->glyph->metrics.horiBearingX; // currentPos.y += mFace->glyph->metrics.horiBearingY; // break; - _org.x += (mFace->glyph->advance.x + mFace->glyph->bitmap_left) >> 6; + _org.x += (mFace->glyph->advance.x + mFace->glyph->metrics.horiBearingX) >> 6; _org.y += mFace->glyph->advance.y >> 6; } @@ -638,29 +638,36 @@ namespace cv { #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); + 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_UInt glyph_index; + FT_Bool use_kerning; + FT_UInt previous; + + use_kerning = FT_HAS_KERNING(mFace); + previous = 0; + + FT_Vector currentPos = { 0,0 }; + FT_Set_Transform(mFace, 0, ¤tPos); #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); hb_buffer_add_utf8(hb_buffer, _text.c_str(), -1, 0, -1); @@ -672,89 +679,102 @@ namespace cv { hb_buffer_get_glyph_infos(hb_buffer, &textLen); CV_Assert(info != NULL); #else - std::wstring_convert> converter; - wstring wstr = converter.from_bytes(_text); + 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; + // 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)); + for (unsigned int i = 0; i < textLen; i++) { + glyph_index = info[i].codepoint; + CV_Assert(!FT_Load_Glyph(mFace, glyph_index, 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)); + 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; + } + glyph_index = FT_Get_Char_Index(mFace, wstr[i]); + CV_Assert(!FT_Load_Glyph(mFace, glyph_index, 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; - } + /* retrieve kerning distance and move pen position */ + if (use_kerning && previous) + { + FT_Vector delta; + FT_Get_Kerning(mFace, previous, glyph_index, FT_KERNING_DEFAULT, &delta); + currentPos.x += delta.x >> 6; + } + + 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); - // Update current position ( in FreeType coordinates ) - currentPos.x += mFace->glyph->advance.x + mFace->glyph->bitmap_left; - currentPos.y += mFace->glyph->advance.y; + // Move to current position ( in FreeType coordinates ) + FT_Outline_Translate(&outline, currentPos.x, currentPos.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)); - } + // 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 + mFace->glyph->bitmap_left); + 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)); + + previous = glyph_index; + } #if defined(USING_HB) - hb_buffer_destroy(hb_buffer); + hb_buffer_destroy(hb_buffer); #endif - // Calcurate width/height/baseline ( in OpenCV coordinates ) - int width = xMax - xMin; - int height = -yMin; + // 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 (_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; - } + if (_baseLine) { + *_baseLine = yMax; + } + + return Size(width, height); + } - return Size(width, height); - } void FreeType2Impl::putPixel_8UC1_mono(Mat& _dst, const int _py, const int _px, const uint8_t *_col) { @@ -1038,6 +1058,7 @@ namespace cv { #endif } + int FreeType2Impl::mvFn(const FT_Vector *to, void * user) { if (user == NULL) { return 1; } diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index 3fd3d05c..1fc57e50 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -942,16 +942,6 @@ void DrawOutlineText(cv::Ptr ft2, cv::Mat& mat, const std::st lineHeight = std::max(fontSize, textSize.height); ft2->putText(mat, *it, pt, fontSize, clr, thickness, cv::LINE_AA, false, true); -#ifdef _DEBUG - if (pt.y > (mat.rows / 2)) - { - ft2->putText(mat, *it, cv::Point(pt.x, pt.y - fontSize * 3), fontSize, clr, thickness, cv::LINE_AA, false); - } - else - { - ft2->putText(mat, *it, cv::Point(pt.x, pt.y + fontSize * 3), fontSize, clr, thickness, cv::LINE_AA, false); - } -#endif pt.x = startPoint.x; pt.y += lineHeight + (lineHeight >> 2); // 125% @@ -1123,8 +1113,8 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) pt.y = height - it->y * ratio - textSize.height; } - cv::Rect rc(pt.x, pt.y, textSize.width, textSize.height); - cv::rectangle(mat, rc, cv::Scalar(0,255,255), 2); + // cv::Rect rc(pt.x, pt.y, textSize.width, textSize.height); + // cv::rectangle(mat, rc, cv::Scalar(0,255,255), 2); DrawOutlineText(ft2, mat, it->text, pt, fontSize, scalar, thickness); }