Logo Search packages:      
Sourcecode: blender version File versions

editfont.c

/**
 * $Id: editfont.c,v 1.16 2004/12/22 19:21:45 ton Exp $
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */

#include <string.h>
#include <fcntl.h>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifndef WIN32 
#include <unistd.h>
#else
#include <io.h>
#endif

#include "MEM_guardedalloc.h"

#include "BLI_blenlib.h"

#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_vfont_types.h"
#include "DNA_scene_types.h"
#include "DNA_text_types.h"

#include "BKE_displist.h"
#include "BKE_font.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_utildefines.h"

#include "BIF_editfont.h"
#include "BIF_editmode_undo.h"
#include "BIF_toolbox.h"
#include "BIF_space.h"
#include "BIF_mywindow.h"

#include "BDR_editobject.h"

#include "mydevice.h"

#include "blendef.h"

#define MAXTEXT   1000

int textediting=0;

static char findaccent(char char1, char code)
{
      char new= 0;
      
      if(char1=='a') {
            if(code=='`') new= 224;
            else if(code==39) new= 225;
            else if(code=='^') new= 226;
            else if(code=='~') new= 227;
            else if(code=='"') new= 228;
            else if(code=='o') new= 229;
            else if(code=='e') new= 230;
            else if(code=='-') new= 170;
      }
      else if(char1=='c') {
            if(code==',') new= 231;
            if(code=='|') new= 162;
      }
      else if(char1=='e') {
            if(code=='`') new= 232;
            else if(code==39) new= 233;
            else if(code=='^') new= 234;
            else if(code=='"') new= 235;
      }
      else if(char1=='i') {
            if(code=='`') new= 236;
            else if(code==39) new= 237;
            else if(code=='^') new= 238;
            else if(code=='"') new= 239;
      }
      else if(char1=='n') {
            if(code=='~') new= 241;
      }
      else if(char1=='o') {
            if(code=='`') new= 242;
            else if(code==39) new= 243;
            else if(code=='^') new= 244;
            else if(code=='~') new= 245;
            else if(code=='"') new= 246;
            else if(code=='/') new= 248;
            else if(code=='-') new= 186;
            else if(code=='e') new= 143;
      }
      else if(char1=='s') {
            if(code=='s') new= 167;
      }
      else if(char1=='u') {
            if(code=='`') new= 249;
            else if(code==39) new= 250;
            else if(code=='^') new= 251;
            else if(code=='"') new= 252;
      }
      else if(char1=='y') {
            if(code==39) new= 253;
            else if(code=='"') new= 255;
      }
      else if(char1=='A') {
            if(code=='`') new= 192;
            else if(code==39) new= 193;
            else if(code=='^') new= 194;
            else if(code=='~') new= 195;
            else if(code=='"') new= 196;
            else if(code=='o') new= 197;
            else if(code=='e') new= 198;
      }
      else if(char1=='C') {
            if(code==',') new= 199;
      }
      else if(char1=='E') {
            if(code=='`') new= 200;
            else if(code==39) new= 201;
            else if(code=='^') new= 202;
            else if(code=='"') new= 203;
      }
      else if(char1=='I') {
            if(code=='`') new= 204;
            else if(code==39) new= 205;
            else if(code=='^') new= 206;
            else if(code=='"') new= 207;
      }
      else if(char1=='N') {
            if(code=='~') new= 209;
      }
      else if(char1=='O') {
            if(code=='`') new= 210;
            else if(code==39) new= 211;
            else if(code=='^') new= 212;
            else if(code=='~') new= 213;
            else if(code=='"') new= 214;
            else if(code=='/') new= 216;
            else if(code=='e') new= 141;
      }
      else if(char1=='U') {
            if(code=='`') new= 217;
            else if(code==39) new= 218;
            else if(code=='^') new= 219;
            else if(code=='"') new= 220;
      }
      else if(char1=='Y') {
            if(code==39) new= 221;
      }
      else if(char1=='1') {
            if(code=='4') new= 188;
            if(code=='2') new= 189;
      }
      else if(char1=='3') {
            if(code=='4') new= 190;
      }
      else if(char1==':') {
            if(code=='-') new= 247;
      }
      else if(char1=='-') {
            if(code==':') new= 247;
            if(code=='|') new= 135;
            if(code=='+') new= 177;
      }
      else if(char1=='|') {
            if(code=='-') new= 135;
            if(code=='=') new= 136;
      }
      else if(char1=='=') {
            if(code=='|') new= 136;
      }
      else if(char1=='+') {
            if(code=='-') new= 177;
      }
      
      if(new) return new;
      else return char1;
}


static char *textbuf=NULL;
static char *oldstr=NULL;

