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:
Diffstat (limited to 'source/blender/blenkernel/intern/font.c')
-rw-r--r--source/blender/blenkernel/intern/font.c168
1 files changed, 86 insertions, 82 deletions
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 36bb031744e..a99f2599f66 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -1,4 +1,4 @@
-/* font.c
+/* font.c
*
*
* $Id$
@@ -34,10 +34,7 @@
#include <math.h>
#include <stdlib.h>
#include <wchar.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include <wctype.h>
#include "MEM_guardedalloc.h"
@@ -47,8 +44,6 @@
#include "DNA_packedFile_types.h"
#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_vfont_types.h"
#include "DNA_scene_types.h"
@@ -60,7 +55,6 @@
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_screen.h"
#include "BKE_anim.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
@@ -163,7 +157,7 @@ According to RFC 3629 "UTF-8, a transformation format of ISO 10646"
(http://tools.ietf.org/html/rfc3629), the valid UTF-8 encoding are:
Char. number range | UTF-8 octet sequence
- (hexadecimal) | (binary)
+ (hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
@@ -205,7 +199,7 @@ int utf8towchar(wchar_t *w, char *c)
*w = '?';
}
} else
- *w=(c[0] & 0x7f);
+ *w=(c[0] & 0x7f);
c++;
w++;
@@ -433,12 +427,12 @@ VFont *load_vfont(char *name)
static VFont *which_vfont(Curve *cu, CharInfo *info)
{
- switch(info->flag & CU_STYLE) {
- case CU_BOLD:
+ switch(info->flag & (CU_CHINFO_BOLD|CU_CHINFO_ITALIC)) {
+ case CU_CHINFO_BOLD:
if (cu->vfontb) return(cu->vfontb); else return(cu->vfont);
- case CU_ITALIC:
+ case CU_CHINFO_ITALIC:
if (cu->vfonti) return(cu->vfonti); else return(cu->vfont);
- case (CU_BOLD|CU_ITALIC):
+ case (CU_CHINFO_BOLD|CU_CHINFO_ITALIC):
if (cu->vfontbi) return(cu->vfontbi); else return(cu->vfont);
default:
return(cu->vfont);
@@ -456,6 +450,17 @@ VFont *get_builtin_font(void)
return load_vfont("<builtin>");
}
+static VChar *find_vfont_char(VFontData *vfd, intptr_t character)
+{
+ VChar *che= NULL;
+
+ for(che = vfd->characters.first; che; che = che->next) {
+ if(che->index == character)
+ break;
+ }
+ return che; /* NULL if not found */
+}
+
static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, int charidx, short mat_nr)
{
Nurb *nu2;
@@ -473,7 +478,7 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i
nu2->pntsv = 1;
nu2->orderu = 4;
nu2->orderv = 1;
- nu2->flagu = CU_CYCLIC;
+ nu2->flagu = CU_NURB_CYCLIC;
bp = (BPoint*)MEM_callocN(4 * sizeof(BPoint),"underline_bp");
if (bp == 0){
@@ -530,14 +535,7 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float
si= (float)sin(rot);
co= (float)cos(rot);
- // Find the correct character from the font
- che = vfd->characters.first;
- while(che)
- {
- if(che->index == character)
- break;
- che = che->next;
- }
+ che= find_vfont_char(vfd, character);
// Select the glyph data
if(che)
@@ -604,9 +602,23 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float
}
bezt2 = nu2->bezt;
+ if(info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
+ const float sca= cu->smallcaps_scale;
+ for (i= nu2->pntsu; i > 0; i--) {
+ fp= bezt2->vec[0];
+ fp[0] *= sca;
+ fp[1] *= sca;
+ fp[3] *= sca;
+ fp[4] *= sca;
+ fp[6] *= sca;
+ fp[7] *= sca;
+ bezt2++;
+ }
+ }
+ bezt2 = nu2->bezt;
+
for (i= nu2->pntsu; i > 0; i--) {
fp= bezt2->vec[0];
-
fp[0]= (fp[0]+ofsx)*fsize;
fp[1]= (fp[1]+ofsy)*fsize;
fp[3]= (fp[3]+ofsx)*fsize;
@@ -642,6 +654,20 @@ int BKE_font_getselection(Object *ob, int *start, int *end)
}
}
+static float char_width(Curve *cu, VChar *che, CharInfo *info)
+{
+ // The character wasn't found, propably ascii = 0, then the width shall be 0 as well
+ if(che == NULL) {
+ return 0.0f;
+ }
+ else if(info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
+ return che->width * cu->smallcaps_scale;
+ }
+ else {
+ return che->width;
+ }
+}
+
struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
{
VFont *vfont, *oldvfont;
@@ -723,7 +749,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
oldvfont = NULL;
- for (i=0; i<slen; i++) custrinfo[i].flag &= ~CU_WRAP;
+ for (i=0; i<slen; i++) custrinfo[i].flag &= ~(CU_CHINFO_WRAP|CU_CHINFO_SMALLCAPS_CHECK);
if (cu->selboxes) MEM_freeN(cu->selboxes);
cu->selboxes = NULL;
@@ -736,18 +762,21 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
makebreak:
// Characters in the list
che = vfd->characters.first;
- ascii = mem[i];
info = &(custrinfo[i]);
+ ascii = mem[i];
+ if(info->flag & CU_CHINFO_SMALLCAPS) {
+ ascii = towupper(ascii);
+ if(mem[i] != ascii) {
+ mem[i]= ascii;
+ info->flag |= CU_CHINFO_SMALLCAPS_CHECK;
+ }
+ }
+
vfont = which_vfont(cu, info);
if(vfont==NULL) break;
-
- // Find the character
- while(che) {
- if(che->index == ascii)
- break;
- che = che->next;
- }
+
+ che= find_vfont_char(vfd, ascii);
/*
* The character wasn't in the current curve base so load it
@@ -759,12 +788,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
}
/* Try getting the character again from the list */
- che = vfd->characters.first;
- while(che) {
- if(che->index == ascii)
- break;
- che = che->next;
- }
+ che= find_vfont_char(vfd, ascii);
/* No VFont found */
if (vfont==0) {
@@ -787,11 +811,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
return 0;
}
- // The character wasn't found, propably ascii = 0, then the width shall be 0 as well
- if(!che)
- twidth = 0;
- else
- twidth = che->width;
+ twidth = char_width(cu, che, info);
// Calculate positions
if((tb->w != 0.0) && (ct->dobreak==0) && ((xof-(tb->x/cu->fsize)+twidth)*cu->fsize) > tb->w) {
@@ -805,13 +825,13 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
i = j-1;
xof = ct->xof;
ct[1].dobreak = 1;
- custrinfo[i+1].flag |= CU_WRAP;
+ custrinfo[i+1].flag |= CU_CHINFO_WRAP;
goto makebreak;
}
if (chartransdata[j].dobreak) {
// fprintf(stderr, "word too long: %c%c%c...\n", mem[j], mem[j+1], mem[j+2]);
ct->dobreak= 1;
- custrinfo[i+1].flag |= CU_WRAP;
+ custrinfo[i+1].flag |= CU_CHINFO_WRAP;
ct -= 1;
cnr -= 1;
i--;
@@ -835,8 +855,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
linedata4[lnr]= wsnr;
if ( (tb->h != 0.0) &&
- ((-(yof-(tb->y/cu->fsize))) > ((tb->h/cu->fsize)-(linedist*cu->fsize))) &&
- (cu->totbox > (curbox+1)) ) {
+ ((-(yof-(tb->y/cu->fsize))) > ((tb->h/cu->fsize)-(linedist*cu->fsize))) &&
+ (cu->totbox > (curbox+1)) ) {
maxlen= 0;
tb++;
curbox++;
@@ -888,10 +908,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
else wsfac = 1.0;
// Set the width of the character
- if(!che)
- twidth = 0;
- else
- twidth = che->width;
+ twidth = char_width(cu, che, info);
xof += (twidth*wsfac*(1.0+(info->kern/40.0)) ) + xtrax;
@@ -930,13 +947,13 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
ct++;
}
} else if((cu->spacemode==CU_FLUSH) &&
- (cu->tb[0].w != 0.0)) {
+ (cu->tb[0].w != 0.0)) {
for(i=0;i<lnr;i++)
if(linedata2[i]>1)
linedata[i]= (linedata3[i]-linedata[i])/(linedata2[i]-1);
for (i=0; i<=slen; i++) {
for (j=i; (mem[j]) && (mem[j]!='\n') &&
- (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
+ (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];
// }
@@ -947,10 +964,10 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
float curofs= 0.0f;
for (i=0; i<=slen; i++) {
for (j=i; (mem[j]) && (mem[j]!='\n') &&
- (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
+ (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
if ((mem[j]!='\r') && (mem[j]!='\n') &&
- ((chartransdata[j].dobreak!=0))) {
- if (mem[i]==' ') curofs += (linedata3[ct->linenr]-linedata[ct->linenr])/linedata4[ct->linenr];
+ ((chartransdata[j].dobreak!=0))) {
+ if (mem[i]==' ') curofs += (linedata3[ct->linenr]-linedata[ct->linenr])/linedata4[ct->linenr];
ct->xof+= curofs;
}
if (mem[i]=='\n' || mem[i]=='\r' || chartransdata[i].dobreak) curofs= 0;
@@ -960,7 +977,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
}
/* TEXT ON CURVE */
- if(cu->textoncurve) {
+ /* Note: Only OB_CURVE objects could have a path */
+ if(cu->textoncurve && cu->textoncurve->type==OB_CURVE) {
Curve *cucu= cu->textoncurve->data;
int oldflag= cucu->flag;
@@ -1021,19 +1039,10 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
/* rotate around center character */
ascii = mem[i];
-
- // Find the character
- che = vfd->characters.first;
- while(che) {
- if(che->index == ascii)
- break;
- che = che->next;
- }
+
+ che= find_vfont_char(vfd, ascii);
- if(che)
- twidth = che->width;
- else
- twidth = 0;
+ twidth = char_width(cu, che, info);
dtime= distfac*0.35f*twidth; /* why not 0.5? */
dtime= distfac*0.5f*twidth; /* why not 0.5? */
@@ -1043,8 +1052,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
/* calc the right loc AND the right rot separately */
/* vec, tvec need 4 items */
- where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL);
- where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL);
+ where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL, NULL);
+ where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL, NULL);
mul_v3_fl(vec, sizefac);
@@ -1157,24 +1166,19 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
if(cha != '\n' && cha != '\r')
buildchar(cu, cha, info, ct->xof, ct->yof, ct->rot, i);
- if ((info->flag & CU_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) {
+ if ((info->flag & CU_CHINFO_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) {
float ulwidth, uloverlap= 0.0f;
if ( (i<(slen-1)) && (mem[i+1] != '\n') && (mem[i+1] != '\r') &&
- ((mem[i+1] != ' ') || (custrinfo[i+1].flag & CU_UNDERLINE)) && ((custrinfo[i+1].flag & CU_WRAP)==0)
+ ((mem[i+1] != ' ') || (custrinfo[i+1].flag & CU_CHINFO_UNDERLINE)) && ((custrinfo[i+1].flag & CU_CHINFO_WRAP)==0)
) {
uloverlap = xtrax + 0.1;
}
// 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;
+ che= find_vfont_char(vfd, cha);
+
+ twidth = char_width(cu, che, info);
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,