Back to index

scribus-ng  1.3.4.dfsg+svn20071115
Functions | Variables
scfontmetrics.cpp File Reference
#include <qpainter.h>
#include <qcolor.h>
#include <qwmatrix.h>
#include <qpixmap.h>
#include <qstringlist.h>
#include <qmap.h>
#include <qregexp.h>
#include "scribusdoc.h"
#include "scfonts.h"
#include "style.h"
#include "scfontmetrics.h"
#include "scpainter.h"
#include "fpoint.h"
#include "fpointarray.h"
#include "page.h"
#include "util.h"

Go to the source code of this file.

Functions

static void readAdobeGlyphNames ()
 init the Adobe Glyph List
static QString adobeGlyphName (FT_ULong charcode)
 if in AGL, use that name, else use "uni1234" or "u12345"
static int traceMoveto (FT_Vector *to, FPointArray *composite)
static int traceLineto (FT_Vector *to, FPointArray *composite)
static int traceQuadraticBezier (FT_Vector *control, FT_Vector *to, FPointArray *composite)
static int traceCubicBezier (FT_Vector *p, FT_Vector *q, FT_Vector *to, FPointArray *composite)
int setBestEncoding (FT_Face face)
FPointArray traceGlyph (FT_Face face, FT_UInt glyphIndex, int chs, double *x, double *y, bool *err)
FPointArray traceChar (FT_Face face, uint chr, int chs, double *x, double *y, bool *err)
QPixmap FontSample (const ScFace &fnt, int s, QString ts, QColor back, bool force)
bool GlyNames (FT_Face face, QMap< uint, std::pair< QChar, QString > > &GList)
 Same as FontSample() with
strings support added.

Variables

static FPoint firstP
static bool FirstM
static QMap< FT_ULong, QString > adobeGlyphNames
static const char * table []
FT_Outline_Funcs OutlineMethods
const double FTSCALE = 64.0

Function Documentation

QString adobeGlyphName ( FT_ULong  charcode) [static]

if in AGL, use that name, else use "uni1234" or "u12345"

Definition at line 433 of file scfontmetrics.cpp.

                                          {
       static const char HEX[] = "0123456789ABCDEF";
       QString result;
       if (adobeGlyphNames.contains(charcode))
              return adobeGlyphNames[charcode];
       else if (charcode < 0x10000) {
              result = QString("uni") + HEX[charcode>>12 & 0xF] 
                                      + HEX[charcode>> 8 & 0xF] 
                                      + HEX[charcode>> 4 & 0xF] 
                                      + HEX[charcode     & 0xF];
       }
       else  {
              result = QString("u");
              for (int i= 28; i >= 0; i-=4) {
                     if (charcode & (0xF << i))
                            result += HEX[charcode >> i & 0xF];
              }
       }
       return result;
}

Here is the caller graph for this function:

QPixmap FontSample ( const ScFace &  fnt,
int  s,
QString  ts,
QColor  back,
bool  force 
)

Definition at line 210 of file scfontmetrics.cpp.

