/*! ========================================================================
-** Sinfg
+** Synfig
** Template File
** $Id: lyr_freetype.cpp,v 1.5 2005/01/24 05:00:18 darco Exp $
**
-** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2006 Paul Wise
**
-** This software and associated documentation
-** are CONFIDENTIAL and PROPRIETARY property of
-** the above-mentioned copyright holder.
+** This package 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.
**
-** You may not copy, print, publish, or in any
-** other way distribute this software without
-** a prior written agreement with
-** the copyright holder.
+** This package 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.
**
** === N O T E S ===========================================================
**
/* === H E A D E R S ======================================================= */
-#define SINFG_LAYER
+#define SYNFIG_LAYER
#ifdef USING_PCH
# include "pch.h"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
+#ifdef WITH_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
#include "lyr_freetype.h"
-#include <sinfg/string.h>
-#include <sinfg/time.h>
-#include <sinfg/context.h>
-#include <sinfg/paramdesc.h>
-#include <sinfg/renddesc.h>
-#include <sinfg/surface.h>
-#include <sinfg/value.h>
-#include <sinfg/valuenode.h>
-#include <sinfg/canvas.h>
-
-#include <ETL/misc>
#endif
using namespace std;
using namespace etl;
-using namespace sinfg;
+using namespace synfig;
/* === M A C R O S ========================================================= */
/* === G L O B A L S ======================================================= */
-SINFG_LAYER_INIT(lyr_freetype);
-SINFG_LAYER_SET_NAME(lyr_freetype,"text");
-SINFG_LAYER_SET_LOCAL_NAME(lyr_freetype,_("Simple Text"));
-SINFG_LAYER_SET_CATEGORY(lyr_freetype,_("Typography"));
-SINFG_LAYER_SET_VERSION(lyr_freetype,"0.2");
-SINFG_LAYER_SET_CVS_ID(lyr_freetype,"$Id: lyr_freetype.cpp,v 1.5 2005/01/24 05:00:18 darco Exp $");
+SYNFIG_LAYER_INIT(lyr_freetype);
+SYNFIG_LAYER_SET_NAME(lyr_freetype,"text");
+SYNFIG_LAYER_SET_LOCAL_NAME(lyr_freetype,_("Simple Text"));
+SYNFIG_LAYER_SET_CATEGORY(lyr_freetype,_("Typography"));
+SYNFIG_LAYER_SET_VERSION(lyr_freetype,"0.2");
+SYNFIG_LAYER_SET_CVS_ID(lyr_freetype,"$Id: lyr_freetype.cpp,v 1.5 2005/01/24 05:00:18 darco Exp $");
/* === P R O C E D U R E S ================================================= */
}
void
-lyr_freetype::new_font(const sinfg::String &family, int style, int weight)
+lyr_freetype::new_font(const synfig::String &family, int style, int weight)
{
if(
!new_font_(family,style,weight) &&
}
bool
-lyr_freetype::new_font_(const sinfg::String &family_, int style, int weight)
+lyr_freetype::new_font_(const synfig::String &font_fam_, int style, int weight)
{
- sinfg::String family(family_);
+ synfig::String font_fam(font_fam_);
+
+ if(new_face(font_fam_))
+ return true;
//start evil hack
- for(int i=0;i<family.size();i++)family[i]=tolower(family[i]);
+ for(unsigned int i=0;i<font_fam.size();i++)font_fam[i]=tolower(font_fam[i]);
//end evil hack
- if(family=="arial black")
+ if(font_fam=="arial black")
#ifndef __APPLE__
if(new_face("ariblk"))
return true;
else
#endif
- family="sans serif";
+ font_fam="sans serif";
- if(family=="sans serif" || family=="arial")
+ if(font_fam=="sans serif" || font_fam=="arial")
{
String arial("arial");
if(weight>WEIGHT_NORMAL)
if(new_face(arial))
return true;
+#ifdef __APPLE__
+ if(new_face("Helvetica RO"))
+ return true;
+#endif
}
- if(family=="comic" || family=="comic sans")
+ if(font_fam=="comic" || font_fam=="comic sans")
{
String filename("comic");
if(weight>WEIGHT_NORMAL)
return true;
}
- if(family=="courier" || family=="courier new")
+ if(font_fam=="courier" || font_fam=="courier new")
{
String filename("cour");
if(weight>WEIGHT_NORMAL)
return true;
}
- if(family=="serif" || family=="times" || family=="times new roman")
+ if(font_fam=="serif" || font_fam=="times" || font_fam=="times new roman")
{
String filename("times");
if(weight>WEIGHT_NORMAL)
return true;
}
- if(family=="trebuchet")
+ if(font_fam=="trebuchet")
{
String filename("trebuc");
if(weight>WEIGHT_NORMAL)
}
- if(family=="sans serif" || family=="luxi sans")
+ if(font_fam=="sans serif" || font_fam=="luxi sans")
{
{
String luxi("luxis");
if(new_face("Arial"))
return true;
}
- if(family=="serif" || family=="times" || family=="times new roman" || family=="luxi serif")
+ if(font_fam=="serif" || font_fam=="times" || font_fam=="times new roman" || font_fam=="luxi serif")
{
{
String luxi("luxir");
if(new_face("Times"))
return true;
}
- if(family=="luxi")
+ if(font_fam=="luxi")
{
{
String luxi("luxim");
return true;
}
- return new_face(family_) || new_face(family);
+ return new_face(font_fam_) || new_face(font_fam);
return false;
}
+#ifdef USE_MAC_FT_FUNCS
+void fss2path(char *path, FSSpec *fss)
+{
+ int l; //fss->name contains name of last item in path
+ for(l=0; l<(fss->name[0]); l++) path[l] = fss->name[l + 1];
+ path[l] = 0;
+
+ if(fss->parID != fsRtParID) //path is more than just a volume name
+ {
+ int i, len;
+ CInfoPBRec pb;
+
+ pb.dirInfo.ioNamePtr = fss->name;
+ pb.dirInfo.ioVRefNum = fss->vRefNum;
+ pb.dirInfo.ioDrParID = fss->parID;
+ do
+ {
+ pb.dirInfo.ioFDirIndex = -1; //get parent directory name
+ pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
+ if(PBGetCatInfoSync(&pb) != noErr) break;
+
+ len = fss->name[0] + 1;
+ for(i=l; i>=0; i--) path[i + len] = path[i];
+ for(i=1; i<len; i++) path[i - 1] = fss->name[i]; //add to start of path
+ path[i - 1] = ':';
+ l += len;
+} while(pb.dirInfo.ioDrDirID != fsRtDirID); //while more directory levels
+ }
+}
+#endif
+
bool
lyr_freetype::new_face(const String &newfont)
{
int error;
- int face_index=0;
+ FT_Long face_index=0;
// If we are already loaded, don't bother reloading.
if(face && font==newfont)
if(error)error=FT_New_Face(ft_library,(get_canvas()->get_file_path()+ETL_DIRECTORY_SEPERATOR+newfont+".ttf").c_str(),face_index,&face);
}
+#ifdef USE_MAC_FT_FUNCS
+ if(error)
+ {
+ FSSpec fs_spec;
+ error=FT_GetFile_From_Mac_Name(newfont.c_str(),&fs_spec,&face_index);
+ if(!error)
+ {
+ char filename[512];
+ fss2path(filename,&fs_spec);
+ //FSSpecToNativePathName(fs_spec,filename,sizeof(filename)-1, 0);
+
+ error=FT_New_Face(ft_library, filename, face_index,&face);
+ //error=FT_New_Face_From_FSSpec(ft_library, &fs_spec, face_index,&face);
+ synfig::info(__FILE__":%d: \"%s\" (%s) -- ft_error=%d",__LINE__,newfont.c_str(),filename,error);
+ }
+ else
+ {
+ synfig::info(__FILE__":%d: \"%s\" -- ft_error=%d",__LINE__,newfont.c_str(),error);
+ // Unable to generate fs_spec
+ }
+
+ }
+#endif
+
+#ifdef WITH_FONTCONFIG
+ if(error)
+ {
+ FcFontSet *fs;
+ FcResult result;
+ if( !FcInit() )
+ {
+ synfig::warning("lyr_freetype: fontconfig: %s",_("unable to initialise")));
+ error = 1;
+ } else {
+ FcPattern* pat = FcNameParse((FcChar8 *) newfont.c_str());
+ FcConfigSubstitute(0, pat, FcMatchPattern);
+ FcDefaultSubstitute(pat);
+ FcPattern *match;
+ fs = FcFontSetCreate();
+ match = FcFontMatch(0, pat, &result);
+ if (match)
+ FcFontSetAdd(fs, match);
+ if (pat)
+ FcPatternDestroy(pat);
+ if(fs){
+ FcChar8* file;
+ if( FcPatternGetString (fs->fonts[0], FC_FILE, 0, &file) == FcResultMatch )
+ error=FT_New_Face(ft_library,(const char*)file,face_index,&face);
+ FcFontSetDestroy(fs);
+ } else
+ synfig::warning("lyr_freetype: fontconfig: %s",_("empty font set")));
+ }
+ }
+#endif
+
#ifdef WIN32
if(error)error=FT_New_Face(ft_library,("C:\\WINDOWS\\FONTS\\"+newfont).c_str(),face_index,&face);
if(error)error=FT_New_Face(ft_library,("C:\\WINDOWS\\FONTS\\"+newfont+".ttf").c_str(),face_index,&face);
#else
- if(error)error=FT_New_Face(ft_library,("/usr/share/fonts/truetype/"+newfont).c_str(),face_index,&face);
- if(error)error=FT_New_Face(ft_library,("/usr/share/fonts/truetype/"+newfont+".ttf").c_str(),face_index,&face);
-
- if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/TTF/"+newfont).c_str(),face_index,&face);
- if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/TTF/"+newfont+".ttf").c_str(),face_index,&face);
-
- if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/truetype/"+newfont).c_str(),face_index,&face);
- if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/truetype/"+newfont+".ttf").c_str(),face_index,&face);
-
- if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/type1/"+newfont).c_str(),face_index,&face);
- if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/type1/"+newfont+".ttf").c_str(),face_index,&face);
#ifdef __APPLE__
if(error)error=FT_New_Face(ft_library,("~/Library/Fonts/"+newfont).c_str(),face_index,&face);
if(error)error=FT_New_Face(ft_library,("~/Library/Fonts/"+newfont+".ttf").c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("~/Library/Fonts/"+newfont+".dfont").c_str(),face_index,&face);
if(error)error=FT_New_Face(ft_library,("/Library/Fonts/"+newfont).c_str(),face_index,&face);
if(error)error=FT_New_Face(ft_library,("/Library/Fonts/"+newfont+".ttf").c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/Library/Fonts/"+newfont+".dfont").c_str(),face_index,&face);
#endif
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/type1/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/type1/"+newfont+".ttf").c_str(),face_index,&face);
+
+ if(error)error=FT_New_Face(ft_library,("/usr/share/fonts/truetype/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/share/fonts/truetype/"+newfont+".ttf").c_str(),face_index,&face);
+
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/TTF/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/TTF/"+newfont+".ttf").c_str(),face_index,&face);
+
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/truetype/"+newfont).c_str(),face_index,&face);
+ if(error)error=FT_New_Face(ft_library,("/usr/X11R6/lib/X11/fonts/truetype/"+newfont+".ttf").c_str(),face_index,&face);
+
#endif
if(error)
{
- //sinfg::error(strprintf("lyr_freetype:%s (err=%d)",_("Unable to open face."),error));
+ //synfig::error(strprintf("lyr_freetype:%s (err=%d)",_("Unable to open face."),error));
return false;
}
lyr_freetype::set_param(const String & param, const ValueBase &value)
{
Mutex::Lock lock(mutex);
+/*
if(param=="font" && value.same_as(font))
{
new_font(etl::basename(value.get(font)),style,weight);
family=etl::basename(value.get(font));
return true;
}
+*/
IMPORT_PLUS(family,new_font(family,style,weight));
IMPORT_PLUS(weight,new_font(family,style,weight));
IMPORT_PLUS(style,new_font(family,style,weight));
}
Color
-lyr_freetype::get_color(Context context, const Point &pos)const
+lyr_freetype::get_color(Context context, const synfig::Point &pos)const
{
if(needs_sync_)
const_cast<lyr_freetype*>(this)->sync();
bool
lyr_freetype::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
{
- static sinfg::RecMutex freetype_mutex;
+ static synfig::RecMutex freetype_mutex;
if(needs_sync_)
const_cast<lyr_freetype*>(this)->sync();
return true;
}
- sinfg::RecMutex::Lock lock(freetype_mutex);
+ synfig::RecMutex::Lock lock(freetype_mutex);
#define CHAR_RESOLUTION (64)
error = FT_Set_Char_Size(
// error in freetype's rendering engine.
const float xerror(abs(size[0]*pw)/(float)face->size->metrics.x_ppem/1.13f/0.996);
const float yerror(abs(size[1]*ph)/(float)face->size->metrics.y_ppem/1.13f/0.996);
- //sinfg::info("xerror=%f, yerror=%f",xerror,yerror);
+ //synfig::info("xerror=%f, yerror=%f",xerror,yerror);
const float compress(lyr_freetype::compress*xerror);
const float vcompress(lyr_freetype::vcompress*yerror);
int string_height;
string_height=round_to_int(((lines.size()-1)*line_height+lines.back().actual_height()));
- //sinfg::info("string_height=%d",string_height);
- //sinfg::info("line_height=%f",line_height);
+ //synfig::info("string_height=%d",string_height);
+ //synfig::info("line_height=%f",line_height);
/*
-- ** -- RENDER THE GLYPHS ---------------------------------------------------
bx=round_to_int((pos[0]-renddesc.get_tl()[0])*pw*CHAR_RESOLUTION-orient[0]*iter->width);
by=round_to_int((pos[1]-renddesc.get_tl()[1])*ph*CHAR_RESOLUTION+(1.0-orient[1])*string_height-line_height*curr_line);
//by=round_to_int(vcompress*((pos[1]-renddesc.get_tl()[1])*ph*64+(1.0-orient[1])*string_height-face->size->metrics.height*curr_line));
- //sinfg::info("curr_line=%d, bx=%d, by=%d",curr_line,bx,by);
+ //synfig::info("curr_line=%d, bx=%d, by=%d",curr_line,bx,by);
std::vector<Glyph>::iterator iter2;
for(iter2=iter->glyph_table.begin();iter2!=iter->glyph_table.end();++iter2)
pen.x = bx + iter2->pos.x;
pen.y = by + iter2->pos.y;
- //sinfg::info("GLYPH: pen.x=%d, pen,y=%d",curr_line,(pen.x+32)>>6,(pen.y+32)>>6);
+ //synfig::info("GLYPH: pen.x=%d, pen,y=%d",curr_line,(pen.x+32)>>6,(pen.y+32)>>6);
error = FT_Glyph_To_Bitmap( &image, ft_render_mode_normal,0/*&pen*/, 1 );
if(error) { FT_Done_Glyph( image ); continue; }
return true;
}
-sinfg::Rect
+synfig::Rect
lyr_freetype::get_bounding_rect()const
{
if(needs_sync_)
const_cast<lyr_freetype*>(this)->sync();
// if(!is_disabled())
- return Rect::full_plane();
+ return synfig::Rect::full_plane();
}