Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

fontfactoryttf_qws.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of the Qtopia Environment.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00015 **
00016 ** Contact info@trolltech.com if any conditions of this licensing are
00017 ** not clear to you.
00018 **
00019 **********************************************************************/
00020 
00021 #include "fontfactoryttf_qws.h"
00022 
00023 #include <opie2/odebug.h>
00024 using namespace Opie::Core;
00025 
00026 #ifdef QT_NO_FREETYPE
00027 
00028 #include "qfontdata_p.h"
00029 #include <string.h>
00030 #include <stdio.h>
00031 
00032 #define FLOOR(x)  ((x) & -64)
00033 #define CEIL(x)   (((x)+63) & -64)
00034 #define TRUNC(x)  ((x) >> 6)
00035 
00036 
00037 extern "C" {
00038 
00039 #include <ft2build.h>
00040 #include FT_FREETYPE_H
00041 
00042 #include <freetype/freetype.h>
00043 #include <freetype/ftglyph.h>
00044 #include <freetype/ftoutln.h>
00045 #include <freetype/ftbbox.h>
00046 }
00047 
00048 class QDiskFontFT : public QDiskFontPrivate {
00049 public:
00050     FT_Face face;
00051 };
00052 
00053 class QRenderedFontFT : public QRenderedFont {
00054 public:
00055     QRenderedFontFT(QDiskFont* f, const QFontDef &d) :
00056         QRenderedFont(f,d)
00057     {
00058         QDiskFontFT *df = (QDiskFontFT*)(f->p);
00059         myface=df->face;
00060         selectThisSize();
00061         // A 1-pixel baseline is excluded in Qt/Windows/X11 fontmetrics
00062         // (see QFontMetrics::height())
00063         //
00064         fascent=CEIL(myface->size->metrics.ascender)/64;
00065         fdescent=-FLOOR(myface->size->metrics.descender)/64-1;
00066         fmaxwidth=CEIL(myface->size->metrics.max_advance)/64;
00067         fleading=CEIL(myface->size->metrics.height)/64
00068             - fascent - fdescent + 1;
00069 
00070         // FT has these in font units
00071         funderlinepos = ptsize/200+1;
00072         funderlinewidth = ptsize/200+1;
00073     }
00074 
00075     ~QRenderedFontFT()
00076     {
00077         // When inter-process glyph sharing is implemented, the glyph data
00078         // for this font can be dereferenced here.
00079     }
00080 
00081     bool unicode(int & i) const
00082     {
00083         int ret;
00084 
00085         FT_Face theface=myface;
00086 
00087         ret=FT_Get_Char_Index(theface,i);
00088 
00089         if (ret==0) {
00090             return FALSE;
00091         } else {
00092             i=ret;
00093             return TRUE;
00094         }
00095     }
00096 
00097     bool inFont(QChar ch) const
00098     {
00099         int index = ch.unicode();
00100         return unicode(index);
00101     }
00102 
00103     QGlyph render(QChar ch)
00104     {
00105         selectThisSize();
00106 
00107         int index = ch.unicode();
00108         if ( !unicode(index) )
00109             index = 0;
00110         QGlyph result;
00111 
00112         FT_Error err;
00113 
00114         err=FT_Load_Glyph(myface,index,FT_LOAD_DEFAULT);
00115         if(err)
00116             ofatal << "Load glyph error " << err << "" << oendl; 
00117 
00118         int width=0,height=0,pitch=0,size=0;
00119         FT_Glyph glyph;
00120         err=FT_Get_Glyph( myface->glyph, &glyph );
00121         if(err)
00122             ofatal << "Get glyph error " << err << "" << oendl; 
00123 
00124         FT_BBox bbox;
00125         FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_gridfit, &bbox);
00126 
00127         FT_Vector origin;
00128         origin.x = -bbox.xMin;
00129         origin.y = -bbox.yMin;
00130 
00131         if ( FT_IS_SCALABLE(myface) ) {
00132             err=FT_Glyph_To_Bitmap(&glyph,
00133                 smooth ? ft_render_mode_normal : ft_render_mode_mono,
00134                 &origin, 1); // destroy original glyph
00135             if(err)
00136                 owarn << "Get bitmap error " << err << "" << oendl; 
00137         }
00138 
00139         if ( !err ) {
00140             FT_Bitmap bm = ((FT_BitmapGlyph)glyph)->bitmap;
00141             pitch = bm.pitch;
00142             size=pitch*bm.rows;
00143             result.data = new uchar[size]; // XXX memory manage me
00144             width=bm.width;
00145             height=bm.rows;
00146             if ( size ) {
00147                 memcpy( result.data, bm.buffer, size );
00148             } else {
00149                 result.data = new uchar[0]; // XXX memory manage me
00150             }
00151         } else {
00152             result.data = new uchar[0]; // XXX memory manage me
00153         }
00154 
00155         result.metrics = new QGlyphMetrics;
00156         memset((char*)result.metrics, 0, sizeof(QGlyphMetrics));
00157         result.metrics->bearingx=myface->glyph->metrics.horiBearingX/64;
00158         result.metrics->advance=myface->glyph->metrics.horiAdvance/64;
00159         result.metrics->bearingy=myface->glyph->metrics.horiBearingY/64;
00160 
00161         result.metrics->linestep=pitch;
00162         result.metrics->width=width;
00163         result.metrics->height=height;
00164 
00165         // XXX memory manage me
00166         // At some point inter-process glyph data sharing must be implemented
00167         // and the flag below can be set to prevent Qt from deleting the glyph
00168         // data.
00169         // result.metrics->flags = QGlyphMetrics::RendererOwnsData;
00170 
00171         FT_Done_Glyph( glyph );
00172 
00173         return result;
00174     }
00175 
00176     FT_Face myface;
00177 
00178 private:
00179     void selectThisSize()
00180     {
00181         int psize=(ptsize<<6)/10;
00182 
00183         // Assume 72 dpi for now
00184         const int dpi=72;
00185         FT_Error err;
00186         err=FT_Set_Char_Size(myface, psize,psize,dpi,dpi);
00187         if (err) {
00188             if (FT_IS_SCALABLE(myface) ) {
00189                 owarn << "Set char size error " << err << " for size " << ptsize << "" << oendl; 
00190             } else {
00191                 int best=-1;
00192                 int bdh=99;
00193                 for (int i=0; i<myface->num_fixed_sizes; i++) {
00194                     FT_Bitmap_Size& sz=myface->available_sizes[i];
00195                     int dh = sz.height - ptsize*dpi/72/10;
00196                     dh = QABS(dh);
00197                     if ( dh < bdh ) {
00198                         bdh=dh;
00199                         best=i;
00200                     }
00201                 }
00202                 if ( best >= 0 )
00203                     err=FT_Set_Pixel_Sizes(myface,
00204                         myface->available_sizes[best].width,
00205                         myface->available_sizes[best].height);
00206                 if ( err )
00207                     owarn << "Set char size error " << err << " for size " << ptsize << "" << oendl; 
00208             }
00209         }
00210     }
00211 };
00212 
00213 QFontFactoryFT::QFontFactoryFT()
00214 {
00215     FT_Error err;
00216     err=FT_Init_FreeType(&library);
00217     if(err) {
00218         ofatal << "Couldn't initialise Freetype library" << oendl; 
00219     }
00220 }
00221 
00222 QFontFactoryFT::~QFontFactoryFT()
00223 {
00224 }
00225 
00226 QString QFontFactoryFT::name()
00227 {
00228     return "FT";
00229 }
00230 
00231 QRenderedFont * QFontFactoryFT::get(const QFontDef & f,QDiskFont * f2)
00232 {
00233     return new QRenderedFontFT(f2, f);
00234 }
00235 
00236 void QFontFactoryFT::load(QDiskFont * qdf) const
00237 {
00238     if(qdf->loaded)
00239         return;
00240     QDiskFontFT *f = new QDiskFontFT;
00241     qdf->p=f;
00242     FT_Error err;
00243     err=FT_New_Face(library,qdf->file.ascii(),0,&(f->face));
00244     if(err) {
00245         ofatal << "Error " << err << " opening face" << oendl; 
00246     }
00247     qdf->loaded=true;
00248 }
00249 
00250 
00251 #endif // QT_NO_FREETYPE

Generated on Sat Nov 5 16:15:59 2005 for OPIE by  doxygen 1.4.2