{
       FT_Face face;
       FT_Library library;
       double x, y, ymax;
       bool error;
       int  pen_x;
       FPoint gp;
       error = FT_Init_FreeType( &library );
       error = FT_New_Face( library, QFile::encodeName(fnt.fontFilePath()), fnt.faceIndex(), &face );
       int encode = setBestEncoding(face);
       double uniEM = static_cast<double>(face->units_per_EM);

       double m_descent = face->descender / uniEM;
       double m_height = face->height / uniEM;
       if (m_height == 0)
              m_height = (face->bbox.yMax - face->bbox.yMin) / uniEM;

       int h = qRound(m_height * s) + 1;
       double a = m_descent * s + 1;
       int w = qRound((face->bbox.xMax - face->bbox.xMin) / uniEM) * s * (ts.length()+1);
       if (w < 1)
              w = s * (ts.length()+1);
       if (h < 1)
              h = s;
       QPixmap pm(w, h);
       pm.fill();
       pen_x = 0;
       ymax = 0.0;
       ScPainter *p = new ScPainter(&pm, pm.width(), pm.height());
       p->setFillMode(1);
       p->setLineWidth(0.0);
       p->setBrush(back);
       p->drawRect(0.0, 0.0, static_cast<double>(w), static_cast<double>(h));
       p->setBrush(Qt::black);
       FPointArray gly;
       uint dv;
       dv = ts[0].unicode();
       error = false;
       gly = traceChar(face, dv, s, &x, &y, &error);
       if (((encode != 0) || (error)) && (!force))
       {
              error = false;
              FT_ULong  charcode;
              FT_UInt gindex;
              gindex = 0;
              charcode = FT_Get_First_Char(face, &gindex );
              for (uint n = 0; n < ts.length(); ++n)
              {
                     gly = traceChar(face, charcode, s, &x, &y, &error);
                     if (error)
                            break;
                     if (gly.size() > 3)
                     {
                            gly.translate(static_cast<double>(pen_x) / 6400.0, a);
                            gp = getMaxClipF(&gly);
                            ymax = QMAX(ymax, gp.y());
                            p->setupPolygon(&gly);
                            p->fillPath();
                     }
                     pen_x += face->glyph->advance.x;
                     charcode = FT_Get_Next_Char(face, charcode, &gindex );
                     if (gindex == 0)
                            break;
              }
       }
       else
       {
              for (uint n = 0; n < ts.length(); ++n)
              {
                     dv = ts[n].unicode();
                     error = false;
                     gly = traceChar(face, dv, s, &x, &y, &error);
                     if (gly.size() > 3)
                     {
                            gly.translate(static_cast<double>(pen_x) / 6400.0, a);
                            gp = getMaxClipF(&gly);
                            ymax = QMAX(ymax, gp.y());
                            p->setupPolygon(&gly);
                            p->fillPath();
                     }
                     pen_x += face->glyph->advance.x;
              }
       }
       p->end();
       pm.resize(QMIN(qRound(gp.x()), w), QMIN(qRound(ymax), h));
       delete p;
       FT_Done_FreeType( library );
       return pm;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool GlyNames ( FT_Face  face,
QMap< uint, std::pair< QChar, QString > > &  GList 
)

Same as FontSample() with
strings support added.

09/26/2004 petr vanek

QPixmap fontSamples(ScFace * fnt, int s, QString ts, QColor back) { QStringList lines = QStringList::split("\n", ts); QPixmap ret(640, 480); QPixmap sample; QPainter *painter = new QPainter(&ret); int y = 0; int x = 0; ret.fill(back); for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) { sample = FontSample(fnt, s, *it, back); if (!sample.isNull()) painter->drawPixmap(0, y, sample, 0, 0); y = y + sample.height(); if (x < sample.width()) x = sample.width(); } // for delete(painter); QPixmap final(x, y); if ((x != 0) && (y != 0)) { QPainter *fpainter = new QPainter(&final); fpainter->drawPixmap(0, 0, ret, 0, 0, x, y); delete(fpainter); } return final; }

Definition at line 334 of file scfontmetrics.cpp.

{
       char buf[50];
       FT_ULong  charcode;
       FT_UInt gindex;
       setBestEncoding(face);
       gindex = 0;
       charcode = FT_Get_First_Char(face, &gindex );
       const bool hasPSNames = FT_HAS_GLYPH_NAMES(face);
       if (adobeGlyphNames.empty())
              readAdobeGlyphNames();
       while (gindex != 0)
       {
              bool notfound = true;
              if (hasPSNames)
                     notfound = FT_Get_Glyph_Name(face, gindex, &buf, 50);

              // just in case FT gives empty string or ".notdef"
              // no valid glyphname except ".notdef" starts with '.'         
              if (notfound || buf[0] == '\0' || buf[0] == '.')
                     GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)),adobeGlyphName(charcode)));
              else
                     GList.insert(gindex, std::make_pair(QChar(static_cast<uint>(charcode)),QString(reinterpret_cast<char*>(buf))));
                     
              charcode = FT_Get_Next_Char(face, charcode, &gindex );
       }
       return true;
}

Here is the call graph for this function:

void readAdobeGlyphNames ( ) [static]

init the Adobe Glyph List

Definition at line 419 of file scfontmetrics.cpp.

                           {
       adobeGlyphNames.clear();
       QRegExp pattern("(\\w*);([0-9A-Fa-f]{4})");
       for (uint i=0; table[i]; ++i) {
              if (pattern.search(table[i]) >= 0) {
                     FT_ULong unicode = pattern.cap(2).toULong(0, 16);
                     qDebug("%s", QString("reading glyph name %1 fo unicode %2(%3)").arg(pattern.cap(1)).arg(unicode).arg(pattern.cap(2)).ascii());
                     adobeGlyphNames.insert(unicode, pattern.cap(1));
              }
       }
}

