25#include <scolPlugin.h> 
   34    class FreeTypeFontImpl CV_FINAL : 
public FreeTypeFont
 
   40      bool loadFontData(String fontFileName, 
int idx) CV_OVERRIDE;
 
   41      bool loadFontData(
const FT_Byte* fontData, FT_Long fontDataSize, 
int idx) CV_OVERRIDE;
 
   43      void setSplitNumber(
int num) CV_OVERRIDE;
 
   46        InputOutputArray img, 
const String& text, Point org,
 
   47        int fontHeight, Scalar color,
 
   48        int thickness, 
int line_type, 
bool bottomLeftOrigin
 
   52        const String& text, 
int fontHeight, 
int thickness,
 
   58      FTC_Manager      mFtcManager;
 
   59      FTC_ImageCache   mImageCache;
 
   60      FTC_ImageTypeRec mImageType;
 
   63      hb_buffer_t*     mHbBuffer;
 
   64      bool             mIsFaceAvailable;
 
   69      static FT_Error Face_Requester(FTC_FaceID face_id, FT_Library library, FT_Pointer req_data, FT_Face *aface);
 
   71      void putTextBitmapMono(
 
   72        InputOutputArray img, 
const String& text, Point org,
 
   73        int fontHeight, Scalar color,
 
   74        int thickness, 
int line_type, 
bool bottomLeftOrigin
 
   77      void putTextBitmapBlend(
 
   78        InputOutputArray img, 
const String& text, Point org,
 
   79        int fontHeight, Scalar color,
 
   80        int thickness, 
int line_type, 
bool bottomLeftOrigin
 
   84        InputOutputArray img, 
const String& text, Point org,
 
   85        int fontHeight, Scalar color,
 
   86        int thickness, 
int line_type, 
bool bottomLeftOrigin
 
   89      static int mvFn(
const FT_Vector *to, 
void * user);
 
   90      static int lnFn(
const FT_Vector *to, 
void * user);
 
   91      static int coFn(
const FT_Vector *cnt, 
const FT_Vector *to, 
void * user);
 
   92      static int cuFn(
const FT_Vector *cnt1, 
const FT_Vector *cnt2, 
const FT_Vector *to, 
void * user);
 
   95      static const unsigned int cOutlineOffset = 0x80000000;
 
  100      static int ftd(
unsigned int fixedInt)
 
  102        unsigned int ret = ((fixedInt + (1 << 5)) >> 6);
 
  103        return (
int)ret - (cOutlineOffset >> 6);
 
  110          PathUserData(InputOutputArray _img) : mImg(_img) {};
 
  112          InputOutputArray mImg;
 
  118          std::vector < Point > mPts;
 
  125        drawGlyph(cv::Point _pos, FTC_Manager* _manager) : pos(_pos), manager(_manager){};
 
  129        FTC_Manager* manager;
 
  135        blitBuffer(InputOutputArray img, std::vector<drawGlyph> lGlyph, cv::Scalar color) : mImg(img), mLglyph(lGlyph), mColor(color) {};
 
  137        InputOutputArray mImg;
 
  138        std::vector<drawGlyph> mLglyph;
 
  142    class blitMono : 
public cv::ParallelLoopBody
 
  145      blitMono(
const blitBuffer _conv)
 
  149      void operator()(
const cv::Range& range)
 const 
  151        const int start = range.start;
 
  152        const int end = range.end;
 
  153        cv::Mat dst = conv.mImg.getMat();
 
  155        for (
unsigned int t = start; t < end; t++)
 
  157          drawGlyph dGlyph = conv.mLglyph[t];
 
  158          if (dGlyph.glyph->format != FT_GLYPH_FORMAT_BITMAP && FT_Glyph_To_Bitmap(&dGlyph.glyph, FT_RENDER_MODE_MONO, 0, 1))
 
  161          FT_BitmapGlyph gbmp = (FT_BitmapGlyph)dGlyph.glyph;
 
  162          FT_Bitmap* bmp = &gbmp->bitmap;
 
  164          dGlyph.pos.y -= gbmp->top;
 
  165          dGlyph.pos.x += gbmp->left;
 
  167          if (!bmp || !bmp->buffer)
 
  170          for (
int row = 0; row < bmp->rows; row++)
 
  172            if (dGlyph.pos.y + row < 0)
 
  175            if (dGlyph.pos.y + row >= dst.rows)
 
  178            for (
int col = 0; col < bmp->pitch; col++)
 
  180              int cl = bmp->buffer[row * bmp->pitch + col];
 
  184              for (
int bit = 7; bit >= 0; bit--)
 
  186                if (dGlyph.pos.x + col * 8 + (7 - bit) < 0)
 
  189                if (dGlyph.pos.x + col * 8 + (7 - bit) >= dst.cols)
 
  192                if (((cl >> bit) & 0x01) == 1)
 
  194                  if (conv.mImg.channels() == 3)
 
  196                    cv::Vec3b* ptr = dst.ptr<cv::Vec3b>(dGlyph.pos.y + row, dGlyph.pos.x + col * 8 + (7 - bit));
 
  197                    (*ptr)[0] = conv.mColor[0];
 
  198                    (*ptr)[1] = conv.mColor[1];
 
  199                    (*ptr)[2] = conv.mColor[2];
 
  203                    uint8_t* ptr = dst.ptr<uint8_t>(dGlyph.pos.y + row, dGlyph.pos.x + col * 8 + (7 - bit));
 
  204                    (*ptr) = conv.mColor[0];
 
  210          FTC_Node_Unref(dGlyph.anode, *dGlyph.manager);
 
  215      blitMono& operator=(
const blitMono&);
 
  216      const blitBuffer conv;
 
  219    class blitBlend : 
public cv::ParallelLoopBody
 
  222      blitBlend(
const blitBuffer _conv)
 
  226      void operator()(
const cv::Range& range)
 const 
  228        const int start = range.start;
 
  229        const int end = range.end;
 
  230        cv::Mat dst = conv.mImg.getMat();
 
  232        for (
unsigned int t = start; t < end; t++)
 
  234          drawGlyph dGlyph = conv.mLglyph[t];
 
  235          if (dGlyph.glyph->format != FT_GLYPH_FORMAT_BITMAP && FT_Glyph_To_Bitmap(&dGlyph.glyph, FT_RENDER_MODE_NORMAL, 0, 1))
 
  238          FT_BitmapGlyph gbmp = (FT_BitmapGlyph)dGlyph.glyph;
 
  239          FT_Bitmap* bmp = &gbmp->bitmap;
 
  241          dGlyph.pos.y -= gbmp->top;
 
  242          dGlyph.pos.x += gbmp->left;
 
  244          if (!bmp || !bmp->buffer)
 
  247          for (
int row = 0; row < bmp->rows; row++)
 
  249            if (dGlyph.pos.y + row < 0)
 
  252            if (dGlyph.pos.y + row >= dst.rows)
 
  255            for (
int col = 0; col < bmp->pitch; col++)
 
  257              int cl = bmp->buffer[row * bmp->pitch + col];
 
  261              if (dGlyph.pos.x + col < 0)
 
  264              if (dGlyph.pos.x + col >= dst.cols)
 
  267              double blendAlpha = (double)cl / 255.0;
 
  268              if (conv.mImg.channels() == 3)
 
  270                cv::Vec3b* ptr = dst.ptr<cv::Vec3b>(dGlyph.pos.y + row, dGlyph.pos.x + col);
 
  271                (*ptr)[0] = (double)conv.mColor[0] * blendAlpha + (*ptr)[0] * (1.0 - blendAlpha);
 
  272                (*ptr)[1] = (double)conv.mColor[1] * blendAlpha + (*ptr)[1] * (1.0 - blendAlpha);
 
  273                (*ptr)[2] = (double)conv.mColor[2] * blendAlpha + (*ptr)[2] * (1.0 - blendAlpha);
 
  277                uchar* ptr = dst.ptr<uchar>(dGlyph.pos.y + row, dGlyph.pos.x + col);
 
  278                (*ptr) = (double)conv.mColor[0] * blendAlpha + (*ptr) * (1.0 - blendAlpha);
 
  282          FTC_Node_Unref(dGlyph.anode, *dGlyph.manager);
 
  287      blitBlend& operator=(
const blitBlend&);
 
  288      const blitBuffer conv;
 
  291    FreeTypeFontImpl::FreeTypeFontImpl()
 
  293      FT_Init_FreeType(&(this->mLibrary));
 
  294      mHbBuffer = hb_buffer_create();
 
  299      mFn.move_to = FreeTypeFontImpl::mvFn;
 
  300      mFn.line_to = FreeTypeFontImpl::lnFn;
 
  301      mFn.cubic_to = FreeTypeFontImpl::cuFn;
 
  302      mFn.conic_to = FreeTypeFontImpl::coFn;
 
  306      FTC_Manager_New(mLibrary, 1, 0, 0 , Face_Requester, 
this, &mFtcManager);
 
  307      FTC_ImageCache_New(mFtcManager, &mImageCache);
 
  309      mIsFaceAvailable = 
false;
 
  312    FreeTypeFontImpl::~FreeTypeFontImpl()
 
  314      hb_buffer_destroy(mHbBuffer);
 
  315      if (mIsFaceAvailable == 
true)
 
  317        hb_font_destroy(mHb_font);
 
  319        mIsFaceAvailable = 
false;
 
  321      FTC_Manager_Done(mFtcManager);
 
  322      CV_Assert(!FT_Done_FreeType(mLibrary));
 
  328    FT_Error FreeTypeFontImpl::Face_Requester(FTC_FaceID face_id, FT_Library library, FT_Pointer req_data, FT_Face *aface)
 
  330      FreeTypeFontImpl *impl = 
static_cast<FreeTypeFontImpl *
>(req_data);
 
  331      *aface = impl->mFace;
 
  335    bool FreeTypeFontImpl::loadFontData(String fontFileName, 
int idx)
 
  337      if (mIsFaceAvailable == 
true)
 
  339        hb_font_destroy(mHb_font);
 
  340        CV_Assert(!FT_Done_Face(mFace));
 
  342        if (mFontData != NULL)
 
  347        mIsFaceAvailable = 
false;
 
  350      std::stringstream stream(std::stringstream::in|std::stringstream::out|std::stringstream::binary);
 
  351      if (!SCfopenStream(fontFileName.c_str(), stream))
 
  355      stream.seekg(0, stream.end);
 
  356      int length = stream.tellg();
 
  357      stream.seekg(0, stream.beg);
 
  359      mFontData = 
new char[length];
 
  360      stream.read(mFontData, length);
 
  362      if (!loadFontData((FT_Byte*)mFontData, (FT_Long)length, 0))
 
  364        if (mFontData != NULL)
 
  374      if (FT_New_Face(mLibrary, fontFileName.c_str(), idx, &(mFace)) != 0)
 
  376        mIsFaceAvailable = 
false;
 
  381      mHb_font = hb_ft_font_create(mFace, NULL);
 
  382      if (mHb_font == NULL)
 
  384        mIsFaceAvailable = 
false;
 
  388      mIsFaceAvailable = 
true;
 
  393    bool FreeTypeFontImpl::loadFontData(
const FT_Byte* fontData, FT_Long fontDataSize, 
int idx)
 
  395      if (mIsFaceAvailable == 
true)
 
  397        hb_font_destroy(mHb_font);
 
  398        CV_Assert(!FT_Done_Face(mFace));
 
  400        if (mFontData != NULL)
 
  407      if (FT_New_Memory_Face(mLibrary, fontData, fontDataSize, idx, &(mFace)) != 0)
 
  409        mIsFaceAvailable = 
false;
 
  414      mHb_font = hb_ft_font_create(mFace, NULL);
 
  415      if (mHb_font == NULL)
 
  417        mIsFaceAvailable = 
false;
 
  421      mIsFaceAvailable = 
true;
 
  425    void FreeTypeFontImpl::setSplitNumber(
int num)
 
  431    void FreeTypeFontImpl::putText(
 
  432      InputOutputArray _img, 
const String& _text, Point _org,
 
  433      int _fontHeight, Scalar _color,
 
  434      int _thickness, 
int _line_type, 
bool _bottomLeftOrigin
 
  437      CV_Assert(mIsFaceAvailable == 
true);
 
  438      CV_Assert((_img.empty() == 
false) &&
 
  439        (_img.isMat() == 
true) &&
 
  440        (_img.depth() == CV_8U) &&
 
  442      CV_Assert((_line_type == CV_AA) ||
 
  445      CV_Assert(_fontHeight >= 0);
 
  450      std::string text = to_utf8(_text);
 
  452      if (_fontHeight == 0)
 
  455      if (_line_type == CV_AA && _img.depth() != CV_8U)
 
  460      CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight));
 
  464        if (_line_type == CV_AA)
 
  466          putTextBitmapBlend(_img, text, _org, _fontHeight, _color,
 
  467            _thickness, _line_type, _bottomLeftOrigin);
 
  471          putTextBitmapMono(_img, text, _org, _fontHeight, _color,
 
  472            _thickness, _line_type, _bottomLeftOrigin);
 
  477        putTextOutline(_img, text, _org, _fontHeight, _color,
 
  478          _thickness, _line_type, _bottomLeftOrigin);
 
  482    void FreeTypeFontImpl::putTextOutline(
 
  483      InputOutputArray _img, 
const String& _text, Point _org,
 
  484      int _fontHeight, Scalar _color,
 
  485      int _thickness, 
int _line_type, 
bool _bottomLeftOrigin)
 
  487      unsigned int textLen;
 
  488      hb_buffer_reset(mHbBuffer);
 
  489      hb_buffer_guess_segment_properties(mHbBuffer);
 
  490      hb_buffer_add_utf8(mHbBuffer, _text.c_str(), -1, 0, -1);
 
  492      hb_glyph_info_t *info = hb_buffer_get_glyph_infos(mHbBuffer, &textLen);
 
  493      CV_Assert(info != NULL);
 
  495      hb_shape(mHb_font, mHbBuffer, NULL, 0);
 
  497      if (_bottomLeftOrigin == 
true)
 
  498        _org.y -= _fontHeight;
 
  500      PathUserData *userData = 
new PathUserData(_img);
 
  501      userData->mColor = _color;
 
  502      userData->mCtoL = mCtoL;
 
  503      userData->mThickness = _thickness;
 
  504      userData->mLine_type = _line_type;
 
  506      mImageType.face_id = (FTC_FaceID)1;
 
  507      mImageType.width = _fontHeight;
 
  508      mImageType.height = _fontHeight;
 
  509      mImageType.flags = FT_LOAD_DEFAULT;
 
  511      for (
unsigned int i = 0; i < textLen; i++)
 
  514        CV_Assert(!FTC_ImageCache_Lookup(mImageCache, &mImageType, info[i].codepoint, &glyph, 
nullptr));
 
  516        FT_OutlineGlyph outlineglyph = (FT_OutlineGlyph)glyph;
 
  518        CV_Assert(!FT_Outline_New(mLibrary, outlineglyph->outline.n_points, outlineglyph->outline.n_contours, &outline));
 
  519        CV_Assert(!FT_Outline_Copy(&outlineglyph->outline, &outline));
 
  522        FT_Matrix mtx = { 1 << 16 , 0 , 0 , -(1 << 16) };
 
  523        FT_Outline_Transform(&outline, &mtx);
 
  526        FT_Outline_Translate(&outline,
 
  531        FT_Outline_Translate(&outline,
 
  532          (FT_Pos)(_org.x << 6),
 
  533          (FT_Pos)((_org.y + _fontHeight) << 6));
 
  536        CV_Assert(!FT_Outline_Decompose(&outline, &mFn, (
void*)userData));
 
  539        mvFn(NULL, (
void*)userData);
 
  541        _org.x += (glyph->advance.x) >> 16;
 
  542        _org.y += (glyph->advance.y) >> 16;
 
  544        FT_Outline_Done(mLibrary, &outline);
 
  549    void FreeTypeFontImpl::putTextBitmapMono(
 
  550      InputOutputArray _img, 
const String& _text, Point _org,
 
  551      int _fontHeight, Scalar _color,
 
  552      int _thickness, 
int _line_type, 
bool _bottomLeftOrigin)
 
  554      CV_Assert(_thickness < 0);
 
  556      unsigned int textLen;
 
  557      hb_buffer_reset(mHbBuffer);
 
  558      hb_buffer_guess_segment_properties(mHbBuffer);
 
  559      hb_buffer_add_utf8(mHbBuffer, _text.c_str(), -1, 0, -1);
 
  560      hb_glyph_info_t *info = hb_buffer_get_glyph_infos(mHbBuffer, &textLen);
 
  561      CV_Assert(info != NULL);
 
  563      hb_shape(mHb_font, mHbBuffer, NULL, 0);
 
  565      _org.y += _fontHeight;
 
  566      if (_bottomLeftOrigin == 
true)
 
  567        _org.y -= _fontHeight;
 
  569      mImageType.face_id = (FTC_FaceID) 1;
 
  570      mImageType.width = _fontHeight;
 
  571      mImageType.height = _fontHeight;
 
  572      mImageType.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_MONO;
 
  574      std::vector<drawGlyph> lGlyph;
 
  575      for (
unsigned int i = 0; i < textLen; i++)
 
  577        drawGlyph dGlyph(_org, &mFtcManager);
 
  579        CV_Assert(!FTC_ImageCache_Lookup(mImageCache, &mImageType, info[i].codepoint, &dGlyph.glyph, &dGlyph.anode));
 
  580        lGlyph.push_back(dGlyph);
 
  582        _org.x += (dGlyph.glyph->advance.x) >> 16;
 
  583        _org.y += (dGlyph.glyph->advance.y) >> 16;
 
  586      blitBuffer conv(_img, lGlyph, _color);
 
  587      cv::parallel_for_(cv::Range(0, lGlyph.size()), blitMono(conv));
 
  590    void FreeTypeFontImpl::putTextBitmapBlend(
 
  591      InputOutputArray _img, 
const String& _text, Point _org,
 
  592      int _fontHeight, Scalar _color,
 
  593      int _thickness, 
int _line_type, 
bool _bottomLeftOrigin)
 
  595      CV_Assert(_thickness < 0);
 
  597      unsigned int textLen;
 
  598      hb_buffer_reset(mHbBuffer);
 
  599      hb_buffer_guess_segment_properties(mHbBuffer);
 
  600      hb_buffer_add_utf8(mHbBuffer, _text.c_str(), -1, 0, -1);
 
  601      hb_glyph_info_t *info = hb_buffer_get_glyph_infos(mHbBuffer, &textLen);
 
  602      CV_Assert(info != NULL);
 
  604      hb_shape(mHb_font, mHbBuffer, NULL, 0);
 
  606      _org.y += _fontHeight;
 
  607      if (_bottomLeftOrigin == 
true)
 
  608        _org.y -= _fontHeight;
 
  610      mImageType.face_id = (FTC_FaceID)1;
 
  611      mImageType.width = _fontHeight;
 
  612      mImageType.height = _fontHeight;
 
  613      mImageType.flags = FT_LOAD_RENDER;
 
  615      std::vector<drawGlyph> lGlyph;
 
  616      for (
unsigned int i = 0; i < textLen; i++)
 
  618        drawGlyph dGlyph(_org, &mFtcManager);
 
  620        CV_Assert(!FTC_ImageCache_Lookup(mImageCache, &mImageType, info[i].codepoint, &dGlyph.glyph, &dGlyph.anode));
 
  621        lGlyph.push_back(dGlyph);
 
  623        _org.x += (dGlyph.glyph->advance.x) >> 16;
 
  624        _org.y += (dGlyph.glyph->advance.y) >> 16;
 
  627      blitBuffer conv(_img, lGlyph, _color);
 
  628      cv::parallel_for_(cv::Range(0, lGlyph.size()), blitBlend(conv));
 
  631    Size FreeTypeFontImpl::getTextSize(
 
  635      CV_OUT 
int* _baseLine)
 
  640      CV_Assert(_fontHeight >= 0);
 
  641      if (_fontHeight == 0)
 
  644      CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight));
 
  648      unsigned int textLen;
 
  649      hb_buffer_reset(mHbBuffer);
 
  650      hb_buffer_guess_segment_properties(mHbBuffer);
 
  651      hb_buffer_add_utf8(mHbBuffer, _text.c_str(), -1, 0, -1);
 
  652      hb_glyph_info_t *info = hb_buffer_get_glyph_infos(mHbBuffer, &textLen);
 
  653      CV_Assert(info != NULL);
 
  654      hb_shape(mHb_font, mHbBuffer, NULL, 0);
 
  656      _org.y -= _fontHeight;
 
  657      int xMin = INT_MAX, xMax = INT_MIN;
 
  658      int yMin = INT_MAX, yMax = INT_MIN;
 
  660      mImageType.face_id = (FTC_FaceID)1;
 
  661      mImageType.width = _fontHeight;
 
  662      mImageType.height = _fontHeight;
 
  663      mImageType.flags = FT_LOAD_RENDER;
 
  665      for (
unsigned int i = 0; i < textLen; i++)
 
  668        CV_Assert(!FTC_ImageCache_Lookup(mImageCache, &mImageType, info[i].codepoint, &glyph, 
nullptr));
 
  670        if (glyph->format != FT_GLYPH_FORMAT_BITMAP)
 
  671          FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0);
 
  673        FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)glyph;
 
  675        FT_Bitmap *bmp = &(glyph_bitmap->bitmap);
 
  679        gPos.y -= glyph_bitmap->top;
 
  680        gPos.x += glyph_bitmap->left;
 
  681        int rows = bmp->rows;
 
  682        int cols = bmp->pitch;
 
  684        yMin = cv::min(yMin, gPos.y);
 
  685        yMax = cv::max(yMax, gPos.y + rows);
 
  686        xMin = cv::min(xMin, gPos.x);
 
  687        xMax = cv::max(xMax, gPos.x + cols);
 
  689        _org.x += (glyph->advance.x) >> 16;
 
  690        _org.y += (glyph->advance.y) >> 16;
 
  693      int width = xMax - xMin;
 
  694      int height = yMax - yMin;
 
  698        width = cvRound(width + _thickness * 2);
 
  699        height = cvRound(height + _thickness * 1);
 
  703        width = cvRound(width + 1);
 
  704        height = cvRound(height + 1);
 
  710      return Size(width, height);
 
  713    int FreeTypeFontImpl::mvFn(
const FT_Vector *to, 
void * user)
 
  718      PathUserData *p = (PathUserData*)user;
 
  720      if (p->mPts.size() > 0)
 
  722        Mat dst = p->mImg.getMat();
 
  723        const Point *ptsList[] = { &(p->mPts[0]) };
 
  724        int npt[1]; npt[0] = p->mPts.size();
 
  743      p->mPts.push_back(Point(ftd(to->x), ftd(to->y)));
 
  748    int FreeTypeFontImpl::lnFn(
const FT_Vector *to, 
void * user)
 
  755      PathUserData *p = (PathUserData *)user;
 
  756      p->mPts.push_back(Point(ftd(to->x), ftd(to->y)));
 
  761    int FreeTypeFontImpl::coFn(
const FT_Vector *cnt,
 
  774      PathUserData *p = (PathUserData *)user;
 
  777      for (
int i = 0; i <= p->mCtoL; i++)
 
  779        double u = (double)i * 1.0 / (p->mCtoL);
 
  782        double p1 = 2.0 * u *        nu;
 
  785        double X = (p->mOldP.x) * p0 + cnt->x * p1 + to->x * p2;
 
  786        double Y = (p->mOldP.y) * p0 + cnt->y * p1 + to->y * p2;
 
  787        p->mPts.push_back(Point(ftd(X), ftd(Y)));
 
  793    int FreeTypeFontImpl::cuFn(
const FT_Vector *cnt1,
 
  794      const FT_Vector *cnt2,
 
  810      PathUserData *p = (PathUserData *)user;
 
  813      for (
int i = 0; i <= p->mCtoL; i++)
 
  815        double u = (double)i * 1.0 / (p->mCtoL);
 
  817        double p0 = nu * nu * nu;
 
  818        double p1 = 3.0 * u *        nu * nu;
 
  819        double p2 = 3.0 * u * u *    nu;
 
  820        double p3 = u * u * u;
 
  822        double X = (p->mOldP.x) * p0 + (cnt1->x)    * p1 +
 
  823          (cnt2->x) * p2 + (to->x)    * p3;
 
  824        double Y = (p->mOldP.y) * p0 + (cnt1->y)    * p1 +
 
  825          (cnt2->y) * p2 + (to->y)    * p3;
 
  827        p->mPts.push_back(Point(ftd(X), ftd(Y)));
 
  835      return Ptr<FreeTypeFontImpl>(
new FreeTypeFontImpl());
 
 
Ptr< FreeTypeFont > createFreeTypeFont()
Create FreeType2 Instance.