static int insert_into_textbuf(Curve *cu, char c)
{
      if (cu->len<MAXTEXT-1) {
            int x;

            for(x= cu->len; x>cu->pos; x--) textbuf[x]= textbuf[x-1];
            textbuf[cu->pos]= c;
                              
            cu->pos++;
            cu->len++;
            textbuf[cu->len]='\0';

            return 1;
      } else {
            return 0;
      }
}


static VFont *get_builtin_font(void)
{
      VFont *vf;
      
      for (vf= G.main->vfont.first; vf; vf= vf->id.next)
            if (BLI_streq(vf->name, "<builtin>"))
                  return vf;
      
      return load_vfont("<builtin>");
}


void txt_export_to_object(struct Text *text)
{
      ID *id;
      Curve *cu;
      struct TextLine *tmp;
      int nchars = 0;
//    char sdir[FILE_MAXDIR];
//    char sfile[FILE_MAXFILE];

      if(!text) return;

      id = (ID *)text;

      if (G.obedit && G.obedit->type==OB_FONT) return;
      check_editmode(OB_FONT);
      
      add_object(OB_FONT);

      base_init_from_view3d(BASACT, G.vd);
      G.obedit= BASACT->object;
      where_is_object(G.obedit);

      cu= G.obedit->data;

/*    
//          renames object, careful with long filenames.

      if (text->name) {
      //ID *find_id(char *type, char *name)     
            BLI_split_dirfile(text->name, sdir, sfile);
//          rename_id((ID *)G.obedit, sfile);
            rename_id((ID *)cu, sfile);
            id->us++;
      }
*/    
      cu->vfont= get_builtin_font();
      cu->vfont->id.us++;

      tmp= text->lines.first;
      while(cu->len<MAXTEXT && tmp) {
            nchars += strlen(tmp->line) + 1;
            tmp = tmp->next;
      }

      if(cu->str) MEM_freeN(cu->str);

      cu->str= MEM_mallocN(nchars+4, "str");
      
      tmp= text->lines.first;
      strcpy(cu->str, tmp->line);
      cu->len= strlen(tmp->line);
      cu->pos= cu->len;

      tmp= tmp->next;

      while(cu->len<MAXTEXT && tmp) {
            strcat(cu->str, "\n");
            strcat(cu->str, tmp->line);
            cu->len+= strlen(tmp->line) + 1;
            cu->pos= cu->len;
            tmp= tmp->next;
      }

      make_editText();
      exit_editmode(1);

      allqueue(REDRAWVIEW3D, 0);
}


