00001 /* 00002 * FreeTypeGX is a wrapper class for libFreeType which renders a compiled 00003 * FreeType parsable font into a GX texture for Wii homebrew development. 00004 * Copyright (C) 2008 Armin Tamzarian 00005 * Modified by Tantric, 2009 00006 * 00007 * This file is part of FreeTypeGX. 00008 * 00009 * FreeTypeGX is free software: you can redistribute it and/or modify 00010 * it under the terms of the GNU Lesser General Public License as published 00011 * by the Free Software Foundation, either version 3 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * FreeTypeGX is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public License 00020 * along with FreeTypeGX. If not, see <http://www.gnu.org/licenses/>. 00021 */ 00022 00023 /** \mainpage FreeTypeGX 00024 * 00025 * \section sec_intro Introduction 00026 * 00027 * FreeTypeGX is a wrapper class for libFreeType which renders a compiled FreeType parsable font into a GX texture for Wii homebrew development. 00028 * <br> 00029 * FreeTypeGX is written in C++ and makes use of a selectable pre-buffered or buffer-on-demand methodology to allow fast and efficient printing of text to the EFB. 00030 * <p> 00031 * This library was developed in-full by Armin Tamzarian with the support of developers in \#wiibrew on EFnet. 00032 * 00033 * \section sec_installation_source Installation (Source Code) 00034 * 00035 * -# Ensure that you have the <a href = "http://www.tehskeen.com/forums/showthread.php?t=9404">libFreeType</a> Wii library installed in your development environment with the library added to your Makefile where appropriate. 00036 * -# Ensure that you have the <a href = "http://code.google.com/p/metaphrasis">Metaphrasis</a> library installed in your development environment with the library added to your Makefile where appropriate. 00037 * -# Extract the FreeTypeGX archive. 00038 * -# Copy the contents of the <i>src</i> directory into your project's development path. 00039 * -# Include the FreeTypeGX header file in your code using syntax such as the following: 00040 * \code 00041 * #include "FreeTypeGX.h" 00042 * \endcode 00043 * 00044 * \section sec_installation_library Installation (Library) 00045 * 00046 * -# Ensure that you have the <a href = "http://www.tehskeen.com/forums/showthread.php?t=9404">libFreeType</a> Wii library installed in your development environment with the library added to your Makefile where appropriate. 00047 * -# Ensure that you have the <a href = "http://code.google.com/p/metaphrasis">Metaphrasis</a> library installed in your development environment with the library added to your Makefile where appropriate. 00048 * -# Extract the FreeTypeGX archive. 00049 * -# Copy the contents of the <i>lib</i> directory into your <i>devKitPro/libogc</i> directory. 00050 * -# Include the FreeTypeGX header file in your code using syntax such as the following: 00051 * \code 00052 * #include "FreeTypeGX.h" 00053 * \endcode 00054 * 00055 * \section sec_freetypegx_prerequisites FreeTypeGX Prerequisites 00056 * 00057 * Before you begin using FreeTypeGX in your project you must ensure that the desired font in compiled into your project. For this example I will assume you are building your project with a Makefile using devKitPro evironment and are attempting to include a font whose filename is rursus_compact_mono.ttf. 00058 * 00059 * -# Copy the font into a directory which will be processed by the project's Makefile. If you are unsure about where you should place your font just copy the it into your project's source directory. 00060 * \n\n 00061 * -# Modify the Makefile to convert the font into an object file: 00062 * \code 00063 * %.ttf.o : %.ttf 00064 * @echo $(notdir $<) 00065 * $(bin2o) 00066 * \endcode 00067 * \n 00068 * -# Include the font object's generated header file in your source code: 00069 * \code 00070 * #include "rursus_compact_mono_ttf.h" 00071 * \endcode 00072 * This header file defines the two variables that you will need for use within your project: 00073 * \code 00074 * extern const u8 rursus_compact_mono_ttf[]; A pointer to the font buffer within the compiled project. 00075 * extern const u32 rursus_compact_mono_ttf_size; The size of the font's buffer in bytes. 00076 * \endcode 00077 * 00078 * \section sec_freetypegx_usage FreeTypeGX Usage 00079 * 00080 * -# Within the file you included the FreeTypeGX.h header create an instance object of the FreeTypeGX class: 00081 * \code 00082 * FreeTypeGX *freeTypeGX = new FreeTypeGX(); 00083 * \endcode 00084 * Alternately you can specify a texture format to which you would like to render the font characters. Note that the default value for this parameter is GX_TF_RGBA8. 00085 * \code 00086 * FreeTypeGX *freeTypeGX = new FreeTypeGX(GX_TF_RGB565); 00087 * \endcode 00088 * Furthermore, you can also specify a vertex format index to avoid conflicts with concurrent libraries or other systems. Note that the default value for this parameter is GX_VTXFMT1. 00089 * \code 00090 * FreeTypeGX *freeTypeGX = new FreeTypeGX(GX_TF_RGB565, GX_VTXFMT1); 00091 * \endcode 00092 * \n 00093 * Currently supported textures are: 00094 * \li <i>GX_TF_I4</i> 00095 * \li <i>GX_TF_I8</i> 00096 * \li <i>GX_TF_IA4</i> 00097 * \li <i>GX_TF_IA8</i> 00098 * \li <i>GX_TF_RGB565</i> 00099 * \li <i>GX_TF_RGB5A3</i> 00100 * \li <i>GX_TF_RGBA8</i> 00101 * 00102 * \n 00103 * -# Using the allocated FreeTypeGX instance object call the loadFont function to load the font from the compiled buffer and specify the desired point size. Note that this function can be called multiple times to load a new: 00104 * \code 00105 * freeTypeGX->loadFont(rursus_compact_mono_ttf, rursus_compact_mono_ttf_size, 64); 00106 * \endcode 00107 * Alternately you can specify a flag which will load and cache all available font glyphs immidiately. Note that on large font sets enabling this feature could take a significant amount of time. 00108 * \code 00109 * freeTypeGX->loadFont(rursus_compact_mono_ttf, rursus_compact_mono_ttf_size, 64, true); 00110 * \endcode 00111 * \n 00112 * -# If necessary you can enable compatibility modes with concurrent libraries or systems. For more information on this feature see the documentation for setCompatibilityMode: 00113 * \code 00114 * freeTypeGX->setCompatibilityMode(FTGX_COMPATIBILITY_GRRLIB); 00115 * \endcode 00116 * -# Using the allocated FreeTypeGX instance object call the drawText function to print a string at the specified screen X and Y coordinates to the current EFB: 00117 * \code 00118 * freeTypeGX->drawText(10, 25, _TEXT("FreeTypeGX Rocks!")); 00119 * \endcode 00120 * Alternately you can specify a <i>GXColor</i> object you would like to apply to the printed characters: 00121 * \code 00122 * freeTypeGX->drawText(10, 25, _TEXT("FreeTypeGX Rocks!"), 00123 * (GXColor){0xff, 0xee, 0xaa, 0xff}); 00124 * \endcode 00125 * Furthermore you can also specify a group of styling parameters which will modify the positioning or style of the text: 00126 * \code 00127 * freeTypeGX->drawText(10, 25, _TEXT("FreeTypeGX Rocks!"), 00128 * (GXColor){0xff, 0xee, 0xaa, 0xff}, 00129 * FTGX_JUSTIFY_CENTER | FTGX_ALIGN_BOTTOM | FTGX_STYLE_UNDERLINE); 00130 * \endcode 00131 * \n 00132 * Currently style parameters are: 00133 * \li <i>FTGX_JUSTIFY_LEFT</i> 00134 * \li <i>FTGX_JUSTIFY_CENTER</i> 00135 * \li <i>FTGX_JUSTIFY_RIGHT</i> 00136 * \li <i>FTGX_ALIGN_TOP</i> 00137 * \li <i>FTGX_ALIGN_MIDDLE</i> 00138 * \li <i>FTGX_ALIGN_BOTTOM</i> 00139 * \li <i>FTGX_STYLE_UNDERLINE</i> 00140 * \li <i>FTGX_STYLE_STRIKE</i> 00141 * 00142 * \section sec_license License 00143 * 00144 * FreeTypeGX is distributed under the GNU Lesser General Public License. 00145 * 00146 * \section sec_contact Contact 00147 * 00148 * If you have any suggestions, questions, or comments regarding this library feel free to e-mail me at tamzarian1989 [at] gmail [dawt] com. 00149 */ 00150 00151 #ifndef FREETYPEGX_H_ 00152 #define FREETYPEGX_H_ 00153 00154 #include <gccore.h> 00155 #include <ft2build.h> 00156 #include FT_FREETYPE_H 00157 #include FT_BITMAP_H 00158 #include "Metaphrasis.h" 00159 00160 #include <malloc.h> 00161 #include <string.h> 00162 #include <wchar.h> 00163 #include <map> 00164 00165 #define MAX_FONT_SIZE 100 00166 00167 /*! \struct ftgxCharData_ 00168 * 00169 * Font face character glyph relevant data structure. 00170 */ 00171 typedef struct ftgxCharData_ { 00172 int16_t renderOffsetX; /**< Texture X axis bearing offset. */ 00173 uint16_t glyphAdvanceX; /**< Character glyph X coordinate advance in pixels. */ 00174 uint16_t glyphIndex; /**< Charachter glyph index in the font face. */ 00175 00176 uint16_t textureWidth; /**< Texture width in pixels/bytes. */ 00177 uint16_t textureHeight; /**< Texture glyph height in pixels/bytes. */ 00178 00179 int16_t renderOffsetY; /**< Texture Y axis bearing offset. */ 00180 int16_t renderOffsetMax; /**< Texture Y axis bearing maximum value. */ 00181 int16_t renderOffsetMin; /**< Texture Y axis bearing minimum value. */ 00182 00183 uint32_t* glyphDataTexture; /**< Glyph texture bitmap data buffer. */ 00184 } ftgxCharData; 00185 00186 /*! \struct ftgxDataOffset_ 00187 * 00188 * Offset structure which hold both a maximum and minimum value. 00189 */ 00190 typedef struct ftgxDataOffset_ { 00191 int16_t ascender; /**< Maximum data offset. */ 00192 int16_t descender; /**< Minimum data offset. */ 00193 int16_t max; /**< Maximum data offset. */ 00194 int16_t min; /**< Minimum data offset. */ 00195 } ftgxDataOffset; 00196 00197 typedef struct ftgxCharData_ ftgxCharData; 00198 typedef struct ftgxDataOffset_ ftgxDataOffset; 00199 00200 #define _TEXT(t) L ## t /**< Unicode helper macro. */ 00201 00202 #define FTGX_NULL 0x0000 00203 #define FTGX_JUSTIFY_LEFT 0x0001 00204 #define FTGX_JUSTIFY_CENTER 0x0002 00205 #define FTGX_JUSTIFY_RIGHT 0x0004 00206 #define FTGX_JUSTIFY_MASK 0x000f 00207 00208 #define FTGX_ALIGN_TOP 0x0010 00209 #define FTGX_ALIGN_MIDDLE 0x0020 00210 #define FTGX_ALIGN_BOTTOM 0x0040 00211 #define FTGX_ALIGN_BASELINE 0x0080 00212 #define FTGX_ALIGN_GLYPH_TOP 0x0100 00213 #define FTGX_ALIGN_GLYPH_MIDDLE 0x0200 00214 #define FTGX_ALIGN_GLYPH_BOTTOM 0x0400 00215 #define FTGX_ALIGN_MASK 0x0ff0 00216 00217 #define FTGX_STYLE_UNDERLINE 0x1000 00218 #define FTGX_STYLE_STRIKE 0x2000 00219 #define FTGX_STYLE_MASK 0xf000 00220 00221 #define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_MODULATE 0X0001 00222 #define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_DECAL 0X0002 00223 #define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_BLEND 0X0004 00224 #define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_REPLACE 0X0008 00225 #define FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR 0X0010 00226 00227 #define FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE 0X0100 00228 #define FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_DIRECT 0X0200 00229 #define FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_INDEX8 0X0400 00230 #define FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_INDEX16 0X0800 00231 00232 #define FTGX_COMPATIBILITY_NONE 0x0000 00233 #define FTGX_COMPATIBILITY_GRRLIB FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_PASSCLR | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_NONE 00234 #define FTGX_COMPATIBILITY_LIBWIISPRITE FTGX_COMPATIBILITY_DEFAULT_TEVOP_GX_MODULATE | FTGX_COMPATIBILITY_DEFAULT_VTXDESC_GX_DIRECT 00235 00236 const GXColor ftgxWhite = (GXColor){0xff, 0xff, 0xff, 0xff}; /**< Constant color value used only to sanitize Doxygen documentation. */ 00237 00238 void InitFreeType(uint8_t* fontBuffer, FT_Long bufferSize); 00239 void ChangeFontSize(FT_UInt pixelSize); 00240 wchar_t* charToWideChar(const char* p); 00241 void ClearFontData(); 00242 00243 /*! \class FreeTypeGX 00244 * \brief Wrapper class for the libFreeType library with GX rendering. 00245 * \author Armin Tamzarian 00246 * \version 0.2.4 00247 * 00248 * FreeTypeGX acts as a wrapper class for the libFreeType library. It supports precaching of transformed glyph data into 00249 * a specified texture format. Rendering of the data to the EFB is accomplished through the application of high performance 00250 * GX texture functions resulting in high throughput of string rendering. 00251 */ 00252 class FreeTypeGX { 00253 00254 private: 00255 FT_UInt ftPointSize; /**< Requested size of the rendered font. */ 00256 bool ftKerningEnabled; /**< Flag indicating the availability of font kerning data. */ 00257 00258 uint8_t textureFormat; /**< Defined texture format of the target EFB. */ 00259 uint8_t vertexIndex; /**< Vertex format descriptor index. */ 00260 uint32_t compatibilityMode; /**< Compatibility mode for default tev operations and vertex descriptors. */ 00261 std::map<wchar_t, ftgxCharData> fontData; /**< Map which holds the glyph data structures for the corresponding characters. */ 00262 int z; /**< Text Z-value. */ 00263 00264 static uint16_t adjustTextureWidth(uint16_t textureWidth, uint8_t textureFormat); 00265 static uint16_t adjustTextureHeight(uint16_t textureHeight, uint8_t textureFormat); 00266 00267 static int16_t getStyleOffsetWidth(uint16_t width, uint16_t format); 00268 static int16_t getStyleOffsetHeight(ftgxDataOffset *offset, uint16_t format); 00269 00270 void unloadFont(); 00271 ftgxCharData *cacheGlyphData(wchar_t charCode); 00272 uint16_t cacheGlyphDataComplete(); 00273 void loadGlyphData(FT_Bitmap *bmp, ftgxCharData *charData); 00274 00275 void setDefaultMode(); 00276 00277 void drawTextFeature(int16_t x, int16_t y, uint16_t width, ftgxDataOffset *offsetData, uint16_t format, GXColor color); 00278 void copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY, GXColor color); 00279 void copyFeatureToFramebuffer(f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY, GXColor color); 00280 00281 public: 00282 FreeTypeGX(FT_UInt pixelSize, uint8_t textureFormat = GX_TF_RGBA8, uint8_t vertexIndex = GX_VTXFMT1); 00283 ~FreeTypeGX(); 00284 00285 void setVertexFormat(uint8_t vertexIndex); 00286 void setCompatibilityMode(uint32_t compatibilityMode); 00287 void setZ(int _z) { z = _z; } 00288 00289 uint16_t drawText(int16_t x, int16_t y, wchar_t *text, GXColor color = ftgxWhite, uint16_t textStyling = FTGX_NULL); 00290 uint16_t drawText(int16_t x, int16_t y, wchar_t const *text, GXColor color = ftgxWhite, uint16_t textStyling = FTGX_NULL); 00291 00292 uint16_t getWidth(wchar_t *text); 00293 uint16_t getWidth(wchar_t const *text); 00294 uint16_t getHeight(wchar_t *text); 00295 uint16_t getHeight(wchar_t const *text); 00296 void getOffset(wchar_t *text, ftgxDataOffset* offset); 00297 void getOffset(wchar_t const *text, ftgxDataOffset* offset); 00298 }; 00299 00300 #endif /* FREETYPEGX_H_ */