Added a 3D font loader that uses the Freetype2 library to
parse the vector data. Freetype2 supports many font formats including Type1, TrueType and OpenType fonts. Enable with the WITH_FREETYPE2 compile flag, in the source/blender/blenkernel and source/blender/blenlib dirs.
This commit is contained in:
@@ -145,8 +145,11 @@ static VFontData *vfont_get_data(VFont *vfont)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pf) {
|
if (pf) {
|
||||||
|
#ifdef WITH_FREETYPE2
|
||||||
|
vfont->data= BLI_vfontdata_from_freetypefont(pf);
|
||||||
|
#else
|
||||||
vfont->data= BLI_vfontdata_from_psfont(pf);
|
vfont->data= BLI_vfontdata_from_psfont(pf);
|
||||||
|
#endif
|
||||||
if (pf != vfont->packedfile) {
|
if (pf != vfont->packedfile) {
|
||||||
freePackedFile(pf);
|
freePackedFile(pf);
|
||||||
}
|
}
|
||||||
@@ -183,7 +186,11 @@ VFont *load_vfont(char *name)
|
|||||||
|
|
||||||
waitcursor(1);
|
waitcursor(1);
|
||||||
|
|
||||||
|
#ifdef WITH_FREETYPE2
|
||||||
|
vfd= BLI_vfontdata_from_freetypefont(pf);
|
||||||
|
#else
|
||||||
vfd= BLI_vfontdata_from_psfont(pf);
|
vfd= BLI_vfontdata_from_psfont(pf);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (vfd) {
|
if (vfd) {
|
||||||
vfont = alloc_libblock(&G.main->vfont, ID_VF, filename);
|
vfont = alloc_libblock(&G.main->vfont, ID_VF, filename);
|
||||||
|
@@ -63,5 +63,19 @@ typedef struct VFontData {
|
|||||||
BLI_vfontdata_from_psfont(
|
BLI_vfontdata_from_psfont(
|
||||||
struct PackedFile *pf);
|
struct PackedFile *pf);
|
||||||
|
|
||||||
|
#ifdef WITH_FREETYPE2
|
||||||
|
/**
|
||||||
|
* Construct a new VFontData structure from
|
||||||
|
* Freetype font data in a PackedFile.
|
||||||
|
*
|
||||||
|
* @param pf The font data.
|
||||||
|
* @retval A new VFontData structure, or NULL
|
||||||
|
* if unable to load.
|
||||||
|
*/
|
||||||
|
VFontData*
|
||||||
|
BLI_vfontdata_from_freetypefont(
|
||||||
|
struct PackedFile *pf);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
445
source/blender/blenlib/intern/freetypefont.c
Normal file
445
source/blender/blenlib/intern/freetypefont.c
Normal file
@@ -0,0 +1,445 @@
|
|||||||
|
/**
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version. The Blender
|
||||||
|
* Foundation also sells licenses for use in proprietary software under
|
||||||
|
* the Blender License. See http://www.blender.org/BL/ for information
|
||||||
|
* about this.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* The Original Code is written by Rob Haarsma (phase)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Contributor(s): none yet.
|
||||||
|
*
|
||||||
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WITH_FREETYPE2
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning (disable:4244)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "BLI_vfontdata.h"
|
||||||
|
#include "BLI_blenlib.h"
|
||||||
|
#include "BLI_arithb.h"
|
||||||
|
|
||||||
|
#include "BIF_toolbox.h"
|
||||||
|
|
||||||
|
#include "DNA_packedFile_types.h"
|
||||||
|
#include "DNA_curve_types.h"
|
||||||
|
|
||||||
|
#define myMIN_ASCII 32
|
||||||
|
#define myMAX_ASCII 126
|
||||||
|
|
||||||
|
// should come from arithb.c
|
||||||
|
#define MIN2(x,y) ( (x)<(y) ? (x) : (y) )
|
||||||
|
#define MAX2(x,y) ( (x)>(y) ? (x) : (y) )
|
||||||
|
|
||||||
|
/* local variables */
|
||||||
|
static FT_Library library;
|
||||||
|
static FT_Error err;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Freetype2 Outline struct
|
||||||
|
|
||||||
|
typedef struct FT_Outline_
|
||||||
|
{
|
||||||
|
short n_contours; /* number of contours in glyph */
|
||||||
|
short n_points; /* number of points in the glyph */
|
||||||
|
|
||||||
|
FT_Vector* points; /* the outline's points */
|
||||||
|
char* tags; /* the points flags */
|
||||||
|
short* contours; /* the contour end points */
|
||||||
|
|
||||||
|
int flags; /* outline masks */
|
||||||
|
|
||||||
|
} FT_Outline;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***//*
|
||||||
|
from: http://www.freetype.org/freetype2/docs/glyphs/glyphs-6.html#section-1
|
||||||
|
|
||||||
|
Vectorial representation of Freetype glyphs
|
||||||
|
|
||||||
|
The source format of outlines is a collection of closed paths called "contours". Each contour is
|
||||||
|
made of a series of line segments and bezier arcs. Depending on the file format, these can be
|
||||||
|
second-order or third-order polynomials. The former are also called quadratic or conic arcs, and
|
||||||
|
they come from the TrueType format. The latter are called cubic arcs and mostly come from the
|
||||||
|
Type1 format.
|
||||||
|
|
||||||
|
Each arc is described through a series of start, end and control points. Each point of the outline
|
||||||
|
has a specific tag which indicates wether it is used to describe a line segment or an arc.
|
||||||
|
|
||||||
|
|
||||||
|
The following rules are applied to decompose the contour's points into segments and arcs :
|
||||||
|
|
||||||
|
# two successive "on" points indicate a line segment joining them.
|
||||||
|
|
||||||
|
# one conic "off" point amidst two "on" points indicates a conic bezier arc, the "off" point being
|
||||||
|
the control point, and the "on" ones the start and end points.
|
||||||
|
|
||||||
|
# Two successive cubic "off" points amidst two "on" points indicate a cubic bezier arc. There must
|
||||||
|
be exactly two cubic control points and two on points for each cubic arc (using a single cubic
|
||||||
|
"off" point between two "on" points is forbidden, for example).
|
||||||
|
|
||||||
|
# finally, two successive conic "off" points forces the rasterizer to create (during the scan-line
|
||||||
|
conversion process exclusively) a virtual "on" point amidst them, at their exact middle. This
|
||||||
|
greatly facilitates the definition of successive conic bezier arcs. Moreover, it's the way
|
||||||
|
outlines are described in the TrueType specification.
|
||||||
|
|
||||||
|
Note that it is possible to mix conic and cubic arcs in a single contour, even though no current
|
||||||
|
font driver produces such outlines.
|
||||||
|
|
||||||
|
* # on
|
||||||
|
* off
|
||||||
|
__---__
|
||||||
|
#-__ _-- -_
|
||||||
|
--__ _- -
|
||||||
|
--__ # \
|
||||||
|
--__ #
|
||||||
|
-#
|
||||||
|
Two "on" points
|
||||||
|
Two "on" points and one "conic" point
|
||||||
|
between them
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*
|
||||||
|
# __ Two "on" points with two "conic"
|
||||||
|
\ - - points between them. The point
|
||||||
|
\ / \ marked '0' is the middle of the
|
||||||
|
- 0 \ "off" points, and is a 'virtual'
|
||||||
|
-_ _- # "on" point where the curve passes.
|
||||||
|
-- It does not appear in the point
|
||||||
|
list.
|
||||||
|
*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
* # on
|
||||||
|
* * off
|
||||||
|
__---__
|
||||||
|
_-- -_
|
||||||
|
_- -
|
||||||
|
# \
|
||||||
|
#
|
||||||
|
|
||||||
|
Two "on" points
|
||||||
|
and two "cubic" point
|
||||||
|
between them
|
||||||
|
|
||||||
|
|
||||||
|
Each glyph's original outline points are located on a grid of indivisible units. The points are stored
|
||||||
|
in the font file as 16-bit integer grid coordinates, with the grid origin's being at (0,0); they thus
|
||||||
|
range from -16384 to 16383.
|
||||||
|
|
||||||
|
|
||||||
|
Convert conic to bezier arcs:
|
||||||
|
Conic P0 P1 P2
|
||||||
|
Bezier B0 B1 B2 B3
|
||||||
|
B0=P0
|
||||||
|
B1=(P0+2*P1)/3
|
||||||
|
B2=(P2+2*P1)/3
|
||||||
|
B3=P2
|
||||||
|
|
||||||
|
*//****/
|
||||||
|
|
||||||
|
static VFontData *objfnt_to_ftvfontdata(PackedFile * pf)
|
||||||
|
{
|
||||||
|
// Blender
|
||||||
|
VFontData *vfd;
|
||||||
|
struct Nurb *nu;
|
||||||
|
struct BezTriple *bezt;
|
||||||
|
|
||||||
|
// Freetype2
|
||||||
|
FT_Face face;
|
||||||
|
FT_GlyphSlot glyph;
|
||||||
|
FT_UInt glyph_index;
|
||||||
|
FT_Outline ftoutline;
|
||||||
|
|
||||||
|
float scale= 1. / 1024.; //needs text_height from metrics to make a standard linedist
|
||||||
|
float dx, dy;
|
||||||
|
int i, j, k, l, m; /* uhoh, kiddie C loops */
|
||||||
|
/* i = characters, j = curves/contours, k = points, l = curvepoint, m = first point on curve */
|
||||||
|
|
||||||
|
// test is used for BIF_printf
|
||||||
|
char test[2];
|
||||||
|
|
||||||
|
|
||||||
|
// load the freetype font
|
||||||
|
err = FT_New_Memory_Face( library,
|
||||||
|
pf->data,
|
||||||
|
pf->size,
|
||||||
|
0,
|
||||||
|
&face );
|
||||||
|
|
||||||
|
if(err) return NULL;
|
||||||
|
|
||||||
|
// allocate blender font
|
||||||
|
vfd= MEM_callocN(sizeof(*vfd), "FTVFontData");
|
||||||
|
|
||||||
|
//FT_Set_Charmap(face, ft_encoding_symbol);
|
||||||
|
|
||||||
|
// extract generic ascii character range (needs international support, dynamic loading of chars, etcetc)
|
||||||
|
for(i = myMIN_ASCII; i <= myMAX_ASCII; i++) {
|
||||||
|
int *npoints; //total points of each contour
|
||||||
|
int *onpoints; //num points on curve
|
||||||
|
|
||||||
|
test[0] = i;
|
||||||
|
test[1] = '\0'; //to print character
|
||||||
|
|
||||||
|
glyph_index = FT_Get_Char_Index( face, i );
|
||||||
|
err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE);
|
||||||
|
glyph = face->glyph;
|
||||||
|
ftoutline = glyph->outline;
|
||||||
|
|
||||||
|
vfd->width[i] = glyph->advance.x* scale;
|
||||||
|
// BIF_printf("sx %d sy %d", glyph->advance.x, face->glyph->metrics->text_height);
|
||||||
|
|
||||||
|
npoints = (int *)MEM_callocN((ftoutline.n_contours)* sizeof(int),"endpoints") ;
|
||||||
|
onpoints = (int *)MEM_callocN((ftoutline.n_contours)* sizeof(int),"onpoints") ;
|
||||||
|
|
||||||
|
// calculate total points of each contour
|
||||||
|
for(j = 0; j < ftoutline.n_contours; j++) {
|
||||||
|
if(j == 0)
|
||||||
|
npoints[j] = ftoutline.contours[j] + 1;
|
||||||
|
else
|
||||||
|
npoints[j] = ftoutline.contours[j] - ftoutline.contours[j - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// get number of on-curve points for beziertriples (including conic virtual on-points)
|
||||||
|
for(j = 0; j < ftoutline.n_contours; j++) {
|
||||||
|
l = 0;
|
||||||
|
for(k = 0; k < npoints[j]; k++) {
|
||||||
|
if(j > 0) l = k + ftoutline.contours[j - 1] + 1; else l = k;
|
||||||
|
|
||||||
|
// if(i == 67) BIF_printf("%d->%s : |k %2d|l %2d|t %2d|", i, test, k, l, ftoutline.n_points);
|
||||||
|
|
||||||
|
if(ftoutline.tags[l] == FT_Curve_Tag_On)
|
||||||
|
onpoints[j]++;
|
||||||
|
|
||||||
|
if(k < npoints[j] - 1 )
|
||||||
|
if( ftoutline.tags[l] == FT_Curve_Tag_Conic &&
|
||||||
|
ftoutline.tags[l+1] == FT_Curve_Tag_Conic)
|
||||||
|
onpoints[j]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//final contour loop, bezier & conic styles merged
|
||||||
|
for(j = 0; j < ftoutline.n_contours; j++) {
|
||||||
|
// add new curve
|
||||||
|
nu = (Nurb*)MEM_callocN(sizeof(struct Nurb),"objfnt_nurb");
|
||||||
|
bezt = (BezTriple*)MEM_callocN((onpoints[j])* sizeof(BezTriple),"objfnt_bezt") ;
|
||||||
|
BLI_addtail(&vfd->nurbsbase[i], nu);
|
||||||
|
nu->type= CU_BEZIER+CU_2D;
|
||||||
|
nu->pntsu = onpoints[j];
|
||||||
|
nu->resolu= 8;
|
||||||
|
nu->flagu= 1;
|
||||||
|
nu->bezt = bezt;
|
||||||
|
|
||||||
|
//individual curve loop, start-end
|
||||||
|
for(k = 0; k < npoints[j]; k++) {
|
||||||
|
if(j > 0) l = k + ftoutline.contours[j - 1] + 1; else l = k;
|
||||||
|
if(k == 0) m = l;
|
||||||
|
|
||||||
|
//virtual conic on-curve points
|
||||||
|
if(k < npoints[j] - 1 )
|
||||||
|
if( ftoutline.tags[l] == FT_Curve_Tag_Conic && ftoutline.tags[l+1] == FT_Curve_Tag_Conic) {
|
||||||
|
dx = (ftoutline.points[l].x + ftoutline.points[l+1].x)* scale / 2.0;
|
||||||
|
dy = (ftoutline.points[l].y + ftoutline.points[l+1].y)* scale / 2.0;
|
||||||
|
|
||||||
|
//left handle
|
||||||
|
bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x)* scale) / 3.0;
|
||||||
|
bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y)* scale) / 3.0;
|
||||||
|
|
||||||
|
//midpoint (virtual on-curve point)
|
||||||
|
bezt->vec[1][0] = (ftoutline.points[l].x + ftoutline.points[l+1].x)* scale / 2.0;
|
||||||
|
bezt->vec[1][1] = (ftoutline.points[l].y + ftoutline.points[l+1].y)* scale / 2.0;
|
||||||
|
|
||||||
|
//right handle
|
||||||
|
bezt->vec[2][0] = (dx + (2 * ftoutline.points[l+1].x)* scale) / 3.0;
|
||||||
|
bezt->vec[2][1] = (dy + (2 * ftoutline.points[l+1].y)* scale) / 3.0;
|
||||||
|
|
||||||
|
bezt->h1= bezt->h2= HD_ALIGN;
|
||||||
|
bezt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//on-curve points
|
||||||
|
if(ftoutline.tags[l] == FT_Curve_Tag_On) {
|
||||||
|
//left handle
|
||||||
|
if(k > 0) {
|
||||||
|
if(ftoutline.tags[l - 1] == FT_Curve_Tag_Cubic) {
|
||||||
|
bezt->vec[0][0] = ftoutline.points[l-1].x* scale;
|
||||||
|
bezt->vec[0][1] = ftoutline.points[l-1].y* scale;
|
||||||
|
bezt->h1= HD_FREE;
|
||||||
|
} else if(ftoutline.tags[l - 1] == FT_Curve_Tag_Conic) {
|
||||||
|
bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l - 1].x))* scale / 3.0;
|
||||||
|
bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l - 1].y))* scale / 3.0;
|
||||||
|
bezt->h1= HD_FREE;
|
||||||
|
} else {
|
||||||
|
bezt->vec[0][0] = ftoutline.points[l].x* scale - (ftoutline.points[l].x - ftoutline.points[l-1].x)* scale / 3.0;
|
||||||
|
bezt->vec[0][1] = ftoutline.points[l].y* scale - (ftoutline.points[l].y - ftoutline.points[l-1].y)* scale / 3.0;
|
||||||
|
bezt->h1= HD_VECT;
|
||||||
|
}
|
||||||
|
} else { //first point on curve
|
||||||
|
if(ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Cubic) {
|
||||||
|
bezt->vec[0][0] = ftoutline.points[ftoutline.contours[j]].x * scale;
|
||||||
|
bezt->vec[0][1] = ftoutline.points[ftoutline.contours[j]].y * scale;
|
||||||
|
bezt->h1= HD_FREE;
|
||||||
|
} else if(ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Conic) {
|
||||||
|
bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[ftoutline.contours[j]].x))* scale / 3.0 ;
|
||||||
|
bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[ftoutline.contours[j]].y))* scale / 3.0 ;
|
||||||
|
bezt->h1= HD_FREE;
|
||||||
|
} else {
|
||||||
|
bezt->vec[0][0] = ftoutline.points[l].x* scale - (ftoutline.points[l].x - ftoutline.points[ftoutline.contours[j]].x)* scale / 3.0;
|
||||||
|
bezt->vec[0][1] = ftoutline.points[l].y* scale - (ftoutline.points[l].y - ftoutline.points[ftoutline.contours[j]].y)* scale / 3.0;
|
||||||
|
bezt->h1= HD_VECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//midpoint (on-curve point)
|
||||||
|
bezt->vec[1][0] = ftoutline.points[l].x* scale;
|
||||||
|
bezt->vec[1][1] = ftoutline.points[l].y* scale;
|
||||||
|
|
||||||
|
//right handle
|
||||||
|
if(k < (npoints[j] - 1)) {
|
||||||
|
if(ftoutline.tags[l+1] == FT_Curve_Tag_Cubic) {
|
||||||
|
bezt->vec[2][0] = ftoutline.points[l+1].x* scale;
|
||||||
|
bezt->vec[2][1] = ftoutline.points[l+1].y* scale;
|
||||||
|
bezt->h2= HD_FREE;
|
||||||
|
} else if(ftoutline.tags[l+1] == FT_Curve_Tag_Conic) {
|
||||||
|
bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l+1].x))* scale / 3.0;
|
||||||
|
bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l+1].y))* scale / 3.0;
|
||||||
|
bezt->h2= HD_FREE;
|
||||||
|
} else {
|
||||||
|
bezt->vec[2][0] = ftoutline.points[l].x* scale - (ftoutline.points[l].x - ftoutline.points[l+1].x)* scale / 3.0;
|
||||||
|
bezt->vec[2][1] = ftoutline.points[l].y* scale - (ftoutline.points[l].y - ftoutline.points[l+1].y)* scale / 3.0;
|
||||||
|
bezt->h2= HD_VECT;
|
||||||
|
}
|
||||||
|
} else { //last point on curve
|
||||||
|
if(ftoutline.tags[m] == FT_Curve_Tag_Cubic) {
|
||||||
|
// okee("hhuh");
|
||||||
|
bezt->vec[2][0] = ftoutline.points[m].x* scale;
|
||||||
|
bezt->vec[2][1] = ftoutline.points[m].y* scale;
|
||||||
|
bezt->h2= HD_FREE;
|
||||||
|
} else if(ftoutline.tags[m] == FT_Curve_Tag_Conic) {
|
||||||
|
bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[m].x))* scale / 3.0 ;
|
||||||
|
bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[m].y))* scale / 3.0 ;
|
||||||
|
bezt->h2= HD_FREE;
|
||||||
|
} else {
|
||||||
|
bezt->vec[2][0] = ftoutline.points[l].x* scale - (ftoutline.points[l].x - ftoutline.points[m].x)* scale / 3.0;
|
||||||
|
bezt->vec[2][1] = ftoutline.points[l].y* scale - (ftoutline.points[l].y - ftoutline.points[m].y)* scale / 3.0;
|
||||||
|
bezt->h2= HD_VECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the handles that are aligned, tricky...
|
||||||
|
// DistVL2Dfl, check if the three beztriple points are on one line
|
||||||
|
// VecLenf, see if there's a distance between the three points
|
||||||
|
// VecLenf again, to check the angle between the handles
|
||||||
|
// finally, check if one of them is a vector handle
|
||||||
|
if((DistVL2Dfl(bezt->vec[0],bezt->vec[1],bezt->vec[2]) < 0.001) &&
|
||||||
|
(VecLenf(bezt->vec[0], bezt->vec[1]) > 0.0001) &&
|
||||||
|
(VecLenf(bezt->vec[1], bezt->vec[2]) > 0.0001) &&
|
||||||
|
(VecLenf(bezt->vec[0], bezt->vec[2]) > 0.0002) &&
|
||||||
|
(VecLenf(bezt->vec[0], bezt->vec[2]) > MAX2(VecLenf(bezt->vec[0], bezt->vec[1]), VecLenf(bezt->vec[1], bezt->vec[2]))) &&
|
||||||
|
bezt->h1 != HD_VECT && bezt->h2 != HD_VECT)
|
||||||
|
{
|
||||||
|
bezt->h1= bezt->h2= HD_ALIGN;
|
||||||
|
}
|
||||||
|
bezt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(npoints) MEM_freeN(npoints);
|
||||||
|
if(onpoints) MEM_freeN(onpoints);
|
||||||
|
}
|
||||||
|
return vfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int check_freetypefont(PackedFile * pf)
|
||||||
|
{
|
||||||
|
FT_Face face;
|
||||||
|
FT_GlyphSlot glyph;
|
||||||
|
FT_UInt glyph_index;
|
||||||
|
|
||||||
|
int success = 0;
|
||||||
|
|
||||||
|
err = FT_New_Memory_Face( library,
|
||||||
|
pf->data,
|
||||||
|
pf->size,
|
||||||
|
0,
|
||||||
|
&face );
|
||||||
|
if(err) {
|
||||||
|
success = 0;
|
||||||
|
error("This is not a valid font");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glyph_index = FT_Get_Char_Index( face, 'A' );
|
||||||
|
err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_BITMAP );
|
||||||
|
if(err) success = 0;
|
||||||
|
else {
|
||||||
|
glyph = face->glyph;
|
||||||
|
if (glyph->format == ft_glyph_format_outline ) {
|
||||||
|
success = 1;
|
||||||
|
} else {
|
||||||
|
error("Selected Font has no outline data");
|
||||||
|
success = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VFontData *BLI_vfontdata_from_freetypefont(PackedFile *pf)
|
||||||
|
{
|
||||||
|
VFontData *vfd= NULL;
|
||||||
|
int success = 0;
|
||||||
|
|
||||||
|
//init Freetype
|
||||||
|
err = FT_Init_FreeType( &library);
|
||||||
|
if(err) {
|
||||||
|
error("Failed loading Freetype font library");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
success = check_freetypefont(pf);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
vfd= objfnt_to_ftvfontdata(pf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//free Freetype
|
||||||
|
FT_Done_FreeType( library);
|
||||||
|
|
||||||
|
return vfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_FREETYPE2
|
Reference in New Issue
Block a user