~ubuntu-branches/debian/jessie/scummvm/jessie

« back to all changes in this revision

Viewing changes to graphics/fonts/ttf.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2014-08-10 00:50:36 UTC
  • mfrom: (1.2.22)
  • Revision ID: package-import@ubuntu.com-20140810005036-wls6i0dsxqfxu70g
Tags: 1.7.0+dfsg-1
* New upstream release [July 2014].
  - remove old/obsolete patches.
  + added new "drop1test.patch" to disable problematic test.
  + build with "--disable-eventrecorder" to avoid FTBFS in tests.
  + added "libjpeg-dev" and "libfaad-dev" to Build-Depends.
* Install all arch-independent files (themes, game data, etc.).
* Build-time re-compression of "classic" theme.
* Added "debian/gbp.conf".
* Standards-Version to 3.9.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
101
101
        TTFFont();
102
102
        virtual ~TTFFont();
103
103
 
104
 
        bool load(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping);
 
104
        bool load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping);
105
105
 
106
106
        virtual int getFontHeight() const;
107
107
 
108
108
        virtual int getMaxCharWidth() const;
109
109
 
110
 
        virtual int getCharWidth(byte chr) const;
111
 
 
112
 
        virtual int getKerningOffset(byte left, byte right) const;
113
 
 
114
 
        virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
 
110
        virtual int getCharWidth(uint32 chr) const;
 
111
 
 
112
        virtual int getKerningOffset(uint32 left, uint32 right) const;
 
113
 
 
114
        virtual void drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const;
115
115
private:
116
116
        bool _initialized;
117
117
        FT_Face _face;
126
126
                Surface image;
127
127
                int xOffset, yOffset;
128
128
                int advance;
 
129
                FT_UInt slot;
129
130
        };
130
131
 
131
 
        bool cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr);
132
 
        typedef Common::HashMap<byte, Glyph> GlyphCache;
133
 
        GlyphCache _glyphs;
134
 
 
135
 
        FT_UInt _glyphSlots[256];
136
 
 
137
 
        bool _monochrome;
 
132
        bool cacheGlyph(Glyph &glyph, uint32 chr) const;
 
133
        typedef Common::HashMap<uint32, Glyph> GlyphCache;
 
134
        mutable GlyphCache _glyphs;
 
135
        bool _allowLateCaching;
 
136
        void assureCached(uint32 chr) const;
 
137
 
 
138
        FT_Int32 _loadFlags;
 
139
        FT_Render_Mode _renderMode;
138
140
        bool _hasKerning;
139
141
};
140
142
 
141
143
TTFFont::TTFFont()
142
144
    : _initialized(false), _face(), _ttfFile(0), _size(0), _width(0), _height(0), _ascent(0),
143
 
      _descent(0), _glyphs(), _glyphSlots(), _monochrome(false), _hasKerning(false) {
 
145
      _descent(0), _glyphs(), _loadFlags(FT_LOAD_TARGET_NORMAL), _renderMode(FT_RENDER_MODE_NORMAL),
 
146
      _hasKerning(false), _allowLateCaching(false) {
144
147
}
145
148
 
146
149
TTFFont::~TTFFont() {
157
160
        }
158
161
}
159
162
 
160
 
bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping) {
 
163
bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) {
161
164
        if (!g_ttf.isInitialized())
162
165
                return false;
163
166
 
202
205
                return false;
203
206
        }
204
207
 
205
 
        _monochrome = monochrome;
 
208
        switch (renderMode) {
 
209
        case kTTFRenderModeNormal:
 
210
                _loadFlags = FT_LOAD_TARGET_NORMAL;
 
211
                _renderMode = FT_RENDER_MODE_NORMAL;
 
212
                break;
 
213
 
 
214
        case kTTFRenderModeLight:
 
215
                _loadFlags = FT_LOAD_TARGET_LIGHT;
 
216
                _renderMode = FT_RENDER_MODE_LIGHT;
 
217
                break;
 
218
 
 
219
        case kTTFRenderModeMonochrome:
 
220
                _loadFlags = FT_LOAD_TARGET_MONO;
 
221
                _renderMode = FT_RENDER_MODE_MONO;
 
222
                break;
 
223
        }
206
224
 
207
225
        FT_Fixed yScale = _face->size->metrics.y_scale;
208
226
        _ascent = ftCeil26_6(FT_MulFix(_face->ascender, yScale));
212
230
        _height = _ascent - _descent + 1;
213
231
 