Here is the caller graph for this function:

int setBestEncoding ( FT_Face  face)

Definition at line 57 of file scfontmetrics.cpp.

{
       FT_ULong  charcode;
       FT_UInt   gindex;
       bool foundEncoding = false;
       int countUniCode = 0;
       int chmapUniCode = -1;
       int chmapCustom = -1;
       int retVal = 0;
       //FT_CharMap defaultEncoding = face->charmap;
//     int defaultchmap=face->charmap ? FT_Get_Charmap_Index(face->charmap) : 0;
// Since the above function is only available in FreeType 2.1.10 its replaced by
// the following line, assuming that the default charmap has the index 0
       int defaultchmap = 0;
       for(int u = 0; u < face->num_charmaps; u++)
       {
              if (face->charmaps[u]->encoding == FT_ENCODING_UNICODE )
              {
                     FT_Set_Charmap(face, face->charmaps[u]);
                     chmapUniCode = u;
                     gindex = 0;
                     charcode = FT_Get_First_Char( face, &gindex );
                     while ( gindex != 0 )
                     {
                            countUniCode++;
                            charcode = FT_Get_Next_Char( face, charcode, &gindex );
                     }
              }
              if (face->charmaps[u]->encoding == FT_ENCODING_ADOBE_CUSTOM)
              {
                     chmapCustom = u;
                     foundEncoding = true;
                     retVal = 1;
                     break;
              }
              else if (face->charmaps[u]->encoding == FT_ENCODING_MS_SYMBOL)
              {
                     chmapCustom = u;
                     foundEncoding = true;
                     retVal = 2;
                     break;
              }
       }
       int mapToSet=defaultchmap;
       if (chmapUniCode>0 && countUniCode >= face->num_glyphs-1)
       {
              mapToSet=chmapUniCode;
              //FT_Set_Charmap(face, face->charmaps[chmapUniCode]);
              retVal = 0;
       }
       else
       if (foundEncoding)
       {
              mapToSet=chmapCustom;
              //FT_Set_Charmap(face, face->charmaps[chmapCustom]);
       }
       else
       {
              mapToSet=defaultchmap;
              //FT_Set_Charmap(face, defaultEncoding);
              retVal = 0;
       }

       //Fixes #2199, missing glyphs from 1.2.1->1.2.2
       //If the currently wanted character map is not already Unicode...
       //if (FT_Get_Charmap_Index(face->charmap)!=chmapUniCode)
       if (mapToSet!=chmapUniCode)
       {
              //Change map so we can count the chars in it
              FT_Set_Charmap(face, face->charmaps[mapToSet]);
              //Count the characters in the current map
              gindex = 0;
              int countCurrMap=0;
              charcode = FT_Get_First_Char( face, &gindex );
              while ( gindex != 0 )
              {
                     countCurrMap++;
                     charcode = FT_Get_Next_Char( face, charcode, &gindex );
              }
              //If the last Unicode map we found before has more characters,
              //then set it to be the current map.
              if (countUniCode>countCurrMap)
              {
                     mapToSet=chmapUniCode;
                     //FT_Set_Charmap(face, face->charmaps[chmapUniCode]);
                     retVal = 0;
              }
       }
//     if (face->charmap == NULL || mapToSet!=FT_Get_Charmap_Index(face->charmap))
              FT_Set_Charmap(face, face->charmaps[mapToSet]);
       return retVal;
}

Here is the caller graph for this function:

FPointArray traceChar ( FT_Face  face,
uint  chr,
int  chs,
double *  x,
double *  y,
bool err 
)

Definition at line 195 of file scfontmetrics.cpp.

