diff options
author | Alexander Ewering <blender@instinctive.de> | 2005-09-14 18:02:21 +0400 |
---|---|---|
committer | Alexander Ewering <blender@instinctive.de> | 2005-09-14 18:02:21 +0400 |
commit | 98bd4615b55bc66410764178148d91409bbf9ee1 (patch) | |
tree | 45e09576bdd916a2e1458abee75ccf7cd33c5a3a /source/blender/blenlib | |
parent | 2cb24cefb2652870a457104d4f3ce6802ef9e16c (diff) |
On behalf of Mika Saari, the famous Unicode Font support!
Further information is available here:
http://wiki.blender.org/bin/view.pl/Blenderdev/UnicodeFont3D
Shortlist of features:
- Unicode character support for Font3D
- UI to select characters from Unicode character list
- UI to select Unicode table areas
- Optimized character loading (Load only those characters which are used
in font object)
Please test extensively if it breaks anything, try also loading/saving
files, packing fonts, etc.
The official text regression file in the regression suite should be a
good start.
Thanks to mikasaari for this very useful addition!
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_vfontdata.h | 34 | ||||
-rw-r--r-- | source/blender/blenlib/intern/freetypefont.c | 496 | ||||
-rw-r--r-- | source/blender/blenlib/intern/psfont.c | 8 |
3 files changed, 350 insertions, 188 deletions
diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h index 516bfb15f3f..1ebcd80b22b 100644 --- a/source/blender/blenlib/BLI_vfontdata.h +++ b/source/blender/blenlib/BLI_vfontdata.h @@ -41,17 +41,36 @@ #include "DNA_listBase.h" struct PackedFile; +struct VFont; #define MAX_VF_CHARS 256 typedef struct VFontData { - ListBase nurbsbase[MAX_VF_CHARS]; - float resol[MAX_VF_CHARS]; - float width[MAX_VF_CHARS]; - float *points[MAX_VF_CHARS]; - char name[128]; + ListBase characters; + // ListBase nurbsbase[MAX_VF_CHARS]; + // float resol[MAX_VF_CHARS]; + // float width[MAX_VF_CHARS]; + // float *points[MAX_VF_CHARS]; + char name[128]; } VFontData; +typedef struct VChar { + struct VChar *next, *prev; + ListBase nurbsbase; + unsigned long index; + float resol; + float width; + float *points; +} VChar; + +struct TmpFont +{ + struct TmpFont *next, *prev; + struct PackedFile *pf; + struct VFont *vfont; +}; + + /** * Construct a new VFontData structure from * PostScript font data in a PackedFile. @@ -75,5 +94,10 @@ BLI_vfontdata_from_psfont( VFontData* BLI_vfontdata_from_freetypefont( struct PackedFile *pf); + + int +BLI_vfontchar_from_freetypefont( + struct VFont *vfont, unsigned long character); + #endif diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 5e1300e9cdf..f20be8ce828 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -54,8 +54,10 @@ #include "BIF_toolbox.h" +#include "BKE_global.h" #include "BKE_utildefines.h" +#include "DNA_vfont_types.h" #include "DNA_packedFile_types.h" #include "DNA_curve_types.h" @@ -67,18 +69,265 @@ static FT_Library library; static FT_Error err; -static VFontData *objfnt_to_ftvfontdata(PackedFile * pf) +void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) { // Blender - VFontData *vfd; struct Nurb *nu; + struct VChar *che; struct BezTriple *bezt; + + // Freetype2 + FT_GlyphSlot glyph; + FT_UInt glyph_index; + FT_Outline ftoutline; + const char *fontname; + float scale, height; + float dx, dy; + int i,j,k,l,m=0; + + // Variables + int *npoints; + int *onpoints; + + // adjust font size + height= ((double) face->bbox.yMax - (double) face->bbox.yMin); + if(height != 0.0) + scale = 1.0 / height; + else + scale = 1.0 / 1000.0; + + // + // Generate the character 3D data + // + // Get the FT Glyph index and load the Glyph + glyph_index= FT_Get_Char_Index(face, charcode); + err= FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP); + + // If loading succeeded, convert the FT glyph to the internal format + if(!err) + { + // First we create entry for the new character to the character list + che= (VChar *) MEM_callocN(sizeof(struct VChar), "objfnt_char"); + BLI_addtail(&vfd->characters, che); + + // Take some data for modifying purposes + glyph= face->glyph; + ftoutline= glyph->outline; + + // Set the width and character code + che->index= charcode; + che->width= glyph->advance.x * scale; + + // Start converting the FT data + 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(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]++; + } + } + + //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(&che->nurbsbase, 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] = dx; + bezt->vec[1][1] = dy; + + //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) { + 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); +} + +int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) +{ // Freetype2 - FT_Face face; - FT_GlyphSlot glyph; - FT_UInt glyph_index; - FT_Outline ftoutline; + FT_Face face; + FT_UInt glyph_index; + struct TmpFont *tf; + + // Find the correct FreeType font + tf= G.ttfdata.first; + while(tf) + { + if(tf->vfont == vfont) + break; + tf= tf->next; + } + + // What, no font found. Something strange here + if(!tf) return FALSE; + + // Load the font to memory + if(tf->pf) + { + err= FT_New_Memory_Face( library, + tf->pf->data, + tf->pf->size, + 0, + &face); + } + else + err= TRUE; + + // Read the char + freetypechar_to_vchar(face, charcode, vfont->data); + + // And everything went ok + return TRUE; +} + + +static VFontData *objfnt_to_ftvfontdata(PackedFile * pf) +{ + // Variables + FT_Face face; + FT_ULong charcode = 0, lcode; + FT_UInt glyph_index; + FT_UInt temp; + const char *fontname; + VFontData *vfd; + /* FT_CharMap found = 0; FT_CharMap charmap; @@ -86,10 +335,6 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile * pf) FT_UShort my_encoding_id = TT_MS_ID_UNICODE_CS; int n; */ - const char *fontname; - float scale, height; - float dx, dy; - int i, j, k, l, m =0; // load the freetype font err = FT_New_Memory_Face( library, @@ -125,187 +370,52 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile * pf) fontname = FT_Get_Postscript_Name(face); strcpy(vfd->name, (fontname == NULL) ? "Fontname not available" : fontname); - // adjust font size - height = ((double) face->bbox.yMax - (double) face->bbox.yMin); - - if(height != 0.0) - scale = 1.0 / height; - else - scale = 1.0 / 1000.0; + // Extract the first 256 character from TTF + lcode= charcode= FT_Get_First_Char(face, &glyph_index); - // extract generic ascii character range - for(i = myMIN_ASCII; i <= myMAX_ASCII; i++) { - int *npoints = NULL; //total points of each contour - int *onpoints = NULL; //num points on curve + // No charmap found from the ttf so we need to figure it out + if(glyph_index == 0) + { + FT_CharMap found = 0; + FT_CharMap charmap; + int n; - glyph_index = FT_Get_Char_Index( face, i ); - err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP); - - if(!err) { - glyph = face->glyph; - ftoutline = glyph->outline; - - vfd->width[i] = glyph->advance.x* scale; - - 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(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]++; - } + for ( n = 0; n < face->num_charmaps; n++ ) + { + charmap = face->charmaps[n]; + if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) + { + found = charmap; + break; } + } - //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] = dx; - bezt->vec[1][1] = dy; - - //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++; - } + err = FT_Set_Charmap( face, found ); - //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; - } - } + if( err ) + return NULL; - //midpoint (on-curve point) - bezt->vec[1][0] = ftoutline.points[l].x* scale; - bezt->vec[1][1] = ftoutline.points[l].y* scale; + lcode= charcode= FT_Get_First_Char(face, &glyph_index); + } - //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) { - 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; - } - } + // Load characters + while(charcode < 256) + { + // Generate the font data + freetypechar_to_vchar(face, charcode, vfd); - // 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++; - } - } - } - } + // Next glyph + charcode = FT_Get_Next_Char(face, charcode, &glyph_index); - if(npoints) MEM_freeN(npoints); - if(onpoints) MEM_freeN(onpoints); + // Check that we won't start infinite loop + if(charcode <= lcode) + break; + lcode = charcode; } - return vfd; + + err = FT_Set_Charmap( face, FT_ENCODING_UNICODE ); + + return vfd; } @@ -393,6 +503,30 @@ VFontData *BLI_vfontdata_from_freetypefont(PackedFile *pf) return vfd; } +int BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character) +{ + int success = FALSE; + + if(!vfont) return FALSE; + + // Init Freetype + err = FT_Init_FreeType(&library); + if(err) { + error("Failed to load the Freetype font library"); + return 0; + } + + // Load the character + success = objchr_to_ftvfontdata(vfont, character); + if(success == FALSE) return FALSE; + + // Free Freetype + FT_Done_FreeType(library); + + // Ahh everything ok + return TRUE; +} + #endif // WITH_FREETYPE2 diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c index f7fbf7e3d16..2fccf09805b 100644 --- a/source/blender/blenlib/intern/psfont.c +++ b/source/blender/blenlib/intern/psfont.c @@ -1956,6 +1956,7 @@ static VFontData *objfnt_to_vfontdata(objfnt *fnt) struct Nurb *nu; struct BezTriple *bezt, *bez2; float scale, dx, dy; + struct VChar *che; if (!fnt || (fnt->type!=SP_TYPE)) { return NULL; @@ -1967,7 +1968,10 @@ static VFontData *objfnt_to_vfontdata(objfnt *fnt) for (i = 0; i < MAX_VF_CHARS; i++) { cd = getchardesc(fnt, i); if (cd && cd->data && cd->datalen) { - vfd->width[i] = scale * cd->movex; + che = (VChar *) MEM_callocN(sizeof(VChar), "objfnt_char"); + BLI_addtail(&vfd->characters, che); + che->index = i; + che->width = scale * cd->movex; _data = data = cd->data; @@ -2015,7 +2019,7 @@ static VFontData *objfnt_to_vfontdata(objfnt *fnt) nu = (Nurb*)MEM_callocN(sizeof(struct Nurb),"objfnt_nurb"); bezt = (BezTriple*)MEM_callocN((count)* sizeof(BezTriple),"objfnt_bezt") ; if (nu != 0 && bezt != 0) { - BLI_addtail(&vfd->nurbsbase[i], nu); + BLI_addtail(&che->nurbsbase, nu); nu->type= CU_BEZIER+CU_2D; nu->pntsu = count; nu->resolu= 8; |