Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F118900
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
95 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/.travis.yml b/.travis.yml.backup
similarity index 100%
rename from .travis.yml
rename to .travis.yml.backup
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e4fbdf8..b78f1d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,182 +1,185 @@
Project (meandmyshadow)
CMake_Minimum_Required (VERSION 3.1)
Set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
Option (DEBUG_MODE "Compile the game with debug mode enabled" OFF)
Option (DISABLED_DEBUG_STUFF "Enable this you'll see a lot of annoying script debug messages which will lag the game." OFF)
#Find the required libraries.
Find_Package (SDL2 REQUIRED)
Find_Package (SDL2_image REQUIRED)
-Find_Package (SDL2_ttf REQUIRED)
+Find_Package (Freetype REQUIRED)
Find_Package (SDL2_mixer REQUIRED)
Find_Package (CURL REQUIRED)
Find_Package (LibArchive REQUIRED)
Find_Package (Lua REQUIRED)
if (NOT SDL2_FOUND)
message (FATAL_ERROR "SDL2 library could not be found!")
endif (NOT SDL2_FOUND)
if (NOT SDL2_IMAGE_FOUND)
message (FATAL_ERROR "SDL2_image library could not be found!")
endif (NOT SDL2_IMAGE_FOUND)
-if (NOT SDL2_TTF_FOUND)
- message (FATAL_ERROR "SDL2_ttf library could not be found!")
-endif (NOT SDL2_TTF_FOUND)
+if (NOT FREETYPE_FOUND)
+ message (FATAL_ERROR "Freetype library could not be found!")
+endif (NOT FREETYPE_FOUND)
if (NOT SDL2_MIXER_FOUND)
message (FATAL_ERROR "SDL2_mixer library could not be found!")
endif (NOT SDL2_MIXER_FOUND)
if (NOT CURL_FOUND)
message(FATAL_ERROR "CURL library could not be found!")
endif (NOT CURL_FOUND)
if (NOT LibArchive_FOUND)
message (FATAL_ERROR "LibArchive library could not be found!")
endif (NOT LibArchive_FOUND)
if (NOT LUA_FOUND)
message (FATAL_ERROR "Lua library could not be found!")
endif (NOT LUA_FOUND)
if (LUA_VERSION_STRING VERSION_LESS "5.2")
message (FATAL_ERROR "Lua version too old ${LUA_VERSION_STRING}, expected at least 5.2!")
endif ()
# check version from Globals.h
file(READ "${PROJECT_SOURCE_DIR}/src/Globals.h" GLOBALS_H)
string(REGEX MATCH "version[ ]*=[ ]*\"[^\"]*\"" MNMS_VERSION_STR ${GLOBALS_H})
string(REGEX REPLACE "^[^\"]*\"([^\"]*)\".*$" "\\1" MNMS_VERSION_STR ${MNMS_VERSION_STR})
message(STATUS "The version read from Globals.h is: ${MNMS_VERSION_STR}")
string(REGEX REPLACE "^V([0-9.]+).*$" "\\1" MNMS_VERSION_NUM ${MNMS_VERSION_STR})
set(MNMS_VERSION_NUM "${MNMS_VERSION_NUM}.0.0.0.0")
string(REGEX REPLACE "^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+).*$" "\\1,\\2,\\3,\\4" MNMS_VERSION_NUM ${MNMS_VERSION_NUM})
message(STATUS "which is: ${MNMS_VERSION_NUM}")
# check version from git
find_package(Git)
if(GIT_FOUND)
exec_program(${GIT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR} ARGS "describe"
OUTPUT_VARIABLE MNMS_GIT_VERSION RETURN_VALUE GIT_RETURN_VALUE)
if(GIT_RETURN_VALUE STREQUAL "0")
set(MNMS_VERSION_STR "${MNMS_VERSION_STR} (${MNMS_GIT_VERSION})")
message(STATUS "The version read from git is: ${MNMS_GIT_VERSION}")
else()
# possibly there are no any tags
exec_program(${GIT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR} ARGS "rev-parse --short HEAD"
OUTPUT_VARIABLE MNMS_GIT_VERSION RETURN_VALUE GIT_RETURN_VALUE)
if(GIT_RETURN_VALUE STREQUAL "0")
set(MNMS_VERSION_STR "${MNMS_VERSION_STR} (git ${MNMS_GIT_VERSION})")
message(STATUS "The version read from git is: ${MNMS_GIT_VERSION}")
endif()
endif()
endif()
# show version information on Windows
Set(WIN32_RESOURCES )
if(WIN32)
Configure_File (
"${PROJECT_SOURCE_DIR}/icons/windows-icon/res.rc.in"
"${PROJECT_BINARY_DIR}/res.rc"
)
Set(WIN32_RESOURCES ${PROJECT_BINARY_DIR}/res.rc)
Include_Directories(${PROJECT_SOURCE_DIR}/icons/windows-icon/)
SOURCE_GROUP("Source Files\\Resources" FILES ${WIN32_RESOURCES})
endif()
#Parse the configure file.
Configure_File (
"${PROJECT_SOURCE_DIR}/src/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
#Add some missing libraries to Windows.
if(WIN32)
include_directories(${PROJECT_SOURCE_DIR}/src/libs/dirent)
endif(WIN32)
#Disable some annoying warnings.
if(MSVC)
# warning C4996: '***': This function or variable may be unsafe
add_definitions(/wd4996)
else()
# Assume it's gcc or clang
# warning: '***' overrides a member function but is not marked 'override'
add_definitions(-Wno-inconsistent-missing-override)
endif()
#Define some debug stuff.
if(DEBUG_MODE)
add_definitions(-DDEBUG)
add_definitions(-D_DEBUG)
endif(DEBUG_MODE)
if(DISABLED_DEBUG_STUFF)
add_definitions(-DDISABLED_DEBUG_STUFF)
endif(DISABLED_DEBUG_STUFF)
#Add the include directories of the (found) libraries.
Include_Directories(
${PROJECT_BINARY_DIR}
${SDL2_INCLUDE_DIR}
${SDL2_IMAGE_INCLUDE_DIR}
- ${SDL2_TTF_INCLUDE_DIR}
+ ${FREETYPE_INCLUDE_DIRS}
${SDL2_MIXER_INCLUDE_DIR}
${CURL_INCLUDE_DIR}
${LibArchive_INCLUDE_DIR}
${LUA_INCLUDE_DIR}
${PROJECT_SOURCE_DIR}/src/libs
+ ${PROJECT_SOURCE_DIR}/src/libs/SDL2_ttf
)
#Set the output path and the source path.
Set (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
Set (SRC_DIR ${PROJECT_SOURCE_DIR}/src)
#List the source files.
File (GLOB SOURCES ${SRC_DIR}/*.cpp)
File (GLOB TINYGETTEXT ${SRC_DIR}/libs/tinygettext/*.cpp)
File (GLOB FINDLOCALE ${SRC_DIR}/libs/findlocale/*.cpp)
+File (GLOB SDL2TTF ${SRC_DIR}/libs/SDL2_ttf/*.c)
#Always use SDL_iconv in tinygettext
add_definitions(-DHAVE_SDL)
SOURCE_GROUP("Source Files\\tinygettext" FILES ${TINYGETTEXT})
SOURCE_GROUP("Source Files\\findlocale" FILES ${FINDLOCALE})
+SOURCE_GROUP("Source Files\\SDL2_ttf" FILES ${SDL2TTF})
-Add_Executable (meandmyshadow ${SOURCES} ${TINYGETTEXT} ${FINDLOCALE} ${WIN32_RESOURCES})
+Add_Executable (meandmyshadow ${SOURCES} ${TINYGETTEXT} ${FINDLOCALE} ${WIN32_RESOURCES} ${SDL2TTF})
set_property(TARGET meandmyshadow PROPERTY CXX_STANDARD 11)
Target_Link_Libraries (
meandmyshadow
${SDL2_LIBRARY}
${SDL2_IMAGE_LIBRARY}
- ${SDL2_TTF_LIBRARY}
+ ${FREETYPE_LIBRARIES}
${SDL2_MIXER_LIBRARY}
${SDL2MAIN_LIBRARY}
${CURL_LIBRARY}
${LibArchive_LIBRARY}
${LUA_LIBRARIES}
)
#Path options
Set (BINDIR "bin" CACHE STRING "Where to install binaries")
Set (DATAROOTDIR "${CMAKE_INSTALL_PREFIX}/share" CACHE STRING "Sets the root of data directories to a non-default location")
Set (ICONDIR "${DATAROOTDIR}/icons" CACHE STRING "Sets the icon directory for desktop entry to a non-default location.")
Set (DESKTOPDIR "${DATAROOTDIR}/applications" CACHE STRING "Sets the desktop file directory for desktop entry to a non-default location.")
#Install locations
Install (DIRECTORY ${PROJECT_SOURCE_DIR}/data DESTINATION ${DATAROOTDIR}/meandmyshadow/)
Install (FILES AUTHORS DESTINATION ${DATAROOTDIR}/meandmyshadow/)
Install (TARGETS meandmyshadow RUNTIME DESTINATION ${BINDIR})
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
Install (FILES meandmyshadow.desktop DESTINATION ${DESKTOPDIR})
Install (FILES icons/16x16/meandmyshadow.png DESTINATION ${ICONDIR}/hicolor/16x16/apps/)
Install (FILES icons/32x32/meandmyshadow.png DESTINATION ${ICONDIR}/hicolor/32x32/apps/)
Install (FILES icons/48x48/meandmyshadow.png DESTINATION ${ICONDIR}/hicolor/48x48/apps/)
Install (FILES icons/64x64/meandmyshadow.png DESTINATION ${ICONDIR}/hicolor/64x64/apps/)
endif ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
diff --git a/appveyor.yml b/appveyor.yml.backup
similarity index 100%
rename from appveyor.yml
rename to appveyor.yml.backup
diff --git a/src/libs/SDL2_ttf/CHANGES.txt b/src/libs/SDL2_ttf/CHANGES.txt
new file mode 100644
index 0000000..d490554
--- /dev/null
+++ b/src/libs/SDL2_ttf/CHANGES.txt
@@ -0,0 +1,37 @@
+2.0.15:
+Sam Lantinga - Sun Sep 10 00:18:45 PDT 2017
+ * Text rendering functions now use the alpha component of the text colors
+Sam Lantinga - Sat Sep 9 22:21:55 PDT 2017
+ * Added support for characters greater than 0xFFFF (e.g. emoji) in the UTF-8 APIs
+
+2.0.14:
+Ryan Gordon - Fri Jan 29 12:53:29 PST 2016
+ * Deprecated TTF_GetFontKerningSize() which takes font glyph indices and added TTF_GetFontKerningSizeGlyphs() which takes characters
+
+2.0.13:
+Sylvain - Sat Jun 28 11:42:42 2014
+ * Fixed bug rendering text starting with a glyph with negative starting offset
+beuc - Sun Jun 15 18:27:28 2014
+ * Fixed regression loading non-scalable fonts
+Sam Lantinga - Sun Jun 15 18:21:04 PDT 2014
+ * TTF_GetFontKerningSize() gets kerning between two characters, not two glyph indices
+David Ludwig - Sun Apr 13 22:28:26 2014
+ * Added support for building for Windows RT and Windows Phone
+
+2.0.12:
+Sam Lantinga - Sat Jun 1 19:11:26 PDT 2013
+ * Updated for SDL 2.0 release
+
+2.0.11:
+Sam Lantinga - Sat Dec 31 10:49:42 EST 2011
+ * SDL_ttf is now under the zlib license
+Peter Kosyh - Mon Feb 28 14:57:03 PST 2011
+ * Improved font glyph caching for non-latin languages
+Erik Snoek - Wed Jan 12 09:10:15 PST 2011
+ * Added API to get kerning info: TTF_GetFontKerningSize()
+Sam Lantinga - Mon Jan 10 10:58:34 2011 -0800
+ * Added Android.mk to build on the Android platform
+
+2.0.10:
+Adam Strzelecki - Wed Oct 21 21:02:37 PDT 2009
+ * Find the Unicode or symbol character map if it's available in the font
diff --git a/src/libs/SDL2_ttf/COPYING.txt b/src/libs/SDL2_ttf/COPYING.txt
new file mode 100644
index 0000000..4a4e814
--- /dev/null
+++ b/src/libs/SDL2_ttf/COPYING.txt
@@ -0,0 +1,20 @@
+/*
+ SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
diff --git a/src/libs/SDL2_ttf/README.txt b/src/libs/SDL2_ttf/README.txt
new file mode 100644
index 0000000..b75b3d7
--- /dev/null
+++ b/src/libs/SDL2_ttf/README.txt
@@ -0,0 +1,25 @@
+
+This library is a wrapper around the excellent FreeType 2.0 library,
+available at:
+ http://www.freetype.org/
+
+This library allows you to use TrueType fonts to render text in SDL
+applications.
+
+To make the library, first install the FreeType library, then type
+'./configure' then 'make' to build the SDL truetype library and the
+showfont and glfont example applications.
+
+Be careful when including fonts with your application, as many of them
+are copyrighted. The Microsoft fonts, for example, are not freely
+redistributable and even the free "web" fonts they provide are only
+redistributable in their special executable installer form (May 1998).
+There are plenty of freeware and shareware fonts available on the Internet
+though, and may suit your purposes.
+
+This library is under the zlib license, see the file "COPYING.txt" for details.
+
+Portions of this software are copyright © 2013 The FreeType Project (www.freetype.org). All rights reserved.
+
+Enjoy!
+ -Sam Lantinga <slouken@libsdl.org> (6/20/2001)
diff --git a/src/libs/SDL2_ttf/SDL_ttf.c b/src/libs/SDL2_ttf/SDL_ttf.c
new file mode 100644
index 0000000..681d966
--- /dev/null
+++ b/src/libs/SDL2_ttf/SDL_ttf.c
@@ -0,0 +1,2319 @@
+/*
+ SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts
+ Copyright (C) 2001-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_OUTLINE_H
+#include FT_STROKER_H
+#include FT_GLYPH_H
+#include FT_TRUETYPE_IDS_H
+
+#include "SDL.h"
+#include "SDL_endian.h"
+#include "SDL_ttf.h"
+
+/* FIXME: Right now we assume the gray-scale renderer Freetype is using
+ supports 256 shades of gray, but we should instead key off of num_grays
+ in the result FT_Bitmap after the FT_Render_Glyph() call. */
+#define NUM_GRAYS 256
+
+/* Handy routines for converting from fixed point */
+#define FT_FLOOR(X) ((X & -64) / 64)
+#define FT_CEIL(X) (((X + 63) & -64) / 64)
+
+#define CACHED_METRICS 0x10
+#define CACHED_BITMAP 0x01
+#define CACHED_PIXMAP 0x02
+
+/* Cached glyph information */
+typedef struct cached_glyph {
+ int stored;
+ FT_UInt index;
+ FT_Bitmap bitmap;
+ FT_Bitmap pixmap;
+ int minx;
+ int maxx;
+ int miny;
+ int maxy;
+ int yoffset;
+ int advance;
+ Uint32 cached;
+} c_glyph;
+
+/* The structure used to hold internal font information */
+struct _TTF_Font {
+ /* Freetype2 maintains all sorts of useful info itself */
+ FT_Face face;
+
+ /* We'll cache these ourselves */
+ int height;
+ int ascent;
+ int descent;
+ int lineskip;
+
+ /* The font style */
+ int face_style;
+ int style;
+ int outline;
+
+ /* Whether kerning is desired */
+ int kerning;
+
+ /* Extra width in glyph bounds for text styles */
+ int glyph_overhang;
+ float glyph_italics;
+
+ /* Information in the font for underlining */
+ int underline_offset;
+ int underline_height;
+
+ /* Cache for style-transformed glyphs */
+ c_glyph *current;
+ c_glyph cache[257]; /* 257 is a prime */
+
+ /* We are responsible for closing the font stream */
+ SDL_RWops *src;
+ int freesrc;
+ FT_Open_Args args;
+
+ /* For non-scalable formats, we must remember which font index size */
+ int font_size_family;
+
+ /* really just flags passed into FT_Load_Glyph */
+ int hinting;
+};
+
+/* Handle a style only if the font does not already handle it */
+#define TTF_HANDLE_STYLE_BOLD(font) (((font)->style & TTF_STYLE_BOLD) && \
+ !((font)->face_style & TTF_STYLE_BOLD))
+#define TTF_HANDLE_STYLE_ITALIC(font) (((font)->style & TTF_STYLE_ITALIC) && \
+ !((font)->face_style & TTF_STYLE_ITALIC))
+#define TTF_HANDLE_STYLE_UNDERLINE(font) ((font)->style & TTF_STYLE_UNDERLINE)
+#define TTF_HANDLE_STYLE_STRIKETHROUGH(font) ((font)->style & TTF_STYLE_STRIKETHROUGH)
+
+/* Font styles that does not impact glyph drawing */
+#define TTF_STYLE_NO_GLYPH_CHANGE (TTF_STYLE_UNDERLINE | TTF_STYLE_STRIKETHROUGH)
+
+/* The FreeType font engine/library */
+static FT_Library library;
+static int TTF_initialized = 0;
+static int TTF_byteswapped = 0;
+
+#define TTF_CHECKPOINTER(p, errval) \
+ if (!TTF_initialized) { \
+ TTF_SetError("Library not initialized"); \
+ return errval; \
+ } \
+ if (!p) { \
+ TTF_SetError("Passed a NULL pointer"); \
+ return errval; \
+ }
+
+/* Gets the top row of the underline. The outline
+ is taken into account.
+*/
+static int TTF_underline_top_row(TTF_Font *font)
+{
+ /* With outline, the underline_offset is underline_offset+outline. */
+ /* So, we don't have to remove the top part of the outline height. */
+ return font->ascent - font->underline_offset - 1;
+}
+
+/* Gets the top row of the underline. for a given glyph. The outline
+ is taken into account.
+ Need to update row according to height difference between font and glyph:
+ font_value - font->ascent + glyph->maxy
+*/
+static int TTF_Glyph_underline_top_row(TTF_Font *font, c_glyph *glyph)
+{
+ return glyph->maxy - font->underline_offset - 1;
+}
+
+/* Gets the bottom row of the underline. The outline
+ is taken into account.
+*/
+static int TTF_underline_bottom_row(TTF_Font *font)
+{
+ int row = TTF_underline_top_row(font) + font->underline_height;
+ if (font->outline > 0) {
+ /* Add underline_offset outline offset and */
+ /* the bottom part of the outline. */
+ row += font->outline * 2;
+ }
+ return row;
+}
+
+/* Gets the bottom row of the underline. for a given glyph. The outline
+ is taken into account.
+ Need to update row according to height difference between font and glyph:
+ font_value - font->ascent + glyph->maxy
+*/
+static int TTF_Glyph_underline_bottom_row(TTF_Font *font, c_glyph *glyph)
+{
+ return TTF_underline_bottom_row(font) - font->ascent + glyph->maxy;
+}
+
+/* Gets the top row of the strikethrough. The outline
+ is taken into account.
+*/
+static int TTF_strikethrough_top_row(TTF_Font *font)
+{
+ /* With outline, the first text row is 'outline'. */
+ /* So, we don't have to remove the top part of the outline height. */
+ return font->height / 2;
+}
+
+/* Gets the top row of the strikethrough for a given glyph. The outline
+ is taken into account.
+ Need to update row according to height difference between font and glyph:
+ font_value - font->ascent + glyph->maxy
+*/
+static int TTF_Glyph_strikethrough_top_row(TTF_Font *font, c_glyph *glyph)
+{
+ return TTF_strikethrough_top_row(font) - font->ascent + glyph->maxy;
+}
+
+static void TTF_initLineMectrics(const TTF_Font *font, const SDL_Surface *textbuf, const int row, Uint8 **pdst, int *pheight)
+{
+ Uint8 *dst;
+ int height;
+
+ dst = (Uint8 *)textbuf->pixels;
+ if (row > 0) {
+ dst += row * textbuf->pitch;
+ }
+
+ height = font->underline_height;
+ /* Take outline into account */
+ if (font->outline > 0) {
+ height += font->outline * 2;
+ }
+ *pdst = dst;
+ *pheight = height;
+}
+
+/* Draw a solid line of underline_height (+ optional outline)
+ at the given row. The row value must take the
+ outline into account.
+*/
+static void TTF_drawLine_Solid(const TTF_Font *font, const SDL_Surface *textbuf, const int row)
+{
+ int line;
+ Uint8 *dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h;
+ Uint8 *dst;
+ int height;
+
+ TTF_initLineMectrics(font, textbuf, row, &dst, &height);
+
+ /* Draw line */
+ for (line=height; line>0 && dst < dst_check; --line) {
+ /* 1 because 0 is the bg color */
+ SDL_memset(dst, 1, textbuf->w);
+ dst += textbuf->pitch;
+ }
+}
+
+/* Draw a shaded line of underline_height (+ optional outline)
+ at the given row. The row value must take the
+ outline into account.
+*/
+static void TTF_drawLine_Shaded(const TTF_Font *font, const SDL_Surface *textbuf, const int row)
+{
+ int line;
+ Uint8 *dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h;
+ Uint8 *dst;
+ int height;
+
+ TTF_initLineMectrics(font, textbuf, row, &dst, &height);
+
+ /* Draw line */
+ for (line=height; line>0 && dst < dst_check; --line) {
+ SDL_memset(dst, NUM_GRAYS - 1, textbuf->w);
+ dst += textbuf->pitch;
+ }
+}
+
+/* Draw a blended line of underline_height (+ optional outline)
+ at the given row. The row value must take the
+ outline into account.
+*/
+static void TTF_drawLine_Blended(const TTF_Font *font, const SDL_Surface *textbuf, const int row, const Uint32 color)
+{
+ int line;
+ Uint32 *dst_check = (Uint32*)textbuf->pixels + textbuf->pitch/4 * textbuf->h;
+ Uint8 *dst8; /* destination, byte version */
+ Uint32 *dst;
+ int height;
+ int col;
+ Uint32 pixel = color | 0xFF000000; /* Amask */
+
+ TTF_initLineMectrics(font, textbuf, row, &dst8, &height);
+ dst = (Uint32 *) dst8;
+
+ /* Draw line */
+ for (line=height; line>0 && dst < dst_check; --line) {
+ for (col=0; col < textbuf->w; ++col) {
+ dst[col] = pixel;
+ }
+ dst += textbuf->pitch/4;
+ }
+}
+
+/* rcg06192001 get linked library's version. */
+const SDL_version *TTF_Linked_Version(void)
+{
+ static SDL_version linked_version;
+ SDL_TTF_VERSION(&linked_version);
+ return(&linked_version);
+}
+
+/* This function tells the library whether UNICODE text is generally
+ byteswapped. A UNICODE BOM character at the beginning of a string
+ will override this setting for that string.
+ */
+void TTF_ByteSwappedUNICODE(int swapped)
+{
+ TTF_byteswapped = swapped;
+}
+
+static void TTF_SetFTError(const char *msg, FT_Error error)
+{
+#ifdef USE_FREETYPE_ERRORS
+#undef FTERRORS_H
+#define FT_ERRORDEF(e, v, s) { e, s },
+ static const struct
+ {
+ int err_code;
+ const char* err_msg;
+ } ft_errors[] = {
+#include <freetype/fterrors.h>
+ };
+ int i;
+ const char *err_msg;
+ char buffer[1024];
+
+ err_msg = NULL;
+ for (i=0; i<((sizeof ft_errors)/(sizeof ft_errors[0])); ++i) {
+ if (error == ft_errors[i].err_code) {
+ err_msg = ft_errors[i].err_msg;
+ break;
+ }
+ }
+ if (!err_msg) {
+ err_msg = "unknown FreeType error";
+ }
+ TTF_SetError("%s: %s", msg, err_msg);
+#else
+ TTF_SetError("%s", msg);
+#endif /* USE_FREETYPE_ERRORS */
+}
+
+int TTF_Init(void)
+{
+ int status = 0;
+
+ if (!TTF_initialized) {
+ FT_Error error = FT_Init_FreeType(&library);
+ if (error) {
+ TTF_SetFTError("Couldn't init FreeType engine", error);
+ status = -1;
+ }
+ }
+ if (status == 0) {
+ ++TTF_initialized;
+ }
+ return status;
+}
+
+static unsigned long RWread(
+ FT_Stream stream,
+ unsigned long offset,
+ unsigned char* buffer,
+ unsigned long count
+)
+{
+ SDL_RWops *src;
+
+ src = (SDL_RWops *)stream->descriptor.pointer;
+ SDL_RWseek(src, (int)offset, RW_SEEK_SET);
+ if (count == 0) {
+ return 0;
+ }
+ return (unsigned long)SDL_RWread(src, buffer, 1, (int)count);
+}
+
+TTF_Font* TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index)
+{
+ TTF_Font* font;
+ FT_Error error;
+ FT_Face face;
+ FT_Fixed scale;
+ FT_Stream stream;
+ FT_CharMap found;
+ Sint64 position;
+ int i;
+
+ if (!TTF_initialized) {
+ TTF_SetError("Library not initialized");
+ if (src && freesrc) {
+ SDL_RWclose(src);
+ }
+ return NULL;
+ }
+
+ if (!src) {
+ TTF_SetError("Passed a NULL font source");
+ return NULL;
+ }
+
+ /* Check to make sure we can seek in this stream */
+ position = SDL_RWtell(src);
+ if (position < 0) {
+ TTF_SetError("Can't seek in stream");
+ if (freesrc) {
+ SDL_RWclose(src);
+ }
+ return NULL;
+ }
+
+ font = (TTF_Font*)SDL_malloc(sizeof *font);
+ if (font == NULL) {
+ TTF_SetError("Out of memory");
+ if (freesrc) {
+ SDL_RWclose(src);
+ }
+ return NULL;
+ }
+ SDL_memset(font, 0, sizeof(*font));
+
+ font->src = src;
+ font->freesrc = freesrc;
+
+ stream = (FT_Stream)SDL_malloc(sizeof(*stream));
+ if (stream == NULL) {
+ TTF_SetError("Out of memory");
+ TTF_CloseFont(font);
+ return NULL;
+ }
+ SDL_memset(stream, 0, sizeof(*stream));
+
+ stream->read = RWread;
+ stream->descriptor.pointer = src;
+ stream->pos = (unsigned long)position;
+ stream->size = (unsigned long)(SDL_RWsize(src) - position);
+
+ font->args.flags = FT_OPEN_STREAM;
+ font->args.stream = stream;
+
+ error = FT_Open_Face(library, &font->args, index, &font->face);
+ if (error) {
+ TTF_SetFTError("Couldn't load font file", error);
+ TTF_CloseFont(font);
+ return NULL;
+ }
+ face = font->face;
+
+ /* Set charmap for loaded font */
+ found = 0;
+#if 0 /* Font debug code */
+ for (i = 0; i < face->num_charmaps; i++) {
+ FT_CharMap charmap = face->charmaps[i];
+ printf("Found charmap: platform id %d, encoding id %d\n", charmap->platform_id, charmap->encoding_id);
+ }
+#endif
+ if (!found) {
+ for (i = 0; i < face->num_charmaps; i++) {
+ FT_CharMap charmap = face->charmaps[i];
+ if (charmap->platform_id == 3 && charmap->encoding_id == 10) { /* UCS-4 Unicode */
+ found = charmap;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ for (i = 0; i < face->num_charmaps; i++) {
+ FT_CharMap charmap = face->charmaps[i];
+ if ((charmap->platform_id == 3 && charmap->encoding_id == 1) /* Windows Unicode */
+ || (charmap->platform_id == 3 && charmap->encoding_id == 0) /* Windows Symbol */
+ || (charmap->platform_id == 2 && charmap->encoding_id == 1) /* ISO Unicode */
+ || (charmap->platform_id == 0)) { /* Apple Unicode */
+ found = charmap;
+ break;
+ }
+ }
+ }
+ if (found) {
+ /* If this fails, continue using the default charmap */
+ FT_Set_Charmap(face, found);
+ }
+
+ /* Make sure that our font face is scalable (global metrics) */
+ if (FT_IS_SCALABLE(face)) {
+ /* Set the character size and use default DPI (72) */
+ error = FT_Set_Char_Size(font->face, 0, ptsize * 64, 0, 0);
+ if (error) {
+ TTF_SetFTError("Couldn't set font size", error);
+ TTF_CloseFont(font);
+ return NULL;
+ }
+
+ /* Get the scalable font metrics for this font */
+ scale = face->size->metrics.y_scale;
+ font->ascent = FT_CEIL(FT_MulFix(face->ascender, scale));
+ font->descent = FT_CEIL(FT_MulFix(face->descender, scale));
+ font->height = font->ascent - font->descent + /* baseline */ 1;
+ font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
+ font->underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale));
+ font->underline_height = FT_FLOOR(FT_MulFix(face->underline_thickness, scale));
+
+ } else {
+ /* Non-scalable font case. ptsize determines which family
+ * or series of fonts to grab from the non-scalable format.
+ * It is not the point size of the font.
+ * */
+ if (ptsize >= font->face->num_fixed_sizes)
+ ptsize = font->face->num_fixed_sizes - 1;
+ font->font_size_family = ptsize;
+ error = FT_Set_Pixel_Sizes(face,
+ face->available_sizes[ptsize].width,
+ face->available_sizes[ptsize].height);
+
+ /* With non-scalale fonts, Freetype2 likes to fill many of the
+ * font metrics with the value of 0. The size of the
+ * non-scalable fonts must be determined differently
+ * or sometimes cannot be determined.
+ * */
+ font->ascent = face->available_sizes[ptsize].height;
+ font->descent = 0;
+ font->height = face->available_sizes[ptsize].height;
+ font->lineskip = FT_CEIL(font->ascent);
+ font->underline_offset = FT_FLOOR(face->underline_position);
+ font->underline_height = FT_FLOOR(face->underline_thickness);
+ }
+
+ if (font->underline_height < 1) {
+ font->underline_height = 1;
+ }
+
+#ifdef DEBUG_FONTS
+ printf("Font metrics:\n");
+ printf("\tascent = %d, descent = %d\n",
+ font->ascent, font->descent);
+ printf("\theight = %d, lineskip = %d\n",
+ font->height, font->lineskip);
+ printf("\tunderline_offset = %d, underline_height = %d\n",
+ font->underline_offset, font->underline_height);
+ printf("\tunderline_top_row = %d, strikethrough_top_row = %d\n",
+ TTF_underline_top_row(font), TTF_strikethrough_top_row(font));
+#endif
+
+ /* Initialize the font face style */
+ font->face_style = TTF_STYLE_NORMAL;
+ if (font->face->style_flags & FT_STYLE_FLAG_BOLD) {
+ font->face_style |= TTF_STYLE_BOLD;
+ }
+ if (font->face->style_flags & FT_STYLE_FLAG_ITALIC) {
+ font->face_style |= TTF_STYLE_ITALIC;
+ }
+
+ /* Set the default font style */
+ font->style = font->face_style;
+ font->outline = 0;
+ font->kerning = 1;
+ font->glyph_overhang = face->size->metrics.y_ppem / 10;
+ /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */
+ font->glyph_italics = 0.207f;
+ font->glyph_italics *= font->height;
+
+ return font;
+}
+
+TTF_Font* TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize)
+{
+ return TTF_OpenFontIndexRW(src, freesrc, ptsize, 0);
+}
+
+TTF_Font* TTF_OpenFontIndex(const char *file, int ptsize, long index)
+{
+ SDL_RWops *rw = SDL_RWFromFile(file, "rb");
+ if (rw == NULL) {
+ return NULL;
+ }
+ return TTF_OpenFontIndexRW(rw, 1, ptsize, index);
+}
+
+TTF_Font* TTF_OpenFont(const char *file, int ptsize)
+{
+ return TTF_OpenFontIndex(file, ptsize, 0);
+}
+
+static void Flush_Glyph(c_glyph* glyph)
+{
+ glyph->stored = 0;
+ glyph->index = 0;
+ if (glyph->bitmap.buffer) {
+ SDL_free(glyph->bitmap.buffer);
+ glyph->bitmap.buffer = 0;
+ }
+ if (glyph->pixmap.buffer) {
+ SDL_free(glyph->pixmap.buffer);
+ glyph->pixmap.buffer = 0;
+ }
+ glyph->cached = 0;
+}
+
+static void Flush_Cache(TTF_Font* font)
+{
+ int i;
+ int size = sizeof(font->cache) / sizeof(font->cache[0]);
+
+ for (i = 0; i < size; ++i) {
+ if (font->cache[i].cached) {
+ Flush_Glyph(&font->cache[i]);
+ }
+
+ }
+}
+
+static FT_Error Load_Glyph(TTF_Font* font, Uint32 ch, c_glyph* cached, int want)
+{
+ FT_Face face;
+ FT_Error error;
+ FT_GlyphSlot glyph;
+ FT_Glyph_Metrics* metrics;
+ FT_Outline* outline;
+
+ if (!font || !font->face) {
+ return FT_Err_Invalid_Handle;
+ }
+
+ face = font->face;
+
+ /* Load the glyph */
+ if (!cached->index) {
+ cached->index = FT_Get_Char_Index(face, ch);
+ }
+ error = FT_Load_Glyph(face, cached->index, FT_LOAD_DEFAULT | font->hinting);
+ if (error) {
+ return error;
+ }
+
+ /* Get our glyph shortcuts */
+ glyph = face->glyph;
+ metrics = &glyph->metrics;
+ outline = &glyph->outline;
+
+ /* Get the glyph metrics if desired */
+ if ((want & CACHED_METRICS) && !(cached->stored & CACHED_METRICS)) {
+ if (FT_IS_SCALABLE(face)) {
+ /* Get the bounding box */
+ cached->minx = FT_FLOOR(metrics->horiBearingX);
+ cached->maxx = FT_CEIL(metrics->horiBearingX + metrics->width);
+ cached->maxy = FT_FLOOR(metrics->horiBearingY);
+ cached->miny = cached->maxy - FT_CEIL(metrics->height);
+ cached->yoffset = font->ascent - cached->maxy;
+ cached->advance = FT_CEIL(metrics->horiAdvance);
+ } else {
+ /* Get the bounding box for non-scalable format.
+ * Again, freetype2 fills in many of the font metrics
+ * with the value of 0, so some of the values we
+ * need must be calculated differently with certain
+ * assumptions about non-scalable formats.
+ * */
+ cached->minx = FT_FLOOR(metrics->horiBearingX);
+ cached->maxx = FT_CEIL(metrics->horiBearingX + metrics->width);
+ cached->maxy = FT_FLOOR(metrics->horiBearingY);
+ cached->miny = cached->maxy - FT_CEIL(face->available_sizes[font->font_size_family].height);
+ cached->yoffset = 0;
+ cached->advance = FT_CEIL(metrics->horiAdvance);
+ }
+
+ /* Adjust for bold and italic text */
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ cached->maxx += font->glyph_overhang;
+ }
+ if (TTF_HANDLE_STYLE_ITALIC(font)) {
+ cached->maxx += (int)SDL_ceil(font->glyph_italics);
+ }
+ cached->stored |= CACHED_METRICS;
+ }
+
+ if (((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) ||
+ ((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP))) {
+ int mono = (want & CACHED_BITMAP);
+ int i;
+ FT_Bitmap* src;
+ FT_Bitmap* dst;
+ FT_Glyph bitmap_glyph = NULL;
+
+ /* Handle the italic style */
+ if (TTF_HANDLE_STYLE_ITALIC(font)) {
+ FT_Matrix shear;
+
+ shear.xx = 1 << 16;
+ shear.xy = (int) (font->glyph_italics * (1 << 16)) / font->height;
+ shear.yx = 0;
+ shear.yy = 1 << 16;
+
+ FT_Outline_Transform(outline, &shear);
+ }
+
+ /* Render as outline */
+ if ((font->outline > 0) && glyph->format != FT_GLYPH_FORMAT_BITMAP) {
+ FT_Stroker stroker;
+ FT_Get_Glyph(glyph, &bitmap_glyph);
+ error = FT_Stroker_New(library, &stroker);
+ if (error) {
+ return error;
+ }
+ FT_Stroker_Set(stroker, font->outline * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
+ FT_Glyph_Stroke(&bitmap_glyph, stroker, 1 /* delete the original glyph */);
+ FT_Stroker_Done(stroker);
+ /* Render the glyph */
+ error = FT_Glyph_To_Bitmap(&bitmap_glyph, mono ? ft_render_mode_mono : ft_render_mode_normal, 0, 1);
+ if (error) {
+ FT_Done_Glyph(bitmap_glyph);
+ return error;
+ }
+ src = &((FT_BitmapGlyph)bitmap_glyph)->bitmap;
+ } else {
+ /* Render the glyph */
+ error = FT_Render_Glyph(glyph, mono ? ft_render_mode_mono : ft_render_mode_normal);
+ if (error) {
+ return error;
+ }
+ src = &glyph->bitmap;
+ }
+ /* Copy over information to cache */
+ if (mono) {
+ dst = &cached->bitmap;
+ } else {
+ dst = &cached->pixmap;
+ }
+ SDL_memcpy(dst, src, sizeof(*dst));
+
+ /* FT_Render_Glyph() and .fon fonts always generate a
+ * two-color (black and white) glyphslot surface, even
+ * when rendered in ft_render_mode_normal. */
+ /* FT_IS_SCALABLE() means that the font is in outline format,
+ * but does not imply that outline is rendered as 8-bit
+ * grayscale, because embedded bitmap/graymap is preferred
+ * (see FT_LOAD_DEFAULT section of FreeType2 API Reference).
+ * FT_Render_Glyph() canreturn two-color bitmap or 4/16/256-
+ * color graymap according to the format of embedded bitmap/
+ * graymap. */
+ if (src->pixel_mode == FT_PIXEL_MODE_MONO) {
+ dst->pitch *= 8;
+ } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) {
+ dst->pitch *= 4;
+ } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) {
+ dst->pitch *= 2;
+ }
+
+ /* Adjust for bold and italic text */
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ int bump = font->glyph_overhang;
+ dst->pitch += bump;
+ dst->width += bump;
+ }
+ if (TTF_HANDLE_STYLE_ITALIC(font)) {
+ int bump = (int)SDL_ceil(font->glyph_italics);
+ dst->pitch += bump;
+ dst->width += bump;
+ }
+
+ if (dst->rows != 0) {
+ dst->buffer = (unsigned char *)SDL_malloc(dst->pitch * dst->rows);
+ if (!dst->buffer) {
+ return FT_Err_Out_Of_Memory;
+ }
+ SDL_memset(dst->buffer, 0, dst->pitch * dst->rows);
+
+ for (i = 0; i < src->rows; i++) {
+ int soffset = i * src->pitch;
+ int doffset = i * dst->pitch;
+ if (mono) {
+ unsigned char *srcp = src->buffer + soffset;
+ unsigned char *dstp = dst->buffer + doffset;
+ int j;
+ if (src->pixel_mode == FT_PIXEL_MODE_MONO) {
+ for (j = 0; j < src->width; j += 8) {
+ unsigned char c = *srcp++;
+ *dstp++ = (c&0x80) >> 7;
+ c <<= 1;
+ *dstp++ = (c&0x80) >> 7;
+ c <<= 1;
+ *dstp++ = (c&0x80) >> 7;
+ c <<= 1;
+ *dstp++ = (c&0x80) >> 7;
+ c <<= 1;
+ *dstp++ = (c&0x80) >> 7;
+ c <<= 1;
+ *dstp++ = (c&0x80) >> 7;
+ c <<= 1;
+ *dstp++ = (c&0x80) >> 7;
+ c <<= 1;
+ *dstp++ = (c&0x80) >> 7;
+ }
+ } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) {
+ for (j = 0; j < src->width; j += 4) {
+ unsigned char c = *srcp++;
+ *dstp++ = (((c&0xA0) >> 6) >= 0x2) ? 1 : 0;
+ c <<= 2;
+ *dstp++ = (((c&0xA0) >> 6) >= 0x2) ? 1 : 0;
+ c <<= 2;
+ *dstp++ = (((c&0xA0) >> 6) >= 0x2) ? 1 : 0;
+ c <<= 2;
+ *dstp++ = (((c&0xA0) >> 6) >= 0x2) ? 1 : 0;
+ }
+ } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) {
+ for (j = 0; j < src->width; j += 2) {
+ unsigned char c = *srcp++;
+ *dstp++ = (((c&0xF0) >> 4) >= 0x8) ? 1 : 0;
+ c <<= 4;
+ *dstp++ = (((c&0xF0) >> 4) >= 0x8) ? 1 : 0;
+ }
+ } else {
+ for (j = 0; j < src->width; j++) {
+ unsigned char c = *srcp++;
+ *dstp++ = (c >= 0x80) ? 1 : 0;
+ }
+ }
+ } else if (src->pixel_mode == FT_PIXEL_MODE_MONO) {
+ /* This special case wouldn't
+ * be here if the FT_Render_Glyph()
+ * function wasn't buggy when it tried
+ * to render a .fon font with 256
+ * shades of gray. Instead, it
+ * returns a black and white surface
+ * and we have to translate it back
+ * to a 256 gray shaded surface.
+ * */
+ unsigned char *srcp = src->buffer + soffset;
+ unsigned char *dstp = dst->buffer + doffset;
+ unsigned char c;
+ int j, k;
+ for (j = 0; j < src->width; j += 8) {
+ c = *srcp++;
+ for (k = 0; k < 8; ++k) {
+ if ((c&0x80) >> 7) {
+ *dstp++ = NUM_GRAYS - 1;
+ } else {
+ *dstp++ = 0x00;
+ }
+ c <<= 1;
+ }
+ }
+ } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY2) {
+ unsigned char *srcp = src->buffer + soffset;
+ unsigned char *dstp = dst->buffer + doffset;
+ unsigned char c;
+ int j, k;
+ for (j = 0; j < src->width; j += 4) {
+ c = *srcp++;
+ for (k = 0; k < 4; ++k) {
+ if ((c&0xA0) >> 6) {
+ *dstp++ = NUM_GRAYS * ((c&0xA0) >> 6) / 3 - 1;
+ } else {
+ *dstp++ = 0x00;
+ }
+ c <<= 2;
+ }
+ }
+ } else if (src->pixel_mode == FT_PIXEL_MODE_GRAY4) {
+ unsigned char *srcp = src->buffer + soffset;
+ unsigned char *dstp = dst->buffer + doffset;
+ unsigned char c;
+ int j, k;
+ for (j = 0; j < src->width; j += 2) {
+ c = *srcp++;
+ for (k = 0; k < 2; ++k) {
+ if ((c&0xF0) >> 4) {
+ *dstp++ = NUM_GRAYS * ((c&0xF0) >> 4) / 15 - 1;
+ } else {
+ *dstp++ = 0x00;
+ }
+ c <<= 4;
+ }
+ }
+ } else {
+ SDL_memcpy(dst->buffer+doffset,
+ src->buffer+soffset, src->pitch);
+ }
+ }
+ }
+
+ /* Handle the bold style */
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ int row;
+ int col;
+ int offset;
+ int pixel;
+ Uint8* pixmap;
+
+ /* The pixmap is a little hard, we have to add and clamp */
+ for (row = dst->rows - 1; row >= 0; --row) {
+ pixmap = (Uint8*) dst->buffer + row * dst->pitch;
+ for (offset=1; offset <= font->glyph_overhang; ++offset) {
+ for (col = dst->width - 1; col > 0; --col) {
+ if (mono) {
+ pixmap[col] |= pixmap[col-1];
+ } else {
+ pixel = (pixmap[col] + pixmap[col-1]);
+ if (pixel > NUM_GRAYS - 1) {
+ pixel = NUM_GRAYS - 1;
+ }
+ pixmap[col] = (Uint8) pixel;
+ }
+ }
+ }
+ }
+ }
+
+ /* Mark that we rendered this format */
+ if (mono) {
+ cached->stored |= CACHED_BITMAP;
+ } else {
+ cached->stored |= CACHED_PIXMAP;
+ }
+
+ /* Free outlined glyph */
+ if (bitmap_glyph) {
+ FT_Done_Glyph(bitmap_glyph);
+ }
+ }
+
+ /* We're done, mark this glyph cached */
+ cached->cached = ch;
+
+ return 0;
+}
+
+static FT_Error Find_Glyph(TTF_Font* font, Uint32 ch, int want)
+{
+ int retval = 0;
+ int hsize = sizeof(font->cache) / sizeof(font->cache[0]);
+
+ int h = ch % hsize;
+ font->current = &font->cache[h];
+
+ if (font->current->cached != ch)
+ Flush_Glyph(font->current);
+
+ if ((font->current->stored & want) != want) {
+ retval = Load_Glyph(font, ch, font->current, want);
+ }
+ return retval;
+}
+
+void TTF_CloseFont(TTF_Font* font)
+{
+ if (font) {
+ Flush_Cache(font);
+ if (font->face) {
+ FT_Done_Face(font->face);
+ }
+ if (font->args.stream) {
+ SDL_free(font->args.stream);
+ }
+ if (font->freesrc) {
+ SDL_RWclose(font->src);
+ }
+ SDL_free(font);
+ }
+}
+
+/* Gets the number of bytes needed to convert a Latin-1 string to UTF-8 */
+static size_t LATIN1_to_UTF8_len(const char *text)
+{
+ size_t bytes = 1;
+ while (*text) {
+ Uint8 ch = *(Uint8*)text++;
+ if (ch <= 0x7F) {
+ bytes += 1;
+ } else {
+ bytes += 2;
+ }
+ }
+ return bytes;
+}
+
+/* Gets the number of bytes needed to convert a UCS2 string to UTF-8 */
+static size_t UCS2_to_UTF8_len(const Uint16 *text)
+{
+ size_t bytes = 1;
+ while (*text) {
+ Uint16 ch = *text++;
+ if (ch <= 0x7F) {
+ bytes += 1;
+ } else if (ch <= 0x7FF) {
+ bytes += 2;
+ } else {
+ bytes += 3;
+ }
+ }
+ return bytes;
+}
+
+/* Convert a Latin-1 string to a UTF-8 string */
+static void LATIN1_to_UTF8(const char *src, Uint8 *dst)
+{
+ while (*src) {
+ Uint8 ch = *(Uint8*)src++;
+ if (ch <= 0x7F) {
+ *dst++ = ch;
+ } else {
+ *dst++ = 0xC0 | ((ch >> 6) & 0x1F);
+ *dst++ = 0x80 | (ch & 0x3F);
+ }
+ }
+ *dst = '\0';
+}
+
+/* Convert a UCS-2 string to a UTF-8 string */
+static void UCS2_to_UTF8(const Uint16 *src, Uint8 *dst)
+{
+ int swapped = TTF_byteswapped;
+
+ while (*src) {
+ Uint16 ch = *src++;
+ if (ch == UNICODE_BOM_NATIVE) {
+ swapped = 0;
+ continue;
+ }
+ if (ch == UNICODE_BOM_SWAPPED) {
+ swapped = 1;
+ continue;
+ }
+ if (swapped) {
+ ch = SDL_Swap16(ch);
+ }
+ if (ch <= 0x7F) {
+ *dst++ = (Uint8) ch;
+ } else if (ch <= 0x7FF) {
+ *dst++ = 0xC0 | (Uint8) ((ch >> 6) & 0x1F);
+ *dst++ = 0x80 | (Uint8) (ch & 0x3F);
+ } else {
+ *dst++ = 0xE0 | (Uint8) ((ch >> 12) & 0x0F);
+ *dst++ = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
+ *dst++ = 0x80 | (Uint8) (ch & 0x3F);
+ }
+ }
+ *dst = '\0';
+}
+
+/* Gets a unicode value from a UTF-8 encoded string and advance the string */
+#define UNKNOWN_UNICODE 0xFFFD
+static Uint32 UTF8_getch(const char **src, size_t *srclen)
+{
+ const Uint8 *p = *(const Uint8**)src;
+ size_t left = 0;
+ SDL_bool overlong = SDL_FALSE;
+ SDL_bool underflow = SDL_FALSE;
+ Uint32 ch = UNKNOWN_UNICODE;
+
+ if (*srclen == 0) {
+ return UNKNOWN_UNICODE;
+ }
+ if (p[0] >= 0xFC) {
+ if ((p[0] & 0xFE) == 0xFC) {
+ if (p[0] == 0xFC && (p[1] & 0xFC) == 0x80) {
+ overlong = SDL_TRUE;
+ }
+ ch = (Uint32) (p[0] & 0x01);
+ left = 5;
+ }
+ } else if (p[0] >= 0xF8) {
+ if ((p[0] & 0xFC) == 0xF8) {
+ if (p[0] == 0xF8 && (p[1] & 0xF8) == 0x80) {
+ overlong = SDL_TRUE;
+ }
+ ch = (Uint32) (p[0] & 0x03);
+ left = 4;
+ }
+ } else if (p[0] >= 0xF0) {
+ if ((p[0] & 0xF8) == 0xF0) {
+ if (p[0] == 0xF0 && (p[1] & 0xF0) == 0x80) {
+ overlong = SDL_TRUE;
+ }
+ ch = (Uint32) (p[0] & 0x07);
+ left = 3;
+ }
+ } else if (p[0] >= 0xE0) {
+ if ((p[0] & 0xF0) == 0xE0) {
+ if (p[0] == 0xE0 && (p[1] & 0xE0) == 0x80) {
+ overlong = SDL_TRUE;
+ }
+ ch = (Uint32) (p[0] & 0x0F);
+ left = 2;
+ }
+ } else if (p[0] >= 0xC0) {
+ if ((p[0] & 0xE0) == 0xC0) {
+ if ((p[0] & 0xDE) == 0xC0) {
+ overlong = SDL_TRUE;
+ }
+ ch = (Uint32) (p[0] & 0x1F);
+ left = 1;
+ }
+ } else {
+ if ((p[0] & 0x80) == 0x00) {
+ ch = (Uint32) p[0];
+ }
+ }
+ ++*src;
+ --*srclen;
+ while (left > 0 && *srclen > 0) {
+ ++p;
+ if ((p[0] & 0xC0) != 0x80) {
+ ch = UNKNOWN_UNICODE;
+ break;
+ }
+ ch <<= 6;
+ ch |= (p[0] & 0x3F);
+ ++*src;
+ --*srclen;
+ --left;
+ }
+ if (left > 0) {
+ underflow = SDL_TRUE;
+ }
+ /* Technically overlong sequences are invalid and should not be interpreted.
+ However, it doesn't cause a security risk here and I don't see any harm in
+ displaying them. The application is responsible for any other side effects
+ of allowing overlong sequences (e.g. string compares failing, etc.)
+ See bug 1931 for sample input that triggers this.
+ */
+ /*if (overlong) return UNKNOWN_UNICODE;*/
+ if (underflow ||
+ (ch >= 0xD800 && ch <= 0xDFFF) ||
+ (ch == 0xFFFE || ch == 0xFFFF) || ch > 0x10FFFF) {
+ ch = UNKNOWN_UNICODE;
+ }
+ return ch;
+}
+
+int TTF_FontHeight(const TTF_Font *font)
+{
+ return(font->height);
+}
+
+int TTF_FontAscent(const TTF_Font *font)
+{
+ return(font->ascent);
+}
+
+int TTF_FontDescent(const TTF_Font *font)
+{
+ return(font->descent);
+}
+
+int TTF_FontLineSkip(const TTF_Font *font)
+{
+ return(font->lineskip);
+}
+
+int TTF_GetFontKerning(const TTF_Font *font)
+{
+ return(font->kerning);
+}
+
+void TTF_SetFontKerning(TTF_Font *font, int allowed)
+{
+ font->kerning = allowed;
+}
+
+long TTF_FontFaces(const TTF_Font *font)
+{
+ return(font->face->num_faces);
+}
+
+int TTF_FontFaceIsFixedWidth(const TTF_Font *font)
+{
+ return(FT_IS_FIXED_WIDTH(font->face));
+}
+
+char *TTF_FontFaceFamilyName(const TTF_Font *font)
+{
+ return(font->face->family_name);
+}
+
+char *TTF_FontFaceStyleName(const TTF_Font *font)
+{
+ return(font->face->style_name);
+}
+
+int TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch)
+{
+ return(FT_Get_Char_Index(font->face, ch));
+}
+
+int TTF_GlyphMetrics(TTF_Font *font, Uint16 ch,
+ int* minx, int* maxx, int* miny, int* maxy, int* advance)
+{
+ FT_Error error;
+
+ error = Find_Glyph(font, ch, CACHED_METRICS);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ return -1;
+ }
+
+ if (minx) {
+ *minx = font->current->minx;
+ }
+ if (maxx) {
+ *maxx = font->current->maxx;
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ *maxx += font->glyph_overhang;
+ }
+ }
+ if (miny) {
+ *miny = font->current->miny;
+ }
+ if (maxy) {
+ *maxy = font->current->maxy;
+ }
+ if (advance) {
+ *advance = font->current->advance;
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ *advance += font->glyph_overhang;
+ }
+ }
+ return 0;
+}
+
+int TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h)
+{
+ int status = -1;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, -1);
+
+ utf8 = SDL_stack_alloc(Uint8, LATIN1_to_UTF8_len(text));
+ if (utf8) {
+ LATIN1_to_UTF8(text, utf8);
+ status = TTF_SizeUTF8(font, (char *)utf8, w, h);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return status;
+}
+
+int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h)
+{
+ int status;
+ int x, z;
+ int minx, maxx;
+ int miny, maxy;
+ c_glyph *glyph;
+ FT_Error error;
+ FT_Long use_kerning;
+ FT_UInt prev_index = 0;
+ int outline_delta = 0;
+ size_t textlen;
+
+ TTF_CHECKPOINTER(text, -1);
+
+ /* Initialize everything to 0 */
+ status = 0;
+ minx = maxx = 0;
+ miny = maxy = 0;
+
+ /* check kerning */
+ use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
+
+ /* Init outline handling */
+ if (font->outline > 0) {
+ outline_delta = font->outline * 2;
+ }
+
+ /* Load each character and sum it's bounding box */
+ textlen = SDL_strlen(text);
+ x= 0;
+ while (textlen > 0) {
+ Uint32 c = UTF8_getch(&text, &textlen);
+ if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) {
+ continue;
+ }
+
+ error = Find_Glyph(font, c, CACHED_METRICS);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ return -1;
+ }
+ glyph = font->current;
+
+ /* handle kerning */
+ if (use_kerning && prev_index && glyph->index) {
+ FT_Vector delta;
+ FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta);
+ x += delta.x >> 6;
+ }
+
+#if 0
+ if ((ch == text) && (glyph->minx < 0)) {
+ /* Fixes the texture wrapping bug when the first letter
+ * has a negative minx value or horibearing value. The entire
+ * bounding box must be adjusted to be bigger so the entire
+ * letter can fit without any texture corruption or wrapping.
+ *
+ * Effects: First enlarges bounding box.
+ * Second, xstart has to start ahead of its normal spot in the
+ * negative direction of the negative minx value.
+ * (pushes everything to the right).
+ *
+ * This will make the memory copy of the glyph bitmap data
+ * work out correctly.
+ * */
+ z -= glyph->minx;
+ }
+#endif
+
+ z = x + glyph->minx;
+ if (minx > z) {
+ minx = z;
+ }
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ x += font->glyph_overhang;
+ }
+ if (glyph->advance > glyph->maxx) {
+ z = x + glyph->advance;
+ } else {
+ z = x + glyph->maxx;
+ }
+ if (maxx < z) {
+ maxx = z;
+ }
+ x += glyph->advance;
+
+ if (glyph->miny < miny) {
+ miny = glyph->miny;
+ }
+ if (glyph->maxy > maxy) {
+ maxy = glyph->maxy;
+ }
+ prev_index = glyph->index;
+ }
+
+ /* Fill the bounds rectangle */
+ if (w) {
+ /* Add outline extra width */
+ *w = (maxx - minx) + outline_delta;
+ }
+ if (h) {
+ /* Some fonts descend below font height (FletcherGothicFLF) */
+ /* Add outline extra height */
+ *h = (font->ascent - miny) + outline_delta;
+ if (*h < font->height) {
+ *h = font->height;
+ }
+ /* Update height according to the needs of the underline style */
+ if (TTF_HANDLE_STYLE_UNDERLINE(font)) {
+ int bottom_row = TTF_underline_bottom_row(font);
+ if (*h < bottom_row) {
+ *h = bottom_row;
+ }
+ }
+ }
+ return status;
+}
+
+int TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h)
+{
+ int status = -1;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, -1);
+
+ utf8 = SDL_stack_alloc(Uint8, UCS2_to_UTF8_len(text));
+ if (utf8) {
+ UCS2_to_UTF8(text, utf8);
+ status = TTF_SizeUTF8(font, (char *)utf8, w, h);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return status;
+}
+
+SDL_Surface *TTF_RenderText_Solid(TTF_Font *font,
+ const char *text, SDL_Color fg)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, LATIN1_to_UTF8_len(text));
+ if (utf8) {
+ LATIN1_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Solid(font, (char *)utf8, fg);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+SDL_Surface *TTF_RenderUTF8_Solid(TTF_Font *font,
+ const char *text, SDL_Color fg)
+{
+ int xstart;
+ int width;
+ int height;
+ SDL_Surface* textbuf;
+ SDL_Palette* palette;
+ Uint8* src;
+ Uint8* dst;
+ Uint8 *dst_check;
+ int row, col;
+ c_glyph *glyph;
+
+ FT_Bitmap *current;
+ FT_Error error;
+ FT_Long use_kerning;
+ FT_UInt prev_index = 0;
+ size_t textlen;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ /* Get the dimensions of the text surface */
+ if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width) {
+ TTF_SetError("Text has zero width");
+ return NULL;
+ }
+
+ /* Create the target surface */
+ textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0);
+ if (textbuf == NULL) {
+ return NULL;
+ }
+
+ /* Adding bound checking to avoid all kinds of memory corruption errors
+ that may occur. */
+ dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h;
+
+ /* Fill the palette with the foreground color */
+ palette = textbuf->format->palette;
+ palette->colors[0].r = 255 - fg.r;
+ palette->colors[0].g = 255 - fg.g;
+ palette->colors[0].b = 255 - fg.b;
+ palette->colors[1].r = fg.r;
+ palette->colors[1].g = fg.g;
+ palette->colors[1].b = fg.b;
+ palette->colors[1].a = fg.a ? fg.a : SDL_ALPHA_OPAQUE;
+ SDL_SetColorKey(textbuf, SDL_TRUE, 0);
+
+ /* check kerning */
+ use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
+
+ /* Load and render each character */
+ textlen = SDL_strlen(text);
+ xstart = 0;
+ while (textlen > 0) {
+ Uint32 c = UTF8_getch(&text, &textlen);
+ if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) {
+ continue;
+ }
+
+ error = Find_Glyph(font, c, CACHED_METRICS|CACHED_BITMAP);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ SDL_FreeSurface(textbuf);
+ return NULL;
+ }
+ glyph = font->current;
+ current = &glyph->bitmap;
+ /* Ensure the width of the pixmap is correct. On some cases,
+ * freetype may report a larger pixmap than possible.*/
+ width = current->width;
+ if (font->outline <= 0 && width > glyph->maxx - glyph->minx) {
+ width = glyph->maxx - glyph->minx;
+ }
+ /* do kerning, if possible AC-Patch */
+ if (use_kerning && prev_index && glyph->index) {
+ FT_Vector delta;
+ FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta);
+ xstart += delta.x >> 6;
+ }
+
+ for (row = 0; row < current->rows; ++row) {
+ /* Make sure we don't go either over, or under the limit */
+ if ((xstart + glyph->minx) < 0) {
+ xstart -= (xstart + glyph->minx);
+ }
+ if ((row + glyph->yoffset) < 0) {
+ continue;
+ }
+ if ((row + glyph->yoffset) >= textbuf->h) {
+ continue;
+ }
+ dst = (Uint8 *)textbuf->pixels +
+ (row+glyph->yoffset) * textbuf->pitch +
+ xstart + glyph->minx;
+ src = current->buffer + row * current->pitch;
+ for (col = width; col > 0 && dst < dst_check; --col) {
+ *dst++ |= *src++;
+ }
+ }
+
+ xstart += glyph->advance;
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ xstart += font->glyph_overhang;
+ }
+ prev_index = glyph->index;
+ }
+
+ /* Handle the underline style */
+ if (TTF_HANDLE_STYLE_UNDERLINE(font)) {
+ row = TTF_underline_top_row(font);
+ TTF_drawLine_Solid(font, textbuf, row);
+ }
+
+ /* Handle the strikethrough style */
+ if (TTF_HANDLE_STYLE_STRIKETHROUGH(font)) {
+ row = TTF_strikethrough_top_row(font);
+ TTF_drawLine_Solid(font, textbuf, row);
+ }
+ return textbuf;
+}
+
+SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font,
+ const Uint16 *text, SDL_Color fg)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, UCS2_to_UTF8_len(text));
+ if (utf8) {
+ UCS2_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Solid(font, (char *)utf8, fg);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+SDL_Surface *TTF_RenderGlyph_Solid(TTF_Font *font, Uint16 ch, SDL_Color fg)
+{
+ Uint16 ucs2[2] = { ch, 0 };
+ Uint8 utf8[4];
+
+ UCS2_to_UTF8(ucs2, utf8);
+ return TTF_RenderUTF8_Solid(font, (char *)utf8, fg);
+}
+
+SDL_Surface *TTF_RenderText_Shaded(TTF_Font *font,
+ const char *text, SDL_Color fg, SDL_Color bg)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, LATIN1_to_UTF8_len(text));
+ if (utf8) {
+ LATIN1_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Shaded(font, (char *)utf8, fg, bg);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+/* Convert the UTF-8 text to UNICODE and render it
+*/
+SDL_Surface *TTF_RenderUTF8_Shaded(TTF_Font *font,
+ const char *text, SDL_Color fg, SDL_Color bg)
+{
+ int xstart;
+ int width;
+ int height;
+ SDL_Surface* textbuf;
+ SDL_Palette* palette;
+ int index;
+ int rdiff;
+ int gdiff;
+ int bdiff;
+ int adiff;
+ Uint8* src;
+ Uint8* dst;
+ Uint8* dst_check;
+ int row, col;
+ FT_Bitmap* current;
+ c_glyph *glyph;
+ FT_Error error;
+ FT_Long use_kerning;
+ FT_UInt prev_index = 0;
+ size_t textlen;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ /* Get the dimensions of the text surface */
+ if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width) {
+ TTF_SetError("Text has zero width");
+ return NULL;
+ }
+
+ /* Create the target surface */
+ textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0);
+ if (textbuf == NULL) {
+ return NULL;
+ }
+
+ /* Adding bound checking to avoid all kinds of memory corruption errors
+ that may occur. */
+ dst_check = (Uint8*)textbuf->pixels + textbuf->pitch * textbuf->h;
+
+ /* Support alpha blending */
+ if (!fg.a) {
+ fg.a = SDL_ALPHA_OPAQUE;
+ }
+ if (!bg.a) {
+ bg.a = SDL_ALPHA_OPAQUE;
+ }
+ if (fg.a != SDL_ALPHA_OPAQUE || bg.a != SDL_ALPHA_OPAQUE) {
+ SDL_SetSurfaceBlendMode(textbuf, SDL_BLENDMODE_BLEND);
+ }
+
+ /* Fill the palette with NUM_GRAYS levels of shading from bg to fg */
+ palette = textbuf->format->palette;
+ rdiff = fg.r - bg.r;
+ gdiff = fg.g - bg.g;
+ bdiff = fg.b - bg.b;
+ adiff = fg.a - bg.a;
+
+ for (index = 0; index < NUM_GRAYS; ++index) {
+ palette->colors[index].r = bg.r + (index*rdiff) / (NUM_GRAYS-1);
+ palette->colors[index].g = bg.g + (index*gdiff) / (NUM_GRAYS-1);
+ palette->colors[index].b = bg.b + (index*bdiff) / (NUM_GRAYS-1);
+ palette->colors[index].a = bg.a + (index*adiff) / (NUM_GRAYS-1);
+ }
+
+ /* check kerning */
+ use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
+
+ /* Load and render each character */
+ textlen = SDL_strlen(text);
+ xstart = 0;
+ while (textlen > 0) {
+ Uint32 c = UTF8_getch(&text, &textlen);
+ if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) {
+ continue;
+ }
+
+ error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ SDL_FreeSurface(textbuf);
+ return NULL;
+ }
+ glyph = font->current;
+ /* Ensure the width of the pixmap is correct. On some cases,
+ * freetype may report a larger pixmap than possible.*/
+ width = glyph->pixmap.width;
+ if (font->outline <= 0 && width > glyph->maxx - glyph->minx) {
+ width = glyph->maxx - glyph->minx;
+ }
+ /* do kerning, if possible AC-Patch */
+ if (use_kerning && prev_index && glyph->index) {
+ FT_Vector delta;
+ FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta);
+ xstart += delta.x >> 6;
+ }
+
+ current = &glyph->pixmap;
+ for (row = 0; row < current->rows; ++row) {
+ /* Make sure we don't go either over, or under the limit */
+ if ((xstart + glyph->minx) < 0) {
+ xstart -= (xstart + glyph->minx);
+ }
+ if ((row + glyph->yoffset) < 0) {
+ continue;
+ }
+ if ((row + glyph->yoffset) >= textbuf->h) {
+ continue;
+ }
+ dst = (Uint8 *)textbuf->pixels +
+ (row+glyph->yoffset) * textbuf->pitch +
+ xstart + glyph->minx;
+ src = current->buffer + row * current->pitch;
+ for (col = width; col > 0 && dst < dst_check; --col) {
+ *dst++ |= *src++;
+ }
+ }
+
+ xstart += glyph->advance;
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ xstart += font->glyph_overhang;
+ }
+ prev_index = glyph->index;
+ }
+
+ /* Handle the underline style */
+ if (TTF_HANDLE_STYLE_UNDERLINE(font)) {
+ row = TTF_underline_top_row(font);
+ TTF_drawLine_Shaded(font, textbuf, row);
+ }
+
+ /* Handle the strikethrough style */
+ if (TTF_HANDLE_STYLE_STRIKETHROUGH(font)) {
+ row = TTF_strikethrough_top_row(font);
+ TTF_drawLine_Shaded(font, textbuf, row);
+ }
+ return textbuf;
+}
+
+SDL_Surface* TTF_RenderUNICODE_Shaded(TTF_Font* font,
+ const Uint16* text,
+ SDL_Color fg,
+ SDL_Color bg)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, UCS2_to_UTF8_len(text));
+ if (utf8) {
+ UCS2_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Shaded(font, (char *)utf8, fg, bg);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+SDL_Surface* TTF_RenderGlyph_Shaded(TTF_Font* font,
+ Uint16 ch,
+ SDL_Color fg,
+ SDL_Color bg)
+{
+ Uint16 ucs2[2] = { ch, 0 };
+ Uint8 utf8[4];
+
+ UCS2_to_UTF8(ucs2, utf8);
+ return TTF_RenderUTF8_Shaded(font, (char *)utf8, fg, bg);
+}
+
+SDL_Surface *TTF_RenderText_Blended(TTF_Font *font,
+ const char *text, SDL_Color fg)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, LATIN1_to_UTF8_len(text));
+ if (utf8) {
+ LATIN1_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Blended(font, (char *)utf8, fg);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+SDL_Surface *TTF_RenderUTF8_Blended(TTF_Font *font,
+ const char *text, SDL_Color fg)
+{
+ int i;
+ int xstart;
+ int width, height;
+ SDL_Surface *textbuf;
+ Uint8 alpha;
+ Uint8 alpha_table[256];
+ Uint32 pixel;
+ Uint8 *src;
+ Uint32 *dst;
+ Uint32 *dst_check;
+ int row, col;
+ c_glyph *glyph;
+ FT_Error error;
+ FT_Long use_kerning;
+ FT_UInt prev_index = 0;
+ size_t textlen;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ /* Get the dimensions of the text surface */
+ if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width) {
+ TTF_SetError("Text has zero width");
+ return(NULL);
+ }
+
+ /* Create the target surface */
+ textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
+ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+ if (textbuf == NULL) {
+ return(NULL);
+ }
+
+ /* Adding bound checking to avoid all kinds of memory corruption errors
+ that may occur. */
+ dst_check = (Uint32*)textbuf->pixels + textbuf->pitch/4 * textbuf->h;
+
+ /* check kerning */
+ use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
+
+ /* Support alpha blending */
+ if (!fg.a) {
+ fg.a = SDL_ALPHA_OPAQUE;
+ }
+ if (fg.a == SDL_ALPHA_OPAQUE) {
+ for (i = 0; i < SDL_arraysize(alpha_table); ++i) {
+ alpha_table[i] = (Uint8)i;
+ }
+ } else {
+ for (i = 0; i < SDL_arraysize(alpha_table); ++i) {
+ alpha_table[i] = (Uint8)(i * fg.a / 255);
+ }
+ SDL_SetSurfaceBlendMode(textbuf, SDL_BLENDMODE_BLEND);
+ }
+
+ /* Load and render each character */
+ textlen = SDL_strlen(text);
+ xstart = 0;
+ pixel = (fg.r<<16)|(fg.g<<8)|fg.b;
+ SDL_FillRect(textbuf, NULL, pixel); /* Initialize with fg and 0 alpha */
+ while (textlen > 0) {
+ Uint32 c = UTF8_getch(&text, &textlen);
+ if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) {
+ continue;
+ }
+
+ error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ SDL_FreeSurface(textbuf);
+ return NULL;
+ }
+ glyph = font->current;
+ /* Ensure the width of the pixmap is correct. On some cases,
+ * freetype may report a larger pixmap than possible.*/
+ width = glyph->pixmap.width;
+ if (font->outline <= 0 && width > glyph->maxx - glyph->minx) {
+ width = glyph->maxx - glyph->minx;
+ }
+ /* do kerning, if possible AC-Patch */
+ if (use_kerning && prev_index && glyph->index) {
+ FT_Vector delta;
+ FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta);
+ xstart += delta.x >> 6;
+ }
+
+ for (row = 0; row < glyph->pixmap.rows; ++row) {
+ /* Make sure we don't go either over, or under the limit */
+ if ((xstart + glyph->minx) < 0) {
+ xstart -= (xstart + glyph->minx);
+ }
+ if ((row + glyph->yoffset) < 0) {
+ continue;
+ }
+ if ((row + glyph->yoffset) >= textbuf->h) {
+ continue;
+ }
+ dst = (Uint32 *)textbuf->pixels +
+ (row+glyph->yoffset) * textbuf->pitch/4 +
+ xstart + glyph->minx;
+ src = (Uint8*)glyph->pixmap.buffer + row * glyph->pixmap.pitch;
+ for (col = width; col > 0 && dst < dst_check; --col) {
+ alpha = *src++;
+ *dst++ |= pixel | ((Uint32)alpha_table[alpha] << 24);
+ }
+ }
+
+ xstart += glyph->advance;
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ xstart += font->glyph_overhang;
+ }
+ prev_index = glyph->index;
+ }
+
+ /* Handle the underline style */
+ if (TTF_HANDLE_STYLE_UNDERLINE(font)) {
+ row = TTF_underline_top_row(font);
+ TTF_drawLine_Blended(font, textbuf, row, pixel | (Uint32)fg.a << 24);
+ }
+
+ /* Handle the strikethrough style */
+ if (TTF_HANDLE_STYLE_STRIKETHROUGH(font)) {
+ row = TTF_strikethrough_top_row(font);
+ TTF_drawLine_Blended(font, textbuf, row, pixel | (Uint32)fg.a << 24);
+ }
+ return(textbuf);
+}
+
+SDL_Surface *TTF_RenderUNICODE_Blended(TTF_Font *font,
+ const Uint16 *text, SDL_Color fg)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, UCS2_to_UTF8_len(text));
+ if (utf8) {
+ UCS2_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Blended(font, (char *)utf8, fg);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+
+SDL_Surface *TTF_RenderText_Blended_Wrapped(TTF_Font *font, const char *text, SDL_Color fg, Uint32 wrapLength)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, LATIN1_to_UTF8_len(text));
+ if (utf8) {
+ LATIN1_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Blended_Wrapped(font, (char *)utf8, fg, wrapLength);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+static SDL_bool CharacterIsDelimiter(char c, const char *delimiters)
+{
+ while (*delimiters) {
+ if (c == *delimiters) {
+ return SDL_TRUE;
+ }
+ ++delimiters;
+ }
+ return SDL_FALSE;
+}
+
+/* Don't define this until we have a release where we can change font rendering
+#define TTF_USE_LINESKIP
+ */
+SDL_Surface *TTF_RenderUTF8_Blended_Wrapped(TTF_Font *font,
+ const char *text, SDL_Color fg, Uint32 wrapLength)
+{
+ int i;
+ int xstart;
+ int width, height;
+ SDL_Surface *textbuf;
+ Uint8 alpha;
+ Uint8 alpha_table[256];
+ Uint32 pixel;
+ Uint8 *src;
+ Uint32 *dst;
+ Uint32 *dst_check;
+ int row, col;
+ c_glyph *glyph;
+ FT_Error error;
+ FT_Long use_kerning;
+ FT_UInt prev_index = 0;
+#ifndef TTF_USE_LINESKIP
+ const int lineSpace = 2;
+#endif
+ int line, numLines, rowSize;
+ char *str, **strLines, **newLines;
+ size_t textlen;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ /* Get the dimensions of the text surface */
+ if ((TTF_SizeUTF8(font, text, &width, &height) < 0) || !width) {
+ TTF_SetError("Text has zero width");
+ return(NULL);
+ }
+
+ numLines = 1;
+ str = NULL;
+ strLines = NULL;
+ if (wrapLength > 0 && *text) {
+ const char *wrapDelims = " \t\r\n";
+ int w, h;
+ char *spot, *tok, *next_tok, *end;
+ char delim;
+ size_t str_len = SDL_strlen(text);
+
+ numLines = 0;
+
+ str = SDL_stack_alloc(char, str_len+1);
+ if (str == NULL) {
+ TTF_SetError("Out of memory");
+ return(NULL);
+ }
+
+ SDL_strlcpy(str, text, str_len+1);
+ tok = str;
+ end = str + str_len;
+ do {
+ newLines = (char **)SDL_realloc(strLines, (numLines+1)*sizeof(*strLines));
+ if (!newLines) {
+ TTF_SetError("Out of memory");
+ SDL_free(strLines);
+ SDL_stack_free(str);
+ return(NULL);
+ }
+ strLines = newLines;
+ strLines[numLines++] = tok;
+
+ /* Look for the end of the line */
+ if ((spot = SDL_strchr(tok, '\r')) != NULL ||
+ (spot = SDL_strchr(tok, '\n')) != NULL) {
+ if (*spot == '\r') {
+ ++spot;
+ }
+ if (*spot == '\n') {
+ ++spot;
+ }
+ } else {
+ spot = end;
+ }
+ next_tok = spot;
+
+ /* Get the longest string that will fit in the desired space */
+ for (; ;) {
+ /* Strip trailing whitespace */
+ while (spot > tok &&
+ CharacterIsDelimiter(spot[-1], wrapDelims)) {
+ --spot;
+ }
+ if (spot == tok) {
+ if (CharacterIsDelimiter(*spot, wrapDelims)) {
+ *spot = '\0';
+ }
+ break;
+ }
+ delim = *spot;
+ *spot = '\0';
+
+ TTF_SizeUTF8(font, tok, &w, &h);
+ if ((Uint32)w <= wrapLength) {
+ break;
+ } else {
+ /* Back up and try again... */
+ *spot = delim;
+ }
+
+ while (spot > tok &&
+ !CharacterIsDelimiter(spot[-1], wrapDelims)) {
+ --spot;
+ }
+ if (spot > tok) {
+ next_tok = spot;
+ }
+ }
+ tok = next_tok;
+ } while (tok < end);
+ }
+
+ /* Create the target surface */
+ textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ (numLines > 1) ? wrapLength : width,
+#ifdef TTF_USE_LINESKIP
+ numLines * TTF_FontLineSkip(font),
+#else
+ height * numLines + (lineSpace * (numLines - 1)),
+#endif
+ 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+ if (textbuf == NULL) {
+ if (strLines) {
+ SDL_free(strLines);
+ SDL_stack_free(str);
+ }
+ return(NULL);
+ }
+
+#ifdef TTF_USE_LINESKIP
+ rowSize = textbuf->pitch/4 * TTF_FontLineSkip(font);
+#else
+ rowSize = textbuf->pitch/4 * height;
+#endif
+
+ /* Adding bound checking to avoid all kinds of memory corruption errors
+ that may occur. */
+ dst_check = (Uint32*)textbuf->pixels + textbuf->pitch/4 * textbuf->h;
+
+ /* check kerning */
+ use_kerning = FT_HAS_KERNING(font->face) && font->kerning;
+
+ /* Support alpha blending */
+ if (!fg.a) {
+ fg.a = SDL_ALPHA_OPAQUE;
+ }
+ if (fg.a == SDL_ALPHA_OPAQUE) {
+ for (i = 0; i < SDL_arraysize(alpha_table); ++i) {
+ alpha_table[i] = (Uint8)i;
+ }
+ } else {
+ for (i = 0; i < SDL_arraysize(alpha_table); ++i) {
+ alpha_table[i] = (Uint8)(i * fg.a / 255);
+ }
+ SDL_SetSurfaceBlendMode(textbuf, SDL_BLENDMODE_BLEND);
+ }
+
+ /* Load and render each character */
+ pixel = (fg.r<<16)|(fg.g<<8)|fg.b;
+ SDL_FillRect(textbuf, NULL, pixel); /* Initialize with fg and 0 alpha */
+
+ for (line = 0; line < numLines; line++) {
+ if (strLines) {
+ text = strLines[line];
+ }
+ textlen = SDL_strlen(text);
+ xstart = 0;
+ while (textlen > 0) {
+ Uint32 c = UTF8_getch(&text, &textlen);
+ if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) {
+ continue;
+ }
+
+ error = Find_Glyph(font, c, CACHED_METRICS|CACHED_PIXMAP);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ SDL_FreeSurface(textbuf);
+ if (strLines) {
+ SDL_free(strLines);
+ SDL_stack_free(str);
+ }
+ return NULL;
+ }
+ glyph = font->current;
+ /* Ensure the width of the pixmap is correct. On some cases,
+ * freetype may report a larger pixmap than possible.*/
+ width = glyph->pixmap.width;
+ if (font->outline <= 0 && width > glyph->maxx - glyph->minx) {
+ width = glyph->maxx - glyph->minx;
+ }
+ /* do kerning, if possible AC-Patch */
+ if (use_kerning && prev_index && glyph->index) {
+ FT_Vector delta;
+ FT_Get_Kerning(font->face, prev_index, glyph->index, ft_kerning_default, &delta);
+ xstart += delta.x >> 6;
+ }
+
+ for (row = 0; row < glyph->pixmap.rows; ++row) {
+ /* Make sure we don't go either over, or under the limit */
+ if ((xstart + glyph->minx) < 0) {
+ xstart -= (xstart + glyph->minx);
+ }
+ if ((row + glyph->yoffset) < 0) {
+ continue;
+ }
+ if ((row + glyph->yoffset) >= textbuf->h) {
+ continue;
+ }
+ dst = ((Uint32*)textbuf->pixels + rowSize * line) +
+ (row+glyph->yoffset) * textbuf->pitch/4 +
+ xstart + glyph->minx;
+ src = (Uint8*)glyph->pixmap.buffer + row * glyph->pixmap.pitch;
+ for (col = width; col > 0 && dst < dst_check; --col) {
+ alpha = *src++;
+ *dst++ |= pixel | ((Uint32)alpha_table[alpha] << 24);
+ }
+ }
+
+ xstart += glyph->advance;
+ if (TTF_HANDLE_STYLE_BOLD(font)) {
+ xstart += font->glyph_overhang;
+ }
+ prev_index = glyph->index;
+ }
+
+ /* Handle the underline style *
+ if (TTF_HANDLE_STYLE_UNDERLINE(font)) {
+ row = TTF_underline_top_row(font);
+ TTF_drawLine_Blended(font, textbuf, row, pixel | (Uint32)fg.a << 24);
+ }
+ */
+
+ /* Handle the strikethrough style *
+ if (TTF_HANDLE_STYLE_STRIKETHROUGH(font)) {
+ row = TTF_strikethrough_top_row(font);
+ TTF_drawLine_Blended(font, textbuf, row, pixel | (Uint32)fg.a << 24);
+ }
+ */
+ }
+
+ if (strLines) {
+ SDL_free(strLines);
+ SDL_stack_free(str);
+ }
+ return(textbuf);
+}
+
+SDL_Surface *TTF_RenderUNICODE_Blended_Wrapped(TTF_Font *font, const Uint16* text,
+ SDL_Color fg, Uint32 wrapLength)
+{
+ SDL_Surface *surface = NULL;
+ Uint8 *utf8;
+
+ TTF_CHECKPOINTER(text, NULL);
+
+ utf8 = SDL_stack_alloc(Uint8, UCS2_to_UTF8_len(text));
+ if (utf8) {
+ UCS2_to_UTF8(text, utf8);
+ surface = TTF_RenderUTF8_Blended_Wrapped(font, (char *)utf8, fg, wrapLength);
+ SDL_stack_free(utf8);
+ } else {
+ SDL_OutOfMemory();
+ }
+ return surface;
+}
+
+SDL_Surface *TTF_RenderGlyph_Blended(TTF_Font *font, Uint16 ch, SDL_Color fg)
+{
+ Uint16 ucs2[2] = { ch, 0 };
+ Uint8 utf8[4];
+
+ UCS2_to_UTF8(ucs2, utf8);
+ return TTF_RenderUTF8_Blended(font, (char *)utf8, fg);
+}
+
+void TTF_SetFontStyle(TTF_Font* font, int style)
+{
+ int prev_style = font->style;
+ font->style = style | font->face_style;
+
+ /* Flush the cache if the style has changed.
+ * Ignore UNDERLINE which does not impact glyph drawning.
+ * */
+ if ((font->style | TTF_STYLE_NO_GLYPH_CHANGE) != (prev_style | TTF_STYLE_NO_GLYPH_CHANGE)) {
+ Flush_Cache(font);
+ }
+}
+
+int TTF_GetFontStyle(const TTF_Font* font)
+{
+ return font->style;
+}
+
+void TTF_SetFontOutline(TTF_Font* font, int outline)
+{
+ font->outline = outline;
+ Flush_Cache(font);
+}
+
+int TTF_GetFontOutline(const TTF_Font* font)
+{
+ return font->outline;
+}
+
+void TTF_SetFontHinting(TTF_Font* font, int hinting)
+{
+ if (hinting == TTF_HINTING_LIGHT)
+ font->hinting = FT_LOAD_TARGET_LIGHT;
+ else if (hinting == TTF_HINTING_MONO)
+ font->hinting = FT_LOAD_TARGET_MONO;
+ else if (hinting == TTF_HINTING_NONE)
+ font->hinting = FT_LOAD_NO_HINTING;
+ else
+ font->hinting = 0;
+
+ Flush_Cache(font);
+}
+
+int TTF_GetFontHinting(const TTF_Font* font)
+{
+ if (font->hinting == FT_LOAD_TARGET_LIGHT)
+ return TTF_HINTING_LIGHT;
+ else if (font->hinting == FT_LOAD_TARGET_MONO)
+ return TTF_HINTING_MONO;
+ else if (font->hinting == FT_LOAD_NO_HINTING)
+ return TTF_HINTING_NONE;
+ return 0;
+}
+
+void TTF_Quit(void)
+{
+ if (TTF_initialized) {
+ if (--TTF_initialized == 0) {
+ FT_Done_FreeType(library);
+ }
+ }
+}
+
+int TTF_WasInit(void)
+{
+ return TTF_initialized;
+}
+
+/* don't use this function. It's just here for binary compatibility. */
+int TTF_GetFontKerningSize(TTF_Font* font, int prev_index, int index)
+{
+ FT_Vector delta;
+ FT_Get_Kerning(font->face, prev_index, index, ft_kerning_default, &delta);
+ return (delta.x >> 6);
+}
+
+int TTF_GetFontKerningSizeGlyphs(TTF_Font *font, Uint16 previous_ch, Uint16 ch)
+{
+ int error;
+ int glyph_index, prev_index;
+ FT_Vector delta;
+
+ if (ch == UNICODE_BOM_NATIVE || ch == UNICODE_BOM_SWAPPED) {
+ return 0;
+ }
+
+ if (previous_ch == UNICODE_BOM_NATIVE || previous_ch == UNICODE_BOM_SWAPPED) {
+ return 0;
+ }
+
+ error = Find_Glyph(font, ch, CACHED_METRICS);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ return -1;
+ }
+ glyph_index = font->current->index;
+
+ error = Find_Glyph(font, previous_ch, CACHED_METRICS);
+ if (error) {
+ TTF_SetFTError("Couldn't find glyph", error);
+ return -1;
+ }
+ prev_index = font->current->index;
+
+ error = FT_Get_Kerning(font->face, prev_index, glyph_index, ft_kerning_default, &delta);
+ if (error) {
+ TTF_SetFTError("Couldn't get glyph kerning", error);
+ return -1;
+ }
+ return (delta.x >> 6);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/libs/SDL2_ttf/SDL_ttf.h b/src/libs/SDL2_ttf/SDL_ttf.h
new file mode 100644
index 0000000..19fc9b9
--- /dev/null
+++ b/src/libs/SDL2_ttf/SDL_ttf.h
@@ -0,0 +1,294 @@
+/*
+ SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts
+ Copyright (C) 2001-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* This library is a wrapper around the excellent FreeType 2.0 library,
+ available at:
+ http://www.freetype.org/
+*/
+
+/* Note: In many places, SDL_ttf will say "glyph" when it means "code point."
+ Unicode is hard, we learn as we go, and we apologize for adding to the
+ confusion. */
+
+#ifndef SDL_TTF_H_
+#define SDL_TTF_H_
+
+#include "SDL.h"
+#include "begin_code.h"
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
+*/
+#define SDL_TTF_MAJOR_VERSION 2
+#define SDL_TTF_MINOR_VERSION 0
+#define SDL_TTF_PATCHLEVEL 14
+
+/* This macro can be used to fill a version structure with the compile-time
+ * version of the SDL_ttf library.
+ */
+#define SDL_TTF_VERSION(X) \
+{ \
+ (X)->major = SDL_TTF_MAJOR_VERSION; \
+ (X)->minor = SDL_TTF_MINOR_VERSION; \
+ (X)->patch = SDL_TTF_PATCHLEVEL; \
+}
+
+/* Backwards compatibility */
+#define TTF_MAJOR_VERSION SDL_TTF_MAJOR_VERSION
+#define TTF_MINOR_VERSION SDL_TTF_MINOR_VERSION
+#define TTF_PATCHLEVEL SDL_TTF_PATCHLEVEL
+#define TTF_VERSION(X) SDL_TTF_VERSION(X)
+
+/**
+ * This is the version number macro for the current SDL_net version.
+ */
+#define SDL_TTF_COMPILEDVERSION \
+ SDL_VERSIONNUM(SDL_TTF_MAJOR_VERSION, SDL_TTF_MINOR_VERSION, SDL_TTF_PATCHLEVEL)
+
+/**
+ * This macro will evaluate to true if compiled with SDL_net at least X.Y.Z.
+ */
+#define SDL_TTF_VERSION_ATLEAST(X, Y, Z) \
+ (SDL_TTF_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
+
+/* Make sure this is defined (only available in newer SDL versions) */
+#ifndef SDL_DEPRECATED
+#define SDL_DEPRECATED
+#endif
+
+/* This function gets the version of the dynamically linked SDL_ttf library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_TTF_VERSION() macro.
+ */
+extern DECLSPEC const SDL_version * SDLCALL TTF_Linked_Version(void);
+
+/* ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark) */
+#define UNICODE_BOM_NATIVE 0xFEFF
+#define UNICODE_BOM_SWAPPED 0xFFFE
+
+/* This function tells the library whether UNICODE text is generally
+ byteswapped. A UNICODE BOM character in a string will override
+ this setting for the remainder of that string.
+*/
+extern DECLSPEC void SDLCALL TTF_ByteSwappedUNICODE(int swapped);
+
+/* The internal structure containing font information */
+typedef struct _TTF_Font TTF_Font;
+
+/* Initialize the TTF engine - returns 0 if successful, -1 on error */
+extern DECLSPEC int SDLCALL TTF_Init(void);
+
+/* Open a font file and create a font of the specified point size.
+ * Some .fon fonts will have several sizes embedded in the file, so the
+ * point size becomes the index of choosing which size. If the value
+ * is too high, the last indexed size will be the default. */
+extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFont(const char *file, int ptsize);
+extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndex(const char *file, int ptsize, long index);
+extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontRW(SDL_RWops *src, int freesrc, int ptsize);
+extern DECLSPEC TTF_Font * SDLCALL TTF_OpenFontIndexRW(SDL_RWops *src, int freesrc, int ptsize, long index);
+
+/* Set and retrieve the font style */
+#define TTF_STYLE_NORMAL 0x00
+#define TTF_STYLE_BOLD 0x01
+#define TTF_STYLE_ITALIC 0x02
+#define TTF_STYLE_UNDERLINE 0x04
+#define TTF_STYLE_STRIKETHROUGH 0x08
+extern DECLSPEC int SDLCALL TTF_GetFontStyle(const TTF_Font *font);
+extern DECLSPEC void SDLCALL TTF_SetFontStyle(TTF_Font *font, int style);
+extern DECLSPEC int SDLCALL TTF_GetFontOutline(const TTF_Font *font);
+extern DECLSPEC void SDLCALL TTF_SetFontOutline(TTF_Font *font, int outline);
+
+/* Set and retrieve FreeType hinter settings */
+#define TTF_HINTING_NORMAL 0
+#define TTF_HINTING_LIGHT 1
+#define TTF_HINTING_MONO 2
+#define TTF_HINTING_NONE 3
+extern DECLSPEC int SDLCALL TTF_GetFontHinting(const TTF_Font *font);
+extern DECLSPEC void SDLCALL TTF_SetFontHinting(TTF_Font *font, int hinting);
+
+/* Get the total height of the font - usually equal to point size */
+extern DECLSPEC int SDLCALL TTF_FontHeight(const TTF_Font *font);
+
+/* Get the offset from the baseline to the top of the font
+ This is a positive value, relative to the baseline.
+ */
+extern DECLSPEC int SDLCALL TTF_FontAscent(const TTF_Font *font);
+
+/* Get the offset from the baseline to the bottom of the font
+ This is a negative value, relative to the baseline.
+ */
+extern DECLSPEC int SDLCALL TTF_FontDescent(const TTF_Font *font);
+
+/* Get the recommended spacing between lines of text for this font */
+extern DECLSPEC int SDLCALL TTF_FontLineSkip(const TTF_Font *font);
+
+/* Get/Set whether or not kerning is allowed for this font */
+extern DECLSPEC int SDLCALL TTF_GetFontKerning(const TTF_Font *font);
+extern DECLSPEC void SDLCALL TTF_SetFontKerning(TTF_Font *font, int allowed);
+
+/* Get the number of faces of the font */
+extern DECLSPEC long SDLCALL TTF_FontFaces(const TTF_Font *font);
+
+/* Get the font face attributes, if any */
+extern DECLSPEC int SDLCALL TTF_FontFaceIsFixedWidth(const TTF_Font *font);
+extern DECLSPEC char * SDLCALL TTF_FontFaceFamilyName(const TTF_Font *font);
+extern DECLSPEC char * SDLCALL TTF_FontFaceStyleName(const TTF_Font *font);
+
+/* Check wether a glyph is provided by the font or not */
+extern DECLSPEC int SDLCALL TTF_GlyphIsProvided(const TTF_Font *font, Uint16 ch);
+
+/* Get the metrics (dimensions) of a glyph
+ To understand what these metrics mean, here is a useful link:
+ http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
+ */
+extern DECLSPEC int SDLCALL TTF_GlyphMetrics(TTF_Font *font, Uint16 ch,
+ int *minx, int *maxx,
+ int *miny, int *maxy, int *advance);
+
+/* Get the dimensions of a rendered string of text */
+extern DECLSPEC int SDLCALL TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h);
+extern DECLSPEC int SDLCALL TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h);
+extern DECLSPEC int SDLCALL TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h);
+
+/* Create an 8-bit palettized surface and render the given text at
+ fast quality with the given font and color. The 0 pixel is the
+ colorkey, giving a transparent background, and the 1 pixel is set
+ to the text color.
+ This function returns the new surface, or NULL if there was an error.
+*/
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Solid(TTF_Font *font,
+ const char *text, SDL_Color fg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Solid(TTF_Font *font,
+ const char *text, SDL_Color fg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Solid(TTF_Font *font,
+ const Uint16 *text, SDL_Color fg);
+
+/* Create an 8-bit palettized surface and render the given glyph at
+ fast quality with the given font and color. The 0 pixel is the
+ colorkey, giving a transparent background, and the 1 pixel is set
+ to the text color. The glyph is rendered without any padding or
+ centering in the X direction, and aligned normally in the Y direction.
+ This function returns the new surface, or NULL if there was an error.
+*/
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Solid(TTF_Font *font,
+ Uint16 ch, SDL_Color fg);
+
+/* Create an 8-bit palettized surface and render the given text at
+ high quality with the given font and colors. The 0 pixel is background,
+ while other pixels have varying degrees of the foreground color.
+ This function returns the new surface, or NULL if there was an error.
+*/
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Shaded(TTF_Font *font,
+ const char *text, SDL_Color fg, SDL_Color bg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Shaded(TTF_Font *font,
+ const char *text, SDL_Color fg, SDL_Color bg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Shaded(TTF_Font *font,
+ const Uint16 *text, SDL_Color fg, SDL_Color bg);
+
+/* Create an 8-bit palettized surface and render the given glyph at
+ high quality with the given font and colors. The 0 pixel is background,
+ while other pixels have varying degrees of the foreground color.
+ The glyph is rendered without any padding or centering in the X
+ direction, and aligned normally in the Y direction.
+ This function returns the new surface, or NULL if there was an error.
+*/
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Shaded(TTF_Font *font,
+ Uint16 ch, SDL_Color fg, SDL_Color bg);
+
+/* Create a 32-bit ARGB surface and render the given text at high quality,
+ using alpha blending to dither the font with the given color.
+ This function returns the new surface, or NULL if there was an error.
+*/
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended(TTF_Font *font,
+ const char *text, SDL_Color fg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Blended(TTF_Font *font,
+ const char *text, SDL_Color fg);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Blended(TTF_Font *font,
+ const Uint16 *text, SDL_Color fg);
+
+
+/* Create a 32-bit ARGB surface and render the given text at high quality,
+ using alpha blending to dither the font with the given color.
+ Text is wrapped to multiple lines on line endings and on word boundaries
+ if it extends beyond wrapLength in pixels.
+ This function returns the new surface, or NULL if there was an error.
+*/
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended_Wrapped(TTF_Font *font,
+ const char *text, SDL_Color fg, Uint32 wrapLength);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Blended_Wrapped(TTF_Font *font,
+ const char *text, SDL_Color fg, Uint32 wrapLength);
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Blended_Wrapped(TTF_Font *font,
+ const Uint16 *text, SDL_Color fg, Uint32 wrapLength);
+
+/* Create a 32-bit ARGB surface and render the given glyph at high quality,
+ using alpha blending to dither the font with the given color.
+ The glyph is rendered without any padding or centering in the X
+ direction, and aligned normally in the Y direction.
+ This function returns the new surface, or NULL if there was an error.
+*/
+extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderGlyph_Blended(TTF_Font *font,
+ Uint16 ch, SDL_Color fg);
+
+/* For compatibility with previous versions, here are the old functions */
+#define TTF_RenderText(font, text, fg, bg) \
+ TTF_RenderText_Shaded(font, text, fg, bg)
+#define TTF_RenderUTF8(font, text, fg, bg) \
+ TTF_RenderUTF8_Shaded(font, text, fg, bg)
+#define TTF_RenderUNICODE(font, text, fg, bg) \
+ TTF_RenderUNICODE_Shaded(font, text, fg, bg)
+
+/* Close an opened font file */
+extern DECLSPEC void SDLCALL TTF_CloseFont(TTF_Font *font);
+
+/* De-initialize the TTF engine */
+extern DECLSPEC void SDLCALL TTF_Quit(void);
+
+/* Check if the TTF engine is initialized */
+extern DECLSPEC int SDLCALL TTF_WasInit(void);
+
+/* Get the kerning size of two glyphs indices */
+/* DEPRECATED: this function requires FreeType font indexes, not glyphs,
+ by accident, which we don't expose through this API, so it could give
+ wildly incorrect results, especially with non-ASCII values.
+ Going forward, please use TTF_GetFontKerningSizeGlyphs() instead, which
+ does what you probably expected this function to do. */
+extern DECLSPEC int TTF_GetFontKerningSize(TTF_Font *font, int prev_index, int index) SDL_DEPRECATED;
+
+/* Get the kerning size of two glyphs */
+extern DECLSPEC int TTF_GetFontKerningSizeGlyphs(TTF_Font *font, Uint16 previous_ch, Uint16 ch);
+
+/* We'll use SDL for reporting errors */
+#define TTF_SetError SDL_SetError
+#define TTF_GetError SDL_GetError
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif /* SDL_TTF_H_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 16, 8:21 PM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63547
Default Alt Text
(95 KB)
Attached To
Mode
R79 meandmyshadow
Attached
Detach File
Event Timeline