Merge pull request #893 from Kumataro:freetype2
* Support freetype2 * Before call pkg_search_module() check it is available. * If using libraries are unavailable, this module is shown in unavailable list. * using ocv_define_modules() insted of target_link_libraries(). * Fix inner indentation in C++ namespaces * Remove mImg from freetype2 and Create UserData class to refer in path drawing callbacks. * to split interface and implementation details. ( and to avoid 3rd headers in public headers) * PKG_CONFIG_FOUND is used instead of COMMAND okg_search_modules * Update Document using Doxygen * Add ocv_module_include_directories() * Do no put pixels over image boundaries. * Fix SIGSEGV (only valgrind) and missing text in top border line * Fix trailing whitespace. * Use Header File Macros * Fix CMP0023 warning in cmake * std::string to cv::String * Fix trailing whitespace * Change splitnumber from unsigned int to int to support python * ocv_include_directories() should be define before ocv_define_module() * Fix boundary problem in putTextBitmapBlend() * Fix to draw an outline glyph which are on the boundary of image. * Remove precomp.cpp * Fix CMakeLists.txt to right order. * Remove prototype definition of removed function. * Add CV_Assert() where FreeType and Harfbuzz are called * Add CV_Assert() to check InputOutputArray and line_typepull/684/merge
parent
cf82f5f812
commit
cac3c9a221
6 changed files with 772 additions and 18 deletions
@ -0,0 +1,26 @@ |
||||
set(the_description "FreeType module. It enables to draw strings with outlines and mono-bitmaps/gray-bitmaps.") |
||||
|
||||
if(PKG_CONFIG_FOUND) |
||||
pkg_search_module(FREETYPE freetype2) |
||||
pkg_search_module(HARFBUZZ harfbuzz) |
||||
endif() |
||||
|
||||
if(NOT FREETYPE_FOUND) |
||||
message(STATUS "freetype2: NO") |
||||
else() |
||||
message(STATUS "freetype2: YES") |
||||
endif() |
||||
|
||||
if(NOT HARFBUZZ_FOUND) |
||||
message(STATUS "harfbuzz: NO") |
||||
else() |
||||
message(STATUS "harfbuzz: YES") |
||||
endif() |
||||
|
||||
|
||||
if( FREETYPE_FOUND AND HARFBUZZ_FOUND ) |
||||
ocv_define_module(freetype opencv_core opencv_imgproc PRIVATE_REQUIRED ${freetype2_LIBRARIES} ${harfbuzz_LIBRARIES} WRAP python) |
||||
ocv_include_directories( ${FREETYPE_INCLUDE_DIRS} ${HARFBUZZ_INCLUDE_DIRS} ) |
||||
else() |
||||
ocv_module_disable(freetype) |
||||
endif() |
@ -0,0 +1,34 @@ |
||||
FreeType Module |
||||
=========== |
||||
|
||||
This FreeType module allows you to draw strings with outlines and bitmaps. |
||||
|
||||
Installation |
||||
----------- |
||||
harfbuzz is requested to convert UTF8 to gid(GlyphID). |
||||
freetype library is requested to rasterize given gid. |
||||
|
||||
harfbuzz https://www.freedesktop.org/wiki/Software/HarfBuzz/ |
||||
freetype https://www.freetype.org/ |
||||
|
||||
Usage |
||||
----------- |
||||
cv::freetype::FreeType2 ft2; |
||||
ft2.loadFontData("your-font.ttf", 0); |
||||
ft2.setSplitNumber( 4 ); // Bezier-line is splited by 4 segment. |
||||
ft2.putText(src, .... ) |
||||
|
||||
Option |
||||
------------ |
||||
- 2nd argument of loadFontData is used if font file has many font data. |
||||
- 3 drawing mode is available. |
||||
-- outline mode is used if lineWidth is larger than 0. (like original putText) |
||||
-- bitmap mode is used if lineWidth is less than 0. |
||||
--- 1bit bitmap mode is used if lineStyle is 4 or 8. |
||||
--- gray bitmap mode is used if lineStyle is 16. |
||||
|
||||
Future work |
||||
------------ |
||||
- test |
||||
-- CJK and ... |
||||
- RTL,LTR,TTB,BTT... |
@ -0,0 +1,130 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009-2012, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
//################################################################################
|
||||
//
|
||||
// Created by Kumataro
|
||||
//
|
||||
//################################################################################
|
||||
|
||||
#ifndef _OPENCV_FREETYPE_H_ |
||||
#define _OPENCV_FREETYPE_H_ |
||||
#ifdef __cplusplus |
||||
|
||||
#include <opencv2/core.hpp> |
||||
|
||||
/**
|
||||
@defgroup freetype Drawing UTF-8 strings with freetype/harfbuzz |
||||
|
||||
This modules is to draw UTF-8 strings with freetype/harfbuzz. |
||||
|
||||
1. Install freetype2 and harfbuzz in your system. |
||||
2. Create FreeType2 instance with createFreeType2() function. |
||||
3. Load font file with loadFontData() function. |
||||
4. Draw text with putText() function. |
||||
|
||||
- If thickness parameter is negative, drawing glyph is filled. |
||||
- If thickness parameter is positive, drawing glyph is outlined with thickness. |
||||
- If line_type parameter is 16(or CV_AA), drawing glyph is smooth. |
||||
|
||||
*/ |
||||
|
||||
namespace cv { |
||||
namespace freetype { |
||||
//! @addtogroup freetype
|
||||
//! @{
|
||||
class CV_EXPORTS_W FreeType2 : public Algorithm |
||||
{ |
||||
public: |
||||
/** @brief Load font data.
|
||||
|
||||
The function loadFontData loads font data. |
||||
|
||||
@param fontFileName FontFile Name |
||||
@param id face_index to select a font faces in a single file. |
||||
*/ |
||||
|
||||
CV_WRAP virtual void loadFontData(String fontFileName, int id) = 0; |
||||
|
||||
/** @brief Set Split Number from Bezier-curve to line
|
||||
|
||||
The function setSplitNumber set the number of split points from bezier-curve to line. |
||||
If you want to draw large glyph, large is better. |
||||
If you want to draw small glyph, small is better. |
||||
|
||||
@param num number of split points from bezier-curve to line |
||||
*/ |
||||
|
||||
CV_WRAP virtual void setSplitNumber( int num ) = 0; |
||||
|
||||
/** @brief Draws a text string.
|
||||
|
||||
The function putText renders the specified text string in the image. Symbols that cannot be rendered using the specified font are replaced by "Tofu" or non-drawn. |
||||
|
||||
@param img Image. |
||||
@param text Text string to be drawn. |
||||
@param org Bottom-left/Top-left corner of the text string in the image. |
||||
@param fontHeight Drawing font size by pixel unit. |
||||
@param color Text color. |
||||
@param thickness Thickness of the lines used to draw a text when negative, the glyph is filled. Otherwise, the glyph is drawn with this thickness. |
||||
@param line_type Line type. See the line for details. |
||||
@param bottomLeftOrigin When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner. |
||||
*/ |
||||
|
||||
CV_WRAP virtual void putText( |
||||
InputOutputArray img, const String& text, Point org, |
||||
int fontHeight, Scalar color, |
||||
int thickness, int line_type, bool bottomLeftOrigin |
||||
) = 0; |
||||
|
||||
}; |
||||
/** @brief Create FreeType2 Instance
|
||||
|
||||
The function createFreeType2 create instance to draw UTF-8 strings. |
||||
|
||||
*/ |
||||
CV_EXPORTS_W Ptr<FreeType2> createFreeType2(); |
||||
|
||||
//! @]
|
||||
} } // namespace freetype
|
||||
|
||||
#endif |
||||
#endif |
@ -0,0 +1,495 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
//################################################################################
|
||||
//
|
||||
// Created by Kumataro
|
||||
//
|
||||
//################################################################################
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
namespace cv { |
||||
namespace freetype { |
||||
|
||||
using namespace std; |
||||
|
||||
class CV_EXPORTS_W FreeType2Impl : public FreeType2 |
||||
{ |
||||
public: |
||||
FreeType2Impl(); |
||||
~FreeType2Impl(); |
||||
void loadFontData(String fontFileName, int id) ; |
||||
void setSplitNumber( int num ); |
||||
void putText( |
||||
InputOutputArray img, const String& text, Point org, |
||||
int fontHeight, Scalar color, |
||||
int thickness, int line_type, bool bottomLeftOrigin |
||||
); |
||||
|
||||
private: |
||||
FT_Library mLibrary; |
||||
FT_Face mFace; |
||||
FT_Outline_Funcs mFn; |
||||
|
||||
Point mOrg; |
||||
int mLine_type; |
||||
int mThickness; |
||||
int mHeight; |
||||
Scalar mColor; |
||||
bool mIsFaceAvailable; |
||||
String mText; |
||||
int mCtoL; |
||||
hb_font_t *mHb_font; |
||||
|
||||
void putTextBitmapMono ( InputOutputArray _img); |
||||
void putTextBitmapBlend( InputOutputArray _img); |
||||
void putTextOutline ( InputOutputArray _img); |
||||
|
||||
static int mvFn( const FT_Vector *to, void * user); |
||||
static int lnFn( const FT_Vector *to, void * user); |
||||
static int coFn( const FT_Vector *cnt, |
||||
const FT_Vector *to, |
||||
void * user); |
||||
static int cuFn( const FT_Vector *cnt1, |
||||
const FT_Vector *cnt2, |
||||
const FT_Vector *to, |
||||
void * user); |
||||
|
||||
// Offset value to handle the position less than 0.
|
||||
static const unsigned int cOutlineOffset = 0x80000000; |
||||
|
||||
/**
|
||||
* Convert from 26.6 real to signed integer |
||||
*/ |
||||
static int ftd(unsigned int fixedInt){ |
||||
unsigned int ret = ( ( fixedInt + (1 << 5) ) >> 6 ); |
||||
return (int)ret - ( cOutlineOffset >> 6 ); |
||||
} |
||||
|
||||
class PathUserData{ |
||||
private: |
||||
public: |
||||
PathUserData( InputOutputArray _img) : mImg(_img) {}; |
||||
|
||||
InputOutputArray mImg; |
||||
Scalar mColor; |
||||
int mThickness; |
||||
int mLine_type; |
||||
FT_Vector mOldP; |
||||
int mCtoL; |
||||
std::vector < Point > mPts; |
||||
}; |
||||
}; |
||||
|
||||
FreeType2Impl::FreeType2Impl() |
||||
{ |
||||
FT_Init_FreeType(&(this->mLibrary) ); |
||||
|
||||
mCtoL = 16; |
||||
mFn.shift = 0; |
||||
mFn.delta = 0; |
||||
mFn.move_to = FreeType2Impl::mvFn; |
||||
mFn.line_to = FreeType2Impl::lnFn; |
||||
mFn.cubic_to = FreeType2Impl::cuFn; |
||||
mFn.conic_to = FreeType2Impl::coFn; |
||||
|
||||
mIsFaceAvailable = false; |
||||
} |
||||
|
||||
FreeType2Impl::~FreeType2Impl() |
||||
{ |
||||
if( mIsFaceAvailable == true ){ |
||||
hb_font_destroy (mHb_font); |
||||
CV_Assert(!FT_Done_Face(mFace)); |
||||
mIsFaceAvailable = false; |
||||
} |
||||
CV_Assert(!FT_Done_FreeType(mLibrary)); |
||||
} |
||||
|
||||
void FreeType2Impl::loadFontData(String fontFileName, int idx) |
||||
{ |
||||
if( mIsFaceAvailable == true ){ |
||||
hb_font_destroy (mHb_font); |
||||
CV_Assert(!FT_Done_Face(mFace)); |
||||
} |
||||
CV_Assert(!FT_New_Face( mLibrary, fontFileName.c_str(), idx, &(mFace) ) ); |
||||
mHb_font = hb_ft_font_create (mFace, NULL); |
||||
CV_Assert( mHb_font != NULL ); |
||||
mIsFaceAvailable = true; |
||||
} |
||||
|
||||
void FreeType2Impl::setSplitNumber(int num ){ |
||||
CV_Assert( num > 0 ); |
||||
mCtoL = num; |
||||
} |
||||
|
||||
void FreeType2Impl::putText( |
||||
InputOutputArray _img, const String& _text, Point _org, |
||||
int _fontHeight, Scalar _color, |
||||
int _thickness, int _line_type, bool bottomLeftOrigin |
||||
) |
||||
{ |
||||
CV_Assert( mIsFaceAvailable == true ); |
||||
CV_Assert( ( _img.empty() == false ) && |
||||
( _img.isMat() == true ) && |
||||
( _img.depth() == CV_8U ) && |
||||
( _img.dims() == 2 ) && |
||||
( _img.channels() == 3 ) ); |
||||
CV_Assert( ( _line_type == CV_AA) || |
||||
( _line_type == 4 ) || |
||||
( _line_type == 8 ) ); |
||||
|
||||
if ( _text.empty() ) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
if( _line_type == CV_AA && _img.depth() != CV_8U ){ |
||||
_line_type = 8; |
||||
} |
||||
|
||||
CV_Assert(!FT_Set_Pixel_Sizes( mFace, _fontHeight, _fontHeight )); |
||||
|
||||
mThickness = _thickness; |
||||
mLine_type = _line_type; |
||||
mColor = _color; |
||||
mHeight = _fontHeight; |
||||
mText = _text; |
||||
mOrg = _org; |
||||
|
||||
if( !bottomLeftOrigin ) { |
||||
mOrg.y += mHeight; |
||||
} |
||||
|
||||
if( mThickness < 0 ) // CV_FILLED
|
||||
{ |
||||
if ( mLine_type == CV_AA ) { |
||||
putTextBitmapBlend(_img); |
||||
}else{ |
||||
putTextBitmapMono (_img); |
||||
} |
||||
}else{ |
||||
putTextOutline(_img); |
||||
} |
||||
} |
||||
|
||||
void FreeType2Impl::putTextOutline(InputOutputArray _img) |
||||
{ |
||||
hb_buffer_t *hb_buffer = hb_buffer_create (); |
||||
CV_Assert( hb_buffer != NULL ); |
||||
|
||||
unsigned int textLen; |
||||
hb_buffer_guess_segment_properties (hb_buffer); |
||||
hb_buffer_add_utf8 (hb_buffer, mText.c_str(), -1, 0, -1); |
||||
hb_glyph_info_t *info = |
||||
hb_buffer_get_glyph_infos(hb_buffer,&textLen ); |
||||
CV_Assert( info != NULL ); |
||||
hb_shape (mHb_font, hb_buffer, NULL, 0); |
||||
|
||||
mOrg.y -= mHeight; |
||||
PathUserData *userData = new PathUserData( _img ); |
||||
userData->mColor = mColor; |
||||
userData->mCtoL = mCtoL; |
||||
userData->mThickness = mThickness; |
||||
userData->mLine_type = mLine_type; |
||||
|
||||
for( unsigned int i = 0 ; i < textLen ; i ++ ){ |
||||
CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0 )); |
||||
|
||||
FT_GlyphSlot slot = mFace->glyph; |
||||
FT_Outline outline = slot->outline; |
||||
|
||||
// Flip
|
||||
FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) }; |
||||
FT_Outline_Transform(&outline, &mtx); |
||||
|
||||
// Move
|
||||
FT_Outline_Translate(&outline, |
||||
cOutlineOffset, |
||||
cOutlineOffset ); |
||||
// Move
|
||||
FT_Outline_Translate(&outline, |
||||
(FT_Pos)(mOrg.x << 6), |
||||
(FT_Pos)((mOrg.y + mHeight) << 6) ); |
||||
|
||||
// Draw
|
||||
CV_Assert( !FT_Outline_Decompose(&outline, &mFn, (void*)userData) ); |
||||
|
||||
// Draw (Last Path)
|
||||
mvFn( NULL, (void*)userData ); |
||||
|
||||
mOrg.x += ( mFace->glyph->advance.x ) >> 6; |
||||
mOrg.y += ( mFace->glyph->advance.y ) >> 6; |
||||
} |
||||
delete userData; |
||||
hb_buffer_destroy (hb_buffer); |
||||
} |
||||
|
||||
void FreeType2Impl::putTextBitmapMono(InputOutputArray _img) |
||||
{ |
||||
Mat dst = _img.getMat(); |
||||
hb_buffer_t *hb_buffer = hb_buffer_create (); |
||||
CV_Assert( hb_buffer != NULL ); |
||||
|
||||
unsigned int textLen; |
||||
hb_buffer_guess_segment_properties (hb_buffer); |
||||
hb_buffer_add_utf8 (hb_buffer, mText.c_str(), -1, 0, -1); |
||||
hb_glyph_info_t *info = |
||||
hb_buffer_get_glyph_infos(hb_buffer,&textLen ); |
||||
CV_Assert( info != NULL ); |
||||
hb_shape (mHb_font, hb_buffer, NULL, 0); |
||||
|
||||
for( unsigned int i = 0 ; i < textLen ; i ++ ){ |
||||
CV_Assert( !FT_Load_Glyph(mFace, info[i].codepoint, 0 ) ); |
||||
CV_Assert( !FT_Render_Glyph( mFace->glyph, FT_RENDER_MODE_MONO ) ); |
||||
FT_Bitmap *bmp = &(mFace->glyph->bitmap); |
||||
|
||||
Point gPos = mOrg; |
||||
gPos.y -= ( mFace->glyph->metrics.horiBearingY >> 6) ; |
||||
gPos.x += ( mFace->glyph->metrics.horiBearingX >> 6) ; |
||||
|
||||
for (int row = 0; row < (int)bmp->rows; row ++) { |
||||
if( gPos.y + row < 0 ) { |
||||
continue; |
||||
} |
||||
if( gPos.y + row >= dst.rows ) { |
||||
break; |
||||
} |
||||
|
||||
for (int col = 0; col < bmp->pitch; col ++) { |
||||
int cl = bmp->buffer[ row * bmp->pitch + col ]; |
||||
if ( cl == 0 ) { |
||||
continue; |
||||
} |
||||
for(int bit = 7; bit >= 0; bit -- ){ |
||||
if( gPos.x + col * 8 + (7 - bit) < 0 ) |
||||
{ |
||||
continue; |
||||
} |
||||
if( gPos.x + col * 8 + (7 - bit) >= dst.cols ) |
||||
{ |
||||
break; |
||||
} |
||||
|
||||
if ( ( (cl >> bit) & 0x01 ) == 1 ) { |
||||
cv::Vec3b* ptr = dst.ptr<cv::Vec3b>( gPos.y + row, gPos.x + col * 8 + (7 - bit) ); |
||||
(*ptr)[0] = mColor[0]; |
||||
(*ptr)[1] = mColor[1]; |
||||
(*ptr)[2] = mColor[2]; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
mOrg.x += ( mFace->glyph->advance.x ) >> 6; |
||||
mOrg.y += ( mFace->glyph->advance.y ) >> 6; |
||||
} |
||||
hb_buffer_destroy (hb_buffer); |
||||
} |
||||
|
||||
void FreeType2Impl::putTextBitmapBlend(InputOutputArray _img) |
||||
{ |
||||
Mat dst = _img.getMat(); |
||||
hb_buffer_t *hb_buffer = hb_buffer_create (); |
||||
CV_Assert( hb_buffer != NULL ); |
||||
|
||||
unsigned int textLen; |
||||
hb_buffer_guess_segment_properties (hb_buffer); |
||||
hb_buffer_add_utf8 (hb_buffer, mText.c_str(), -1, 0, -1); |
||||
hb_glyph_info_t *info = |
||||
hb_buffer_get_glyph_infos(hb_buffer,&textLen ); |
||||
CV_Assert( info != NULL ); |
||||
|
||||
hb_shape (mHb_font, hb_buffer, NULL, 0); |
||||
|
||||
for( unsigned int i = 0 ; i < textLen ; i ++ ){ |
||||
CV_Assert( !FT_Load_Glyph(mFace, info[i].codepoint, 0 ) ); |
||||
CV_Assert( !FT_Render_Glyph( mFace->glyph, FT_RENDER_MODE_NORMAL ) ); |
||||
FT_Bitmap *bmp = &(mFace->glyph->bitmap); |
||||
|
||||
Point gPos = mOrg; |
||||
gPos.y -= ( mFace->glyph->metrics.horiBearingY >> 6) ; |
||||
gPos.x += ( mFace->glyph->metrics.horiBearingX >> 6) ; |
||||
|
||||
for (int row = 0; row < (int)bmp->rows; row ++) { |
||||
if( gPos.y + row < 0 ) { |
||||
continue; |
||||
} |
||||
if( gPos.y + row >= dst.rows ) { |
||||
break; |
||||
} |
||||
|
||||
for (int col = 0; col < bmp->pitch; col ++) { |
||||
int cl = bmp->buffer[ row * bmp->pitch + col ]; |
||||
if ( cl == 0 ) { |
||||
continue; |
||||
} |
||||
if( gPos.x + col < 0 ) |
||||
{ |
||||
continue; |
||||
} |
||||
if( gPos.x + col >= dst.cols ) |
||||
{ |
||||
break; |
||||
} |
||||
|
||||
cv::Vec3b* ptr = dst.ptr<cv::Vec3b>( gPos.y + row , gPos.x + col); |
||||
double blendAlpha = (double ) cl / 255.0; |
||||
|
||||
(*ptr)[0] = (double) mColor[0] * blendAlpha + (*ptr)[0] * (1.0 - blendAlpha ); |
||||
(*ptr)[1] = (double) mColor[1] * blendAlpha + (*ptr)[1] * (1.0 - blendAlpha ); |
||||
(*ptr)[2] = (double) mColor[2] * blendAlpha + (*ptr)[2] * (1.0 - blendAlpha ); |
||||
} |
||||
} |
||||
mOrg.x += ( mFace->glyph->advance.x ) >> 6; |
||||
mOrg.y += ( mFace->glyph->advance.y ) >> 6; |
||||
} |
||||
hb_buffer_destroy (hb_buffer); |
||||
} |
||||
|
||||
int FreeType2Impl::mvFn( const FT_Vector *to, void * user) |
||||
{ |
||||
if(user == NULL ) { return 1; } |
||||
PathUserData *p = (PathUserData*)user; |
||||
|
||||
if( p->mPts.size() > 0 ){ |
||||
Mat dst = p->mImg.getMat(); |
||||
const Point *ptsList[] = { &(p->mPts[0]) }; |
||||
int npt[1]; npt[0] = p->mPts.size(); |
||||
polylines( |
||||
dst, |
||||
ptsList, |
||||
npt, |
||||
1, |
||||
false, |
||||
p->mColor, |
||||
p->mThickness, |
||||
p->mLine_type, |
||||
0 |
||||
); |
||||
} |
||||
|
||||
p->mPts.clear(); |
||||
|
||||
if( to == NULL ) { return 1; } |
||||
|
||||
p->mPts.push_back( Point ( ftd(to->x), ftd(to->y) ) ); |
||||
p->mOldP = *to; |
||||
return 0; |
||||
} |
||||
|
||||
int FreeType2Impl::lnFn( const FT_Vector *to, void * user) |
||||
{ |
||||
if(to == NULL ) { return 1; } |
||||
if(user == NULL ) { return 1; } |
||||
|
||||
PathUserData *p = (PathUserData *)user; |
||||
p->mPts.push_back( Point ( ftd(to->x), ftd(to->y) ) ); |
||||
p->mOldP = *to; |
||||
return 0; |
||||
} |
||||
|
||||
int FreeType2Impl::coFn( const FT_Vector *cnt, |
||||
const FT_Vector *to, |
||||
void * user) |
||||
{ |
||||
if(cnt == NULL ) { return 1; } |
||||
if(to == NULL ) { return 1; } |
||||
if(user == NULL ) { return 1; } |
||||
|
||||
PathUserData *p = (PathUserData *)user; |
||||
|
||||
// Bezier to Line
|
||||
for(int i = 0;i <= p->mCtoL; i++){ |
||||
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; |
||||
|
||||
double X = (p->mOldP.x) * p0 + cnt->x * p1 + to->x * p2; |
||||
double Y = (p->mOldP.y) * p0 + cnt->y * p1 + to->y * p2; |
||||
p->mPts.push_back( Point ( ftd(X), ftd(Y) ) ); |
||||
} |
||||
p->mOldP = *to; |
||||
return 0; |
||||
} |
||||
|
||||
int FreeType2Impl::cuFn( const FT_Vector *cnt1, |
||||
const FT_Vector *cnt2, |
||||
const FT_Vector *to, |
||||
void * user) |
||||
{ |
||||
if(cnt1 == NULL ) { return 1; } |
||||
if(cnt2 == NULL ) { return 1; } |
||||
if(to == NULL ) { return 1; } |
||||
if(user == NULL ) { return 1; } |
||||
|
||||
PathUserData *p = (PathUserData *)user; |
||||
|
||||
// Bezier to Line
|
||||
for(int i = 0; i <= p->mCtoL ;i++){ |
||||
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; |
||||
|
||||
p->mPts.push_back( Point ( ftd(X), ftd(Y) ) ); |
||||
} |
||||
p->mOldP = *to; |
||||
return 0; |
||||
} |
||||
|
||||
CV_EXPORTS_W Ptr<FreeType2> createFreeType2() |
||||
{ |
||||
return Ptr<FreeType2Impl> (new FreeType2Impl () ); |
||||
} |
||||
|
||||
|
||||
}} // namespace freetype2
|
@ -0,0 +1,67 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
//################################################################################
|
||||
//
|
||||
// Created by Kumataro
|
||||
//
|
||||
//################################################################################
|
||||
|
||||
#ifndef __OPENCV_PRECOMP_H__ |
||||
#define __OPENCV_PRECOMP_H__ |
||||
|
||||
#include <opencv2/core.hpp> |
||||
#include <opencv2/imgproc.hpp> |
||||
#include <opencv2/imgproc/imgproc_c.h> // for CV_AA |
||||
#include <opencv2/freetype.hpp> |
||||
#include "opencv2/opencv_modules.hpp" |
||||
|
||||
#include <iostream> |
||||
#include <cstdio> |
||||
#include <vector> |
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include FT_OUTLINE_H |
||||
|
||||
#include <hb.h> |
||||
#include <hb-ft.h> |
||||
#endif |
Loading…
Reference in new issue