214
232
        if (!mapping) {
 
233
                // Allow loading of all unicode characters.
 
234
                _allowLateCaching = true;
 
235
 
215
236
                // Load all ISO-8859-1 characters.
216
237
                for (uint i = 0; i < 256; ++i) {
217
 
                        if (!cacheGlyph(_glyphs[i], _glyphSlots[i], i))
218
 
                                _glyphSlots[i] = 0;
 
238
                        if (!cacheGlyph(_glyphs[i], i)) {
 
239
                                _glyphs.erase(i);
 
240
                        }
219
241
                }
220
242
        } else {
 
243
                // We have a fixed map of characters do not load more later.
 
244
                _allowLateCaching = false;
 
245
 
221
246
                for (uint i = 0; i < 256; ++i) {
222
247
                        const uint32 unicode = mapping[i] & 0x7FFFFFFF;
223
248
                        const bool isRequired = (mapping[i] & 0x80000000) != 0;
224
249
                        // Check whether loading an important glyph fails and error out if
225
250
                        // that is the case.
226
 
                        if (!cacheGlyph(_glyphs[i], _glyphSlots[i], unicode)) {
227
 
                                _glyphSlots[i] = 0;
 
251
                        if (!cacheGlyph(_glyphs[i], unicode)) {
 
252
                                _glyphs.erase(i);
228
253
                                if (isRequired)
229
254
                                        return false;
230
255
                        }
243
268
        return _width;
244
269
}
245
270
 
246
 
int TTFFont::getCharWidth(byte chr) const {
 
271
int TTFFont::getCharWidth(uint32 chr) const {
 
272
        assureCached(chr);
247
273
        GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
248
274
        if (glyphEntry == _glyphs.end())
249
275
                return 0;
251
277
                return glyphEntry->_value.advance;
252
278
}
253
279
 
254
 
int TTFFont::getKerningOffset(byte left, byte right) const {
 
280
int TTFFont::getKerningOffset(uint32 left, uint32 right) const {
255
281
        if (!_hasKerning)
256
282
                return 0;
257
283
 
258
 
        FT_UInt leftGlyph = _glyphSlots[left];
259
 
        FT_UInt rightGlyph = _glyphSlots[right];
 
284
        assureCached(left);
 
285
        assureCached(right);
 
286
 
 
287
        FT_UInt leftGlyph, rightGlyph;
 
288
        GlyphCache::const_iterator glyphEntry;
 
289
 
 
290
        glyphEntry = _glyphs.find(left);
 
291
        if (glyphEntry != _glyphs.end()) {
 
292
                leftGlyph = glyphEntry->_value.slot;
 
293
        } else {
 
294
                return 0;
 
295
        }
 
296
 
 
297
        glyphEntry = _glyphs.find(right);
 
298
        if (glyphEntry != _glyphs.end()) {
 
299
                rightGlyph = glyphEntry->_value.slot;
 
300
        } else {
 
301
                return 0;
 
302
        }
260
303
 
261
304
        if (!leftGlyph || !rightGlyph)
262
305
                return 0;
304
347
 
305
348
} // End of anonymous namespace
306
349
 
307
 
void TTFFont::drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const {
 
350
void TTFFont::drawChar(Surface *dst, uint32 chr, int x, int y, uint32 color) const {
 
351
        assureCached(chr);
308
352
        GlyphCache::const_iterator glyphEntry = _glyphs.find(chr);
309
353
        if (glyphEntry == _glyphs.end())
310
354
                return;
322
366
        int w = glyph.image.w;
323
367
        int h = glyph.image.h;
324
368
 
325
 
        const uint8 *srcPos = (const uint8 *)glyph.image.getBasePtr(0, 0);
 
369
        const uint8 *srcPos = (const uint8 *)glyph.image.getPixels();
326
370
 
327
371
        // Make sure we are not drawing outside the screen bounds
328
372
        if (x < 0) {
376
420
        }
377
421
}
378
422
 
379
 
bool TTFFont::cacheGlyph(Glyph &glyph, FT_UInt &slot, uint chr) {
380
 
        slot = FT_Get_Char_Index(_face, chr);
 
423
bool TTFFont::cacheGlyph(Glyph &glyph, uint32 chr) const {
 
424
        FT_UInt slot = FT_Get_Char_Index(_face, chr);
381
425
        if (!slot)
382
426
                return false;
383
427
 
 
428
        glyph.slot = slot;
 
429
 
384
430
        // We use the light target and render mode to improve the looks of the
385
431
        // glyphs. It is most noticable in FreeSansBold.ttf, where otherwise the
386
432
        // 't' glyph looks like it is cut off on the right side.
387
 
        if (FT_Load_Glyph(_face, slot, (_monochrome ? FT_LOAD_TARGET_MONO : FT_LOAD_TARGET_LIGHT)))
 
433
        if (FT_Load_Glyph(_face, slot, _loadFlags))
388
434
                return false;
389
435
 
390
 
        if (FT_Render_Glyph(_face->glyph, (_monochrome ? FT_RENDER_MODE_MONO : FT_RENDER_MODE_LIGHT)))
 
436
        if (FT_Render_Glyph(_face->glyph, _renderMode))
391
437
                return false;
392
438
 
393
439
        if (_face->glyph->format != FT_GLYPH_FORMAT_BITMAP)
422
468
                srcPitch = -srcPitch;
423
469
        }
424
470
 
425
 
        uint8 *dst = (uint8 *)glyph.image.getBasePtr(0, 0);
 
471
        uint8 *dst = (uint8 *)glyph.image.getPixels();
426
472
        memset(dst, 0, glyph.image.h * glyph.image.pitch);
427
473
 
428
474
        switch (bitmap.pixel_mode) {
456
502
 
457
503
        default:
458
504
                warning("TTFFont::cacheGlyph: Unsupported pixel mode %d", bitmap.pixel_mode);
 
505
                glyph.image.free();
459
506
                return false;
460
507
        }
461
508
 
462
509
        return true;
463
510
}
464
511
 
465
 
Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi, bool monochrome, const uint32 *mapping) {
 
512
void TTFFont::assureCached(uint32 chr) const {
 
513
        if (!chr || !_allowLateCaching || _glyphs.contains(chr)) {
 
514
                return;
 
515
        }
 
516
 
 
517
        Glyph newGlyph;
 
518
        if (cacheGlyph(newGlyph, chr)) {
 
519
                _glyphs[chr] = newGlyph;
 
520
        }
 
521
}
 
522
 
 
523
Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) {
466
524
        TTFFont *font = new TTFFont();
467
525
 
468
 
        if (!font->load(stream, size, dpi, monochrome, mapping)) {
 
526
        if (!font->load(stream, size, dpi, renderMode, mapping)) {
469
527
                delete font;
470
528
                return 0;
471
529
        }