00001 #ifndef SC_FACE_H
00002 #define SC_FACE_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <QString>
00017
00018 #include <QMap>
00019
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
00074 SFNT, TTCF, UNKNOWN_FORMAT };
00075
00076 static const uint CONTROL_GLYPHS = 2000000000;
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
00129 mutable QMap<uint,double> m_glyphWidth;
00130 mutable QMap<uint,GlyphData> m_glyphOutline;
00131 mutable QMap<uint, uint> m_cMap;
00132
00133
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 ) const {}
00154
00155
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 ) 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 ) const { return -1.0; }
00168 virtual double strokeWidth(double ) const { return 0.1; }
00169 virtual double maxAdvanceWidth(double sz) const { return sz; }
00170 virtual uint char2CMap(QChar ) 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 &) const { return false; }
00175 virtual void RawData(QByteArray & ) const {}
00176 virtual bool glyphNames(QMap<uint, std::pair<QChar, QString> >& gList) const;
00177
00178
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
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
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
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