void do_textedit(unsigned short event, short val, char _ascii)
{
      Curve *cu;
      static int accentcode= 0;
      int x, doit=0, cursmove=0;
      int ascii = _ascii;

      cu= G.obedit->data;

      if(ascii) {
      
            /* handle case like TAB (TAB==9) */
            if( (ascii > 31 && ascii < 254 && ascii != 127) || (ascii==13) || (ascii==10) || (ascii==8)) {
      
                  if(accentcode) {
                        if(cu->pos>0) textbuf[cu->pos-1]= findaccent(textbuf[cu->pos-1], ascii);
                        accentcode= 0;
                  }
                  else if(cu->len<MAXTEXT-1) {
                        if(G.qual & LR_ALTKEY ) {
                        
                              /* might become obsolete, apple has default values for this, other OS's too? */
                        
                              if(ascii=='t') ascii= 137;
                              else if(ascii=='c') ascii= 169;
                              else if(ascii=='f') ascii= 164;
                              else if(ascii=='g') ascii= 176;
                              else if(ascii=='l') ascii= 163;
                              else if(ascii=='r') ascii= 174;
                              else if(ascii=='s') ascii= 223;
                              else if(ascii=='v') ascii= 1001;
                              else if(ascii=='y') ascii= 165;
                              else if(ascii=='.') ascii= 138;
                              else if(ascii=='1') ascii= 185;
                              else if(ascii=='2') ascii= 178;
                              else if(ascii=='3') ascii= 179;
                              else if(ascii=='%') ascii= 139;
                              else if(ascii=='?') ascii= 191;
                              else if(ascii=='!') ascii= 161;
                              else if(ascii=='x') ascii= 215;
                              else if(ascii=='>') ascii= 187;
                              else if(ascii=='<') ascii= 171;
                        }
                        
                        if(ascii==1001) {
                              int file, filelen;
                              char *strp;
                              
/* this should be solved by clipboard support */
#ifdef __WIN32_DISABLED 
                              file= open("C:\\windows\\temp\\cutbuf", O_BINARY|O_RDONLY);
#else
                              file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY);
#endif
                              if(file>0) {
                              
                                    filelen = BLI_filesize(file);
                              
                                    strp= MEM_mallocN(filelen+4, "tempstr");
                                    read(file, strp, filelen);
                                    close(file);
                                    strp[filelen]= 0;
                                    if(cu->len+filelen<MAXTEXT) {
                                          strcat( textbuf, strp);
                                          cu->len= strlen(textbuf);
                                          cu->pos= cu->len;
                                    }
                                    MEM_freeN(strp);
                              }
                        }
                        else {
                              insert_into_textbuf(cu, ascii);
                        }
                  }
                  
                  doit= 1;
            }
      }
      else if(val) {
            cursmove= 0;
            
            switch(event) {
            case RETKEY:
                  insert_into_textbuf(cu, '\n');
                  doit= 1;
                  break;

            case RIGHTARROWKEY:     
                  if(G.qual & LR_SHIFTKEY) {
                        while(cu->pos<cu->len) {
                              if( textbuf[cu->pos]==0) break;
                              if( textbuf[cu->pos]=='\n') break;
                              cu->pos++;
                        }
                  }
                  else {
                        cu->pos++;
                  }
                  cursmove= FO_CURS;
                  break;
                  
            case LEFTARROWKEY:
                  
                  if(G.qual & LR_SHIFTKEY) {
                        while(cu->pos>0) {
                              if( textbuf[cu->pos-1]=='\n') break;
                              cu->pos--;
                        }
                  }
                  else {
                        cu->pos--;
                  }
                  cursmove=FO_CURS;
                  break;

            case UPARROWKEY:
                  if(G.qual & LR_SHIFTKEY) {
                        cu->pos= 0;
                        cursmove= FO_CURS;
                  }
                  else if(G.qual & LR_ALTKEY) {
                        if (cu->pos && textbuf[cu->pos - 1] < 255) {
                              textbuf[cu->pos - 1]++;
                              doit= 1;
                        }
                  }
                  else cursmove=FO_CURSUP;
                  break;
                  
            case DOWNARROWKEY:
                  if(G.qual & LR_SHIFTKEY) {
                        cu->pos= cu->len;
                        cursmove= FO_CURS;
                  }
                  else if(G.qual & LR_ALTKEY) {
                        if (cu->pos && textbuf[cu->pos - 1] > 1) {
                              textbuf[cu->pos - 1]--;
                              doit= 1;
                        }
                  }
                  else cursmove= FO_CURSDOWN;
                  break;
                  
            case BACKSPACEKEY:
                  if(cu->len!=0) {
                        if(G.qual & LR_ALTKEY) {
                              if(cu->pos>0) accentcode= 1;
                        }
                        else if(G.qual & LR_SHIFTKEY) {
                              cu->pos= 0;
                              textbuf[0]= 0;
                              cu->len= 0;
                        }
                        else if(cu->pos>0) {
                              for(x=cu->pos;x<=cu->len;x++) textbuf[x-1]= textbuf[x];
                              cu->pos--;
                              textbuf[--cu->len]='\0';
                        }
                  }
                  doit= 1;
                  break;

            case DELKEY:
                  if(cu->len!=0) {
                        if(cu->pos<cu->len) {
                              for(x=cu->pos;x<cu->len;x++) textbuf[x]= textbuf[x+1];
                              textbuf[--cu->len]='\0';
                        }
                  }
                  doit= 1;
                  break;
            }
                  
            if(cursmove) {
                  if(cu->pos>cu->len) cu->pos= cu->len;
                  else if(cu->pos>=MAXTEXT) cu->pos= MAXTEXT;
                  else if(cu->pos<0) cu->pos= 0;
            }
      }
      if(doit || cursmove) {
            text_to_curve(G.obedit, cursmove);
            if(cursmove==0) makeDispList(G.obedit);
            BIF_undo_push("Textedit");
            allqueue(REDRAWVIEW3D, 0);
      }
}


void paste_editText(void)
{
      Curve *cu;
      int file, filelen, doit= 0;
      char *strp;


#ifdef WIN32
      file= open("C:\\windows\\temp\\cutbuf.txt", O_BINARY|O_RDONLY);

//    The following is more likely to work on all Win32 installations.
//    suggested by Douglas Toltzman. Needs windows include files...
/*
      char tempFileName[MAX_PATH];
      DWORD pathlen;
      static const char cutbufname[]="cutbuf.txt";

      if ((pathlen=GetTempPath(sizeof(tempFileName),tempFileName)) > 0 &&
            pathlen + sizeof(cutbufname) <= sizeof(tempFileName))
      {
            strcat(tempFileName,cutbufname);
            file= open(tempFileName, O_BINARY|O_RDONLY);
      }
*/
#else
      file= open("/tmp/.cutbuffer", O_BINARY|O_RDONLY);
#endif

      if(file>0) {
            cu= G.obedit->data;
            filelen = BLI_filesize(file);
                        
            strp= MEM_mallocN(filelen+4, "tempstr");
            read(file, strp, filelen);
            close(file);
            strp[filelen]= 0;
            if(cu->len+filelen<MAXTEXT) {
                  strcat( textbuf, strp);
                  cu->len= strlen(textbuf);
                  cu->pos= cu->len;
            }
            MEM_freeN(strp);
            doit = 1;
      }
      if(doit) {
            text_to_curve(G.obedit, 0);
            makeDispList(G.obedit);
            allqueue(REDRAWVIEW3D, 0);
            BIF_undo_push("Paste text");
      }
}