{
       bool error = false;
       FT_UInt glyphIndex;
       error = FT_Set_Char_Size( face, 0, chs*64, 72, 72 );
       if (error)
       {
              *err = error;
              return FPointArray();
       }
       glyphIndex = FT_Get_Char_Index(face, chr);
       return traceGlyph(face, glyphIndex, chs, x, y, err);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int traceCubicBezier ( FT_Vector *  p,
FT_Vector *  q,
FT_Vector *  to,
FPointArray *  composite 
) [static]

Definition at line 402 of file scfontmetrics.cpp.

{
       double x1 = ( p->x / FTSCALE );
       double y1 = ( p->y / FTSCALE );
       double x2 = ( q->x / FTSCALE );
       double y2 = ( q->y / FTSCALE );
       double x3 = ( to->x / FTSCALE );
       double y3 = ( to->y / FTSCALE );
       if ( !composite->hasLastQuadPoint(x3, y3, x2, y2, x3, y3, x3, y3) )
       {
              composite->setPoint(composite->size()-1, FPoint(x1, y1));
              composite->addQuadPoint(x3, y3, x2, y2, x3, y3, x3, y3);
       }
       return 0;
}
FPointArray traceGlyph ( FT_Face  face,
FT_UInt  glyphIndex,
int  chs,
double *  x,
double *  y,
bool err 
)

Definition at line 150 of file scfontmetrics.cpp.

{
       bool error = false;
       //AV: not threadsave, but tracechar is only used in ReadMetrics() and fontSample()
       static FPointArray pts; 
       FPointArray pts2;
       pts.resize(0);
       pts2.resize(0);
       firstP = FPoint(0,0);
       FirstM = true;
       error = FT_Set_Char_Size( face, 0, chs*6400, 72, 72 );
       if (error)
       {
              *err = error;
              return pts2;
       }
       if (glyphIndex == 0)
       {
              *err = true;
              return pts2;
       }
       error = FT_Load_Glyph( face, glyphIndex, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP );
       if (error)
       {
              *err = error;
              return pts2;
       }
       error = FT_Outline_Decompose(&face->glyph->outline, &OutlineMethods, reinterpret_cast<void*>(&pts));
       if (error)
       {
              *err = error;
              return pts2;
       }
       *x = face->glyph->metrics.horiBearingX / 6400.0;
       *y = face->glyph->metrics.horiBearingY / 6400.0;
       QWMatrix ma;
       ma.scale(0.01, -0.01);
       pts.map(ma);
       pts.translate(0, chs);
       pts2.putPoints(0, pts.size()-2, pts, 0);

       return pts2;
}

Here is the caller graph for this function:

static int traceLineto ( FT_Vector *  to,
FPointArray *  composite 
) [static]

Definition at line 382 of file scfontmetrics.cpp.

{
       double tox = ( to->x / FTSCALE );
       double toy = ( to->y / FTSCALE );
       if ( !composite->hasLastQuadPoint(tox, toy, tox, toy, tox, toy, tox, toy))
              composite->addQuadPoint(tox, toy, tox, toy, tox, toy, tox, toy);
       return 0;
}
static int traceMoveto ( FT_Vector *  to,
FPointArray *  composite 
) [static]

Definition at line 364 of file scfontmetrics.cpp.

{
       double tox = ( to->x / FTSCALE );
       double toy = ( to->y / FTSCALE );
       if (!FirstM)
       {
              composite->addPoint(firstP);
              composite->addPoint(firstP);
              composite->setMarker();
       }
       else
              FirstM = false;
       composite->addPoint(tox, toy);
       composite->addPoint(tox, toy);
       firstP.setXY(tox, toy);
       return 0;
}
static int traceQuadraticBezier ( FT_Vector *  control,
FT_Vector *  to,
FPointArray *  composite 
) [static]

Definition at line 391 of file scfontmetrics.cpp.

{
       double x1 = ( control->x / FTSCALE );
       double y1 = ( control->y / FTSCALE );
       double x2 = ( to->x / FTSCALE );
       double y2 = ( to->y / FTSCALE );
       if ( !composite->hasLastQuadPoint(x2, y2, x1, y1, x2, y2, x2, y2))
              composite->addQuadPoint(x2, y2, x1, y1, x2, y2, x2, y2);
       return 0;
}

Variable Documentation

QMap<FT_ULong, QString> adobeGlyphNames [static]

Definition at line 30 of file scfontmetrics.cpp.

bool FirstM [static]

Definition at line 29 of file scfontmetrics.cpp.

FPoint firstP [static]

Definition at line 28 of file scfontmetrics.cpp.

const double FTSCALE = 64.0

Definition at line 54 of file scfontmetrics.cpp.

FT_Outline_Funcs OutlineMethods
Initial value:
    {
        (FT_Outline_MoveTo_Func) traceMoveto,
        (FT_Outline_LineTo_Func) traceLineto,
        (FT_Outline_ConicTo_Func) traceQuadraticBezier,
        (FT_Outline_CubicTo_Func) traceCubicBezier,
        0,
        0
    }

Definition at line 43 of file scfontmetrics.cpp.

const char* table[] [static]
Initial value:
 {

                                   NULL}

Definition at line 31 of file scfontmetrics.cpp.