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/blenkernel
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/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_font.h4
-rw-r--r--source/blender/blenkernel/BKE_global.h5
-rw-r--r--source/blender/blenkernel/intern/blender.c4
-rw-r--r--source/blender/blenkernel/intern/font.c417
4 files changed, 379 insertions, 51 deletions
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index ab0fcf6b994..fbc0d70fa22 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -56,6 +56,10 @@ int mat_to_sel(void);
void font_duplilist(struct Object *par);
int getselection(int *start, int *end);
+void chtoutf8(unsigned long c, char *o);
+void wcs2utf8s(char *dst, wchar_t *src);
+int wcsleninu8(wchar_t *src);
+int utf8towchar_(wchar_t *w, char *c);
#endif
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 5ea8b398363..2335510ac2d 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -117,6 +117,11 @@ typedef struct Global {
/* Rob's variables */
int have_quicktime;
int ui_international;
+ int charstart;
+ int charmin;
+ int charmax;
+ struct VFont *selfont;
+ struct ListBase ttfdata;
/* this variable is written to / read from FileGlobal->fileflags */
int fileflags;
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index b08b99a4010..2fca941a651 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -217,6 +217,10 @@ void initglobals(void)
#endif
clear_workob(); /* object.c */
+
+ G.charstart = 0x0000;
+ G.charmin = 0x0000;
+ G.charmax = 0xffff;
}
/***/
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index af7a94e079e..500fed8831a 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -37,6 +37,7 @@
#include <string.h>
#include <math.h>
#include <stdlib.h>
+#include <wchar.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -80,19 +81,151 @@ struct chartrans {
char dobreak;
};
-void free_vfont(struct VFont *vf)
+/* UTF-8 <-> wchar transformations */
+void
+chtoutf8(unsigned long c, char *o)
+{
+ // Variables and initialization
+ memset(o, 0, 16);
+
+ // Create the utf-8 string
+ if (c < 0x80)
+ {
+ o[0] = (char) c;
+ }
+ else if (c < 0x800)
+ {
+ o[0] = (0xC0 | (c>>6));
+ o[1] = (0x80 | (c & 0x3f));
+ }
+ else if (c < 0x10000)
+ {
+ o[0] = (0xe0 | (c >> 12));
+ o[1] = (0x80 | (c >>6 & 0x3f));
+ o[2] = (0x80 | (c & 0x3f));
+ }
+ else if (c < 0x200000)
+ {
+ o[0] = (0xf0 | (c>>18));
+ o[1] = (0x80 | (c >>12 & 0x3f));
+ o[2] = (0x80 | (c >> 6 & 0x3f));
+ o[3] = (0x80 | (c & 0x3f));
+ }
+}
+
+void
+wcs2utf8s(char *dst, wchar_t *src)
{
- int i;
+ char ch[5];
+ while(*src)
+ {
+ memset(ch, 0, 5);
+ chtoutf8(*src++, ch);
+ strcat(dst, ch);
+ }
+}
+
+int
+wcsleninu8(wchar_t *src)
+{
+ char ch[16];
+ int len = 0;
+
+ while(*src)
+ {
+ memset(ch, 0, 16);
+ chtoutf8(*src++, ch);
+ len = len + strlen(ch);
+ }
+
+ return len;
+}
+
+int
+utf8slen(char *src)
+{
+ int size = 0, index = 0;
+ unsigned char c;
+
+ c = src[index++];
+ while(c)
+ {
+ if((c & 0x80) == 0)
+ {
+ index += 0;
+ }
+ else if((c & 0xe0) == 0xe0)
+ {
+ index += 2;
+ }
+ else
+ {
+ index += 1;
+ }
+ size += 1;
+ c = src[index++];
+ }
+
+ return size;
+}
+
+int utf8towchar_(wchar_t *w, char *c)
+{
+ int len=0;
+ if(w==NULL || c==NULL) return(0);
+ //printf("%s\n",c);
+ while(*c)
+ {
+ if(*c & 0x80)
+ {
+ if(*c & 0x40)
+ {
+ if(*c & 0x20)
+ {
+ if(*c & 0x10)
+ {
+ *w=(c[0] & 0x0f)<<18 | (c[1]&0x1f)<<12 | (c[2]&0x3f)<<6 | (c[3]&0x7f);
+ c++;
+ }
+ else
+ *w=(c[0] & 0x1f)<<12 | (c[1]&0x3f)<<6 | (c[2]&0x7f);
+ c++;
+ }
+ else
+ *w=(((c[0] &0x3f)<<6) | (c[1]&0x7f));
+ c++;
+ }
+ else
+ *w=(c[0] & 0x7f);
+ }
+ else
+ *w=(c[0] & 0x7f);
+
+ c++;
+ w++;
+ len++;
+ }
+ return len;
+}
+
+/* The vfont code */
+void free_vfont(struct VFont *vf)
+{
if (vf == 0) return;
if (vf->data) {
- for (i = 0; i < MAX_VF_CHARS; i++){
- while (vf->data->nurbsbase[i].first) {
- Nurb *nu = vf->data->nurbsbase[i].first;
+ while(vf->data->characters.first)
+ {
+ VChar *che = vf->data->characters.first;
+
+ while (che->nurbsbase.first) {
+ Nurb *nu = che->nurbsbase.first;
if (nu->bezt) MEM_freeN(nu->bezt);
- BLI_freelinkN(&vf->data->nurbsbase[i], nu);
+ BLI_freelinkN(&che->nurbsbase, nu);
}
+
+ BLI_freelinkN(&vf->data->characters, che);
}
MEM_freeN(vf->data);
@@ -131,6 +264,20 @@ static PackedFile *get_builtin_packedfile(void)
static VFontData *vfont_get_data(VFont *vfont)
{
+ struct TmpFont *tmpfnt = NULL;
+ PackedFile *tpf;
+
+ // Try finding the font from font list
+ tmpfnt = G.ttfdata.first;
+
+ while(tmpfnt)
+ {
+ if(tmpfnt->vfont == vfont)
+ break;
+ tmpfnt = tmpfnt->next;
+ }
+
+ // And then set the data
if (!vfont->data) {
PackedFile *pf;
@@ -139,8 +286,34 @@ static VFontData *vfont_get_data(VFont *vfont)
} else {
if (vfont->packedfile) {
pf= vfont->packedfile;
+
+ // We need to copy a tmp font to memory unless it is already there
+ if(!tmpfnt)
+ {
+ tpf= MEM_callocN(sizeof(*tpf), "PackedFile");
+ tpf->data= MEM_mallocN(pf->size, "packFile");
+ tpf->size= pf->size;
+ memcpy(tpf->data, pf->data, pf->size);
+
+ // Add temporary packed file to globals
+ tmpfnt= (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
+ tmpfnt->pf= tpf;
+ tmpfnt->vfont= vfont;
+ BLI_addtail(&G.ttfdata, tmpfnt);
+ }
} else {
pf= newPackedFile(vfont->name);
+
+ if(!tmpfnt)
+ {
+ tpf= newPackedFile(vfont->name);
+
+ // Add temporary packed file to globals
+ tmpfnt= (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
+ tmpfnt->pf= tpf;
+ tmpfnt->vfont= vfont;
+ BLI_addtail(&G.ttfdata, tmpfnt);
+ }
}
if(!pf) {
printf("Font file doesn't exist: %s\n", vfont->name);
@@ -170,7 +343,9 @@ VFont *load_vfont(char *name)
char filename[FILE_MAXFILE];
VFont *vfont= NULL;
PackedFile *pf;
+ PackedFile *tpf = NULL;
int is_builtin;
+ struct TmpFont *tmpfnt;
if (BLI_streq(name, "<builtin>")) {
strcpy(filename, name);
@@ -184,6 +359,8 @@ VFont *load_vfont(char *name)
BLI_splitdirstring(dir, filename);
pf= newPackedFile(name);
+ tpf= newPackedFile(name);
+
is_builtin= 0;
}
@@ -196,7 +373,7 @@ VFont *load_vfont(char *name)
vfd= BLI_vfontdata_from_freetypefont(pf);
#else
vfd= BLI_vfontdata_from_psfont(pf);
-#endif
+#endif
if (vfd) {
vfont = alloc_libblock(&G.main->vfont, ID_VF, filename);
@@ -208,7 +385,18 @@ VFont *load_vfont(char *name)
if (!is_builtin && (G.fileflags & G_AUTOPACK)) {
vfont->packedfile = pf;
}
+
+ // Do not add <builtin> to temporary listbase
+ if(strcmp(filename, "<builtin>"))
+ {
+ tmpfnt= (struct TmpFont *) MEM_callocN(sizeof(struct TmpFont), "temp_font");
+ tmpfnt->pf= tpf;
+ tmpfnt->vfont= vfont;
+ BLI_addtail(&G.ttfdata, tmpfnt);
+ }
}
+
+ // Free the packed file
if (!vfont || vfont->packedfile != pf) {
freePackedFile(pf);
}
@@ -281,12 +469,13 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i
}
-static void buildchar(Curve *cu, unsigned char ascii, CharInfo *info, float ofsx, float ofsy, float rot, int charidx)
+static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float ofsx, float ofsy, float rot, int charidx)
{
BezTriple *bezt1, *bezt2;
- Nurb *nu1, *nu2;
+ Nurb *nu1 = NULL, *nu2 = NULL;
float *fp, fsize, shear, x, si, co;
- VFontData *vfd;
+ VFontData *vfd = NULL;
+ VChar *che = NULL;
int i, sel=0;
vfd= vfont_get_data(which_vfont(cu, info));
@@ -307,7 +496,20 @@ static void buildchar(Curve *cu, unsigned char ascii, CharInfo *info, float ofsx
si= (float)sin(rot);
co= (float)cos(rot);
- nu1 = vfd->nurbsbase[ascii].first;
+ // Find the correct character from the font
+ che = vfd->characters.first;
+ while(che)
+ {
+ if(che->index == character)
+ break;
+ che = che->next;
+ }
+
+ // Select the glyph data
+ if(che)
+ nu1 = che->nurbsbase.first;
+
+ // Create the character
while(nu1)
{
bezt1 = nu1->bezt;
@@ -419,7 +621,7 @@ struct chartrans *text_to_curve(Object *ob, int mode)
float *f, maxlen=0, xof, yof, xtrax, linedist, *linedata, *linedata2, *linedata3, *linedata4;
int i, slen, oldflag, j;
short cnr=0, lnr=0, wsnr= 0;
- char ascii, *mem;
+ wchar_t *mem, *tmp, ascii;
int outta;
float vecyo[3], curofs;
CharInfo *info;
@@ -429,22 +631,39 @@ struct chartrans *text_to_curve(Object *ob, int mode)
int curbox;
int selstart, selend;
SelBox *sb= NULL; /* to please gcc */
+ VChar *che;
+ float twidth;
+ int utf8len;
/* renark: do calculations including the trailing '\0' of a string
because the cursor can be at that location */
if(ob->type!=OB_FONT) return 0;
- cu= ob->data;
- mem= cu->str;
- slen = strlen(mem);
+ // Set font data
+ cu= (Curve *) ob->data;
+ vfont= cu->vfont;
+
+ if(cu->str == 0) return 0;
+ if(vfont == 0) return 0;
+
+ // Create unicode string
+ utf8len = utf8slen(cu->str);
+ tmp = mem = MEM_callocN(((utf8len + 1) * sizeof(wchar_t)), "convertedmem");
+
+ utf8towchar_(mem, cu->str);
+
+ // Count the wchar_t string length
+ slen = wcslen(mem);
if (cu->ulheight == 0.0) cu->ulheight = 0.05;
- if (cu->str==0) return 0;
if (cu->strinfo==NULL) { /* old file */
cu->strinfo = MEM_callocN((slen+1) * sizeof(CharInfo), "strinfo compat");
}
+ vfd= vfont_get_data(vfont);
+ if(!vfd) goto errcse;
+
/* calc offset and rotation of each char */
ct = chartransdata =
(struct chartrans*)MEM_callocN((slen+1)* sizeof(struct chartrans),"buildtext");
@@ -476,23 +695,65 @@ struct chartrans *text_to_curve(Object *ob, int mode)
curbox= 0;
for (i = 0 ; i<=slen ; i++) {
makebreak:
- ascii = cu->str[i];
+ // Characters in the list
+ che = vfd->characters.first;
+ ascii = mem[i];
info = &(cu->strinfo[i]);
vfont = which_vfont(cu, info);
- if (vfont==0) return 0;
+
+ // Find the character
+ while(che)
+ {
+ if(che->index == ascii)
+ break;
+ che = che->next;
+ }
+
+#ifdef WITH_FREETYPE2
+ // The character wasn't in the current curve base so load it
+ // But if the font is <builtin> then do not try loading since whole font is in the memory already
+ if(che == NULL && strcmp(vfont->name, "<builtin>"))
+ {
+ BLI_vfontchar_from_freetypefont(vfont, ascii);
+ }
+
+ // Try getting the character again from the list
+ che = vfd->characters.first;
+ while(che)
+ {
+ if(che->index == ascii)
+ break;
+ che = che->next;
+ }
+#endif
+
+
+ if (vfont==0) goto errcse;
if (vfont != oldvfont) {
vfd= vfont_get_data(vfont);
oldvfont = vfont;
}
- if (!vfd) return 0;
- if((tb->w != 0.0) && (ct->dobreak==0) && ((xof-(tb->x/cu->fsize)+vfd->width[ascii])*cu->fsize) > tb->w) {
-// fprintf(stderr, "linewidth exceeded: %c%c%c...\n", cu->str[i], cu->str[i+1], cu->str[i+2]);
- for (j=i; j && (cu->str[j] != '\n') && (cu->str[j] != '\r') && (chartransdata[j].dobreak==0); j--) {
- if (cu->str[j]==' ' || cu->str[j]=='-') {
+ if (!vfd) goto errcse;
+
+ // The character wasn't found, propably ascii = 0, then the width shall be 0 as well
+ if(!che)
+ {
+ twidth = 0;
+ }
+ else
+ {
+ twidth = che->width;
+ }
+
+ // Calculate positions
+ if((tb->w != 0.0) && (ct->dobreak==0) && ((xof-(tb->x/cu->fsize)+twidth)*cu->fsize) > tb->w) {
+// fprintf(stderr, "linewidth exceeded: %c%c%c...\n", mem[i], mem[i+1], mem[i+2]);
+ for (j=i; j && (mem[j] != '\n') && (mem[j] != '\r') && (chartransdata[j].dobreak==0); j--) {
+ if (mem[j]==' ' || mem[j]=='-') {
ct -= (i-(j-1));
cnr -= (i-(j-1));
- if (cu->str[j] == ' ') wsnr--;
- if (cu->str[j] == '-') wsnr++;
+ if (mem[j] == ' ') wsnr--;
+ if (mem[j] == '-') wsnr++;
i = j-1;
xof = ct->xof;
ct[1].dobreak = 1;
@@ -500,7 +761,7 @@ struct chartrans *text_to_curve(Object *ob, int mode)
goto makebreak;
}
if (chartransdata[j].dobreak) {
-// fprintf(stderr, "word too long: %c%c%c...\n", cu->str[j], cu->str[j+1], cu->str[j+2]);
+// fprintf(stderr, "word too long: %c%c%c...\n", mem[j], mem[j+1], mem[j+2]);
ct->dobreak= 1;
cu->strinfo[i+1].flag |= CU_WRAP;
ct -= 1;
@@ -533,7 +794,12 @@ struct chartrans *text_to_curve(Object *ob, int mode)
curbox++;
yof= cu->yof + tb->y/cu->fsize;
}
-
+
+ if(ascii == '\n' || ascii == '\r')
+ xof = cu->xof;
+ else
+ xof= cu->xof + (tb->x/cu->fsize);
+
xof= cu->xof + (tb->x/cu->fsize);
lnr++;
cnr= 0;
@@ -566,7 +832,16 @@ struct chartrans *text_to_curve(Object *ob, int mode)
wsfac = cu->wordspace;
wsnr++;
} else wsfac = 1.0;
- xof += (vfd->width[ascii]*wsfac*(1.0+(info->kern/40.0)) ) + xtrax;
+ // Set the width of the character
+ if(!che)
+ {
+ twidth = 0;
+ }
+ else
+ {
+ twidth = che->width;
+ }
+ xof += (twidth*wsfac*(1.0+(info->kern/40.0)) ) + xtrax;
if (selboxes && (i>=selstart) && (i<=selend)) sb->w = (xof*cu->fsize) - sb->w;
}
@@ -577,8 +852,9 @@ struct chartrans *text_to_curve(Object *ob, int mode)
cu->lines= 1;
ct= chartransdata;
- for (i= 0; i<=slen; i++, mem++, ct++) {
- ascii = *mem;
+ tmp = mem;
+ for (i= 0; i<=slen; i++, tmp++, ct++) {
+ ascii = *tmp;
if(ascii== '\n' || ascii== '\r' || ct->dobreak) cu->lines++;
}
@@ -608,9 +884,9 @@ struct chartrans *text_to_curve(Object *ob, int mode)
if(linedata2[i]>1)
linedata[i]= (linedata3[i]-linedata[i])/(linedata2[i]-1);
for (i=0; i<=slen; i++) {
- for (j=i; (cu->str[j]) && (cu->str[j]!='\n') &&
- (cu->str[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
-// if ((cu->str[j]!='\r') && (cu->str[j]!='\n') && (cu->str[j])) {
+ for (j=i; (mem[j]) && (mem[j]!='\n') &&
+ (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
+// if ((mem[j]!='\r') && (mem[j]!='\n') && (mem[j])) {
ct->xof+= ct->charnr*linedata[ct->linenr];
// }
ct++;
@@ -619,14 +895,14 @@ struct chartrans *text_to_curve(Object *ob, int mode)
(cu->tb[0].w != 0.0)) {
curofs= 0;
for (i=0; i<=slen; i++) {
- for (j=i; (cu->str[j]) && (cu->str[j]!='\n') &&
- (cu->str[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
- if ((cu->str[j]!='\r') && (cu->str[j]!='\n') &&
+ for (j=i; (mem[j]) && (mem[j]!='\n') &&
+ (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
+ if ((mem[j]!='\r') && (mem[j]!='\n') &&
((chartransdata[j].dobreak!=0))) {
- if (cu->str[i]==' ') curofs += (linedata3[ct->linenr]-linedata[ct->linenr])/linedata4[ct->linenr];
+ if (mem[i]==' ') curofs += (linedata3[ct->linenr]-linedata[ct->linenr])/linedata4[ct->linenr];
ct->xof+= curofs;
}
- if (cu->str[i]=='\n' || cu->str[i]=='\r' || chartransdata[i].dobreak) curofs= 0;
+ if (mem[i]=='\n' || mem[i]=='\r' || chartransdata[i].dobreak) curofs= 0;
ct++;
}
}
@@ -685,9 +961,28 @@ struct chartrans *text_to_curve(Object *ob, int mode)
for (i=0; i<=slen; i++, ct++) {
/* rotate around centre character */
- ascii = cu->str[i];
- dtime= distfac*0.35f*vfd->width[ascii]; /* why not 0.5? */
- dtime= distfac*0.0f*vfd->width[ascii]; /* why not 0.5? */
+ ascii = mem[i];
+
+ // Find the character
+ che = vfd->characters.first;
+ while(che)
+ {
+ if(che->index == ascii)
+ break;
+ che = che->next;
+ }
+
+ if(che)
+ {
+ twidth = che->width;
+ }
+ else
+ {
+ twidth = 0;
+ }
+
+ dtime= distfac*0.35f*twidth; /* why not 0.5? */
+ dtime= distfac*0.0f*twidth; /* why not 0.5? */
ctime= timeofs + distfac*( ct->xof - minx);
CLAMP(ctime, 0.0, 1.0);
@@ -782,32 +1077,47 @@ struct chartrans *text_to_curve(Object *ob, int mode)
if (mode == FO_SELCHANGE) {
MEM_freeN(chartransdata);
+ MEM_freeN(mem);
return NULL;
}
if(mode==0) {
/* make nurbdata */
-
+ unsigned long cha;
+
freeNurblist(&cu->nurb);
ct= chartransdata;
if (cu->sepchar==0) {
for (i= 0; i<slen; i++) {
- ascii = cu->str[i];
+ cha = (unsigned long) mem[i];
info = &(cu->strinfo[i]);
if (info->mat_nr > (ob->totcol)) {
printf("Error: Illegal material index (%d) in text object, setting to 0\n", info->mat_nr);
info->mat_nr = 0;
}
- buildchar(cu, ascii, info, ct->xof, ct->yof, ct->rot, i);
- if ((info->flag & CU_UNDERLINE) && (ascii != '\n') && (ascii != '\r')) {
+ // We do not want to see any character for \n or \r
+ if(cha != '\n' && cha != '\r')
+ buildchar(cu, cha, info, ct->xof, ct->yof, ct->rot, i);
+ if ((info->flag & CU_UNDERLINE) && (cha != '\n') && (cha != '\r')) {
uloverlap = 0;
- if ( (i<(slen-1)) && (cu->str[i+1] != '\n') && (cu->str[i+1] != '\r') &&
- ((cu->str[i+1] != ' ') || (cu->strinfo[i+1].flag & CU_UNDERLINE)) && ((cu->strinfo[i+1].flag & CU_WRAP)==0)
+ if ( (i<(slen-1)) && (mem[i+1] != '\n') && (mem[i+1] != '\r') &&
+ ((mem[i+1] != ' ') || (cu->strinfo[i+1].flag & CU_UNDERLINE)) && ((cu->strinfo[i+1].flag & CU_WRAP)==0)
) {
uloverlap = xtrax + 0.1;
}
- ulwidth = cu->fsize * ((vfd->width[ascii]* (1.0+(info->kern/40.0)))+uloverlap);
+ // Find the character, the characters has to be in the memory already
+ // since character checking has been done earlier already.
+ che = vfd->characters.first;
+ while(che)
+ {
+ if(che->index == cha)
+ break;
+ che = che->next;
+ }
+
+ if(!che) twidth =0; else twidth=che->width;
+ ulwidth = cu->fsize * ((twidth* (1.0+(info->kern/40.0)))+uloverlap);
build_underline(cu, ct->xof*cu->fsize, ct->yof*cu->fsize + (cu->ulpos-0.05)*cu->fsize,
ct->xof*cu->fsize + ulwidth,
ct->yof*cu->fsize + (cu->ulpos-0.05)*cu->fsize - cu->ulheight*cu->fsize,
@@ -819,11 +1129,11 @@ struct chartrans *text_to_curve(Object *ob, int mode)
else {
outta = 0;
for (i= 0; (i<slen) && (outta==0); i++) {
- ascii = cu->str[i];
+ ascii = mem[i];
info = &(cu->strinfo[i]);
if (cu->sepchar == (i+1)) {
- cu->str[0] = ascii;
- cu->str[1] = 0;
+ mem[0] = ascii;
+ mem[1] = 0;
cu->strinfo[0]= *info;
cu->pos = 1;
cu->len = 1;
@@ -841,9 +1151,14 @@ struct chartrans *text_to_curve(Object *ob, int mode)
}
if(mode==FO_DUPLI) {
+ MEM_freeN(mem);
return chartransdata;
}
+errcse:
+ if(mem)
+ MEM_freeN(mem);
+
MEM_freeN(chartransdata);
return 0;
}