Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Ewering <blender@instinctive.de>2005-09-14 18:02:21 +0400
committerAlexander Ewering <blender@instinctive.de>2005-09-14 18:02:21 +0400
commit98bd4615b55bc66410764178148d91409bbf9ee1 (patch)
tree45e09576bdd916a2e1458abee75ccf7cd33c5a3a /source/blender/blenlib
parent2cb24cefb2652870a457104d4f3ce6802ef9e16c (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.h34
-rw-r--r--source/blender/blenlib/intern/freetypefont.c496
-rw-r--r--source/blender/blenlib/intern/psfont.c8
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;