Scribus
Open source desktop publishing at your fingertips
scface.h
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 
8 #ifndef SC_FACE_H
9 #define SC_FACE_H
10 
11 /* ScFace responsibilities:
12 
13 font storage: type, format, filepath, index, document-local, substitute, etc.
14 usage: use, embed, subset, ...
15 face info: family, effect, alternative, flags, charset
16 encoding: CMap2String, glyphnames,
17 metrics: cwidth, bearing, bbox, "real" widths, paths
18 opentype: apply features, script support (-)
19 embedding: fontdictionary, rawdata, embedPS, embedPDF, subsetPS, subsetPDF
20 virtual: dispatch to constituents, handle embedding (-)
21 */
22 
23 #include <QHash>
24 #include <QMap>
25 #include <QString>
26 #include <utility>
27 
28 #include "fpointarray.h"
29 
30 
31 
32 struct GlyphMetrics {
33  qreal width;
34  qreal ascent;
35  qreal descent;
36 };
37 
38 
39 
73 class SCRIBUS_API ScFace
74 {
75 public:
76  enum Status { UNKNOWN, LOADED, CHECKED, BROKENGLYPHS, BROKEN, NULLFACE };
77  enum FontType { TYPE0, TYPE1, TYPE3, TTF, CFF, OTF, UNKNOWN_TYPE };
78  enum FontFormat { PFA, PFB, TYPE2, TYPE42,
79  // handled by freetype: PFB_MAC, DFONT, HQX, MACBIN,
80  SFNT, TTCF, UNKNOWN_FORMAT };
81 
82  typedef uint gid_type;
83  typedef uint ucs4_type;
84  typedef QMap<gid_type, std::pair<ucs4_type, QString> > FaceEncoding;
85 
86  static const gid_type CONTROL_GLYPHS = 2000000000; // 2 billion
87 
88  struct GlyphData {
89  FPointArray Outlines;
90  qreal x;
91  qreal y;
92  qreal bbox_width;
93  qreal bbox_ascent;
94  qreal bbox_descent;
95  bool broken;
96  GlyphData() : Outlines(), x(0), y(0), bbox_width(1), bbox_ascent(1), bbox_descent(0), broken(true) {}
97  };
98 
99 
101  class ScFaceData {
102  public:
104  mutable int refs;
106  mutable int usage;
107 
108  QString scName;
109  QString fontFile;
110  int faceIndex;
111  QString psName;
112  QString family;
113  QString style;
114  QString variant;
115 
116  QString forDocument;
117 
118  mutable ScFace::Status status;
119  ScFace::FontType typeCode;
120  ScFace::FontFormat formatCode;
121 
122  bool usable;
123  bool embedPs;
124  bool subset;
125  bool outline;
126 
127  bool isStroked;
128  bool isFixedPitch;
129  bool hasGlyphNames;
130  gid_type maxGlyph;
131 
132  ScFaceData();
133  virtual ~ScFaceData() { };
134  protected:
135 
136  friend class ScFace;
137  Status cachedStatus;
138 
139  // caches
140  mutable QHash<gid_type, qreal> m_glyphWidth;
141  mutable QHash<gid_type, GlyphData> m_glyphOutline;
142  //mutable QHash<gid_type, uint> m_cMap;
143 
144  // fill caches & members
145 
146  virtual void load() const
147  {
148  m_glyphWidth.clear();
149  m_glyphOutline.clear();
150  //m_cMap.clear();
151 
152  status = qMax(cachedStatus, ScFace::LOADED);
153  }
154 
155  virtual void unload() const
156  {
157  m_glyphWidth.clear();
158  m_glyphOutline.clear();
159  //m_cMap.clear();
160 
161  status = ScFace::UNKNOWN;
162  }
163 
164  virtual void loadGlyph(gid_type /*gl*/) const {}
165 
166  // dummy implementations
167  virtual qreal ascent(qreal sz) const { return sz; }
168  virtual QString pdfAscentAsString() const { return "0" ; }
169  virtual QString pdfDescentAsString() const { return "0"; }
170  virtual QString pdfCapHeightAsString() const { return "0"; }
171  virtual QString pdfFontBBoxAsString() const { return "0 0 0 0"; }
172  virtual QString italicAngleAsString() const { return "0"; }
173  virtual qreal descent(qreal /*sz*/) const { return 0.0; }
174  virtual qreal xHeight(qreal sz) const { return sz; }
175  virtual qreal capHeight(qreal sz) const { return sz; }
176  virtual qreal height(qreal sz) const { return sz; }
177  virtual qreal strikeoutPos(qreal sz) const { return sz / 2; }
178  virtual qreal underlinePos(qreal /*sz*/) const { return -1.0; }
179  virtual qreal strokeWidth(qreal /*sz*/) const { return 0.1; }
180  virtual qreal maxAdvanceWidth(qreal sz) const { return sz; }
181  virtual gid_type char2CMap(QChar /*ch*/) const { return 0; }
182  virtual qreal glyphKerning(gid_type gl1, gid_type gl2, qreal sz) const;
183  virtual QMap<QString,QString> fontDictionary(qreal sz=1.0) const;
184  virtual GlyphMetrics glyphBBox(gid_type gl, qreal sz) const;
185  virtual bool EmbedFont(QByteArray &/*str*/) const { return false; }
186  virtual void RawData(QByteArray & /*bb*/) const {}
187 
188  virtual bool hasNames() const { return hasGlyphNames; }
189  virtual bool glyphNames(QMap<gid_type, std::pair<ucs4_type, QString> >& gList) const;
190 
191  // these use the cache:
192  virtual qreal glyphWidth(gid_type gl, qreal sz) const;
193  virtual FPointArray glyphOutline(gid_type gl, qreal sz) const;
194  virtual FPoint glyphOrigin (gid_type gl, qreal sz) const;
195 
196  virtual bool isSymbolic() const { return false; }
197  };
198 
199 
200 
201  ScFace();
202  ScFace(const ScFace& other);
203  ~ScFace();
204 
206  static const ScFace& none();
207 
209  bool isNone() const { return m->status == NULLFACE; }
210 
212  bool isSymbolic() const;
213 
214  ScFace& operator=(const ScFace& other);
218  bool operator==(const ScFace& other) const ;
219  bool operator!=(const ScFace& other) const { return ! (*this == other); }
220 
221 
222  bool EmbedFont(QByteArray &str);
223  void RawData(QByteArray & bb);
224  bool glyphNames(QMap<gid_type, std::pair<ucs4_type, QString> >& gList);
225 
227  void increaseUsage() const;
228 
230  void decreaseUsage() const;
231 
233  void unload() const;
234 
236  QString scName() const { return replacedName.isEmpty() ? m->scName : replacedName; }
237 
239  QString replacementName() const { return m->scName; }
240 
242  QString replacementForDoc() const { return replacedInDoc; }
243 
245  bool isReplacement() const { return !replacedName.isEmpty(); }
246 
248  ScFace mkReplacementFor(QString name, QString doc) {
249  ScFace result(m);
250  result.replacedName = name;
251  result.replacedInDoc = doc;
252  return result;
253  }
254 
255  void chReplacementTo(ScFace& other, QString doc) {
256  QString oldName = replacedName;
257  (*this) = other;
258  replacedName = oldName;
259  replacedInDoc = doc;
260  }
261 
263  QString psName() const { return m->psName; }
264 
266  QString fontPath() const { return m->faceIndex >= 0 ? QString("%1(%2)").arg(m->fontFile).arg(m->faceIndex+1) : m->fontFile; }
267 
269  QString fontFilePath() const { return m->fontFile; }
270 
272  int faceIndex() const { return m->faceIndex; }
273 
275  QString localForDocument() const { return m->forDocument; }
276 
278  FontType type() const { return m->typeCode; }
279 
281  FontFormat format()const { return m->formatCode; }
282 
284  bool usable() const { return m->usable && !isNone(); }
285 
287  bool outline() const { return usable() && m->outline; }
288 
290  bool embedPs() const { return m->embedPs && m->status < BROKENGLYPHS; }
291 
293  bool subset() const { return m->subset && m->status < BROKEN; }
294 
295  void usable(bool flag) { m->usable = flag; }
296  void embedPs(bool flag) { m->embedPs = flag; }
297  void subset(bool flag) { m->subset = flag; }
298  void outline(bool flag) { m->outline = flag; }
299 
301  bool hasNames() const { return m->hasNames(); }
302 
304  bool isStroked() const { return m->isStroked; }
305 
307  bool isFixedPitch()const { return m->isFixedPitch; }
308 
310  bool isOTF() const { return m->typeCode == OTF; }
311 
313  gid_type maxGlyph() const { return m->maxGlyph; }
314 
316  QString family() const { return m->family; }
317 
319  QString style() const { return m->style; }
320 
322  QString variant() const { return m->variant; }
323 
324  // font metrics
325  QString pdfAscentAsString() const;
326  QString pdfDescentAsString() const;
327  QString pdfCapHeightAsString() const;
328  QString pdfFontBBoxAsString() const;
329  QString italicAngleAsString() const;
330  qreal ascent(qreal sz=1.0) const;
331  qreal descent(qreal sz=1.0) const;
332  qreal xHeight(qreal sz=1.0) const;
333  qreal capHeight(qreal sz=1.0) const;
334  qreal height(qreal sz=1.0) const;
335  qreal strikeoutPos(qreal sz=1.0) const;
336  qreal underlinePos(qreal sz=1.0) const;
337  qreal strokeWidth(qreal sz=1.0) const;
338  qreal maxAdvanceWidth(qreal sz=1.0) const;
339 
341  QString stemV(qreal sz=1.0) const { return fontDictionary(sz)["/StemV"]; }
342 
344  QString italicAngle(qreal sz=1.0) const { return fontDictionary(sz)["/ItalicAngle"]; }
345 
347  QString fontBBox(qreal sz=1.0) const { return fontDictionary(sz)["/FontBBox"]; }
348 
350  QMap<QString,QString> fontDictionary(qreal sz=1.0) const { return m->fontDictionary(sz); }
351  // glyph interface
352 
354  qreal glyphWidth(gid_type gl, qreal sz=1.0) const { return m->glyphWidth(gl, sz); }
355 
357  qreal glyphKerning(gid_type gl1, gid_type gl2, qreal sz=1.0) const { return qMax(gl1,gl2) < CONTROL_GLYPHS ? m->glyphKerning(gl1, gl2, sz) : 0; }
358 
360  GlyphMetrics glyphBBox(gid_type gl, qreal sz=1.0) const { return m->glyphBBox(gl, sz); }
361 
363  FPointArray glyphOutline(gid_type gl, qreal sz=1.0) const { return m->glyphOutline(gl, sz); }
364 
366  FPoint glyphOrigin(gid_type gl, qreal sz=1.0) const { return m->glyphOrigin(gl, sz); }
367 
368  // char interface
369 
371  bool canRender(QChar ch) const;
372 
374  gid_type char2CMap(QChar ch) const;
375 
377  qreal charWidth(QChar ch, qreal sz=1.0, QChar ch2 = QChar(0)) const;
378 
380  qreal realCharWidth(QChar ch, qreal sz=1.0) const { return glyphBBox(char2CMap(ch),sz).width; }
381 
383  qreal realCharHeight(QChar ch, qreal sz=1.0) const { GlyphMetrics gm=glyphBBox(char2CMap(ch),sz); return gm.ascent + gm.descent; }
384 
386  qreal realCharAscent(QChar ch, qreal sz=1.0) const { return glyphBBox(char2CMap(ch),sz).ascent; }
387 
389  qreal realCharDescent(QChar ch, qreal sz=1.0) const { return glyphBBox(char2CMap(ch),sz).descent; }
390 
391 private:
392 
393  friend class SCFonts;
394 
395  ScFace(ScFaceData* md);
396  ScFaceData* m;
397  QString replacedName;
398  QString replacedInDoc;
399 
400  void initFaceData();
401  void checkAllGlyphs();
402  gid_type emulateGlyph(QChar c) const;
403 };
404 
405 #endif
int usage
controls load()
Definition: scface.h:106
QString style() const
returns the font style as seen by Scribus (eg. bold, Italic)
Definition: scface.h:319
bool isOTF() const
tells if this is an OTF/CFF font
Definition: scface.h:310
static const ScFace & none()
used as a null object
Definition: scface.cpp:198
QString fontBBox(qreal sz=1.0) const
deprecated
Definition: scface.h:347
gid_type maxGlyph() const
returns the highest glyph index in this face
Definition: scface.h:313
QString fontPath() const
the physical location of the fontfile
Definition: scface.h:266
Definition: scface.h:88
gid_type char2CMap(QChar ch) const
translate unicode to glyph index
Definition: scface.cpp:365
qreal glyphKerning(gid_type gl1, gid_type gl2, qreal sz=1.0) const
returns the glyph kerning between 'gl1' and 'gl2' at size 'sz'
Definition: scface.h:357
QString fontFilePath() const
the file path of the fontfile
Definition: scface.h:269
GlyphMetrics glyphBBox(gid_type gl, qreal sz=1.0) const
returns the glyphs bounding box at size 'sz', ie. the area where this glyph will produce marks ...
Definition: scface.h:360
bool embedPs() const
test if this face can be embedded in PS/PDF
Definition: scface.h:290
void decreaseUsage() const
unload face data if not used any more
Definition: scface.cpp:328
FontFormat format() const
font format, which might be a little more complicated
Definition: scface.h:281
bool canRender(QChar ch) const
test if the face can render this char
Definition: scface.cpp:383
qreal realCharDescent(QChar ch, qreal sz=1.0) const
deprecated, see glyphBBox()
Definition: scface.h:389
bool subset() const
test if this face can be embedded as outlines in PS/PDF
Definition: scface.h:293
qreal charWidth(QChar ch, qreal sz=1.0, QChar ch2=QChar(0)) const
returns the combined glyph width and kerning for 'ch' if followed by 'ch2'
Definition: scface.cpp:402
QString italicAngle(qreal sz=1.0) const
deprecated
Definition: scface.h:344
QString replacementName() const
the name of the font which was used for replacement
Definition: scface.h:239
bool isReplacement() const
check if this is a replacement font
Definition: scface.h:245
QString replacementForDoc() const
the name of the font which was used for replacement
Definition: scface.h:242
void increaseUsage() const
prevent unloading of face data
Definition: scface.cpp:322
bool isNone() const
test for null object
Definition: scface.h:209
QString family() const
returns the font family as seen by Scribus
Definition: scface.h:316
int refs
controls destruction
Definition: scface.h:104
bool isStroked() const
tells if this font is an outline font
Definition: scface.h:304
Definition: scface.h:32
qreal glyphWidth(gid_type gl, qreal sz=1.0) const
returns the glyphs normal advance width at size 'sz'
Definition: scface.h:354
A point with floating point precision.
Definition: fpoint.h:43
FontType type() const
font type, eg. Type1 or TTF
Definition: scface.h:278
qreal realCharHeight(QChar ch, qreal sz=1.0) const
deprecated, see glyphBBox()
Definition: scface.h:383
bool usable() const
test if this face can be used in documents
Definition: scface.h:284
bool hasNames() const
deprecated? tells if the face has PS names
Definition: scface.h:301
QMap< QString, QString > fontDictionary(qreal sz=1.0) const
returns a map of values used for font dictionaries in PS/PDF
Definition: scface.h:350
void unload() const
unload face data. It will be reloaded on need
Definition: scface.cpp:336
bool isSymbolic() const
test if font is a symbolic font
Definition: scface.cpp:204
bool operator==(const ScFace &other) const
Definition: scface.cpp:185
FPoint glyphOrigin(gid_type gl, qreal sz=1.0) const
returns the glyph's origin FIXME: what's that exactly?
Definition: scface.h:366
QString variant() const
returns an additional discriminating String for this face
Definition: scface.h:322
qreal realCharAscent(QChar ch, qreal sz=1.0) const
deprecated, see glyphBBox()
Definition: scface.h:386
Base Class ScFace : This is a total rewrite of the old Foi class.
Definition: scface.h:73
see accessors for ScFace for docs
Definition: scface.h:101
QString scName() const
the name Scribus uses for this font
Definition: scface.h:236
bool outline() const
test if this face should be outlined in documents
Definition: scface.h:287
bool isFixedPitch() const
tells if this font is a fixed pitch font
Definition: scface.h:307
FPointArray glyphOutline(gid_type gl, qreal sz=1.0) const
returns the glyph's outline as a cubic Bezier path
Definition: scface.h:363
Definition: fpointarray.h:42
QString stemV(qreal sz=1.0) const
deprecated
Definition: scface.h:341
qreal realCharWidth(QChar ch, qreal sz=1.0) const
deprecated, see glyphBBox()
Definition: scface.h:380
ScFace mkReplacementFor(QString name, QString doc)
makes a repalcement font for font "name" using this fonts data
Definition: scface.h:248
int faceIndex() const
if the fontfile contains more than one face, the index, else -1
Definition: scface.h:272
QString localForDocument() const
path name of the document this face is local to
Definition: scface.h:275
QString psName() const
the name PostScript uses for this font
Definition: scface.h:263
Main class SCFonts. Subclass of QDict. This class replaces the previous SCFonts typedef...
Definition: scfonts.h:36