Back to index

scribus-ng  1.3.4.dfsg+svn20071115
scface_ps.h
Go to the documentation of this file.
00001 /*
00002  For general Scribus (>=1.3.2) copyright and licensing information please refer
00003  to the COPYING file provided with the program. Following this notice may exist
00004  a copyright and/or license notice that predates the release of Scribus 1.3.2
00005  for which a new license (GPL+exception) is in place.
00006  */
00007 #ifndef SCFACE_PS_H
00008 #define SCFACE_PS_H
00009 
00010 #include <qstring.h>
00011 #include <qstrlist.h>
00012 #include <qstringlist.h>
00013 #include <qdict.h>
00014 #include <qfont.h>
00015 #include <qmap.h>
00016 
00017 #include <ft2build.h>
00018 #include FT_FREETYPE_H
00019 #include FT_OUTLINE_H
00020 #include FT_GLYPH_H
00021 
00022 #include "scribusapi.h"
00023 #include "fpointarray.h"
00024 #include "scconfig.h"
00025 
00026 
00027 /*
00028        Class ScFace_postscript
00029        Subclass of ScFace, for PostScript fonts that could possibly have a .afm file
00030        associated with them for metrics information.
00031 */
00032 
00033 class ScFace_postscript : public FtFace
00034 {
00035        public:
00036               ScFace_postscript(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) :
00037               FtFace(fam,sty,alt,scname,psname,path,face)
00038               {
00039                      isFixedPitch = false;
00040                      typeCode = ScFace::TYPE1;
00041               }
00042 
00043               virtual void load()  const // routine by Franz Schmid - modified by Alastair M. Robinson
00044               {
00045                      FtFace::load();
00046 //                   bool error;
00047                      FT_Face face = ftFace();
00048                      if (!face)
00049                      {
00050                             const_cast<ScFace_postscript*>(this)->usable = false;
00051                             qDebug(QObject::tr("Font %1 is broken (no Face), discarding it").arg(fontFile));
00052                             return;
00053                      }
00054                      QString afnm = fontFile.left(fontFile.length()-3);
00055                      QFile afm(afnm+"afm");
00056                      if(!(afm.exists()))
00057                      {
00058                             afm.setName(afnm+"Afm");
00059                      }
00060                      if(!(afm.exists()))
00061                      {
00062                             afm.setName(afnm+"AFM");
00063                      }
00064                      if(!(afm.exists()))
00065                      {
00066                             afm.setName(afnm+"pfm");
00067                      }
00068                      if(!(afm.exists()))
00069                      {
00070                             afm.setName(afnm+"Pfm");
00071                      }
00072                      if(!(afm.exists())) {
00073                             afm.setName(afnm+"PFM");
00074                      }
00075                      if (afm.exists())
00076                      {
00077                             if(FT_Attach_File(face, afm.name()))
00078                                    qDebug(QObject::tr("Font %1 has broken metrics in file %2, ignoring metrics").arg(fontFile).arg(afm.name()));
00079                             else
00080                                    // re-initialize: ScFaceData::load() just clears caches,
00081                                    // FtFace::load() skips FT_New_Face if m_face is already defined.
00082                                    // dont mind checking glyphs again for now (PS files have only 255 glyphs max, anyway)
00083                                    FtFace::load();
00084                      }
00085 //                   Ascent = tmp.setNum(face->ascender);
00086 //                   Descender = tmp.setNum(face->descender);
00087 //                   CapHeight = Ascent;
00088 //                   ItalicAngle = "0";
00089 //                   StdVW = "1";
00090 //                   FontBBox = tmp.setNum(face->bbox.xMin)+" "+tmp2.setNum(face->bbox.yMin)+" "+tmp3.setNum(face->bbox.xMax)+" "+tmp4.setNum(face->bbox.yMax);
00091 /*
00092  setBestEncoding(face);
00093                      gindex = 0;
00094                      charcode = FT_Get_First_Char( face, &gindex );
00095                      int goodGlyph = 0;
00096                      int invalidGlyph = 0;
00097                      while ( gindex != 0 )
00098                      {
00099                             error = FT_Load_Glyph( face, gindex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
00100                             if (error)
00101                             {
00102                                    ++invalidGlyph;
00103                                    sDebug(QObject::tr("Font %1 has broken glyph %2 (charcode %3)").arg(fontPath()).arg(gindex).arg(charcode));
00104                                    charcode = FT_Get_Next_Char( face, charcode, &gindex );
00105                                    continue;
00106                             }
00107                             ++goodGlyph;
00108                             double ww = face->glyph->metrics.horiAdvance / uniEM;
00109                             if (face->glyph->format == FT_GLYPH_FORMAT_PLOTTER)
00110                                    isStroked = true;
00111                             error = false;
00112                             outlines = traceChar(face, charcode, 10, &x, &y, &error);
00113                             if (!error)
00114                             {
00115                                    CharWidth.insert(charcode, ww);
00116                                    GRec.Outlines = outlines.copy();
00117                                    GRec.x = x;
00118                                    GRec.y = y;
00119                                    GlyphArray.insert(charcode, GRec);
00120                             }
00121                             charcode = FT_Get_Next_Char( face, charcode, &gindex );
00122                      }
00123  */
00124               }
00125 };
00126 
00127 /*
00128        Class ScFace_pfb
00129        Subclass of ScFace, specifically for Adobe type 1 .pfb fonts.
00130        Implements: RealName() and EmbedFont().
00131 */
00132 
00133 class ScFace_pfb : public ScFace_postscript
00134 {
00135        public:
00136               ScFace_pfb(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) :
00137               ScFace_postscript(fam,sty,alt,scname,psname,path,face)
00138               {
00139                      formatCode = ScFace::PFB;
00140               }
00141 
00142               virtual bool EmbedFont(QString &str) const
00143               {
00144                      QByteArray bb;
00145                      RawData(bb);
00146                      QString tmp2 = "";
00147                      if ((bb.size() > 2) &&  (bb[0] == char(0x80)) && (static_cast<int>(bb[1]) == 1))
00148                      {
00149                             QString tmp3="";
00150                             QString tmp4 = "";
00151                             uint posi,cxxc=0;
00152                             for (posi = 6; posi < bb.size(); ++posi)
00153                             {
00154                                    if ((bb[posi] == char(0x80)) && (posi+1 < bb.size()) && (static_cast<int>(bb[posi+1]) == 2))
00155                                           break;
00156                                    str += bb[posi];
00157                             }
00158                             uint ulen;
00159                             if (posi+6 < bb.size()) 
00160                             {
00161                                    ulen = bb[posi+2] & 0xff;
00162                                    ulen |= (bb[posi+3] << 8) & 0xff00;
00163                                    ulen |= (bb[posi+4] << 16) & 0xff0000;
00164                                    ulen |= (bb[posi+5] << 24) & 0xff000000;
00165                                    posi += 6;
00166                                    if (posi + ulen > bb.size())
00167                                           ulen = bb.size() - posi - 1;
00168                                    char linebuf[80];
00169                                    cxxc=0;
00170                                    for (uint j = 0; j < ulen; ++j)
00171                                    {
00172                                           unsigned char u=bb[posi];
00173                                           linebuf[cxxc]=((u >> 4) & 15) + '0';
00174                                           if(u>0x9f) linebuf[cxxc]+='a'-':';
00175                                           ++cxxc;
00176                                           u&=15; linebuf[cxxc]=u + '0';
00177                                           if(u>0x9) linebuf[cxxc]+='a'-':';
00178                                           ++posi;
00179                                           ++cxxc;
00180                                           if (cxxc > 72)
00181                                           {
00182                                                  linebuf[cxxc++]='\n';
00183                                                  linebuf[cxxc++]=0;
00184                                                  str += linebuf;
00185                                                  cxxc = 0;
00186                                           }
00187                                    }
00188                                    linebuf[cxxc]=0;
00189                                    str += linebuf;
00190                                    str += "\n";
00191                             }
00192                             posi += 6;
00193                             for (uint j = posi; j < bb.size(); ++j)
00194                             {
00195                                    if ((bb[j] == static_cast<char>(0x80)) && (j+1 < bb.size()) && (static_cast<int>(bb[j+1]) == 3))
00196                                           break;
00197                                    if(bb[j]=='\r')
00198                                           str+="\n";
00199                                    else
00200                                           str += bb[j];
00201                             }
00202                             str += "\n";
00203                             cxxc = 0;
00204                             return true;
00205                      }
00206                      else 
00207                      {
00208                             qDebug(QObject::tr("Font %1 cannot be read, no embedding").arg(fontFile));
00209                             return false;
00210                      }
00211               }
00212 };
00213 
00214 /*
00215        Class ScFace_pfa
00216        Subclass of ScFace, specifically for Adobe type 1 and type 3 .pfa fonts.
00217        Implements: RealName() and EmbedFont().
00218 */
00219 
00220 class ScFace_pfa : public ScFace_postscript
00221 {
00222        public:
00223               ScFace_pfa(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) :
00224               ScFace_postscript(fam,sty,alt,scname,psname,path,face)
00225               {
00226                      formatCode = ScFace::PFA;
00227               }
00228               virtual bool EmbedFont(QString &str) const
00229               {
00230                      QByteArray bb;
00231                      RawData(bb);
00232                      if (bb.size() > 2 && bb[0] == '%' && bb[1] == '!') 
00233                      {
00234                             // this is ok since bb will not contain '\0'
00235                             str.append(bb);
00236                             return true; 
00237                      }
00238                      qDebug(QObject::tr("Font %1 cannot be read, no embedding").arg(fontFile));
00239                      return false;
00240               }
00241 };
00242 
00243 
00244 #endif