Subversion Repositories Scribus

Rev

Rev 10151 | Rev 11114 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5979 avox 1
/*
2
 For general Scribus (>=1.3.2) copyright and licensing information please refer
3
 to the COPYING file provided with the program. Following this notice may exist
4
 a copyright and/or license notice that predates the release of Scribus 1.3.2
5
 for which a new license (GPL+exception) is in place.
6
 */
7
#ifndef SCFACE_PS_H
8
#define SCFACE_PS_H
9
 
10151 cbradney 10
#include <QString>
11
#include <QStringList>
12
#include <QFont>
13
#include <QMap>
5979 avox 14
 
15
#include <ft2build.h>
16
#include FT_FREETYPE_H
17
#include FT_OUTLINE_H
18
#include FT_GLYPH_H
19
 
20
#include "scribusapi.h"
21
#include "fpointarray.h"
22
#include "scconfig.h"
23
 
24
 
25
/*
26
        Class ScFace_postscript
27
        Subclass of ScFace, for PostScript fonts that could possibly have a .afm file
28
        associated with them for metrics information.
29
*/
30
 
31
class ScFace_postscript : public FtFace
32
{
33
        public:
34
                ScFace_postscript(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) :
35
                FtFace(fam,sty,alt,scname,psname,path,face)
36
                {
37
                        isFixedPitch = false;
38
                        typeCode = ScFace::TYPE1;
39
                }
40
 
6307 avox 41
                virtual void load()  const // routine by Franz Schmid - modified by Alastair M. Robinson
5979 avox 42
                {
6307 avox 43
                        FtFace::load();
9380 fschmid 44
//                      bool error;
5979 avox 45
                        FT_Face face = ftFace();
46
                        if (!face)
47
                        {
6307 avox 48
                                const_cast<ScFace_postscript*>(this)->usable = false;
10561 fschmid 49
                                qDebug(QObject::tr("Font %1 is broken (no Face), discarding it").arg(fontFile).toLatin1().constData());
5979 avox 50
                                return;
51
                        }
52
                        QString afnm = fontFile.left(fontFile.length()-3);
53
                        QFile afm(afnm+"afm");
54
                        if(!(afm.exists()))
55
                        {
10561 fschmid 56
                                afm.setFileName(afnm+"Afm");
5979 avox 57
                        }
58
                        if(!(afm.exists()))
59
                        {
10561 fschmid 60
                                afm.setFileName(afnm+"AFM");
5979 avox 61
                        }
62
                        if(!(afm.exists()))
63
                        {
10561 fschmid 64
                                afm.setFileName(afnm+"pfm");
5979 avox 65
                        }
66
                        if(!(afm.exists()))
67
                        {
10561 fschmid 68
                                afm.setFileName(afnm+"Pfm");
5979 avox 69
                        }
70
                        if(!(afm.exists())) {
10561 fschmid 71
                                afm.setFileName(afnm+"PFM");
5979 avox 72
                        }
73
                        if (afm.exists())
8861 cbradney 74
                        {
10561 fschmid 75
                                if (FT_Attach_File(face, afm.fileName().toLatin1().constData()))
76
                                        qDebug(QObject::tr("Font %1 has broken metrics in file %2, ignoring metrics").arg(fontFile).arg(afm.fileName()).toLatin1().constData());
8861 cbradney 77
                                else
78
                                        // re-initialize: ScFaceData::load() just clears caches,
79
                                        // FtFace::load() skips FT_New_Face if m_face is already defined.
80
                                        // dont mind checking glyphs again for now (PS files have only 255 glyphs max, anyway)
81
                                        FtFace::load();
82
                        }
5979 avox 83
//                      Ascent = tmp.setNum(face->ascender);
84
//                      Descender = tmp.setNum(face->descender);
85
//                      CapHeight = Ascent;
86
//                      ItalicAngle = "0";
87
//                      StdVW = "1";
88
//                      FontBBox = tmp.setNum(face->bbox.xMin)+" "+tmp2.setNum(face->bbox.yMin)+" "+tmp3.setNum(face->bbox.xMax)+" "+tmp4.setNum(face->bbox.yMax);
89
/*
90
 setBestEncoding(face);
91
                        gindex = 0;
92
                        charcode = FT_Get_First_Char( face, &gindex );
93
                        int goodGlyph = 0;
94
                        int invalidGlyph = 0;
95
                        while ( gindex != 0 )
96
                        {
97
                                error = FT_Load_Glyph( face, gindex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
98
                                if (error)
99
                                {
100
                                        ++invalidGlyph;
101
                                        sDebug(QObject::tr("Font %1 has broken glyph %2 (charcode %3)").arg(fontPath()).arg(gindex).arg(charcode));
102
                                        charcode = FT_Get_Next_Char( face, charcode, &gindex );
103
                                        continue;
104
                                }
105
                                ++goodGlyph;
106
                                double ww = face->glyph->metrics.horiAdvance / uniEM;
107
                                if (face->glyph->format == FT_GLYPH_FORMAT_PLOTTER)
108
                                        isStroked = true;
109
                                error = false;
110
                                outlines = traceChar(face, charcode, 10, &x, &y, &error);
111
                                if (!error)
112
                                {
113
                                        CharWidth.insert(charcode, ww);
114
                                        GRec.Outlines = outlines.copy();
115
                                        GRec.x = x;
116
                                        GRec.y = y;
117
                                        GlyphArray.insert(charcode, GRec);
118
                                }
119
                                charcode = FT_Get_Next_Char( face, charcode, &gindex );
120
                        }
121
 */
122
                }
123
};
124
 
