/* For general Scribus (>=1.3.2) copyright and licensing information please refer to the COPYING file provided with the program. Following this notice may exist a copyright and/or license notice that predates the release of Scribus 1.3.2 for which a new license (GPL+exception) is in place. */ #ifndef SCFACE_PS_H #define SCFACE_PS_H #include #include #include #include #include #include FT_FREETYPE_H #include FT_OUTLINE_H #include FT_GLYPH_H #include "scribusapi.h" #include "fpointarray.h" #include "scconfig.h" /* Class ScFace_postscript Subclass of ScFace, for PostScript fonts that could possibly have a .afm file associated with them for metrics information. */ class ScFace_postscript : public FtFace { public: ScFace_postscript(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) : FtFace(fam,sty,alt,scname,psname,path,face) { isFixedPitch = false; typeCode = ScFace::TYPE1; } virtual QStringList findFontMetrics(const QString& fontPath) const; virtual QStringList findFontMetrics(const QString& baseDir, const QString& baseName) const; virtual bool loadFontMetrics(FT_Face face, const QString& fontPath) const; virtual void load() const // routine by Franz Schmid - modified by Alastair M. Robinson { FtFace::load(); // bool error; FT_Face face = ftFace(); if (!face) { const_cast(this)->usable = false; qDebug("%s", QObject::tr("Font %1 is broken (no Face), discarding it").arg(fontFile).toLocal8Bit().constData()); return; } if (loadFontMetrics(face, fontFile)) { // re-initialize: ScFaceData::load() just clears caches, // FtFace::load() skips FT_New_Face if m_face is already defined. // dont mind checking glyphs again for now (PS files have only 255 glyphs max, anyway) FtFace::load(); } // Ascent = tmp.setNum(face->ascender); // Descender = tmp.setNum(face->descender); // CapHeight = Ascent; // ItalicAngle = "0"; // StdVW = "1"; // FontBBox = tmp.setNum(face->bbox.xMin)+" "+tmp2.setNum(face->bbox.yMin)+" "+tmp3.setNum(face->bbox.xMax)+" "+tmp4.setNum(face->bbox.yMax); /* setBestEncoding(face); gindex = 0; charcode = FT_Get_First_Char( face, &gindex ); int goodGlyph = 0; int invalidGlyph = 0; while ( gindex != 0 ) { error = FT_Load_Glyph( face, gindex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ); if (error) { ++invalidGlyph; sDebug(QObject::tr("Font %1 has broken glyph %2 (charcode %3)").arg(fontPath()).arg(gindex).arg(charcode)); charcode = FT_Get_Next_Char( face, charcode, &gindex ); continue; } ++goodGlyph; qreal ww = face->glyph->metrics.horiAdvance / uniEM; if (face->glyph->format == FT_GLYPH_FORMAT_PLOTTER) isStroked = true; error = false; outlines = traceChar(face, charcode, 10, &x, &y, &error); if (!error) { CharWidth.insert(charcode, ww); GRec.Outlines = outlines.copy(); GRec.x = x; GRec.y = y; GlyphArray.insert(charcode, GRec); } charcode = FT_Get_Next_Char( face, charcode, &gindex ); } */ } }; /* Class ScFace_pfb Subclass of ScFace, specifically for Adobe type 1 .pfb fonts. Implements: RealName() and EmbedFont(). */ class ScFace_pfb : public ScFace_postscript { public: ScFace_pfb(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) : ScFace_postscript(fam,sty,alt,scname,psname,path,face) { formatCode = ScFace::PFB; } virtual bool EmbedFont(QString &str) const { QByteArray bb; RawData(bb); QString tmp2 = ""; if ((bb.size() > 2) && (bb[0] == char(0x80)) && (static_cast(bb[1]) == 1)) { QString tmp3=""; QString tmp4 = ""; int posi,cxxc=0; for (posi = 6; posi < bb.size(); ++posi) { if ((bb[posi] == char(0x80)) && (posi+1 < bb.size()) && (static_cast(bb[posi+1]) == 2)) break; str += bb[posi]; } int ulen; if (posi+6 < bb.size()) { ulen = bb[posi+2] & 0xff; ulen |= (bb[posi+3] << 8) & 0xff00; ulen |= (bb[posi+4] << 16) & 0xff0000; ulen |= (bb[posi+5] << 24) & 0xff000000; posi += 6; if (posi + ulen > bb.size()) ulen = bb.size() - posi - 1; char linebuf[80]; cxxc=0; for (int j = 0; j < ulen; ++j) { unsigned char u=bb[posi]; linebuf[cxxc]=((u >> 4) & 15) + '0'; if(u>0x9f) linebuf[cxxc]+='a'-':'; ++cxxc; u&=15; linebuf[cxxc]=u + '0'; if(u>0x9) linebuf[cxxc]+='a'-':'; ++posi; ++cxxc; if (cxxc > 72) { linebuf[cxxc++]='\n'; linebuf[cxxc++]=0; str += linebuf; cxxc = 0; } } linebuf[cxxc]=0; str += linebuf; str += "\n"; } posi += 6; for (int j = posi; j < bb.size(); ++j) { if ((bb[j] == static_cast(0x80)) && (j+1 < bb.size()) && (static_cast(bb[j+1]) == 3)) break; if(bb[j]=='\r') str+="\n"; else str += bb[j]; } str += "\n"; cxxc = 0; return true; } else { qDebug("%s", QObject::tr("Font %1 cannot be read, no embedding").arg(fontFile).toLatin1().constData()); return false; } } }; /* Class ScFace_pfa Subclass of ScFace, specifically for Adobe type 1 and type 3 .pfa fonts. Implements: RealName() and EmbedFont(). */ class ScFace_pfa : public ScFace_postscript { public: ScFace_pfa(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) : ScFace_postscript(fam,sty,alt,scname,psname,path,face) { formatCode = ScFace::PFA; } virtual bool EmbedFont(QString &str) const { QByteArray bb; RawData(bb); if (bb.size() > 2 && bb[0] == '%' && bb[1] == '!') { // this is ok since bb will not contain '\0' str.append(bb); return true; } qDebug("%s", QObject::tr("Font %1 cannot be read, no embedding").arg(fontFile).toLatin1().constData()); return false; } }; #endif