[Scummvm-cvs-logs] scummvm-tools master -> 505d800f83c6619c5f55cf3ef40ea676782d2b4f

lordhoto lordhoto at gmail.com
Fri Jul 1 03:24:36 CEST 2011


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

Summary:
927bd1d333 TOOLS: Cleanup create_sjisfnt tool a little.
b9db877d6c TOOLS: Move create_sjisfnt TTF code to a class.
a7fe09a023 TOOLS: Implement proper character layouting in create_sjisfnt.
505d800f83 TOOLS: Further clean up create_sjisfnt.


Commit: 927bd1d3335fda2c7256ed8ecd7efaa45b7f1ba7
    https://github.com/scummvm/scummvm-tools/commit/927bd1d3335fda2c7256ed8ecd7efaa45b7f1ba7
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2011-06-30T17:09:45-07:00

Commit Message:
TOOLS: Cleanup create_sjisfnt tool a little.

Changed paths:
  A create_sjisfnt.h
    create_sjisfnt.cpp



diff --git a/create_sjisfnt.cpp b/create_sjisfnt.cpp
index 63e252b..901cb46 100644
--- a/create_sjisfnt.cpp
+++ b/create_sjisfnt.cpp
@@ -18,69 +18,22 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * $URL$
- * $Id$
- *
  */
 
+#include "create_sjisfnt.h"
+
+#include "common/endian.h"
+#include "common/file.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <iconv.h>
-#include <list>
 #include <assert.h>
 #include <errno.h>
 
