Back to index

scribus-ng  1.3.4.dfsg+svn20071115
scface.h
Go to the documentation of this file.
00001 #ifndef SC_FACE_H
00002 #define SC_FACE_H
00003 
00004 /* ScFace responsibilities:
00005 
00006 font storage: type, format, filepath, index, document-local, substitute, etc.
00007 usage:        use, embed, subset, ...
00008 face info:    family, effect, alternative, flags, charset
00009 encoding:     CMap2String, glyphnames, 
00010 metrics:      cwidth, bearing, bbox, "real" widths, paths
00011 opentype:     apply features, script support (-)
00012 embedding:    fontdictionary, rawdata, embedPS, embedPDF, subsetPS, subsetPDF
00013 virtual:      dispatch to constituents, handle embedding (-)
00014 */
00015 
00016 #include <qstring.h>
00017 //#include <qvector.h>
00018 #include <qmap.h>
00019 //#include <qarray.h>
00020 #include <utility>
00021 
00022 #include "fpointarray.h"
00023 
00024 
00025 
00026 struct GlyphMetrics {
00027        double width;
00028        double ascent;
00029        double descent;
00030 };
00031 
00032 
00033 
00067 class SCRIBUS_API ScFace
00068 {
00069 public:
00070        enum Status  { UNKNOWN, LOADED, CHECKED, BROKENGLYPHS, BROKEN, NULLFACE };
00071        enum FontType { TYPE0, TYPE1, TYPE3, TTF, CFF, OTF, UNKNOWN_TYPE };
00072        enum FontFormat { PFA, PFB, TYPE2, TYPE42,
00073               // handled by freetype:     PFB_MAC, DFONT, HQX, MACBIN,
00074               SFNT, TTCF, UNKNOWN_FORMAT };
00075 
00076        static const uint CONTROL_GLYPHS = 2000000000; // 2 billion
00077        
00078        struct GlyphData { 
00079               FPointArray Outlines;
00080               double x;
00081               double y;
00082               double bbox_width;
00083               double bbox_ascent;
00084               double bbox_descent;
00085               bool broken;
00086               GlyphData() : Outlines(), x(0), y(0), bbox_width(1), bbox_ascent(1), bbox_descent(0), broken(true) {}
00087        };
00088        
00089        
00091        class ScFaceData {
00092        public:
00094               mutable int refs;
00096               mutable int usage;
00097               
00098               QString scName;
00099               QString fontFile;
00100               int     faceIndex;
00101               QString psName;
00102               QString family;
00103               QString style;
00104               QString variant;
00105 
00106               QString forDocument;
00107 
00108               mutable ScFace::Status status;
00109               ScFace::FontType typeCode;
00110               ScFace::FontFormat formatCode;
00111               
00112               bool usable;
00113               bool embedPs;
00114               bool subset;
00115               
00116               bool isStroked;
00117               bool isFixedPitch;
00118               bool hasNames;
00119               uint maxGlyph;
00120 
00121               ScFaceData();
00122               virtual ~ScFaceData() { };
00123        protected:
00124                      
00125               friend class ScFace;
00126               Status cachedStatus;
00127               
00128               // caches
00129               mutable QMap<uint,double>    m_glyphWidth;
00130               mutable QMap<uint,GlyphData> m_glyphOutline;
00131               mutable QMap<uint, uint>     m_cMap;
00132               
00133               // fill caches & members
00134               
00135               virtual void load()             const 
00136               { 
00137                      m_glyphWidth.clear();
00138                      m_glyphOutline.clear();
00139                      m_cMap.clear();
00140 
00141                      status = QMAX(cachedStatus, ScFace::LOADED);
00142               }
00143               
00144               virtual void unload()           const 
00145               {
00146                      m_glyphWidth.clear();
00147                      m_glyphOutline.clear();
00148                      m_cMap.clear();
00149 
00150                      status = ScFace::UNKNOWN;
00151               }
00152               
00153               virtual void loadGlyph(uint /*gl*/) const {}
00154 
00155               // dummy implementations
00156               virtual double ascent(double sz)           const { return sz; }
00157               virtual QString ascentAsString()    const { return "0" ; }
00158               virtual QString descentAsString()    const { return "0"; }
00159               virtual QString capHeightAsString()    const { return "0"; }
00160               virtual QString FontBBoxAsString()    const { return "0 0 0 0"; }
00161               virtual QString ItalicAngleAsString()    const { return "0"; }
00162               virtual double descent(double /*sz*/)          const { return 0.0; }
00163               virtual double xHeight(double sz)          const { return sz; }
00164               virtual double capHeight(double sz)        const { return sz; }
00165               virtual double height(double sz)           const { return sz; }
00166               virtual double strikeoutPos(double sz)     const { return sz / 2; }
00167               virtual double underlinePos(double /*sz*/)     const { return -1.0; }
00168               virtual double strokeWidth(double /*sz*/)      const { return 0.1; }
00169               virtual double maxAdvanceWidth(double sz)  const { return sz; }
00170               virtual uint   char2CMap(QChar /*ch*/)         const { return 0; }
00171               virtual double glyphKerning(uint gl1, uint gl2, double sz) const;
00172               virtual QMap<QString,QString> fontDictionary(double sz=1.0) const;
00173               virtual GlyphMetrics glyphBBox(uint gl, double sz) const;
00174               virtual bool EmbedFont(QString &/*str*/)       const { return false; }
00175               virtual void RawData(QByteArray & /*bb*/)      const {}
00176               virtual bool glyphNames(QMap<uint, std::pair<QChar, QString> >& gList) const;
00177 
00178               // these use the cache:
00179               virtual double      glyphWidth(uint gl, double sz)   const;
00180               virtual FPointArray glyphOutline(uint gl, double sz) const; 
00181               virtual FPoint      glyphOrigin (uint gl, double sz) const;
00182               
00183        };
00184               
00185        
00186        
00187        ScFace();
00188        ScFace(const ScFace& other);
00189        ~ScFace();
00190 
00192        static const ScFace& none();
00193 
00195        bool isNone() const   { return m->status == NULLFACE; }
00196        
00197        ScFace& operator=(const ScFace& other);
00201        bool operator==(const ScFace& other) const ;
00202        bool operator!=(const ScFace& other) const { return ! (*this == other); }
00203        
00204        
00205        bool EmbedFont(QString &str);
00206        void RawData(QByteArray & bb);
00207        bool glyphNames(QMap<uint, std::pair<QChar, QString> >& gList);
00208        
00210        void increaseUsage() const;
00211        
00213        void decreaseUsage() const;
00214        
00216        void unload()      const;
00217        
00219        QString scName()   const { return replacedName.isEmpty() ? m->scName : replacedName; }
00220        
00222        QString replacementName()   const { return m->scName; }
00223        
00225        QString replacementForDoc()   const { return replacedInDoc; }
00226        
00228        bool isReplacement()   const { return !replacedName.isEmpty(); }
00229        
00231        ScFace mkReplacementFor(QString name, QString doc) { 
00232               ScFace result(m); 
00233               result.replacedName = name; 
00234               result.replacedInDoc = doc; 
00235               return result; 
00236        }
00237 
00238        void chReplacementTo(ScFace& other, QString doc) { 
00239               QString oldName = replacedName;
00240               (*this) = other;
00241               replacedName = oldName;
00242               replacedInDoc = doc; 
00243        }
00244        
00246        QString psName()   const { return m->psName; }
00247        
00249        QString fontPath() const { return m->faceIndex >= 0 ? QString("%1(%2)").arg(m->fontFile).arg(m->faceIndex+1) : m->fontFile; }
00250        
00252        QString fontFilePath()      const { return m->fontFile; }
00253        
00255        int faceIndex()    const { return m->faceIndex; }
00256        
00258        QString localForDocument()  const { return m->forDocument; }
00259        
00261        FontType type()    const { return m->typeCode; }
00262        
00264        FontFormat format()const { return m->formatCode; }
00265        
00267        bool usable()      const { return m->usable && !isNone(); }
00268        
00270        bool embedPs()     const { return m->embedPs && m->status < BROKENGLYPHS; }
00271        
00273        bool subset()      const { return m->subset && m->status < BROKEN; }
00274        
00275        void usable(bool flag)   { m->usable = flag; }
00276        void embedPs(bool flag)  { m->embedPs = flag; }
00277        void subset(bool flag)   { m->subset = flag; }
00278        
00280        bool hasNames()    const { return m->hasNames; }
00281 
00283        bool isStroked()   const { return m->isStroked; }
00284 
00286        bool isFixedPitch()const { return m->isFixedPitch; }
00287        
00289        bool isOTF()       const { return m->typeCode == OTF; }
00290               
00292        uint maxGlyph()    const { return m->maxGlyph; }
00293        
00295        QString family()   const { return m->family; }
00296        
00298        QString style()    const { return m->style; }
00299        
00301        QString variant()  const { return m->variant; }
00302        
00303        // font metrics
00304        double ascent(double sz=1.0)          const { return m->ascent(sz); }
00305        QString ascentAsString()    const { return m->ascentAsString() ; }
00306        QString descentAsString()    const { return m->descentAsString() ; }
00307        QString capHeightAsString()    const { return m->capHeightAsString() ; }
00308        QString FontBBoxAsString()    const { return m->FontBBoxAsString() ; }
00309        QString ItalicAngleAsString()    const { return m->ItalicAngleAsString() ; }
00310        double descent(double sz=1.0)         const { return m->descent(sz); }
00311        double xHeight(double sz=1.0)         const { return m->xHeight(sz); }
00312        double capHeight(double sz=1.0)       const { return m->capHeight(sz); }
00313        double height(double sz=1.0)          const { return m->height(sz); }
00314        double strikeoutPos(double sz=1.0)    const { return m->strikeoutPos(sz); }
00315        double underlinePos(double sz=1.0)    const { return m->underlinePos(sz); }
00316        double strokeWidth(double sz=1.0)     const { return m->strokeWidth(sz); }
00317        double maxAdvanceWidth(double sz=1.0) const { return m->maxAdvanceWidth(sz); }
00318        
00320        QString stemV(double sz=1.0)    const { return fontDictionary(sz)["/StemV"]; }
00321        
00323        QString italicAngle(double sz=1.0)      const { return fontDictionary(sz)["/ItalicAngle"]; }
00324        
00326        QString fontBBox(double sz=1.0)         const { return fontDictionary(sz)["/FontBBox"]; }
00327 
00329        QMap<QString,QString> fontDictionary(double sz=1.0) const { return m->fontDictionary(sz); }       
00330        // glyph interface
00331        
00333        double glyphWidth(uint gl, double sz=1.0) const { return m->glyphWidth(gl, sz); }
00334 
00336        double glyphKerning(uint gl1, uint gl2, double sz=1.0) const { return QMAX(gl1,gl2) < CONTROL_GLYPHS ? m->glyphKerning(gl1, gl2, sz) : 0; } 
00337 
00339        GlyphMetrics glyphBBox(uint gl, double sz=1.0) const { return m->glyphBBox(gl, sz); }
00340 
00342        FPointArray glyphOutline(uint gl, double sz=1.0) const { return m->glyphOutline(gl, sz); }
00343 
00345        FPoint glyphOrigin(uint gl, double sz=1.0)    const { return m->glyphOrigin(gl, sz); }
00346        
00347        // char interface
00348 
00350        bool canRender(QChar ch)   const;
00351 
00353        uint char2CMap(QChar ch)   const;
00354 
00356        double charWidth(QChar ch, double sz=1.0, QChar ch2 = QChar(0)) const;
00357        
00359        double realCharWidth(QChar ch, double sz=1.0) const { return glyphBBox(char2CMap(ch),sz).width; }
00360        
00362        double realCharHeight(QChar ch, double sz=1.0) const { GlyphMetrics gm=glyphBBox(char2CMap(ch),sz); return gm.ascent + gm.descent; }
00363        
00365        double realCharAscent(QChar ch, double sz=1.0) const { return glyphBBox(char2CMap(ch),sz).ascent; }
00366        
00368        double realCharDescent(QChar ch, double sz=1.0) const { return glyphBBox(char2CMap(ch),sz).descent; }
00369        
00370 private:
00371               
00372        friend class SCFonts;
00373        
00374        ScFace(ScFaceData* md);
00375        ScFaceData* m;
00376        QString replacedName;
00377        QString replacedInDoc;
00378        
00379        void initFaceData();
00380        void checkAllGlyphs();
00381        uint emulateGlyph(QChar c) const;
00382 };
00383 
00384 #endif