125
/*
126
        Class ScFace_pfb
127
        Subclass of ScFace, specifically for Adobe type 1 .pfb fonts.
128
        Implements: RealName() and EmbedFont().
129
*/
130
 
131
class ScFace_pfb : public ScFace_postscript
132
{
133
        public:
134
                ScFace_pfb(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) :
135
                ScFace_postscript(fam,sty,alt,scname,psname,path,face)
136
                {
137
                        formatCode = ScFace::PFB;
138
                }
139
 
6307 avox 140
                virtual bool EmbedFont(QString &str) const
5979 avox 141
                {
142
                        QByteArray bb;
143
                        RawData(bb);
144
                        QString tmp2 = "";
145
                        if ((bb.size() > 2) &&  (bb[0] == char(0x80)) && (static_cast<int>(bb[1]) == 1))
146
                        {
147
                                QString tmp3="";
148
                                QString tmp4 = "";
8570 jghali 149
                                int posi,cxxc=0;
5979 avox 150
                                for (posi = 6; posi < bb.size(); ++posi)
151
                                {
152
                                        if ((bb[posi] == char(0x80)) && (posi+1 < bb.size()) && (static_cast<int>(bb[posi+1]) == 2))
153
                                                break;
154
                                        str += bb[posi];
155
                                }
8570 jghali 156
                                int ulen;
5979 avox 157
                                if (posi+6 < bb.size())
158
                                {
159
                                        ulen = bb[posi+2] & 0xff;
160
                                        ulen |= (bb[posi+3] << 8) & 0xff00;
161
                                        ulen |= (bb[posi+4] << 16) & 0xff0000;
162
                                        ulen |= (bb[posi+5] << 24) & 0xff000000;
163
                                        posi += 6;
164
                                        if (posi + ulen > bb.size())
165
                                                ulen = bb.size() - posi - 1;
166
                                        char linebuf[80];
167
                                        cxxc=0;
8570 jghali 168
                                        for (int j = 0; j < ulen; ++j)
5979 avox 169
                                        {
170
                                                unsigned char u=bb[posi];
171
                                                linebuf[cxxc]=((u >> 4) & 15) + '0';
172
                                                if(u>0x9f) linebuf[cxxc]+='a'-':';
173
                                                ++cxxc;
174
                                                u&=15; linebuf[cxxc]=u + '0';
175
                                                if(u>0x9) linebuf[cxxc]+='a'-':';
176
                                                ++posi;
177
                                                ++cxxc;
178
                                                if (cxxc > 72)
179
                                                {
180
                                                        linebuf[cxxc++]='\n';
181
                                                        linebuf[cxxc++]=0;
182
                                                        str += linebuf;
183
                                                        cxxc = 0;
184
                                                }
185
                                        }
186
                                        linebuf[cxxc]=0;
187
                                        str += linebuf;
188
                                        str += "\n";
189
                                }
190
                                posi += 6;
8570 jghali 191
                                for (int j = posi; j < bb.size(); ++j)
5979 avox 192
                                {
193
                                        if ((bb[j] == static_cast<char>(0x80)) && (j+1 < bb.size()) && (static_cast<int>(bb[j+1]) == 3))
194
                                                break;
195
                                        if(bb[j]=='\r')
196
                                                str+="\n";
197
                                        else
198
                                                str += bb[j];
199
                                }
200
                                str += "\n";
201
                                cxxc = 0;
202
                                return true;
203
                        }
204
                        else
205
                        {
10561 fschmid 206
                                qDebug(QObject::tr("Font %1 cannot be read, no embedding").arg(fontFile).toLatin1().constData());
5979 avox 207
                                return false;
208
                        }
209
                }
210
};
211
 
212
/*
213
        Class ScFace_pfa
214
        Subclass of ScFace, specifically for Adobe type 1 and type 3 .pfa fonts.
215
        Implements: RealName() and EmbedFont().
216
*/
217
 
218
class ScFace_pfa : public ScFace_postscript
219
{
220
        public:
221
                ScFace_pfa(QString fam, QString sty, QString alt, QString scname, QString psname, QString path, int face) :
222
                ScFace_postscript(fam,sty,alt,scname,psname,path,face)
223
                {
224
                        formatCode = ScFace::PFA;
225
                }
6307 avox 226
                virtual bool EmbedFont(QString &str) const
5979 avox 227
                {
228
                        QByteArray bb;
229
                        RawData(bb);
230
                        if (bb.size() > 2 && bb[0] == '%' && bb[1] == '!')
231
                        {
232
                                // this is ok since bb will not contain '\0'
233
                                str.append(bb);
234
                                return true;
235
                        }
10561 fschmid 236
                        qDebug(QObject::tr("Font %1 cannot be read, no embedding").arg(fontFile).toLatin1().constData());
5979 avox 237
                        return false;
238
                }
239
};
240
 
241
 
242
#endif