diff options
Diffstat (limited to 'source/blender/blenkernel/intern/font.c')
-rw-r--r-- | source/blender/blenkernel/intern/font.c | 168 |
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, |