void make_editText(void)
{
      Curve *cu;

      cu= G.obedit->data;
      if(textbuf==NULL) textbuf= MEM_mallocN(MAXTEXT+4, "texteditbuf");
      BLI_strncpy(textbuf, cu->str, MAXTEXT);
      oldstr= cu->str;
      cu->str= textbuf;

      cu->len= strlen(textbuf);
      if(cu->pos>cu->len) cu->pos= cu->len;
      
      text_to_curve(G.obedit, 0);
      makeDispList(G.obedit);
      
      textediting= 1;
      BIF_undo_push("Original");
}


void load_editText(void)
{
      Curve *cu;
      
      cu= G.obedit->data;

      MEM_freeN(oldstr);
      oldstr= NULL;
      
      cu->str= MEM_mallocN(cu->len+4, "tekstedit");
      strcpy(cu->str, textbuf);
      
      /* this memory system is weak... */
      MEM_freeN(textbuf);
      textbuf= NULL;
      
      cu->len= strlen(cu->str);
      textediting= 0;
}


void remake_editText(void)
{
      Curve *cu;
            
      if(okee("Reload original text")==0) return;
      
      BLI_strncpy(textbuf, oldstr, MAXTEXT);
      cu= G.obedit->data;
      cu->len= strlen(textbuf);
      if(cu->pos>cu->len) cu->pos= cu->len;
      
      text_to_curve(G.obedit, 0);
      makeDispList(G.obedit);
      
      allqueue(REDRAWVIEW3D, 0);
      BIF_undo_push("Reload");
}


void free_editText(void)
{
      if(oldstr) MEM_freeN(oldstr);
      textbuf= oldstr= NULL;
      textediting= 0;
}


void add_primitiveFont(int dummy_argument)
{
      Curve *cu;

      if (G.obedit && G.obedit->type==OB_FONT) return;
      check_editmode(OB_FONT);
      
      add_object_draw(OB_FONT);
      base_init_from_view3d(BASACT, G.vd);
      G.obedit= BASACT->object;
      where_is_object(G.obedit);
      
      cu= G.obedit->data;
      
      cu->vfont= get_builtin_font();
      cu->vfont->id.us++;
      cu->str= MEM_mallocN(12, "str");
      strcpy(cu->str, "Text");
      cu->pos= 4;
      
      make_editText();

      allqueue(REDRAWALL, 0);
}

void to_upper(void)
{
      Curve *cu;
      int len, ok;
      char *str;
      
      if(G.obedit==0) {
            return;
      }
      
      ok= 0;
      cu= G.obedit->data;
      
      len= strlen(cu->str);
      str= cu->str;
      while(len) {
            if( *str>=97 && *str<=122) {
                  ok= 1;
                  *str-= 32;
            }
            len--;
            str++;
      }
      
      if(ok==0) {
            len= strlen(cu->str);
            str= cu->str;
            while(len) {
                  if( *str>=65 && *str<=90) {
                        *str+= 32;
                  }
                  len--;
                  str++;
            }
      }
      text_to_curve(G.obedit, 0);
      makeDispList(G.obedit);

      allqueue(REDRAWVIEW3D, 0);
      BIF_undo_push("To upper");
}


/* **************** undo for font object ************** */

static void undoFont_to_editFont(void *strv)
{
      Curve *cu= G.obedit->data;
      char *str= strv;
      
      strncpy(textbuf, str+2, MAXTEXT);
      cu->pos= *((short *)str);
      cu->len= strlen(textbuf);
      text_to_curve(G.obedit, 0);
      makeDispList(G.obedit);
      
      allqueue(REDRAWVIEW3D, 0);
}

static void *editFont_to_undoFont(void)
{
      Curve *cu= G.obedit->data;
      char *str;
      
      str= MEM_callocN(MAXTEXT+4, "string undo");
      
      strncpy(str+2, textbuf, MAXTEXT);
      *((short *)str)= cu->pos;
      
      return str;
}

static void free_undoFont(void *strv)
{
      MEM_freeN(strv);
}

/* and this is all the undo system needs to know */
void undo_push_font(char *name)
{
      undo_editmode_push(name, free_undoFont, undoFont_to_editFont, editFont_to_undoFont);
}



/***/

Generated by  Doxygen 1.6.0   Back to index