-#include "common/endian.h"
-#include "common/file.h"
-#include "common/util.h"
-
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
-namespace {
-
-bool isASCII(uint8 fB);
-
-int mapASCIItoChunk(uint8 fB);
-int mapSJIStoChunk(uint8 fB, uint8 sB);
-
-bool initSJIStoUTF32Conversion();
-void deinitSJIStoUTF32Conversion();
-uint32 convertSJIStoUTF32(uint8 fB, uint8 sB);
-
-bool initFreeType(const char *font);
-void deinitFreeType();
-
-struct Glyph {
-	uint8 fB, sB;
-
-	int xOffset;
-	int yOffset;
-	int height;
-	int width;
-
-	int pitch;
-	uint8 *plainData;
-};
-
-bool setGlyphSize(int width, int height);
-bool checkGlyphSize(const Glyph &g, const int baseLine, const int maxW, const int maxH);
-
-bool drawGlyph(uint8 fB, uint8 sB, Glyph &glyph);
-bool drawGlyph(uint32 unicode, Glyph &glyph);
-
-void convertChar8x16(uint8 *dst, const Glyph &g);
-void convertChar16x16(uint8 *dst, const Glyph &g);
-
-typedef std::list<Glyph> GlyphList;
-void freeGlyphlist(GlyphList &list) {
-	for (GlyphList::iterator i = list.begin(); i != list.end(); ++i)
-		delete[] i->plainData;
-	list.clear();
-}
-
-} // end of anonymous namespace
-
 int main(int argc, char *argv[]) {
 	if (argc < 2 || argc > 3) {
 		printf("Usage:\n\t%s <input ttf font> [outfile]\n", argv[0]);
@@ -112,13 +65,6 @@ int main(int argc, char *argv[]) {
 	int chars8x16 = 0;
 	int chars16x16 = 0;
 
-	// FIXME: It seems some ttf fonts will only render invalid data,
-	// when FreeType2 is asked to provide 8x16 glyphs. "sazanami-mincho.ttf"
-	// is such a case. When we will render them in the default 16x16 setting
-	// all ASCII chars will be rendered correctly and still fit within 8x16.
-	// Some fonts might require special setup as 8x16 though.
-	// We should try to find some proper way of detecting and handling this.
-
 	// ASCII chars will be rendererd as 8x16
 	if (!setGlyphSize(8, 16))
 		return -1;
@@ -263,7 +209,11 @@ int main(int argc, char *argv[]) {
 	return 0;
 }
 
-namespace {
+void freeGlyphlist(GlyphList &list) {
+	for (GlyphList::iterator i = list.begin(); i != list.end(); ++i)
+		delete[] i->plainData;
+	list.clear();
+}
 
 bool isASCII(uint8 fB) {
 	return (mapASCIItoChunk(fB) != -1);
@@ -533,5 +483,3 @@ void convertChar16x16(uint8 *dst, const Glyph &g) {
 	}
 }
 
-} // end of anonymous namespace
-
diff --git a/create_sjisfnt.h b/create_sjisfnt.h
new file mode 100644
index 0000000..abb85df
--- /dev/null
+++ b/create_sjisfnt.h
@@ -0,0 +1,67 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef CREATE_SJISFNT_H
+#define CREATE_SJISFNT_H
+
+#include "common/util.h"
+
+#include <list>
+
+bool isASCII(uint8 fB);
+
+int mapASCIItoChunk(uint8 fB);
+int mapSJIStoChunk(uint8 fB, uint8 sB);
+
+bool initSJIStoUTF32Conversion();
+void deinitSJIStoUTF32Conversion();
+uint32 convertSJIStoUTF32(uint8 fB, uint8 sB);
+
+bool initFreeType(const char *font);
+void deinitFreeType();
+
+struct Glyph {
+	uint8 fB, sB;
+
+	int xOffset;
+	int yOffset;
+	int height;
+	int width;
+
+	int pitch;
+	uint8 *plainData;
+};
+
+bool setGlyphSize(int width, int height);
+bool checkGlyphSize(const Glyph &g, const int baseLine, const int maxW, const int maxH);
+
+bool drawGlyph(uint8 fB, uint8 sB, Glyph &glyph);
+bool drawGlyph(uint32 unicode, Glyph &glyph);
+
+void convertChar8x16(uint8 *dst, const Glyph &g);
+void convertChar16x16(uint8 *dst, const Glyph &g);
+
+typedef std::list<Glyph> GlyphList;
+void freeGlyphlist(GlyphList &list);
+
+#endif
+


Commit: b9db877d6c86f235adcac9940a13d163ea2a0211
    https://github.com/scummvm/scummvm-tools/commit/b9db877d6c86f235adcac9940a13d163ea2a0211
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2011-06-30T17:29:11-07:00

Commit Message:
TOOLS: Move create_sjisfnt TTF code to a class.

Changed paths:
    create_sjisfnt.cpp
    create_sjisfnt.h



diff --git a/create_sjisfnt.cpp b/create_sjisfnt.cpp
index 901cb46..40a64ba 100644
--- a/create_sjisfnt.cpp
+++ b/create_sjisfnt.cpp
@@ -31,9 +31,6 @@
 #include <assert.h>
 #include <errno.h>
 
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
 int main(int argc, char *argv[]) {
 	if (argc < 2 || argc > 3) {
 		printf("Usage:\n\t%s <input ttf font> [outfile]\n", argv[0]);
@@ -54,20 +51,22 @@ int main(int argc, char *argv[]) {
 
 	atexit(deinitSJIStoUTF32Conversion);
 
-	if (!initFreeType(font)) {
+	TrueTypeFont *ttf = new TrueTypeFont();
+	if (!ttf->load(font)) {
+		delete ttf;
 		error("Could not initialize FreeType library.");
 		return -1;
 	}
 
-	atexit(deinitFreeType);
-
 	GlyphList glyphs;
 	int chars8x16 = 0;
 	int chars16x16 = 0;
 
 	// ASCII chars will be rendererd as 8x16
-	if (!setGlyphSize(8, 16))
+	if (!ttf->setSize(8, 16)) {
+		delete ttf;
 		return -1;
+	}
 
 	for (uint8 fB = 0x00; fB <= 0xDF; ++fB) {
 		if (mapASCIItoChunk(fB) == -1)
@@ -76,12 +75,13 @@ int main(int argc, char *argv[]) {
 		++chars8x16;
 
 		Glyph data;
-		if (drawGlyph(fB, 0, data))
+		if (ttf->renderGlyph(fB, 0, data))
 			glyphs.push_back(data);
 	}
 
 	// The two byte SJIS chars will be rendered as 16x16
-	if (!setGlyphSize(16, 16)) {
+	if (!ttf->setSize(16, 16)) {
+		delete ttf;
 		freeGlyphlist(glyphs);
 		return -1;
 	}
@@ -97,11 +97,14 @@ int main(int argc, char *argv[]) {
 			++chars16x16;
 
 			Glyph data;
-			if (drawGlyph(fB, sB, data))
+			if (ttf->renderGlyph(fB, sB, data))
 				glyphs.push_back(data);
 		}
 	}
 
+	delete ttf;
+	ttf = 0;
+
 	// Post process all chars, so that xOffset is at least 0
 	int minXOffset = 0;
 	for (GlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
@@ -146,10 +149,16 @@ int main(int argc, char *argv[]) {
 	const int sjis8x16DataSize = chars8x16 * 16;
 	uint8 *sjis8x16FontData = new uint8[sjis8x16DataSize];
 
+	if (!sjis8x16FontData) {
+		freeGlyphlist(glyphs);
+		error("Out of memory");
+	}
+
 	const int sjis16x16DataSize = chars16x16 * 32;
 	uint8 *sjis16x16FontData = new uint8[sjis16x16DataSize];
 
 	if (!sjis16x16FontData) {
+		delete[] sjis8x16FontData;
 		freeGlyphlist(glyphs);
 		error("Out of memory");
 	}
@@ -308,26 +317,36 @@ uint32 convertSJIStoUTF32(uint8 fB, uint8 sB) {
 		return ret;
 }
 
-FT_Library ft = NULL;
-FT_Face sjisFont = NULL;
+bool checkGlyphSize(const Glyph &g, const int baseLine, const int maxW, const int maxH) {
+	if (baseLine - g.yOffset < 0 || baseLine - g.yOffset + g.height > (maxH + 1) ||
+		g.xOffset > (maxW - 1) || g.xOffset + g.width > (maxW + 1))
+		return false;
+	return true;
+}
+
+TrueTypeFont::TrueTypeFont()
+	: _library(0), _sjisFont(0) {
+}
+
+TrueTypeFont::~TrueTypeFont() {
+	FT_Done_Face(_sjisFont);
+	FT_Done_FreeType(_library);
+}
 
-bool initFreeType(const char *font) {
-	FT_Error err = FT_Init_FreeType(&ft);
+bool TrueTypeFont::load(const char *font) {
+	FT_Error err = FT_Init_FreeType(&_library);
 	if (err) {
 		warning("Could not initialize FreeType2 library.");
 		return false;
 	}
 
-	err = FT_New_Face(ft, font, 0, &sjisFont);
+	err = FT_New_Face(_library, font, 0, &_sjisFont);
 	if (err) {
 		warning("Could not load font '%s'", font);
 		return false;
 	}
 
-	if (!setGlyphSize(16, 16))
-		return false;
-
-	err = FT_Select_Charmap(sjisFont, FT_ENCODING_UNICODE);
+	err = FT_Select_Charmap(_sjisFont, FT_ENCODING_UNICODE);
 	if (err) {
 		warning("Could not select unicode charmap.");
 		return false;
@@ -336,29 +355,17 @@ bool initFreeType(const char *font) {
 	return true;
 }
 
-void deinitFreeType() {
-	FT_Done_Face(sjisFont);
-	FT_Done_FreeType(ft);
-}
-
-bool setGlyphSize(int width, int height) {
-	FT_Error err = FT_Set_Pixel_Sizes(sjisFont, width, height);
+bool TrueTypeFont::setSize(int width, int height) {
+	FT_Error err = FT_Set_Pixel_Sizes(_sjisFont, width, height);
 	if (err) {
-		warning("Could not initialize font for %dx%d outout.", width, height);
+		warning("Could not initialize font for %dx%d output.", width, height);
 		return false;
 	}
 
 	return true;
 }
 
-bool checkGlyphSize(const Glyph &g, const int baseLine, const int maxW, const int maxH) {
-	if (baseLine - g.yOffset < 0 || baseLine - g.yOffset + g.height > (maxH + 1) ||
-		g.xOffset > (maxW - 1) || g.xOffset + g.width > (maxW + 1))
-		return false;
-	return true;
-}
-
-bool drawGlyph(uint8 fB, uint8 sB, Glyph &glyph) {
+bool TrueTypeFont::renderGlyph(uint8 fB, uint8 sB, Glyph &glyph) {
 	uint32 utf32 = convertSJIStoUTF32(fB, sB);
 	if (utf32 == (uint32)-1) {
 		// For now we disable that warning, since iconv will fail for all reserved,
@@ -374,7 +381,7 @@ bool drawGlyph(uint8 fB, uint8 sB, Glyph &glyph) {
 
 	glyph.fB = fB;
 	glyph.sB = sB;
-	if (!drawGlyph(utf32, glyph)) {
+	if (!renderGlyph(utf32, glyph)) {
 		warning("Could not render glyph: %.2X %.2X", fB, sB);
 		return false;
 	}
@@ -382,23 +389,23 @@ bool drawGlyph(uint8 fB, uint8 sB, Glyph &glyph) {
 	return true;
 }
 
-bool drawGlyph(uint32 unicode, Glyph &glyph) {
-	uint32 index = FT_Get_Char_Index(sjisFont, unicode);
+bool TrueTypeFont::renderGlyph(uint32 unicode, Glyph &glyph) {
+	uint32 index = FT_Get_Char_Index(_sjisFont, unicode);
 	if (!index)
 		return false;
 
-	FT_Error err = FT_Load_Glyph(sjisFont, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING);
+	FT_Error err = FT_Load_Glyph(_sjisFont, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING);
 	if (err)
 		return false;
 
-	err = FT_Render_Glyph(sjisFont->glyph, FT_RENDER_MODE_MONO);
+	err = FT_Render_Glyph(_sjisFont->glyph, FT_RENDER_MODE_MONO);
 	if (err)
 		return false;
 
-	const FT_Bitmap &bitmap = sjisFont->glyph->bitmap;
+	const FT_Bitmap &bitmap = _sjisFont->glyph->bitmap;
 
-	glyph.yOffset = sjisFont->glyph->bitmap_top;
-	glyph.xOffset = sjisFont->glyph->bitmap_left;
+	glyph.yOffset = _sjisFont->glyph->bitmap_top;
+	glyph.xOffset = _sjisFont->glyph->bitmap_left;
 	glyph.height = bitmap.rows;
 	glyph.width = bitmap.width;
 	glyph.pitch = bitmap.pitch;
diff --git a/create_sjisfnt.h b/create_sjisfnt.h
index abb85df..ca5a25c 100644
--- a/create_sjisfnt.h
+++ b/create_sjisfnt.h
@@ -27,6 +27,9 @@
 
 #include <list>
 
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
 bool isASCII(uint8 fB);
 
 int mapASCIItoChunk(uint8 fB);
@@ -36,9 +39,6 @@ bool initSJIStoUTF32Conversion();
 void deinitSJIStoUTF32Conversion();
 uint32 convertSJIStoUTF32(uint8 fB, uint8 sB);
 
-bool initFreeType(const char *font);
-void deinitFreeType();
-
 struct Glyph {
 	uint8 fB, sB;
 
@@ -51,17 +51,30 @@ struct Glyph {
 	uint8 *plainData;
 };
 
-bool setGlyphSize(int width, int height);
 bool checkGlyphSize(const Glyph &g, const int baseLine, const int maxW, const int maxH);
 
-bool drawGlyph(uint8 fB, uint8 sB, Glyph &glyph);
-bool drawGlyph(uint32 unicode, Glyph &glyph);
-
 void convertChar8x16(uint8 *dst, const Glyph &g);
 void convertChar16x16(uint8 *dst, const Glyph &g);
 
 typedef std::list<Glyph> GlyphList;
 void freeGlyphlist(GlyphList &list);
 
+class TrueTypeFont {
+public:
+	TrueTypeFont();
+	~TrueTypeFont();
+
+	bool load(const char *filename);
+
+	bool setSize(int width, int height);
+
+	bool renderGlyph(uint8 fb, uint8 sB, Glyph &glyph);
+private:
+	bool renderGlyph(uint32 unicode, Glyph &glyph);
+
+	FT_Library _library;
+	FT_Face _sjisFont;
+};
+
 #endif
 


Commit: a7fe09a0235f19a935ec82dca853de04a60de676
    https://github.com/scummvm/scummvm-tools/commit/a7fe09a0235f19a935ec82dca853de04a60de676
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2011-06-30T17:54:23-07:00

Commit Message:
TOOLS: Implement proper character layouting in create_sjisfnt.

Changed paths:
    create_sjisfnt.cpp
    create_sjisfnt.h



diff --git a/create_sjisfnt.cpp b/create_sjisfnt.cpp
index 40a64ba..5609541 100644
--- a/create_sjisfnt.cpp
+++ b/create_sjisfnt.cpp
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
 	atexit(deinitSJIStoUTF32Conversion);
 
 	TrueTypeFont *ttf = new TrueTypeFont();
-	if (!ttf->load(font)) {
+	if (!ttf->load(font, 16)) {
 		delete ttf;
 		error("Could not initialize FreeType library.");
 		return -1;
@@ -62,12 +62,6 @@ int main(int argc, char *argv[]) {
 	int chars8x16 = 0;
 	int chars16x16 = 0;
 
-	// ASCII chars will be rendererd as 8x16
-	if (!ttf->setSize(8, 16)) {
-		delete ttf;
-		return -1;
-	}
-
 	for (uint8 fB = 0x00; fB <= 0xDF; ++fB) {
 		if (mapASCIItoChunk(fB) == -1)
 			continue;
@@ -79,13 +73,6 @@ int main(int argc, char *argv[]) {
 			glyphs.push_back(data);
 	}
 
-	// The two byte SJIS chars will be rendered as 16x16
-	if (!ttf->setSize(16, 16)) {
-		delete ttf;
-		freeGlyphlist(glyphs);
-		return -1;
-	}
-
 	for (uint8 fB = 0x81; fB <= 0xEF; ++fB) {
 		if (mapSJIStoChunk(fB, 0x40) == -1)
 			continue;
@@ -105,44 +92,32 @@ int main(int argc, char *argv[]) {
 	delete ttf;
 	ttf = 0;
 
-	// Post process all chars, so that xOffset is at least 0
-	int minXOffset = 0;
-	for (GlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i)
-		minXOffset = std::min(minXOffset, i->xOffset);
-
-	minXOffset = abs(minXOffset);
-
-	for (GlyphList::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
-		i->xOffset += minXOffset;
-
-	// Calculate the base line for the font. The possible range is [0, 15].
-	// TODO: This logic might need some more tinkering, it's pretty hacky right now.
-	int baseLine = 0;
+	// We try to find the minimum y offset here so we can substract it to make it 0 in the end.
+	// We need to do this, since otherwise the characters will take up too much vertical space.
+	int minYOffset = 16;
 	for (GlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i) {
-		int bL = 0;
-
-		// Try to center the glyph vertically
-		if (i->height + i->yOffset <= 16)
-			bL = i->yOffset + (16 - (i->height + i->yOffset)) / 2;
-
-		bL = std::min(bL, 15);
+		if (i->pitch == 0)
+			continue;
 
-		baseLine = std::max(baseLine, bL);
+		minYOffset = std::min(minYOffset, i->yOffset);
 	}
 
 	// Check whether we have an character which does not fit within the boundaries6
-	for (GlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i) {
+	for (GlyphList::iterator i = glyphs.begin(); i != glyphs.end(); ++i) {
 		if (i->pitch == 0)
 			continue;
 
-		if ((isASCII(i->fB) && !checkGlyphSize(*i, baseLine, 8, 16)) ||
-			(!isASCII(i->fB) && !checkGlyphSize(*i, baseLine, 16, 16))) {
+		// Substract our minimum y offset
+		i->yOffset -= minYOffset;
+
+		if ((isASCII(i->fB) && !checkGlyphSize(*i, 8, 16)) ||
+			(!isASCII(i->fB) && !checkGlyphSize(*i, 16, 16))) {
 			for (GlyphList::iterator j = glyphs.begin(); j != glyphs.end(); ++j)
 				delete[] j->plainData;
 
-			error("Could not fit glyph for %.2X %.2X top: %d bottom: %d, left: %d right: %d, xOffset: %d, yOffset: %d, width: %d, height: %d, baseLine: %d",
-				   i->fB, i->sB, baseLine - i->yOffset, baseLine - i->yOffset + i->height, i->xOffset, i->xOffset + i->width,
-				   i->xOffset, i->yOffset, i->width, i->height, baseLine);
+			error("Could not fit glyph for %.2X %.2X top: %d bottom: %d, left: %d right: %d, xOffset: %d, yOffset: %d, width: %d, height: %d",
+				   i->fB, i->sB, i->yOffset, i->yOffset + i->height, i->xOffset, i->xOffset + i->width,
+				   i->xOffset, i->yOffset, i->width, i->height);
 		}
 	}
 
@@ -172,7 +147,7 @@ int main(int argc, char *argv[]) {
 
 			if (chunk != -1) {
 				uint8 *dst = sjis8x16FontData + chunk * 16;
-				dst += (baseLine - i->yOffset);
+				dst += i->yOffset;
 				convertChar8x16(dst, *i);
 			}
 		} else {
@@ -180,7 +155,7 @@ int main(int argc, char *argv[]) {
 
 			if (chunk != -1) {
 				uint8 *dst = sjis16x16FontData + chunk * 32;
-				dst += (baseLine - i->yOffset) * 2;
+				dst += i->yOffset * 2;
 				convertChar16x16(dst, *i);
 			}
 		}
@@ -317,15 +292,15 @@ uint32 convertSJIStoUTF32(uint8 fB, uint8 sB) {
 		return ret;
 }
 
-bool checkGlyphSize(const Glyph &g, const int baseLine, const int maxW, const int maxH) {
-	if (baseLine - g.yOffset < 0 || baseLine - g.yOffset + g.height > (maxH + 1) ||
-		g.xOffset > (maxW - 1) || g.xOffset + g.width > (maxW + 1))
+bool checkGlyphSize(const Glyph &g, const int maxW, const int maxH) {
+	if (g.yOffset < 0 || g.yOffset + g.height > maxH ||
+		g.xOffset > maxW || g.xOffset + g.width > maxW)
 		return false;
 	return true;
 }
 
 TrueTypeFont::TrueTypeFont()
-	: _library(0), _sjisFont(0) {
+	: _library(0), _sjisFont(0), _ascent(0), _descent(0), _width(0), _height(0) {
 }
 
 TrueTypeFont::~TrueTypeFont() {
@@ -333,7 +308,15 @@ TrueTypeFont::~TrueTypeFont() {
 	FT_Done_FreeType(_library);
 }
 
-bool TrueTypeFont::load(const char *font) {
+inline int ftFloor26_6(FT_Pos x) {
+	return x / 64;
+}
+
+inline int ftCeil26_6(FT_Pos x) {
+	return (x + 63) / 64;
+}
+
+bool TrueTypeFont::load(const char *font, int height) {
 	FT_Error err = FT_Init_FreeType(&_library);
 	if (err) {
 		warning("Could not initialize FreeType2 library.");
@@ -352,16 +335,24 @@ bool TrueTypeFont::load(const char *font) {
 		return false;
 	}
 
-	return true;
-}
+	if (!FT_IS_SCALABLE(_sjisFont)) {
+		warning("Font '%s' is not scalable", font);
+		return false;
+	}
 
-bool TrueTypeFont::setSize(int width, int height) {
-	FT_Error err = FT_Set_Pixel_Sizes(_sjisFont, width, height);
+	err = FT_Set_Char_Size(_sjisFont, 0, height * 64, 0, 0);
 	if (err) {
-		warning("Could not initialize font for %dx%d output.", width, height);
+		warning("Could not initialize font for height %d", height);
 		return false;
 	}
 
+	FT_Fixed yScale = _sjisFont->size->metrics.y_scale;
+	_ascent = ftCeil26_6(FT_MulFix(_sjisFont->ascender, yScale));
+	_descent = ftCeil26_6(FT_MulFix(_sjisFont->descender, yScale));
+
+	_width = ftCeil26_6(FT_MulFix(_sjisFont->max_advance_width, _sjisFont->size->metrics.x_scale));
+	_height = _ascent - _descent + 1;
+
 	return true;
 }
 
@@ -402,10 +393,18 @@ bool TrueTypeFont::renderGlyph(uint32 unicode, Glyph &glyph) {
 	if (err)
 		return false;
 
+	FT_Glyph_Metrics &metrics = _sjisFont->glyph->metrics;
+
+	glyph.xOffset = ftFloor26_6(metrics.horiBearingX);
+	glyph.yOffset = _ascent - ftFloor26_6(metrics.horiBearingY);
+
+	// In case we got a negative xMin we adjust that, this might make some
+	// characters give a odd layout though.
+	if (glyph.xOffset < 0)
+		glyph.xOffset = 0;
+
 	const FT_Bitmap &bitmap = _sjisFont->glyph->bitmap;
 
-	glyph.yOffset = _sjisFont->glyph->bitmap_top;
-	glyph.xOffset = _sjisFont->glyph->bitmap_left;
 	glyph.height = bitmap.rows;
 	glyph.width = bitmap.width;
 	glyph.pitch = bitmap.pitch;
diff --git a/create_sjisfnt.h b/create_sjisfnt.h
index ca5a25c..51ead01 100644
--- a/create_sjisfnt.h
+++ b/create_sjisfnt.h
@@ -44,6 +44,7 @@ struct Glyph {
 
 	int xOffset;
 	int yOffset;
+
 	int height;
 	int width;
 
@@ -51,7 +52,7 @@ struct Glyph {
 	uint8 *plainData;
 };
 
-bool checkGlyphSize(const Glyph &g, const int baseLine, const int maxW, const int maxH);
+bool checkGlyphSize(const Glyph &g, const int maxW, const int maxH);
 
 void convertChar8x16(uint8 *dst, const Glyph &g);
 void convertChar16x16(uint8 *dst, const Glyph &g);
@@ -64,16 +65,16 @@ public:
 	TrueTypeFont();
 	~TrueTypeFont();
 
-	bool load(const char *filename);
-
-	bool setSize(int width, int height);
-
+	bool load(const char *filename, int height);
 	bool renderGlyph(uint8 fb, uint8 sB, Glyph &glyph);
 private:
 	bool renderGlyph(uint32 unicode, Glyph &glyph);
 
 	FT_Library _library;
 	FT_Face _sjisFont;
+
+	int _ascent, _descent;
+	int _width, _height;
 };
 
 #endif


Commit: 505d800f83c6619c5f55cf3ef40ea676782d2b4f
    https://github.com/scummvm/scummvm-tools/commit/505d800f83c6619c5f55cf3ef40ea676782d2b4f
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2011-06-30T18:22:58-07:00

Commit Message:
TOOLS: Further clean up create_sjisfnt.

Changed paths:
    create_sjisfnt.cpp
    create_sjisfnt.h



diff --git a/create_sjisfnt.cpp b/create_sjisfnt.cpp
index 5609541..635e70a 100644
--- a/create_sjisfnt.cpp
+++ b/create_sjisfnt.cpp
@@ -110,8 +110,8 @@ int main(int argc, char *argv[]) {
 		// Substract our minimum y offset
 		i->yOffset -= minYOffset;
 
-		if ((isASCII(i->fB) && !checkGlyphSize(*i, 8, 16)) ||
-			(!isASCII(i->fB) && !checkGlyphSize(*i, 16, 16))) {
+		if ((isASCII(i->fB) && !i->checkSize(8, 16)) ||
+			(!isASCII(i->fB) && !i->checkSize(16, 16))) {
 			for (GlyphList::iterator j = glyphs.begin(); j != glyphs.end(); ++j)
 				delete[] j->plainData;
 
@@ -124,17 +124,14 @@ int main(int argc, char *argv[]) {
 	const int sjis8x16DataSize = chars8x16 * 16;
 	uint8 *sjis8x16FontData = new uint8[sjis8x16DataSize];
 
-	if (!sjis8x16FontData) {
-		freeGlyphlist(glyphs);
+	if (!sjis8x16FontData)
 		error("Out of memory");
-	}
 
 	const int sjis16x16DataSize = chars16x16 * 32;
 	uint8 *sjis16x16FontData = new uint8[sjis16x16DataSize];
 
 	if (!sjis16x16FontData) {
 		delete[] sjis8x16FontData;
-		freeGlyphlist(glyphs);
 		error("Out of memory");
 	}
 
@@ -145,24 +142,16 @@ int main(int argc, char *argv[]) {
 		if (isASCII(i->fB)) {
 			int chunk = mapASCIItoChunk(i->fB);
 
-			if (chunk != -1) {
-				uint8 *dst = sjis8x16FontData + chunk * 16;
-				dst += i->yOffset;
-				convertChar8x16(dst, *i);
-			}
+			if (chunk != -1)
+				i->convertChar8x16(sjis8x16FontData + chunk * 16);
 		} else {
 			int chunk = mapSJIStoChunk(i->fB, i->sB);
 
-			if (chunk != -1) {
-				uint8 *dst = sjis16x16FontData + chunk * 32;
-				dst += i->yOffset * 2;
-				convertChar16x16(dst, *i);
-			}
+			if (chunk != -1)
+				i->convertChar16x16(sjis16x16FontData + chunk * 32);
 		}
 	}
 
-	freeGlyphlist(glyphs);
-
 	Common::File sjisFont(out, "wb");
 	if (sjisFont.isOpen()) {
 		// Write our magic bytes
@@ -193,12 +182,6 @@ int main(int argc, char *argv[]) {
 	return 0;
 }
 
-void freeGlyphlist(GlyphList &list) {
-	for (GlyphList::iterator i = list.begin(); i != list.end(); ++i)
-		delete[] i->plainData;
-	list.clear();
-}
-
 bool isASCII(uint8 fB) {
 	return (mapASCIItoChunk(fB) != -1);
 }
@@ -292,13 +275,6 @@ uint32 convertSJIStoUTF32(uint8 fB, uint8 sB) {
 		return ret;
 }
 
-bool checkGlyphSize(const Glyph &g, const int maxW, const int maxH) {
-	if (g.yOffset < 0 || g.yOffset + g.height > maxH ||
-		g.xOffset > maxW || g.xOffset + g.width > maxW)
-		return false;
-	return true;
-}
-
 TrueTypeFont::TrueTypeFont()
 	: _library(0), _sjisFont(0), _ascent(0), _descent(0), _width(0), _height(0) {
 }
@@ -433,21 +409,58 @@ bool TrueTypeFont::renderGlyph(uint32 unicode, Glyph &glyph) {
 	return true;
 }
 
-// TODO: merge these two
+Glyph::Glyph()
+	: fB(0), sB(0), xOffset(0), yOffset(0), height(0), width(0), pitch(0),
+	  plainData(0) {
+}
+
+Glyph::Glyph(const Glyph &r)
+	: fB(r.fB), sB(r.sB), xOffset(r.xOffset), yOffset(r.yOffset),
+	  height(r.height), width(r.width), pitch(r.pitch), plainData(0) {
+	plainData = new uint8[height * pitch];
+	memcpy(plainData, r.plainData, height * pitch);
+}
 
-void convertChar8x16(uint8 *dst, const Glyph &g) {
-	const uint8 *src = g.plainData;
+Glyph::~Glyph() {
+	delete[] plainData;
+}
+
+Glyph &Glyph::operator=(const Glyph &r) {
+	delete[] plainData;
+
+	fB = r.fB;
+	sB = r.sB;
+	xOffset = r.xOffset;
+	yOffset = r.yOffset;
+	height = r.height;
+	width = r.width;
+	pitch = r.pitch;
+
+	plainData = new uint8[height * pitch];
+	memcpy(plainData, r.plainData, height * pitch);
+
+	return *this;
+}
+
+bool Glyph::checkSize(const int maxW, const int maxH) const {
+	if (yOffset < 0 || yOffset + height > maxH ||
+		xOffset < 0 || xOffset + width > maxW)
+		return false;
+	return true;
+}
 
-	assert(g.width + g.xOffset <= 8);
+void Glyph::convertChar8x16(uint8 *dst) const {
+	const uint8 *src = plainData;
+	dst += yOffset;
 
-	for (int y = 0; y < g.height; ++y) {
-		uint8 mask = 1 << (7 - g.xOffset);
+	for (int y = 0; y < height; ++y) {
+		uint8 mask = 1 << (7 - xOffset);
 
 		const uint8 *curSrc = src;
 
 		uint8 line = 0;
 		uint8 d = 0;
-		for (int x = 0; x < g.width; ++x) {
+		for (int x = 0; x < width; ++x) {
 			if (x == 0)
 				d = *curSrc++;
 
@@ -459,21 +472,22 @@ void convertChar8x16(uint8 *dst, const Glyph &g) {
 		}
 
 		*dst++ = line;
-		src += g.pitch;
+		src += pitch;
 	}
 }
 
-void convertChar16x16(uint8 *dst, const Glyph &g) {
-	const uint8 *src = g.plainData;
+void Glyph::convertChar16x16(uint8 *dst) const {
+	const uint8 *src = plainData;
+	dst += yOffset * 2;
 
-	for (int y = 0; y < g.height; ++y) {
-		uint16 mask = 1 << (15 - g.xOffset);
+	for (int y = 0; y < height; ++y) {
+		uint16 mask = 1 << (15 - xOffset);
 
 		const uint8 *curSrc = src;
 
 		uint16 line = 0;
 		uint8 d = 0;
-		for (int x = 0; x < g.width; ++x) {
+		for (int x = 0; x < width; ++x) {
 			if (x == 0 || x == 8)
 				d = *curSrc++;
 
@@ -485,7 +499,7 @@ void convertChar16x16(uint8 *dst, const Glyph &g) {
 		}
 
 		WRITE_BE_UINT16(dst, line); dst += 2;
-		src += g.pitch;
+		src += pitch;
 	}
 }
 
diff --git a/create_sjisfnt.h b/create_sjisfnt.h
index 51ead01..44088ec 100644
--- a/create_sjisfnt.h
+++ b/create_sjisfnt.h
@@ -40,6 +40,12 @@ void deinitSJIStoUTF32Conversion();
 uint32 convertSJIStoUTF32(uint8 fB, uint8 sB);
 
 struct Glyph {
+	Glyph();
+	Glyph(const Glyph &r);
+	~Glyph();
+
+	Glyph &operator=(const Glyph &r);
+
 	uint8 fB, sB;
 
 	int xOffset;
@@ -50,15 +56,14 @@ struct Glyph {
 
 	int pitch;
 	uint8 *plainData;
-};
 
-bool checkGlyphSize(const Glyph &g, const int maxW, const int maxH);
+	bool checkSize(const int maxW, const int maxH) const;
 
-void convertChar8x16(uint8 *dst, const Glyph &g);
-void convertChar16x16(uint8 *dst, const Glyph &g);
+	void convertChar8x16(uint8 *dst) const;
+	void convertChar16x16(uint8 *dst) const;
+};
 
 typedef std::list<Glyph> GlyphList;
-void freeGlyphlist(GlyphList &list);
 
 class TrueTypeFont {
 public:






More information about the Scummvm-git-logs mailing list