[Scummvm-cvs-logs] scummvm master -> 774b3755c8daccb14a42d0a19b32c71747423569

lordhoto lordhoto at gmail.com
Mon Dec 21 18:50:06 CET 2015


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
2d86f6da9c GRAPHICS: Introduce a size mode for TrueType fonts
68be74e0a3 ZVISION: Use the cell size mode when loading TrueType fonts
774b3755c8 Merge pull request #639 from bgK/ttf-size-mode


Commit: 2d86f6da9c0ee2ffa80a2b570c148ea337b09cec
    https://github.com/scummvm/scummvm/commit/2d86f6da9c0ee2ffa80a2b570c148ea337b09cec
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2015-12-21T18:41:14+01:00

Commit Message:
GRAPHICS: Introduce a size mode for TrueType fonts

Allows to match Windows font size selection by converting font heights
to point sizes using the TrueType tables.

Changed paths:
    engines/wintermute/base/font/base_font_truetype.cpp
    engines/zvision/text/truetype_font.cpp
    graphics/fonts/ttf.cpp
    graphics/fonts/ttf.h
    gui/ThemeEngine.cpp



diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index f27b565..fa6973c 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -581,7 +581,7 @@ bool BaseFontTT::initFont() {
 	}
 
 	if (file) {
-		_deletableFont = Graphics::loadTTFFont(*file, _fontHeight, 96); // Use the same dpi as WME (96 vs 72).
+		_deletableFont = Graphics::loadTTFFont(*file, _fontHeight, Graphics::kTTFSizeModeCharacter, 96); // Use the same dpi as WME (96 vs 72).
 		_font = _deletableFont;
 		BaseFileManager::getEngineInstance()->closeFile(file);
 		file = nullptr;
@@ -607,7 +607,7 @@ bool BaseFontTT::initFont() {
 			if (themeArchive->hasFile(fallbackFilename)) {
 				file = nullptr;
 				file = themeArchive->createReadStreamForMember(fallbackFilename);
-				_deletableFont = Graphics::loadTTFFont(*file, _fontHeight, 96); // Use the same dpi as WME (96 vs 72).
+				_deletableFont = Graphics::loadTTFFont(*file, _fontHeight, Graphics::kTTFSizeModeCharacter, 96); // Use the same dpi as WME (96 vs 72).
 				_font = _deletableFont;
 			}
 			// We're not using BaseFileManager, so clean up after ourselves:
diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
index acb053e..ed4a81a 100644
--- a/engines/zvision/text/truetype_font.cpp
+++ b/engines/zvision/text/truetype_font.cpp
@@ -123,7 +123,7 @@ bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint st
 		!file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
 		error("Unable to open font file %s (Liberation Font alternative: %s, FreeFont alternative: %s)", newFontName.c_str(), liberationFontName.c_str(), freeFontName.c_str());
 
-	Graphics::Font *newFont = Graphics::loadTTFFont(file, point, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
+	Graphics::Font *newFont = Graphics::loadTTFFont(file, point, Graphics::kTTFSizeModeCharacter, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
 	if (newFont == nullptr) {
 		return false;
 	}
diff --git a/graphics/fonts/ttf.cpp b/graphics/fonts/ttf.cpp
index dc7335f..98420f6 100644
--- a/graphics/fonts/ttf.cpp
+++ b/graphics/fonts/ttf.cpp
@@ -33,11 +33,15 @@
 
 #include "common/singleton.h"
 #include "common/stream.h"
+#include "common/memstream.h"
 #include "common/hashmap.h"
+#include "common/ptr.h"
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_GLYPH_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TRUETYPE_TAGS_H
 
 namespace Graphics {
 
@@ -47,6 +51,10 @@ inline int ftCeil26_6(FT_Pos x) {
 	return (x + 63) / 64;
 }
 
+inline int divRoundToNearest(int dividend, int divisor) {
+	return (dividend + (divisor / 2)) / divisor;
+}
+
 } // End of anonymous namespace
 
 class TTFLibrary : public Common::Singleton<TTFLibrary> {
@@ -101,7 +109,7 @@ public:
 	TTFFont();
 	virtual ~TTFFont();
 
-	bool load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping);
+	bool load(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode, uint dpi, TTFRenderMode renderMode, const uint32 *mapping);
 
 	virtual int getFontHeight() const;
 
@@ -137,6 +145,12 @@ private:
 	bool _allowLateCaching;
 	void assureCached(uint32 chr) const;
 
+	Common::SeekableReadStream *readTTFTable(FT_ULong tag) const;
+
+	int computePointSize(int size, TTFSizeMode sizeMode) const;
+	int readPointSizeFromVDMXTable(int height) const;
+	int computePointSizeFromHeaders(int height) const;
+
 	FT_Int32 _loadFlags;
 	FT_Render_Mode _renderMode;
 	bool _hasKerning;
@@ -162,7 +176,7 @@ TTFFont::~TTFFont() {
 	}
 }
 
-bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) {
+bool TTFFont::load(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) {
 	if (!g_ttf.isInitialized())
 		return false;
 
@@ -200,7 +214,7 @@ bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRe
 	// Check whether we have kerning support
 	_hasKerning = (FT_HAS_KERNING(_face) != 0);
 
-	if (FT_Set_Char_Size(_face, 0, size * 64, dpi, dpi)) {
+	if (FT_Set_Char_Size(_face, 0, computePointSize(size, sizeMode) * 64, dpi, dpi)) {
 		delete[] _ttfFile;
 		_ttfFile = 0;
 
@@ -262,6 +276,126 @@ bool TTFFont::load(Common::SeekableReadStream &stream, int size, uint dpi, TTFRe
 	return _initialized;
 }
 
+int TTFFont::computePointSize(int size, TTFSizeMode sizeMode) const {
+	int ptSize;
+	switch (sizeMode) {
+	case kTTFSizeModeCell: {
+		ptSize = readPointSizeFromVDMXTable(size);
+
+		if (ptSize == 0) {
+			ptSize = computePointSizeFromHeaders(size);
+		}
+
+		if (ptSize == 0) {
+			warning("Unable to compute point size for font '%s'", _face->family_name);
+			ptSize = 1;
+		}
+		break;
+	}
+	case kTTFSizeModeCharacter:
+		ptSize = size;
+		break;
+	}
+
+	return ptSize;
+}
+
+Common::SeekableReadStream *TTFFont::readTTFTable(FT_ULong tag) const {
+	// Find the required buffer size by calling the load function with nullptr
+	FT_ULong size = 0;
+	FT_Error err = FT_Load_Sfnt_Table(_face, tag, 0, nullptr, &size);
+	if (err) {
+		return nullptr;
+	}
+
+	byte *buf = (byte *)malloc(size);
+	if (!buf) {
+		return nullptr;
+	}
+
+	err = FT_Load_Sfnt_Table(_face, tag, 0, buf, &size);
+	if (err) {
+		free(buf);
+		return nullptr;
+	}
+
+	return new Common::MemoryReadStream(buf, size, DisposeAfterUse::YES);
+}
+
+int TTFFont::readPointSizeFromVDMXTable(int height) const {
+	// The Vertical Device Metrics table matches font heights with point sizes.
+	// FreeType does not expose it, we have to parse it ourselves.
+	// See https://www.microsoft.com/typography/otspec/vdmx.htm
+
+	Common::ScopedPtr<Common::SeekableReadStream> vdmxBuf(readTTFTable(TTAG_VDMX));
+	if (!vdmxBuf) {
+		return 0;
+	}
+
+	// Read the main header
+	vdmxBuf->skip(4); // Skip the version
+	uint16 numRatios = vdmxBuf->readUint16BE();
+
+	// Compute the starting position for the group table positions table
+	int32 offsetTableStart = vdmxBuf->pos() + 4 * numRatios;
+
+	// Search the ratio table for the 1:1 ratio, or the default record (0, 0, 0)
+	int32 selectedRatio = -1;
+	for (uint16 i = 0; i < numRatios; i++) {
+		vdmxBuf->skip(1); // Skip the charset subset
+		uint8 xRatio = vdmxBuf->readByte();
+		uint8 yRatio1 = vdmxBuf->readByte();
+		uint8 yRatio2 = vdmxBuf->readByte();
+
+		if ((xRatio == 1 && yRatio1 <= 1 && yRatio2 >= 1)
+		    || (xRatio == 0 && yRatio1 == 0 && yRatio2 == 0)) {
+			selectedRatio = i;
+			break;
+		}
+	}
+	if (selectedRatio < 0) {
+		return 0;
+	}
+
+	// Read from group table positions table to get the group table offset
+	vdmxBuf->seek(offsetTableStart + sizeof(uint16) * selectedRatio);
+	uint16 groupOffset = vdmxBuf->readUint16BE();
+
+	// Read the group table header
+	vdmxBuf->seek(groupOffset);
+	uint16 numRecords = vdmxBuf->readUint16BE();
+	vdmxBuf->skip(2); // Skip the table bounds
+
+	// Search a record matching the required height
+	for (uint16 i = 0; i < numRecords; i++) {
+		uint16 pointSize = vdmxBuf->readUint16BE();
+		int16 yMax = vdmxBuf->readSint16BE();
+		int16 yMin = vdmxBuf->readSint16BE();
+
+		if (yMax + -yMin > height) {
+			return 0;
+		}
+		if (yMax + -yMin == height) {
+			return pointSize;
+		}
+	}
+
+	return 0;
+}
+
+int TTFFont::computePointSizeFromHeaders(int height) const {
+	TT_OS2 *os2Header = (TT_OS2 *)FT_Get_Sfnt_Table(_face, ft_sfnt_os2);
+	TT_HoriHeader *horiHeader = (TT_HoriHeader *)FT_Get_Sfnt_Table(_face, ft_sfnt_hhea);
+
+	if (os2Header && (os2Header->usWinAscent + os2Header->usWinDescent != 0)) {
+		return divRoundToNearest(_face->units_per_EM * height, os2Header->usWinAscent + os2Header->usWinDescent);
+	} else if (horiHeader && (horiHeader->Ascender + horiHeader->Descender != 0)) {
+		return divRoundToNearest(_face->units_per_EM * height, horiHeader->Ascender + horiHeader->Descender);
+	}
+
+	return 0;
+}
+
 int TTFFont::getFontHeight() const {
 	return _height;
 }
@@ -521,10 +655,10 @@ void TTFFont::assureCached(uint32 chr) const {
 	}
 }
 
-Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) {
+Font *loadTTFFont(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode, uint dpi, TTFRenderMode renderMode, const uint32 *mapping) {
 	TTFFont *font = new TTFFont();
 
-	if (!font->load(stream, size, dpi, renderMode, mapping)) {
+	if (!font->load(stream, size, sizeMode, dpi, renderMode, mapping)) {
 		delete font;
 		return 0;
 	}
diff --git a/graphics/fonts/ttf.h b/graphics/fonts/ttf.h
index bd25b69..4110486 100644
--- a/graphics/fonts/ttf.h
+++ b/graphics/fonts/ttf.h
@@ -56,10 +56,32 @@ enum TTFRenderMode {
 };
 
 /**
+ * This specifies how the font size is defined.
+ */
+enum TTFSizeMode {
+	/**
+	 * Character height only.
+	 *
+	 * This matches rendering obtained when calling
+	 * CreateFont in Windows with negative height values.
+	 */
+	kTTFSizeModeCharacter,
+
+	/**
+	 * Full cell height.
+	 *
+	 * This matches rendering obtained when calling
+	 * CreateFont in Windows with positive height values.
+	 */
+	kTTFSizeModeCell
+};
+
+/**
  * Loads a TTF font file from a given data stream object.
  *
  * @param stream     Stream object to load font data from.
  * @param size       The point size to load.
+ * @param sizeMode   The point size definition used for the size parameter.
  * @param dpi        The dpi to use for size calculations, by default 72dpi
  *                   are used.
  * @param renderMode FreeType2 mode used to render glyphs. @see TTFRenderMode
@@ -71,7 +93,7 @@ enum TTFRenderMode {
  *                   supported.
  * @return 0 in case loading fails, otherwise a pointer to the Font object.
  */
-Font *loadTTFFont(Common::SeekableReadStream &stream, int size, uint dpi = 0, TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0);
+Font *loadTTFFont(Common::SeekableReadStream &stream, int size, TTFSizeMode sizeMode = kTTFSizeModeCharacter, uint dpi = 0, TTFRenderMode renderMode = kTTFRenderModeLight, const uint32 *mapping = 0);
 
 void shutdownTTF();
 
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 6562a1d..536e519 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -1459,7 +1459,7 @@ const Graphics::Font *ThemeEngine::loadScalableFont(const Common::String &filena
 	for (Common::ArchiveMemberList::const_iterator i = members.begin(), end = members.end(); i != end; ++i) {
 		Common::SeekableReadStream *stream = (*i)->createReadStream();
 		if (stream) {
-			font = Graphics::loadTTFFont(*stream, pointsize, 0, Graphics::kTTFRenderModeLight,
+			font = Graphics::loadTTFFont(*stream, pointsize, Graphics::kTTFSizeModeCharacter, 0, Graphics::kTTFRenderModeLight,
 #ifdef USE_TRANSLATION
 			                             TransMan.getCharsetMapping()
 #else


Commit: 68be74e0a319bb31b9a934b7fd976c8c250b0260
    https://github.com/scummvm/scummvm/commit/68be74e0a319bb31b9a934b7fd976c8c250b0260
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2015-12-21T18:41:14+01:00

Commit Message:
ZVISION: Use the cell size mode when loading TrueType fonts

Changed paths:
    engines/zvision/text/truetype_font.cpp



diff --git a/engines/zvision/text/truetype_font.cpp b/engines/zvision/text/truetype_font.cpp
index ed4a81a..ccb86d9 100644
--- a/engines/zvision/text/truetype_font.cpp
+++ b/engines/zvision/text/truetype_font.cpp
@@ -123,7 +123,7 @@ bool StyledTTFont::loadFont(const Common::String &fontName, int32 point, uint st
 		!file.open(freeFontName) && !_engine->getSearchManager()->openFile(file, freeFontName))
 		error("Unable to open font file %s (Liberation Font alternative: %s, FreeFont alternative: %s)", newFontName.c_str(), liberationFontName.c_str(), freeFontName.c_str());
 
-	Graphics::Font *newFont = Graphics::loadTTFFont(file, point, Graphics::kTTFSizeModeCharacter, 60, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal)); // 66 dpi for 640 x 480 on 14" display
+	Graphics::Font *newFont = Graphics::loadTTFFont(file, point, Graphics::kTTFSizeModeCell, 0, (sharp ? Graphics::kTTFRenderModeMonochrome : Graphics::kTTFRenderModeNormal));
 	if (newFont == nullptr) {
 		return false;
 	}


Commit: 774b3755c8daccb14a42d0a19b32c71747423569
    https://github.com/scummvm/scummvm/commit/774b3755c8daccb14a42d0a19b32c71747423569
Author: Johannes Schickel (lordhoto at gmail.com)
Date: 2015-12-21T18:49:34+01:00

Commit Message:
Merge pull request #639 from bgK/ttf-size-mode

GRAPHICS: TrueType font creation from character height

Changed paths:
    engines/wintermute/base/font/base_font_truetype.cpp
    engines/zvision/text/truetype_font.cpp
    graphics/fonts/ttf.cpp
    graphics/fonts/ttf.h
    gui/ThemeEngine.cpp









More information about the Scummvm-git-logs mailing list