--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+typedef void (*NL_registerPtr)( const char *name, int (*f)(lua_State *) );\r
+typedef void (*NL_gettablePtr)( lua_State *L, int index );\r
+typedef int (*NL_isstringPtr)( lua_State *L, int index );\r
+typedef int (*NL_istablePtr)( lua_State *L, int index );\r
+typedef void (*NL_popPtr)( lua_State *L, int n );\r
+typedef void (*NL_pushintegerPtr)( lua_State *L, int n );\r
+typedef void (*NL_pushstringPtr)( lua_State *L, const char *str );\r
+typedef int (*NL_tobooleanPtr)( lua_State *L, int index );\r
+typedef int (*NL_tointegerPtr)( lua_State *L, int index );\r
+typedef double (*NL_tonumberPtr)( lua_State *L, int index );\r
+typedef const char *(*NL_tostringPtr)( lua_State *L, int index );
\ No newline at end of file
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+#include "Color.h"\r
+namespace nsdfont\r
+{\r
+ class ArgbArray\r
+ {\r
+ private:\r
+ Color *colors;\r
+ size_t length;\r
+ public:\r
+\r
+ ArgbArray( unsigned char *head ) :\r
+ colors( reinterpret_cast<Color *>( head ) ),\r
+ length( 0 )\r
+ {\r
+ }\r
+\r
+ ArgbArray( unsigned char *head, size_t length ) :\r
+ colors( reinterpret_cast<Color *>( head ) ),\r
+ length( length )\r
+ {\r
+ }\r
+\r
+ virtual ~ArgbArray(void)\r
+ {\r
+ }\r
+\r
+\r
+ inline Color &operator[]( size_t i ) const { return colors[i]; }\r
+ };\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#include "ArgbBitmap.h"\r
+\r
+namespace nsdfont\r
+{\r
+ ArgbBitmap::ArgbBitmap( int width, int height, unsigned char *bits ) :\r
+ width( width ),\r
+ height( height ),\r
+ bits( bits ),\r
+ allocated( 0 )\r
+ {\r
+ }\r
+\r
+ ArgbBitmap::ArgbBitmap( int width, int height ) :\r
+ width( width ),\r
+ height( height )\r
+ {\r
+ allocated = width * height * 4;\r
+ bits = new unsigned char[allocated]();\r
+ }\r
+\r
+ ArgbBitmap::~ArgbBitmap( void )\r
+ {\r
+ if ( allocated > 0 && bits )\r
+ {\r
+ delete[] bits;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+\r
+#include "ArgbArray.h"\r
+\r
+namespace nsdfont\r
+{\r
+ class ArgbBitmap\r
+ {\r
+ private:\r
+ int width;\r
+ int height;\r
+ unsigned char *bits;\r
+ size_t allocated;\r
+ public:\r
+ ArgbBitmap( int width, int height, unsigned char *bits );\r
+ ArgbBitmap( int width, int height );\r
+ virtual ~ArgbBitmap( void );\r
+ inline unsigned char &operator[]( size_t i ) const { return bits[i]; }\r
+ inline int getWidth( void ) const { return width; }\r
+ inline int getHeight( void ) const { return height; }\r
+ inline int getPitch( void ) const { return width * 4; }\r
+ /**\r
+ * \8ew\92è\82µ\82½\88Ê\92u\82©\82ç\82Ì\89æ\91f\97ñ\82ð\8eæ\93¾\82·\82é.\r
+ * @param x x\95û\8cü\82Ì\88Ê\92u.\r
+ * @param y y\95û\8cü\82Ì\88Ê\92u.\r
+ * @return \89æ\91f\97ñ\r
+ * @attention \94z\97ñ\82Ì\91å\82«\82³\82É\82Â\82¢\82Ä\82Ì\8fî\95ñ\82Í\8e\9d\82½\82È\82¢. \8eg\97p\8eÒ\82ª\92\8d\88Ó\82µ\82Ä\88µ\82¤\82±\82Æ.\r
+ */\r
+ inline ArgbArray getArray( int x, int y ) const\r
+ {\r
+ return ArgbArray( &bits[(x + y * width) * 4] );\r
+ }\r
+ };\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#include "CharacterMap.h"\r
+\r
+// This code is based on a sample code of\r
+// KB\81F241020 (http://support.microsoft.com/kb/241020/)\r
+\r
+namespace nsdfont\r
+{\r
+ CharacterMap::CharacterMap( void )\r
+ {\r
+ hdc = CreateCompatibleDC( NULL );\r
+ hFont = NULL;\r
+ cmapTable = NULL;\r
+ }\r
+\r
+ CharacterMap::~CharacterMap( void )\r
+ {\r
+ if ( NULL != hdc )\r
+ {\r
+ DeleteDC( hdc );\r
+ }\r
+ clearFont();\r
+ }\r
+\r
+ bool CharacterMap::selectFont( const LOGFONTA *font )\r
+ {\r
+ clearFont();\r
+ HFONT hFont = CreateFontIndirectA( font );\r
+ SelectObject( hdc, hFont );\r
+\r
+ if ( !fetchUnicodeCMapTable() )\r
+ {\r
+ clearFont();\r
+ return false;\r
+ }\r
+ characterCount = getCharacterCount( cmapTable );\r
+ return true;\r
+ }\r
+\r
+ void CharacterMap::clearFont( void )\r
+ {\r
+ if ( NULL != hFont )\r
+ {\r
+ DeleteObject( hFont );\r
+ hFont = NULL;\r
+ }\r
+\r
+ delete [] cmapTable;\r
+ cmapTable = NULL;\r
+\r
+ characterCount = 0;\r
+ }\r
+\r
+ void CharacterMap::swapArrays( CMap4 *format4 )\r
+ {\r
+ const USHORT *startCount = getStartCountArray( format4 );\r
+ const USHORT *idDelta = getIdDeltaArray( format4 );\r
+ const USHORT *idRangeOffset = getIdRangeOffsetArray( format4 );\r
+ const USHORT *endCount = getEndCountArray( format4 );\r
+ const USHORT *endOfBuffer = reinterpret_cast<const USHORT *>( \r
+ reinterpret_cast<LPBYTE>( format4 ) + format4->length );\r
+ \r
+ const DWORD segCount = format4->segCountX2 / 2;\r
+ for( DWORD i = 0; i < segCount; ++i )\r
+ {\r
+ swap( static_cast<USHORT>( endCount[i] ) );\r
+ swap( static_cast<USHORT>( startCount[i] ) );\r
+ swap( static_cast<USHORT>( idDelta[i] ) );\r
+ swap( static_cast<USHORT>( idRangeOffset[i] ) );\r
+ }\r
+\r
+ USHORT *glyphId = const_cast<USHORT *>( &idRangeOffset[segCount] );\r
+ while( glyphId < endOfBuffer )\r
+ {\r
+ swap( *glyphId++ );\r
+ }\r
+ }\r
+\r
+\r
+ bool CharacterMap::getEncoding( CMapEncoding *encoding, int index ) const\r
+ {\r
+ DWORD result = GetFontData( hdc, cmapName, \r
+ cmapHeaderSize + encodingSize * index, \r
+ encoding, sizeof( CMapEncoding ) );\r
+ if ( result != sizeof( CMapEncoding ) ) return false;\r
+\r
+ swap( encoding->PlatformId );\r
+ swap( encoding->EncodingId );\r
+ swap( encoding->Offset );\r
+\r
+ return true;\r
+ }\r
+\r
+ bool CharacterMap::getFormat4Header( CMap4 *header, DWORD offset ) const\r
+ {\r
+ DWORD written = GetFontData( hdc, cmapName, offset, header, format4HeaderSize );\r
+ if ( written != format4HeaderSize ) return false;\r
+ \r
+ USHORT *fields = reinterpret_cast<USHORT *>( header );\r
+ for( int i = 0; i < 7; ++i )\r
+ {\r
+ swap( fields[i] );\r
+ }\r
+ return true;\r
+ }\r
+\r
+\r
+ bool CharacterMap::getFormat4Subtable( CMap4 *subtable, DWORD offset ) const\r
+ {\r
+ if ( !getFormat4Header( subtable, offset ) ) return false;\r
+\r
+ const DWORD length = subtable->length - format4HeaderSize;\r
+ DWORD written = GetFontData( hdc, cmapName, offset + format4HeaderSize,\r
+ subtable->Arrays, length );\r
+\r
+ if ( written != length ) return false;\r
+ \r
+ swapArrays( subtable );\r
+\r
+ return true;\r
+ }\r
+\r
+\r
+ unsigned int CharacterMap::getCharacterCount( const CMap4 *format4 )\r
+ { \r
+ if ( format4 == NULL ) return 0;\r
+\r
+ const USHORT *endCount = getEndCountArray( format4 );\r
+ const USHORT *startCount = getStartCountArray( format4 );\r
+ const USHORT *idRangeOffset = getIdRangeOffsetArray( format4 );\r
+ const USHORT segCount = format4->segCountX2 / 2;\r
+\r
+ unsigned int numberOfGlyphs = 0;\r
+\r
+ // by adding up the coverage of each segment\r
+ for ( USHORT i = 0; i < segCount; ++i )\r
+ {\r
+ if ( idRangeOffset[i] == 0 )\r
+ {\r
+ // if per the TT spec, the idRangeOffset element is zero,\r
+ // all of the characters in this segment exist.\r
+ numberOfGlyphs += endCount[i] - startCount[i] + 1;\r
+ continue;\r
+ }\r
+\r
+ const USHORT *glyphId = &(idRangeOffset[i]) + idRangeOffset[i] / 2;\r
+\r
+ for (USHORT ch = startCount[i]; ch <= endCount[i]; ++ch )\r
+ {\r
+ USHORT idResult = glyphId[ch - startCount[i]];\r
+ if (idResult != 0) numberOfGlyphs++;\r
+ }\r
+ }\r
+ return numberOfGlyphs;\r
+ }\r
+\r
+ bool CharacterMap::fetchUnicodeCMapTable( void )\r
+ {\r
+ USHORT numberOfEncodings;\r
+ // Get the number of subtables in the CMAP table from the CMAP header\r
+ // The # of subtables is the second USHORT in the CMAP table, per the TT Spec.\r
+ DWORD written = GetFontData( hdc, cmapName, sizeof( USHORT ), &numberOfEncodings, sizeof( USHORT ) );\r
+ if ( written != sizeof( USHORT ) )\r
+ {\r
+ // Something is wrong, we probably got GDI_ERROR back\r
+ // Probably this means that the Device Context does not have\r
+ // a TrueType font selected into it.\r
+ return false;\r
+ }\r
+ swap( numberOfEncodings );\r
+ \r
+ CMapEncoding encoding = {}; // The current encoding\r
+\r
+ // Get the encodings and look for a Unicode Encoding\r
+ DWORD iUnicode = numberOfEncodings;\r
+ for ( DWORD i = 0; i < numberOfEncodings; ++i )\r
+ {\r
+ if ( !getEncoding( &encoding, i ) ) return false;\r
+\r
+ if (encoding.PlatformId == 3 && \r
+ (encoding.EncodingId == 1 || encoding.EncodingId == 0) )\r
+ {\r
+ iUnicode = i; // Set the index to the Unicode encoding\r
+ }\r
+ }\r
+\r
+ // index out of range means failure to find a Unicode mapping\r
+ if ( iUnicode >= numberOfEncodings )\r
+ {\r
+ // No Unicode encoding found.\r
+ return false;\r
+ }\r
+\r
+ CMap4 format4; // Unicode subtable format\r
+ // Get the header entries(first 7 USHORTs) for the Unicode encoding.\r
+ if ( !getFormat4Header( &format4, encoding.Offset ) )\r
+ {\r
+ return false;\r
+ }\r
+\r
+ if ( format4.format != 4 )\r
+ {\r
+ // Windows7\82Ì"\82l\82r \96¾\92©"\93\99\82Íformat4.format\82ª12\r
+ return false;\r
+ }\r
+\r
+ delete [] cmapTable;\r
+ cmapTable = reinterpret_cast<CMap4 *>( new unsigned char[format4.length] );\r
+ if ( cmapTable == NULL ) return false;\r
+\r
+ if ( !getFormat4Subtable( cmapTable, encoding.Offset )) return false;\r
+\r
+ return true;\r
+ }\r
+\r
+ bool CharacterMap::findFormat4Segment(\r
+ CMap4 *table, // a valid Format4 subtable buffer\r
+ USHORT ch, // Unicode character to search for\r
+ USHORT &index // out: index of segment containing ch\r
+ ) const\r
+ {\r
+ if ( NULL == table ) return FALSE;\r
+\r
+ const USHORT segCount = table->segCountX2 / 2;\r
+ const USHORT *startCount = getStartCountArray( table );\r
+ const USHORT *endCount = getEndCountArray( table );\r
+\r
+ // Find segment that could contain the Unicode character code\r
+ for( USHORT i = 0; i < segCount; ++i )\r
+ {\r
+ if ( endCount[i] >= ch ) \r
+ {\r
+ // character code not within the range of the segment\r
+ if ( startCount[i] > ch ) return false;\r
+ // this segment contains the character code\r
+ index = i;\r
+ return true;\r
+ }\r
+ }\r
+ // We looked in them all, ch not there\r
+ return false;\r
+ }\r
+\r
+\r
+ unsigned int CharacterMap::getGlyphIndex( unsigned int character )\r
+ /*\r
+ When the TrueType font contains a glyph for ch, the\r
+ function returns the glyph index for that character.\r
+\r
+ If an error occurs, or there is no glyph for ch, the\r
+ function will return the missing glyph index of zero.\r
+ */ \r
+ {\r
+ if ( NULL == cmapTable ) return 0;\r
+\r
+ USHORT i;\r
+ // Find the cmap segment that has the character code.\r
+ if ( !findFormat4Segment( cmapTable, static_cast<USHORT>( character ), i ) )\r
+ {\r
+ return 0; // \8c©\82Â\82©\82ç\82È\82©\82Á\82½\r
+ }\r
+\r
+ // Get pointers to the cmap data\r
+ \r
+ const USHORT *idRangeOffset = getIdRangeOffsetArray( cmapTable );\r
+ const USHORT *idDelta = getIdDeltaArray( cmapTable );\r
+ const USHORT *startCount = getStartCountArray( cmapTable );\r
+\r
+ if ( idRangeOffset[i] == 0 ) // Per TT spec, if the RangeOffset is zero,\r
+ {\r
+ // calculate the glyph index directly\r
+ return static_cast<unsigned int>( (idDelta[i] + character) & 0xFFFF );\r
+ }\r
+ \r
+ const USHORT *glyphId = &idRangeOffset[i] + idRangeOffset[i] / 2;\r
+ // otherwise, use the glyph id array to get the index\r
+ USHORT idResult = glyphId[character - startCount[i]]; // indexing equation from TT spec\r
+\r
+ if ( !idResult ) return 0; // return the missing glyph\r
+ // Per TT spec, nonzero means there is a glyph\r
+ return (idDelta[i] + idResult) & 0xFFFF;\r
+ }\r
+\r
+\r
+ /* CMAP table Data\r
+ From the TrueType Spec revision 1.66\r
+\r
+ USHORT Table Version #\r
+ USHORT Number of encoding tables\r
+ */ \r
+ const size_t CharacterMap::cmapHeaderSize = sizeof( USHORT ) * 2;\r
+\r
+ /* ENCODING entry Data aka CMAPENCODING\r
+ From the TrueType Spec revision 1.66\r
+\r
+ USHORT Platform Id\r
+ USHORT Platform Specific Encoding Id\r
+ ULONG Byte Offset from beginning of table\r
+ */ \r
+ const size_t CharacterMap::encodingSize = sizeof( USHORT ) * 2 + sizeof( ULONG );\r
+\r
+ const size_t CharacterMap::format4HeaderSize = sizeof( USHORT ) * 7;\r
+\r
+ // DWORD packed four letter table name for each GetFontData()\r
+ // function call when working with the CMAP TrueType table\r
+ const DWORD CharacterMap::cmapName = makeTableName( 'c','m','a','p' );\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+\r
+#define NOMINMAX\r
+#include <windows.h>\r
+namespace nsdfont\r
+{\r
+ /**\r
+ * TrueType\83t\83H\83\93\83g\82Ì\83e\81[\83u\83\8b\82©\82ç\83O\83\8a\83t\83C\83\93\83f\83b\83N\83X\82ð\92T\82·.\r
+ */\r
+ class CharacterMap\r
+ {\r
+ #pragma pack(1) // for byte alignment\r
+ private:\r
+ struct CMap4 // From the TrueType Spec. revision 1.66\r
+ {\r
+ USHORT format; // Format number is set to 4. \r
+ USHORT length; // Length in bytes. \r
+ USHORT version; // Version number (starts at 0).\r
+ USHORT segCountX2; // 2 x segCount.\r
+ USHORT searchRange; // 2 x (2**floor(log2(segCount)))\r
+ USHORT entrySelector; // log2(searchRange/2)\r
+ USHORT rangeShift; // 2 x segCount - searchRange\r
+\r
+ USHORT Arrays[1]; // Placeholder symbol for address of arrays following\r
+ };\r
+\r
+ struct CMapEncoding\r
+ {\r
+ USHORT PlatformId;\r
+ USHORT EncodingId;\r
+ ULONG Offset;\r
+ };\r
+\r
+ private:\r
+ HDC hdc;\r
+ HFONT hFont;\r
+ CMap4 *cmapTable;\r
+ unsigned int characterCount; // the number of Unicode character glyphs\r
+ static const size_t cmapHeaderSize;\r
+ static const size_t encodingSize;\r
+ static const size_t format4HeaderSize;\r
+ static const DWORD cmapName;\r
+ public:\r
+ CharacterMap( void );\r
+ ~CharacterMap( void );\r
+\r
+ /**\r
+ * \83O\83\8a\83t\83C\83\93\83f\83b\83N\83X\82ð\8eæ\93¾.\r
+ * @param character \83O\83\8a\83t\82ð\8eæ\93¾\82·\82é\95¶\8e\9a\82ÌUnicode\r
+ * @return \83O\83\8a\83t\83C\83\93\83f\83b\83N\83X\r
+ */\r
+ unsigned int getGlyphIndex( unsigned int character );\r
+\r
+ /**\r
+ * \83t\83H\83\93\83g\82ð\91I\91ð.\r
+ * @param font \83t\83H\83\93\83g\8fî\95ñ\r
+ * @return \90¬\8c÷\82Ì\89Â\94Û\r
+ * @retval true \90¬\8c÷\r
+ * @retval false \8e¸\94s\r
+ */\r
+ bool selectFont( const LOGFONTA *font );\r
+\r
+\r
+ inline HDC getDC( void ){ return hdc; }\r
+ private:\r
+ void clearFont( void );\r
+ bool fetchUnicodeCMapTable( void );\r
+ bool getEncoding( CMapEncoding *encoding, int index ) const;\r
+ bool getFormat4Header( CMap4 *format4, DWORD offset ) const;\r
+ bool getFormat4Subtable ( CMap4 *subtable, DWORD offset ) const;\r
+ bool findFormat4Segment( CMap4 *table, USHORT ch, USHORT &index ) const;\r
+ static unsigned int getCharacterCount( const CMap4 *format4 );\r
+\r
+ inline static DWORD makeTableName( char c1, char c2, char c3, char c4 ) \r
+ {\r
+ DWORD name = 0;\r
+ name |= static_cast<DWORD>( c4 ) << 0x18;\r
+ name |= static_cast<DWORD>( c3 ) << 0x10;\r
+ name |= static_cast<DWORD>( c2 ) << 0x08;\r
+ name |= static_cast<DWORD>( c1 );\r
+ return name;\r
+ }\r
+\r
+ inline static void swap( USHORT &x ){ x = ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);}\r
+ inline static void swap( ULONG &x )\r
+ {\r
+ x = ((x & 0xFF) << 24) | ((x & 0xFF000000) >> 24) | \r
+ ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8);\r
+ }\r
+\r
+ inline static const USHORT *getEndCountArray( const CMap4 *cmap4 )\r
+ {\r
+ const USHORT *p = reinterpret_cast<const USHORT *>( cmap4 );\r
+ return &p[7]; // 7 header\r
+ }\r
+\r
+ inline static const USHORT *getStartCountArray( const CMap4 *cmap4 )\r
+ {\r
+ const DWORD segCount = cmap4->segCountX2 / 2;\r
+ const USHORT *p = reinterpret_cast<const USHORT *>( cmap4 );\r
+ return &p[7 + 1 + segCount * 1]; // 7 header + 1 reserved USHORT\r
+ }\r
+\r
+ inline static const USHORT *getIdDeltaArray( const CMap4 *cmap4 )\r
+ {\r
+ const DWORD segCount = cmap4->segCountX2 / 2;\r
+ const USHORT *p = reinterpret_cast<const USHORT *>( cmap4 );\r
+ return &p[7 + 1 + segCount * 2]; // 7 header + 1 reserved USHORT\r
+ }\r
+\r
+ inline static const USHORT *getIdRangeOffsetArray( const CMap4 *cmap4 )\r
+ {\r
+ const DWORD segCount = cmap4->segCountX2 / 2;\r
+ const USHORT *p = reinterpret_cast<const USHORT *>( cmap4 );\r
+ return &p[7 + 1 + segCount * 3]; // 7 header + 1 reserved USHORT\r
+ }\r
+ /**\r
+ * \83G\83\93\83f\83B\83A\83\93\95Ï\8dX.\r
+ */\r
+ static void swapArrays( CMap4 *format4 );\r
+ };\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+#include <algorithm>\r
+\r
+namespace nsdfont\r
+{\r
+ struct Color\r
+ {\r
+ private:\r
+ unsigned int argb;\r
+ public:\r
+ Color( void ) : argb( 0x00000000 ){}\r
+ \r
+ Color( unsigned int argb ) :\r
+ argb( argb )\r
+ {\r
+ }\r
+\r
+ Color( unsigned int rgb, unsigned int alpha )\r
+ {\r
+ setArgb( rgb, alpha );\r
+ }\r
+ Color( unsigned int red, unsigned int green,\r
+ unsigned int blue, unsigned int alpha )\r
+ {\r
+ setArgb( red, green, blue , alpha );\r
+ }\r
+\r
+ ~Color(void) {}\r
+\r
+ /*\r
+ inline Color &operator=( const Color &c )\r
+ {\r
+ argb = c.getArgb();\r
+ return *this;\r
+ }\r
+ */\r
+ \r
+ inline unsigned int getArgb( void ) const { return argb; }\r
+ inline unsigned int getRgb( void ) const { return argb & 0xFFFFFF; }\r
+ inline unsigned int getR( void ) const { return (argb >> 16) & 0xFF; }\r
+ inline unsigned int getG( void ) const { return (argb >> 8) & 0xFF; }\r
+ inline unsigned int getB( void ) const { return argb & 0xFF; }\r
+ inline unsigned int getA( void ) const { return argb >> 24; }\r
+ inline void setArgb( unsigned int argb ){ this->argb = argb; }\r
+ inline void setArgb( unsigned int rgb, unsigned int alpha )\r
+ {\r
+ if ( 0xFF <= alpha ) alpha = 0xFF;\r
+ argb = (rgb & 0xFFFFFF) | ( alpha << 24 );\r
+ }\r
+ inline void setArgb( unsigned int red, unsigned int green,\r
+ unsigned int blue, unsigned int alpha )\r
+ {\r
+ argb = blue | (green << 8) | (red << 16) | ( alpha << 24 );\r
+ }\r
+ inline void setA( unsigned int alpha )\r
+ {\r
+ argb = (argb & 0xFFFFFF) | ( alpha << 24 );\r
+ }\r
+ inline void setRgb( unsigned int rgb )\r
+ {\r
+ argb = (argb & 0xFF000000) | (rgb & 0xFFFFFF);\r
+ }\r
+ inline void setRgb( unsigned int red, unsigned int green, unsigned int blue )\r
+ {\r
+ argb = (argb & 0xFF000000) | blue | (green << 8) | (red << 16);\r
+ }\r
+\r
+ /**\r
+ * RGB\90F\8bó\8aÔ\82©\82çHSV\90F\8bó\8aÔ\82É\95Ï\8a·\82·\82é.\r
+ * @attention HSV\82»\82ê\82¼\82ê8bit\82Ì\82½\82ß\95Ï\8a·\82É\8dÛ\82µ\8fî\95ñ\82ª\97ò\89»\82·\82é.\r
+ */\r
+ inline void toHsv( void )\r
+ {\r
+ const unsigned int r = getR();\r
+ const unsigned int g = getG();\r
+ const unsigned int b = getB();\r
+ const unsigned int cmax = std::max( r, std::max( g, b ) );\r
+ const unsigned int cmin = std::min( r, std::min( g, b ) );\r
+ const unsigned int delta = cmax - cmin;\r
+ const unsigned int s = (cmax == 0) ? 0 : (255 * delta) / cmax;\r
+ if ( s == 0 )\r
+ {\r
+ argb = (argb & 0xFF000000) | cmax;\r
+ return;\r
+ }\r
+ if ( r == cmax )\r
+ {\r
+ // 2796203 = (256 << 16) / 6\r
+ setRgb( 2796203 * (g - b) / (delta << 16), s, cmax );\r
+ }\r
+ else if ( g == cmax )\r
+ {\r
+ // 5592405 = (256 << 16) / 3\r
+ setRgb( (2796203 * (b - r) + 5592405) / (delta << 16), s, cmax );\r
+ }\r
+ else if ( b == cmax )\r
+ {\r
+ // 11184811 = (256 << 16) * 2 / 3\r
+ setRgb( (2796203 * (r - g) + 11184811) / (delta << 16), s, cmax );\r
+ }\r
+ }\r
+\r
+ inline void toRgb( void )\r
+ {\r
+ \r
+ }\r
+\r
+ };\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#include "ColorBlender.h"\r
+\r
+namespace nsdfont\r
+{\r
+ ColorBlender::ColorBlender( void )\r
+ {\r
+ }\r
+\r
+ ColorBlender::~ColorBlender( void )\r
+ {\r
+ }\r
+\r
+ ColorBlender::MulTable::MulTable( void )\r
+ {\r
+ size_t i = 0;\r
+ for( int y = 0; y < 256; ++y )\r
+ {\r
+ int acc = 0;\r
+ for(;;)\r
+ {\r
+ table[i++] = static_cast<unsigned char>( (acc + 255) / 510 );\r
+ if ( (i & 0xFF) == 0 ) break;\r
+ acc += y + y;\r
+ }\r
+ }\r
+ }\r
+\r
+ ColorBlender::DivTable::DivTable( void )\r
+ {\r
+ size_t i = 0x100;\r
+ for( int divider = 1; divider < 256; ++divider )\r
+ {\r
+ const int divider2 = divider << 1;\r
+ for( int x = 0; x < 256 * 510; x += 510 )\r
+ {\r
+ // x <= divider2 \82Å\83I\81[\83o\81[\83t\83\8d\81[\r
+ table[i++] = static_cast<unsigned char>( (x + divider) / divider2 );\r
+ }\r
+ }\r
+ }\r
+ \r
+ const ColorBlender::MulTable ColorBlender::mulTable;\r
+ const ColorBlender::DivTable ColorBlender::divTable;\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+#include "Color.h"\r
+\r
+namespace nsdfont\r
+{\r
+ class ColorBlender\r
+ {\r
+ private:\r
+ class Table\r
+ {\r
+ protected:\r
+ unsigned char table[256*256];\r
+ public:\r
+ inline unsigned int operator[]( size_t i ) const\r
+ {\r
+ return static_cast<unsigned int>( table[i] );\r
+ }\r
+ };\r
+ \r
+ /**\r
+ * \8fæ\8eZ\83e\81[\83u\83\8b.\r
+ */\r
+ class MulTable : public Table\r
+ {\r
+ public:\r
+ MulTable();\r
+ };\r
+ /**\r
+ * \8f\9c\8eZ\83e\81[\83u\83\8b.\r
+ */\r
+ class DivTable : public Table\r
+ {\r
+ public:\r
+ DivTable();\r
+ };\r
+\r
+ static const MulTable mulTable;\r
+ static const DivTable divTable;\r
+ public:\r
+ ColorBlender( void );\r
+\r
+ ~ColorBlender( void );\r
+\r
+ /**\r
+ * \8fæ\8eZ\r
+ */\r
+ static inline unsigned int mul( const unsigned int v1, const unsigned int v2 )\r
+ {\r
+ const size_t i = v1 + (v2 << 8);\r
+ return mulTable[i];\r
+ }\r
+ \r
+ /**\r
+ * \83X\83N\83\8a\81[\83\93(\94½\93]\8fæ\8eZ)\r
+ */\r
+ static inline unsigned int scr( const unsigned int v1, const unsigned int v2 )\r
+ {\r
+ const size_t i = (v1 + (v2 << 8)) ^ 0xFFFF;\r
+ return mulTable[i] ^ 0xFF;\r
+ }\r
+\r
+ static inline unsigned int div( const unsigned int numerator, const unsigned int divider )\r
+ {\r
+ const size_t i = numerator + (divider << 8);\r
+ return divTable[i];\r
+ }\r
+ \r
+ static inline Color blend( const Color &c1, const Color &c2, unsigned int rate )\r
+ {\r
+ const unsigned int inv = 255 - rate;\r
+ const unsigned int newA = mul( c1.getA(), inv ) + mul( c2.getA(), rate );\r
+ const unsigned int newR = mul( c1.getR(), inv ) + mul( c2.getR(), rate );\r
+ const unsigned int newG = mul( c1.getG(), inv ) + mul( c2.getG(), rate );\r
+ const unsigned int newB = mul( c1.getB(), inv ) + mul( c2.getB(), rate );\r
+ return Color( newR, newG, newB, newA );\r
+ }\r
+ \r
+ static inline Color interpolate( const Color &c1, const Color &c2, double rate )\r
+ {\r
+ const unsigned int r = static_cast<unsigned int>( 255 * rate );\r
+ return blend( c1, c2, r );\r
+ }\r
+\r
+ static inline Color interpolateHsv( const Color &c1, const Color &c2, double rate )\r
+ {\r
+ const unsigned int r = static_cast<unsigned int>( 255 * rate );\r
+ return blend( c1, c2, r );\r
+ }\r
+\r
+ \r
+ /**\r
+ * 2\82Â\82Ì\90F\82ð\8fd\82Ë\8d\87\82í\82¹\82½\90F\82ð\90¶\90¬\82·\82é.\r
+ * @param back \89º\91w\82Ì\90F\r
+ * @param fore \91O\96Ê\82Ì\90F\r
+ * @return \8fd\82Ë\8d\87\82í\82¹\82½\90F\r
+ */\r
+ static inline Color merge( const Color &back, const Color &fore )\r
+ {\r
+ // C = blend( blend( C0, C1, A1), C2, A2 )\r
+ // = blend( C0*(1-A1) + C1*A1, C2, A2 )\r
+ // = C0*(1-A1)*(1-A2) + C1*A1*(1-A2) + C2*A2\r
+ // = blend( C0, {C1*A1*(1-A2) + C2*A2}/{1-(1-A1)*(1-A2)}, 1-(1-A1)*(1-A2) )\r
+ // = blend( C0, {C1*A1 + C2*A2 - C1*A1*A2}/scr(A1,A2), scr(A1,A2) )\r
+ const unsigned int backA = back.getA();\r
+ if ( backA == 0 ) return Color( fore );\r
+ const unsigned int foreA = fore.getA();\r
+ if ( foreA == 0 ) return Color( back );\r
+ const unsigned int mulA = mul( backA, foreA );\r
+\r
+ const unsigned int backR = back.getR();\r
+ const unsigned int foreR = fore.getR();\r
+ const unsigned int newR = mul( backR, backA ) + mul( foreR, foreA )\r
+ - mul( backR, mulA );\r
+ const unsigned int backG = back.getG();\r
+ const unsigned int foreG = fore.getG();\r
+ const unsigned int newG = mul( backG, backA ) + mul( foreG, foreA )\r
+ - mul( backG, mulA ); \r
+ const unsigned int backB = back.getB();\r
+ const unsigned int foreB = fore.getB();\r
+ const unsigned int newB = mul( backB, backA ) + mul( foreB, foreA )\r
+ -mul( backB, mulA );\r
+ const unsigned int newA = scr( backA, foreA );\r
+ return Color( div( newR, newA ), \r
+ div( newG, newA ),\r
+ div( newB, newA ), newA );\r
+ }\r
+ };\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#include "Decorator.h"\r
+#include <cmath>\r
+\r
+namespace nsdfont\r
+{\r
+ Decorator::Decorator( void )\r
+ {\r
+ face1 = Color( 0xFFFFFFFF );\r
+ }\r
+\r
+ Decorator::~Decorator( void )\r
+ {\r
+ }\r
+\r
+ void Decorator::setFace( const Color color )\r
+ {\r
+ face1 = color;\r
+ face2 = color;\r
+ }\r
+\r
+ void Decorator::setEdge( const double width, const Color color )\r
+ {\r
+ // \r
+ // :\r
+ // l : l l2,2l\r
+ // +-+-+---+---+\r
+ // l : l1,1l2,1l\r
+ // +-+-+---+---+---+\r
+ // --+0,0+1,0+2,0+3,0+---->\r
+ // +-:-+---+---+---+\r
+ // | : l l l |\r
+ // :\r
+ \r
+ // \83e\81[\83u\83\8b\8f\89\8aú\89»\r
+ // \90³\95û\8c`\82Å\82 \82é\82±\82Æ\82ð\91O\92ñ\r
+ const size_t tableSize = sizeof( edgePower ) / sizeof( edgePower[0] );\r
+ for( size_t j = 0; j < tableSize; ++j )\r
+ {\r
+ for( size_t i = 0; i < tableSize; ++i )\r
+ {\r
+ edgePower[j][i] = 0;\r
+ }\r
+ }\r
+\r
+ if ( width <= 1e-20 )\r
+ {\r
+ edgeWidth = 0.0;\r
+ return;\r
+ }\r
+\r
+ edge1 = color;\r
+ exTop = exBottom = exLeft = exRight = static_cast<unsigned int>( std::ceil( edgeWidth ) );\r
+\r
+ const double r = width + rEqu; // \89~\82Ì\94¼\8ca\r
+ const double s = rPi * r * r; // \89~\82Ì\96Ê\90Ï\r
+ const double scale( edge1.getA() );\r
+ if ( r <= rSqrt0_5 ) // (0.5,0.5)\93\9e\92B\82Ü\82Å\r
+ {\r
+ // a0 = SQRT(r^2-0.5^2) * 2 + 2*r^2*(\r
+ // ASIN(0.5/r)-ACOS(0.5/r) \r
+ // + 0.5*SIN(2*ASIN(0.5/r))-0.5*SIN(2*ACOS(0.5/r))\r
+ // )\r
+ const double a0 = 1.0 - 4.333 * (r - rSqrt0_5) * (r - rSqrt0_5); //2\8e\9f\8bß\8e\97\r
+ const double a1 = 0.25 * (s - a0);\r
+ edgePower[0][0] = static_cast<int>( a0 * scale );\r
+ edgePower[1][0] = static_cast<int>( a1 * scale );\r
+ edgePower[1][1] = 0;\r
+ return;\r
+ }\r
+ if ( r <= 1.5 ) // (1.5,0.0)\93\9e\92B\82Ü\82Å\r
+ {\r
+ // b0 = 0.5*SQRT(r^2-0.5^2)-0.5+r^2*ASIN(0.5/r)\r
+\r
+ const double b0 = 1.0422359371 * r - 0.5878914747; //1\8e\9f\8bß\8e\97\r
+ const double b1 = 0.25 * (s - 1.0) - b0;\r
+ edgePower[0][0] = static_cast<int>( scale );\r
+ edgePower[1][0] = static_cast<int>( b0 * scale );\r
+ edgePower[1][1] = static_cast<int>( b1 * scale );\r
+ return;\r
+ }\r
+ \r
+ }\r
+\r
+ void Decorator::drawFace( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const\r
+ {\r
+ if ( glyph.getBufferSize() <= 0 ) return;\r
+\r
+ drawCoreSimple( x, y, bmp, glyph, face1 );\r
+ }\r
+\r
+ void Decorator::drawCoreSimple( int x, int y, ArgbBitmap &bmp, const Glyph &glyph, const Color color ) const\r
+ {\r
+ // \8a®\91S\82É\93§\96¾\82È\82ç\95`\89æ\82µ\82È\82¢\r
+ if ( color.getA() == 0 ) return;\r
+\r
+ x += exLeft;\r
+ y += exTop;\r
+ \r
+ int width, height;\r
+ unsigned char *src = clip( x, y, width, height, bmp, glyph );\r
+\r
+ for( int j = 0; j < height; ++j )\r
+ {\r
+ ArgbArray dest = bmp.getArray( x, y + j );\r
+ for( int i = 0; i < width; ++i )\r
+ {\r
+ if ( src[i] == 0 ) continue;\r
+ const Color face( color.getArgb(), blend.mul( color.getA(), src[i] ) );\r
+ dest[i] = blend.merge( dest[i], face );\r
+ }\r
+ src += glyph.getPitch();\r
+ }\r
+ }\r
+\r
+ void Decorator::drawEdge( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const\r
+ {\r
+ if ( glyph.getBufferSize() <= 0 ) return;\r
+\r
+ const Color c00( edge1.getArgb(), edgePower[0][0] );\r
+ const Color c10( edge1.getArgb(), edgePower[1][0] );\r
+ const Color c11( edge1.getArgb(), edgePower[1][1] );\r
+\r
+ drawCoreSimple( x-1, y-1, bmp, glyph, c11 ); // \8d¶\8fã\r
+ drawCoreSimple( x+0, y-1, bmp, glyph, c10 ); // \92\86\8fã\r
+ drawCoreSimple( x+1, y-1, bmp, glyph, c11 ); // \89E\8fã\r
+ drawCoreSimple( x-1, y+0, bmp, glyph, c10 ); // \8d¶\92\86\r
+ drawCoreSimple( x+0, y+0, bmp, glyph, c00 ); // \92\86\92\86\r
+ drawCoreSimple( x+1, y+0, bmp, glyph, c10 ); // \89E\92\86\r
+ drawCoreSimple( x-1, y+1, bmp, glyph, c11 ); // \8d¶\89º\r
+ drawCoreSimple( x+0, y+1, bmp, glyph, c10 ); // \92\86\89º\r
+ drawCoreSimple( x+1, y+1, bmp, glyph, c11 ); // \89E\89º\r
+ if ( edgePower[2][0] > 0 )\r
+ {\r
+ \r
+ }\r
+ return;\r
+ }\r
+\r
+ unsigned char *Decorator::clip( int &x, int &y, int &width, int &height, \r
+ const ArgbBitmap &bmp, const Glyph&glyph ) const\r
+ {\r
+ width = glyph.getWidth();\r
+ height = glyph.getHeight();\r
+ unsigned char *src = glyph.getBuffer();\r
+\r
+ if ( x < 0 ) //(\8d¶\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
+ {\r
+ width += x;\r
+ src -= x;\r
+ x = 0;\r
+ }\r
+ if ( y < 0 ) //(\8fã\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
+ {\r
+ height += y;\r
+ src -= y * glyph.getPitch();\r
+ y = 0;\r
+ }\r
+ if ( x + width > bmp.getWidth() ) //(\89E\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
+ {\r
+ width = bmp.getWidth() - x;\r
+ }\r
+ if ( y + height > bmp.getHeight() ) //(\89º\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
+ {\r
+ height = bmp.getHeight() - y;\r
+ }\r
+ return src;\r
+ }\r
+\r
+\r
+ const double Decorator::rPi( 3.14159265358979323846 ); // pi\r
+ const double Decorator::rEqu( 0.564189583547756286948 ); // sqrt( 1 / pi )\r
+ const double Decorator::rSqrt0_5( 0.7071067811865475244 ); // sqrt( 0.5 )\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+#include "ArgbBitmap.h"\r
+#include "ColorBlender.h"\r
+#include "Glyph.h"\r
+\r
+namespace nsdfont\r
+{\r
+ /**\r
+ * \91\95\8fü\82ð\8e{\82µ\82Ä\83O\83\8a\83t\82ð\95`\89æ\82·\82é.\r
+ */\r
+ class Decorator\r
+ {\r
+ private:\r
+ const ColorBlender blend;\r
+ static const double rPi; // pi\r
+ static const double rEqu; // sqrt( 1 / pi )\r
+ static const double rSqrt0_5; // sqrt( 0.5 )\r
+ mutable Color face1;\r
+ Color face2;\r
+ Color edge1;\r
+ Color edge2;\r
+ double edgeWidth;\r
+ static const size_t maxRadius;\r
+ int edgePower[4][4];\r
+ int exLeft;\r
+ int exTop;\r
+ int exRight;\r
+ int exBottom;\r
+ public:\r
+ Decorator( void );\r
+ ~Decorator( void );\r
+ Decorator &operator=( const Decorator &d );\r
+ void setFace( const Color color );\r
+ void setEdge( const double width, const Color color );\r
+ void drawEdge( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const;\r
+ void drawFace( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const;\r
+ inline void getExtensionSize( int &left, int &top, int &right, int &bottom ) const\r
+ {\r
+ left = exLeft;\r
+ top = exTop;\r
+ right = exRight;\r
+ bottom = exBottom;\r
+ }\r
+ private:\r
+ void drawCoreSimple( int x, int y, ArgbBitmap &bmp, const Glyph &glyph, const Color color ) const;\r
+ void drawEdge1( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const;\r
+ void drawEdge2( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const;\r
+ unsigned char *clip( int &x, int &y, int &width, int &height,\r
+ const ArgbBitmap &bmp, const Glyph&glyph ) const;\r
+ };\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#include "Glyph.h"\r
+#include <cmath>\r
+\r
+namespace nsdfont\r
+{\r
+#undef GetGlyphOutline\r
+\r
+ Glyph::Glyph( void )\r
+ {\r
+ bufferSize = 0;\r
+ buffer = NULL;\r
+ }\r
+\r
+ Glyph::Glyph( const Glyph& glyph )\r
+ {\r
+ character = glyph.character;\r
+ memcpy( &metrics, &glyph.metrics, sizeof( metrics ) );\r
+ bufferSize = glyph.bufferSize;\r
+ if ( bufferSize > 0 )\r
+ {\r
+ buffer = new unsigned char[bufferSize];\r
+ memcpy( buffer, glyph.buffer, bufferSize );\r
+ }\r
+ else\r
+ {\r
+ buffer = NULL;\r
+ }\r
+ }\r
+\r
+ Glyph::Glyph( unsigned int character )\r
+ {\r
+ bufferSize = 0;\r
+ buffer = NULL;\r
+ this->character = character;\r
+ const unsigned int index = \r
+ ( mode & GGO_GLYPH_INDEX ) ? cm.getGlyphIndex( character ) : character;\r
+\r
+ // \95K\97v\83o\83b\83t\83@\83T\83C\83Y\81C\83\81\83g\83\8a\83N\83X\8eæ\93¾(lpvBuffer=NULL)\r
+ const DWORD bufferRequest = GetGlyphOutline( cm.getDC(), index, mode, &metrics, 0, NULL, &transform );\r
+ if ( bufferRequest == GDI_ERROR ) return;\r
+\r
+ if ( bufferRequest == 0 )\r
+ {\r
+ // GetGlyphOutline\82Ì\83o\83O\82É\82æ\82è0\82É\82È\82ç\82È\82¢\8fê\8d\87\82ª\82 \82é\r
+ metrics.gmBlackBoxX = 0;\r
+ metrics.gmBlackBoxY = 0;\r
+ return;\r
+ }\r
+ // GetGlyphOutline\82Ì\95Ô\82·\83o\83b\83t\83@\83T\83C\83Y\82Í\90M\97p\82µ\82Ä\82Í\82¢\82¯\82È\82¢\82ç\82µ\82¢\r
+ // \82ä\82¦\82É\83\81\83g\83\8a\83N\83X\82©\82ç\8cv\8eZ\82µ\82½\92l\82Æ\94ä\8ar\82µ\82Ä\91å\82«\82¢\82Ù\82¤\82ð\8dÌ\97p\r
+ bufferSize = static_cast<size_t>( getHeight() * getPitch() );\r
+ if ( bufferSize < bufferRequest ) bufferSize = bufferRequest;\r
+\r
+ buffer = new unsigned char[bufferSize];\r
+ GetGlyphOutline( cm.getDC(), index, mode, &metrics, bufferSize, buffer, &transform );\r
+\r
+ switch( mode & ~GGO_GLYPH_INDEX )\r
+ {\r
+ case GGO_GRAY4_BITMAP:\r
+ for( size_t i = 0; i < bufferSize; ++i )\r
+ {\r
+ const int alpha = (255 * buffer[i]) >> 4; // 0~16 -> 0~255\r
+ buffer[i] = static_cast<unsigned char>( alpha );\r
+ }\r
+ break;\r
+ case GGO_GRAY8_BITMAP: \r
+ for( size_t i = 0; i < bufferSize; ++i )\r
+ {\r
+ const int alpha = (255 * buffer[i]) >> 6; // 0~64 -> 0~255\r
+ buffer[i] = static_cast<unsigned char>( alpha );\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ Glyph::~Glyph(void)\r
+ {\r
+ if ( NULL != buffer )\r
+ {\r
+ delete [] buffer;\r
+ }\r
+ }\r
+\r
+ void Glyph::setFont( const LOGFONTA *font )\r
+ {\r
+ cm.selectFont( font );\r
+ GetTextMetrics( cm.getDC(), &textMetrics );\r
+ cache.flush();\r
+ }\r
+\r
+ void Glyph::setTransformation( double xScale, double xAngle, double yAngle )\r
+ {\r
+ const double deg2rad = 0.0174532925199432957692369; // pi / 180\r
+ xAngle *= deg2rad;\r
+ yAngle *= deg2rad;\r
+ // \82±\82Ì\95Ï\8a·\8ds\97ñ\82Í\89¡\83x\83N\83g\83\8b\82É\91Î\82·\82é\82à\82Ì\82ç\82µ\82¢\r
+ const double m11 = xScale * std::cos( yAngle );\r
+ const double m21 = xScale * std::sin( xAngle );\r
+ const double m12 = -std::sin( yAngle );\r
+ const double m22 = std::cos( xAngle );\r
+ doubleToFixed( m11, transform.eM11 );\r
+ doubleToFixed( m12, transform.eM12 );\r
+ doubleToFixed( m21, transform.eM21 );\r
+ doubleToFixed( m22, transform.eM22 );\r
+ }\r
+\r
+ void Glyph::doubleToFixed( double d, FIXED &f )\r
+ {\r
+ int i = static_cast<int>( 0x10000 * d ); \r
+ f.fract = static_cast<WORD>( i & 0xFFFF );\r
+ f.value = static_cast<WORD>( i >> 16 );\r
+ }\r
+\r
+ UINT Glyph::detectMode( void )\r
+ {\r
+ HMODULE hGdi = GetModuleHandleA( "gdi32.dll" );\r
+ GetGlyphOutline = reinterpret_cast<GetGlyphOutlinePtr>( GetProcAddress( hGdi, "GetGlyphOutlineW" ) );\r
+ // GetGlyphOutline = NULL;\r
+ if ( GetGlyphOutline )\r
+ {\r
+ return GGO_GRAY8_BITMAP;\r
+ }\r
+ GetGlyphOutline = reinterpret_cast<GetGlyphOutlinePtr>( GetGlyphOutlineA );\r
+ return GGO_GLYPH_INDEX | GGO_GRAY8_BITMAP;\r
+ }\r
+\r
+\r
+ const Glyph *Glyph::get( unsigned int character )\r
+ {\r
+ return cache.fetch( character );\r
+ }\r
+\r
+ // ------------------------------------------------------------------------\r
+\r
+ Glyph::Cache::Cache( size_t capacity )\r
+ {\r
+ this->capacity = capacity;\r
+ allocated = 0;\r
+ }\r
+\r
+ Glyph::Cache::~Cache( void )\r
+ {\r
+ flush();\r
+ }\r
+\r
+ const Glyph *Glyph::Cache::fetch( unsigned int character )\r
+ {\r
+ if ( glyphs.count( character ) <= 0 )\r
+ {\r
+ add( character ); // \91¶\8dÝ\82µ\82È\82¯\82ê\82Î\92Ç\89Á\r
+ }\r
+ else\r
+ {\r
+ // \90æ\93ª\82É\88Ú\93®\r
+ order.remove( character ); // \88ê\92U\8dí\8f\9c\r
+ order.push_front( character ); // \90æ\93ª\82É\8dÄ\91}\93ü\r
+ }\r
+ return glyphs[character];\r
+ }\r
+\r
+ void Glyph::Cache::add( unsigned int character )\r
+ {\r
+ remove( character ); // \94O\82Ì\82½\82ß\8aù\91¶\83f\81[\83^\82ð\8dí\8f\9c\r
+ reduce(); // \92Ç\89Á\82·\82é\83O\83\8a\83t\82ð\8fÁ\82³\82È\82¢\82½\82ß\82É\90æ\82É\8eÀ\8ds\r
+ const Glyph *g = new Glyph( character );\r
+ glyphs[character] = g;\r
+ allocated += g->getBufferSize();\r
+ order.push_front( character );\r
+ }\r
+\r
+ void Glyph::Cache::remove( unsigned int character )\r
+ {\r
+ if ( glyphs.count( character ) > 0 ) // character\82ª\91¶\8dÝ\82·\82é\82©\r
+ {\r
+ const Glyph *g = glyphs[character];\r
+ allocated -= g->getBufferSize();\r
+ delete g;\r
+ glyphs.erase( character );\r
+ order.remove( character );\r
+ }\r
+ }\r
+\r
+ void Glyph::Cache::reduce()\r
+ {\r
+ while( allocated > capacity )\r
+ {\r
+ const unsigned int &character = order.back(); // \8dÅ\8cã\82Ìfetch\82©\82ç\88ê\94Ô\8e\9e\8aÔ\82ª\82½\82Á\82½\95¶\8e\9a\r
+ const Glyph *g = glyphs[character];\r
+ allocated -= g->getBufferSize();\r
+ delete g;\r
+ glyphs.erase( character );\r
+ order.pop_back();\r
+ }\r
+ }\r
+\r
+ void Glyph::Cache::flush( void )\r
+ {\r
+ std::map<unsigned int, const Glyph *>::iterator it;\r
+ for( it = glyphs.begin(); it != glyphs.end(); ++it )\r
+ {\r
+ delete (*it).second;\r
+ }\r
+ glyphs.clear();\r
+ order.clear();\r
+ }\r
+\r
+\r
+\r
+ Glyph::GetGlyphOutlinePtr Glyph::GetGlyphOutline = NULL;\r
+ const UINT Glyph::mode = Glyph::detectMode();\r
+ CharacterMap Glyph::cm;\r
+ TEXTMETRICA Glyph::textMetrics;\r
+ Glyph::Cache Glyph::cache( 1024 * 256 );\r
+ MAT2 Glyph::transform = {{1,0}, {0,0}, {0,0}, {0,1}};\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+#define NOMINMAX\r
+#include <windows.h>\r
+#include "CharacterMap.h"\r
+#include <map>\r
+#include <list>\r
+\r
+namespace nsdfont\r
+{\r
+ class Glyph\r
+ {\r
+ private:\r
+ class Cache\r
+ {\r
+ private:\r
+ size_t capacity;\r
+ size_t allocated;\r
+ std::map<unsigned int, const Glyph *> glyphs;\r
+ std::list<unsigned int> order;\r
+ public:\r
+ Cache( size_t capacity );\r
+ ~Cache( void );\r
+ const Glyph *fetch( unsigned int character );\r
+ void add( unsigned int character );\r
+ void remove( unsigned int character );\r
+ void flush( void ); ///< \83O\83\8a\83t\83L\83\83\83b\83V\83\85\82ð\82·\82×\82Ä\8dí\8f\9c\82·\82é.\r
+ void reduce( void ); ///< \8ew\92è\83T\83C\83Y\91\8a\93\96\82É\8eû\82Ü\82é\82Ü\82Å\8eg\82í\82ê\82Ä\82¢\82È\82¢\83O\83\8a\83t\82ð\83L\83\83\83b\83V\83\85\82©\82ç\8dí\8f\9c\r
+ private:\r
+ };\r
+ private:\r
+#undef GetGlyphOutline\r
+ typedef DWORD (WINAPI *GetGlyphOutlinePtr)( __in HDC hdc,\r
+ __in UINT uChar,\r
+ __in UINT fuFormat,\r
+ __out LPGLYPHMETRICS lpgm,\r
+ __in DWORD cjBuffer,\r
+ __out_bcount_opt(cjBuffer) LPVOID pvBuffer,\r
+ __in CONST MAT2 *lpmat2\r
+ );\r
+ static GetGlyphOutlinePtr GetGlyphOutline;\r
+ unsigned int character; ///< \95¶\8e\9a\83R\81[\83h(Unicode)\r
+ GLYPHMETRICS metrics;\r
+ size_t bufferSize; ///< \83O\83\8a\83t\83r\83b\83g\83}\83b\83v\82Ì\83T\83C\83Y\r
+ unsigned char *buffer; ///< \83O\83\8a\83t\83r\83b\83g\83}\83b\83v\82Ö\82Ì\83|\83C\83\93\83^\r
+ static const UINT mode;\r
+ static CharacterMap cm;\r
+ static TEXTMETRICA textMetrics;\r
+ static MAT2 transform;\r
+ static Cache cache;\r
+\r
+ public:\r
+ Glyph( void );\r
+ Glyph( const Glyph &glyph );\r
+ ~Glyph( void );\r
+\r
+ /**\r
+ * \8ew\92è\82µ\82½\95¶\8e\9a\82Ì\83O\83\8a\83t\82ð\8eæ\93¾.\r
+ * @param \8eæ\93¾\82·\82é\95¶\8e\9a(Unicode)\r
+ * @return \8eæ\93¾\82µ\82½\83O\83\8a\83t\r
+ * @attention Glyph\83N\83\89\83X\82É\91Î\82µ\89½\82ç\82©\82Ì\91\80\8dì\82ð\8ds\82¤\82Æ\81C\8eæ\93¾\82µ\82½\83O\83\8a\83t\82Í\96³\8cø\82É\82È\82é\89Â\94\\90«\82ª\82 \82é. \r
+ * \92·\8aú\93I\82É\8eg\82¤\8fê\8d\87\82Í\81C\82Ü\82¸\95¡\90»\82µ\81C\95¡\90»\82µ\82½\82à\82Ì\82ð\8eg\82¤\82±\82Æ.\r
+ * \82Ü\82½\81C\8eæ\93¾\82µ\82½\83O\83\8a\83t\82Í\93à\95\94\82Å\8aÇ\97\9d\82³\82ê\82Ä\82¢\82é\82½\82ß\81Cdelete\82µ\82Ä\82Í\82È\82ç\82È\82¢. \r
+ */\r
+ static const Glyph *get( unsigned int character );\r
+ \r
+ inline int getX( void ) const ///<\83O\83\8a\83t\82Ìx\95û\8cü\82Ì\8aî\93_\82ð\8eæ\93¾\r
+ { \r
+ return static_cast<int>( metrics.gmptGlyphOrigin.x ); \r
+ }\r
+ inline int getY( void ) const ///<\83O\83\8a\83t\82Ìy\95û\8cü\82Ì\8aî\93_\82ð\8eæ\93¾\r
+ { \r
+ return static_cast<int>( metrics.gmptGlyphOrigin.y ); \r
+ }\r
+ inline int getWidth( void ) const\r
+ { \r
+ return static_cast<int>( metrics.gmBlackBoxX ); \r
+ }\r
+ inline int getHeight( void ) const\r
+ { \r
+ return static_cast<int>( metrics.gmBlackBoxY ); \r
+ }\r
+ inline int getPitch( void ) const\r
+ {\r
+ return (getWidth() + 3) & -4;\r
+ }\r
+ inline int getCellWidth( void ) const\r
+ { \r
+ return static_cast<int>( metrics.gmCellIncX ); \r
+ }\r
+ inline int getAscent( void ) const\r
+ {\r
+ return static_cast<int>( textMetrics.tmAscent ); \r
+ }\r
+ inline int getDescent( void ) const\r
+ { \r
+ return static_cast<int>( textMetrics.tmDescent ); \r
+ }\r
+ inline unsigned char *getBuffer( void ) const{ return buffer; }\r
+ inline size_t getBufferSize( void ) const{ return bufferSize; }\r
+ static void setFont( const LOGFONTA *font );\r
+ static void setTransformation( double xScale, double xAngle = 0.0, double yAngle = 0.0 );\r
+ private:\r
+ Glyph( unsigned int character );\r
+ Glyph operator=(const Glyph&); // \91ã\93ü\8bÖ\8e~\r
+ static UINT detectMode( void );\r
+ static void doubleToFixed( double d, FIXED &f );\r
+ };\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#include "Typesetter.h"\r
+\r
+namespace nsdfont\r
+{\r
+ Typesetter::Typesetter( void )\r
+ {\r
+ }\r
+\r
+ Typesetter::~Typesetter( void )\r
+ {\r
+ }\r
+\r
+ void Typesetter::setSpace( int horizontal, int vertical )\r
+ {\r
+ hSpace = horizontal;\r
+ vSpace = vertical;\r
+ }\r
+ \r
+ void Typesetter::calculateRect( int &width, int &height, \r
+ UnicodeString &str, const Decorator &decorator ) const\r
+ {\r
+ str.rewind();\r
+ width = 0;\r
+ height = 0;\r
+ int x = 0;\r
+ int y = 0;\r
+ int lineHeight = 0; // \8c»\8dÝ\91Î\8fÛ\82Æ\82µ\82Ä\82¢\82é\8ds\82Ì\8d\82\82³\r
+ while( const unsigned int unicode = str.peek() )\r
+ {\r
+ const Glyph &glyph = *Glyph::get( unicode );\r
+ if ( '\n' == unicode ) // \89ü\8ds\r
+ {\r
+ if ( x > hSpace ) x -= hSpace;\r
+ if ( x > width ) width = x;\r
+ x = 0;\r
+ y += glyph.getAscent() + glyph.getDescent(); //1\95¶\8e\9a\82Ì\8d\82\82³\95ª\89º\82É\88Ú\93®\r
+ y += vSpace; // \8ds\8aÔ\95ª\88Ú\93®\r
+ lineHeight = 0;\r
+ continue;\r
+ }\r
+ const int bottom = glyph.getAscent() - glyph.getY() + glyph.getHeight();\r
+ if ( bottom > lineHeight ) lineHeight = bottom;\r
+ x += glyph.getCellWidth();\r
+ x += hSpace;\r
+ }\r
+ if ( x > hSpace ) x -= hSpace;\r
+ if ( x > width ) width = x;\r
+ height = y + lineHeight;\r
+ \r
+ int exTop,exLeft,exBottom,exRight;\r
+ decorator.getExtensionSize( exLeft, exTop, exRight, exBottom );\r
+ width += exLeft + exRight;\r
+ height+= exTop + exBottom;\r
+ }\r
+\r
+ void Typesetter::draw( ArgbBitmap &bmp, UnicodeString &str, const Decorator &decorator ) const\r
+ {\r
+ str.rewind();\r
+ int x = 0;\r
+ int y = 0;\r
+ while( const unsigned int unicode = str.peek() )\r
+ {\r
+ const Glyph &glyph = *Glyph::get( unicode );\r
+ if ( '\n' == unicode )\r
+ {\r
+ x = 0;\r
+ y += glyph.getAscent() + glyph.getDescent();\r
+ y += vSpace;\r
+ continue;\r
+ }\r
+ const int gx = glyph.getX();\r
+ const int gy = glyph.getAscent()-glyph.getY();\r
+\r
+ decorator.drawEdge( x + gx, y + gy, bmp, glyph );\r
+ decorator.drawFace( x + gx, y + gy, bmp, glyph );\r
+\r
+ x += glyph.getCellWidth();\r
+ x += hSpace;\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+\r
+#include "UnicodeString.h"\r
+#include "ArgbBitmap.h"\r
+#include "Decorator.h"\r
+\r
+namespace nsdfont\r
+{\r
+ class Typesetter\r
+ {\r
+ private:\r
+ int hSpace;\r
+ int vSpace;\r
+ public:\r
+ Typesetter( void) ;\r
+ ~Typesetter( void );\r
+ void setSpace( int horizonal, int vertical );\r
+ void calculateRect( int &width, int &height, \r
+ UnicodeString &str, const Decorator &decorator ) const;\r
+ void draw( ArgbBitmap &bmp, UnicodeString &str, const Decorator &decorator ) const;\r
+ };\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#include "UnicodeString.h"\r
+\r
+namespace nsdfont\r
+{\r
+ UnicodeString::UnicodeString( Codepage codepage, const char *str, size_t length )\r
+ {\r
+ this->length = MultiByteToWideChar( codepage, MB_PRECOMPOSED, str, length, NULL, 0 );\r
+ unicodeStr = new wchar_t[this->length];\r
+ this->length = MultiByteToWideChar( codepage, MB_PRECOMPOSED, str, length, unicodeStr, this->length );\r
+ position = 0;\r
+ }\r
+\r
+ UnicodeString::~UnicodeString( void )\r
+ {\r
+ delete[] unicodeStr;\r
+ }\r
+\r
+ unsigned int UnicodeString::peek( void )\r
+ {\r
+ if ( position >= length ) return 0;\r
+\r
+ wchar_t character = unicodeStr[position++];\r
+ if ( character == L'&' )\r
+ {\r
+ if ( position >= length ) return L'&';\r
+ character = unicodeStr[position];\r
+ if ( character == L'#' )\r
+ {\r
+ return parseNumericEntity();\r
+ }\r
+ return parseCharacterEntity();\r
+ }\r
+ return character;\r
+ }\r
+\r
+ unsigned int UnicodeString::parseNumericEntity( void )\r
+ {\r
+ if ( (position + 1) >= length ) return L'&';\r
+ position++;\r
+ wchar_t code = 0;\r
+ if ( unicodeStr[position] == L'x' ) //16\90i\90\94\r
+ {\r
+ position++;\r
+ while( position < length )\r
+ {\r
+ const wchar_t w = unicodeStr[position++];\r
+ if ( L'0' <= w && w <= L'9' ) \r
+ {\r
+ code = (code << 4) + w - L'0';\r
+ }\r
+ else if ( L'A' <= w && w <= L'F' )\r
+ {\r
+ code = (code << 4) + w - L'A' + 10;\r
+ }\r
+ else if ( L'a' <= w && w <= L'f' ) \r
+ {\r
+ code = (code << 4) + w - L'a' + 10;\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ return code;\r
+ }\r
+ \r
+ while( position < length )\r
+ {\r
+ const wchar_t w = unicodeStr[position++];\r
+ if ( L'0' <= w && w <= L'9' ) \r
+ {\r
+ code = code * 10 + w - L'0';\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ \r
+ }\r
+ return code;\r
+ }\r
+\r
+ unsigned int UnicodeString::parseCharacterEntity( void )\r
+ {\r
+ char c[10];\r
+ size_t len = 0;\r
+ size_t limit = length - position;\r
+ if ( limit > 10 ) limit = 10;\r
+ for( size_t i = 0; i < limit; ++i )\r
+ {\r
+ len = i;\r
+ wchar_t w = unicodeStr[position++];\r
+ if ( w & 0xFF00 ) return L'&';\r
+ if ( w == L';' ) break;\r
+ c[i] = static_cast< unsigned char>( w & 0xFF );\r
+ }\r
+ // \88È\89º\81A\95¶\8e\9a\90\94\96\88\82É\90ü\8c`\92T\8dõ\r
+ if ( 2 == len )\r
+ {\r
+ const int entries = 15;\r
+ static const char e2[entries][2] = {\r
+ {'l','t'}, {'g','t'}, {'M','u'}, {'N','u'}, \r
+ {'X','i'}, {'P','i'}, {'m','u'}, {'n','u'}, \r
+ {'x','i'}, {'p','i'}, {'n','i'}, {'o','r'}, \r
+ {'n','e'}, {'l','e'}, {'g','e'}\r
+ };\r
+ static const wchar_t c2[entries] = {\r
+ 0x003C, 0x003E, 0x039C, 0x039D, \r
+ 0x039E, 0x03A0, 0x03BC, 0x03BD, \r
+ 0x03BE, 0x03C0, 0x220B, 0x2228, \r
+ 0x2260, 0x2264, 0x2265\r
+ };\r
+ \r
+ for( size_t i = 0; i < entries; ++i )\r
+ {\r
+ if ( *reinterpret_cast<const short *>( c ) == \r
+ *reinterpret_cast<const short *>( e2[i] ) )\r
+ {\r
+ return c2[i];\r
+ }\r
+ }\r
+ }\r
+ else if ( 3 == len )\r
+ {\r
+ const int entries = 35;\r
+ static const char e3[entries][4] = {\r
+ {'a','m','p'}, {'y','e','n'}, {'u','m','l'}, {'n','o','t'}, \r
+ {'s','h','y'}, {'r','e','g'}, {'d','e','g'}, {'E','T','H'}, \r
+ {'e','t','h'}, {'E','t','a'}, {'R','h','o'}, {'T','a','u'}, \r
+ {'P','h','i'}, {'C','h','i'}, {'P','s','i'}, {'e','t','a'}, \r
+ {'r','h','o'}, {'t','a','u'}, {'p','h','i'}, {'c','h','i'}, \r
+ {'p','s','i'}, {'p','i','v'}, {'z','w','j'}, {'l','r','m'}, \r
+ {'r','l','m'}, {'s','u','m'}, {'a','n','g'}, {'a','n','d'}, \r
+ {'c','a','p'}, {'c','u','p'}, {'i','n','t'}, {'s','i','m'}, \r
+ {'s','u','b'}, {'s','u','p'}, {'l','o','z'}\r
+ };\r
+ static const wchar_t c3[entries] = {\r
+ 0x0026, 0x00A5, 0x00A8, 0x00AC, \r
+ 0x00AD, 0x00AE, 0x00B0, 0x00D0, \r
+ 0x00F0, 0x0397, 0x03A1, 0x03A4, \r
+ 0x03A6, 0x03A7, 0x03A8, 0x03B7, \r
+ 0x03C1, 0x03C4, 0x03C6, 0x03C7, \r
+ 0x03C8, 0x03D6, 0x200D, 0x200E, \r
+ 0x200F, 0x2211, 0x2220, 0x2227, \r
+ 0x2229, 0x222A, 0x222B, 0x223C, \r
+ 0x2282, 0x2283, 0x25CA\r
+ };\r
+ c[3] = 0;\r
+ for( size_t i = 0; i < entries; ++i )\r
+ {\r
+ if ( *reinterpret_cast<const unsigned int *>( c ) == \r
+ *reinterpret_cast<const unsigned int *>( e3[i] ) )\r
+ {\r
+ return c3[i];\r
+ }\r
+ }\r
+ }\r
+ else if ( 4 == len )\r
+ {\r
+ const int entries = 60;\r
+ static const char e4[entries][4] = {\r
+ {'q','u','o','t'}, {'n','b','s','p'}, {'c','e','n','t'}, {'s','e','c','t'}, \r
+ {'c','o','p','y'}, {'o','r','d','f'}, {'m','a','c','r'}, {'s','u','p','2'}, \r
+ {'s','u','p','3'}, {'p','a','r','a'}, {'s','u','p','1'}, {'o','r','d','m'}, \r
+ {'A','u','m','l'}, {'E','u','m','l'}, {'I','u','m','l'}, {'O','u','m','l'}, \r
+ {'U','u','m','l'}, {'a','u','m','l'}, {'e','u','m','l'}, {'i','u','m','l'}, \r
+ {'o','u','m','l'}, {'u','u','m','l'}, {'y','u','m','l'}, {'Y','u','m','l'}, \r
+ {'f','n','o','f'}, {'c','i','r','c'}, {'B','e','t','a'}, {'Z','e','t','a'}, \r
+ {'I','o','t','a'}, {'b','e','t','a'}, {'z','e','t','a'}, {'i','o','t','a'}, \r
+ {'e','n','s','p'}, {'e','m','s','p'}, {'z','w','n','j'}, {'b','u','l','l'}, \r
+ {'e','u','r','o'}, {'r','e','a','l'}, {'l','a','r','r'}, {'u','a','r','r'}, \r
+ {'r','a','r','r'}, {'d','a','r','r'}, {'h','a','r','r'}, {'l','A','r','r'}, \r
+ {'u','A','r','r'}, {'r','A','r','r'}, {'d','A','r','r'}, {'h','A','r','r'}, \r
+ {'p','a','r','t'}, {'i','s','i','n'}, {'p','r','o','d'}, {'p','r','o','p'}, \r
+ {'c','o','n','g'}, {'n','s','u','b'}, {'s','u','b','e'}, {'s','u','p','e'}, \r
+ {'p','e','r','p'}, {'s','d','o','t'}, {'l','a','n','g'}, {'r','a','n','g'}\r
+\r
+ };\r
+ static const wchar_t c4[entries] = {\r
+ 0x0022, 0x00A0, 0x00A2, 0x00A7, \r
+ 0x00A9, 0x00AA, 0x00AF, 0x00B2, \r
+ 0x00B3, 0x00B6, 0x00B9, 0x00BA, \r
+ 0x00C4, 0x00CB, 0x00CF, 0x00D6, \r
+ 0x00DC, 0x00E4, 0x00EB, 0x00EF, \r
+ 0x00F6, 0x00FC, 0x00FF, 0x0178, \r
+ 0x0192, 0x02C6, 0x0392, 0x0396, \r
+ 0x0399, 0x03B2, 0x03B6, 0x03B9, \r
+ 0x2002, 0x2003, 0x200C, 0x2022, \r
+ 0x20AC, 0x211C, 0x2190, 0x2191, \r
+ 0x2192, 0x2193, 0x2194, 0x21D0, \r
+ 0x21D1, 0x21D2, 0x21D3, 0x21D4, \r
+ 0x2202, 0x2208, 0x220F, 0x221D, \r
+ 0x2245, 0x2284, 0x2286, 0x2287, \r
+ 0x22A5, 0x22C5, 0x2329, 0x232A\r
+ };\r
+ for( size_t i = 0; i < entries; ++i )\r
+ {\r
+ if ( *reinterpret_cast<const unsigned int *>( c ) == \r
+ *reinterpret_cast<const unsigned int *>( e4[i] ) )\r
+ {\r
+ return c4[i];\r
+ }\r
+ }\r
+ }\r
+ else if ( 5 == len )\r
+ {\r
+ const int entries = 72;\r
+ static const char e5[entries][5] = {\r
+ {'i','e','x','c','l'}, {'p','o','u','n','d'}, {'l','a','q','u','o'}, {'a','c','u','t','e'}, \r
+ {'m','i','c','r','o'}, {'c','e','d','i','l'}, {'r','a','q','u','o'}, {'A','c','i','r','c'}, \r
+ {'A','r','i','n','g'}, {'A','E','l','i','g'}, {'E','c','i','r','c'}, {'I','c','i','r','c'}, \r
+ {'O','c','i','r','c'}, {'t','i','m','e','s'}, {'U','c','i','r','c'}, {'T','H','O','R','N'}, \r
+ {'s','z','l','i','g'}, {'a','c','i','r','c'}, {'a','r','i','n','g'}, {'a','e','l','i','g'}, \r
+ {'e','c','i','r','c'}, {'i','c','i','r','c'}, {'o','c','i','r','c'}, {'u','c','i','r','c'}, \r
+ {'t','h','o','r','n'}, {'O','E','l','i','g'}, {'o','e','l','i','g'}, {'t','i','l','d','e'}, \r
+ {'A','l','p','h','a'}, {'G','a','m','m','a'}, {'D','e','l','t','a'}, {'T','h','e','t','a'}, \r
+ {'K','a','p','p','a'}, {'S','i','g','m','a'}, {'O','m','e','g','a'}, {'a','l','p','h','a'}, \r
+ {'g','a','m','m','a'}, {'d','e','l','t','a'}, {'t','h','e','t','a'}, {'k','a','p','p','a'}, \r
+ {'s','i','g','m','a'}, {'o','m','e','g','a'}, {'u','p','s','i','h'}, {'n','d','a','s','h'}, \r
+ {'m','d','a','s','h'}, {'l','s','q','u','o'}, {'r','s','q','u','o'}, {'s','b','q','u','o'}, \r
+ {'l','d','q','u','o'}, {'r','d','q','u','o'}, {'b','d','q','u','o'}, {'p','r','i','m','e'}, \r
+ {'P','r','i','m','e'}, {'o','l','i','n','e'}, {'f','r','a','s','l'}, {'i','m','a','g','e'}, \r
+ {'t','r','a','d','e'}, {'c','r','a','r','r'}, {'e','x','i','s','t'}, {'e','m','p','t','y'}, \r
+ {'n','a','b','l','a'}, {'n','o','t','i','n'}, {'m','i','n','u','s'}, {'r','a','d','i','c'}, \r
+ {'i','n','f','i','n'}, {'a','s','y','m','p'}, {'e','q','u','i','v'}, {'o','p','l','u','s'}, \r
+ {'l','c','e','i','l'}, {'r','c','e','i','l'}, {'c','l','u','b','s'}, {'d','i','a','m','s'}\r
+ };\r
+ static const wchar_t c5[entries] = {\r
+ 0x00A1, 0x00A3, 0x00AB, 0x00B4, \r
+ 0x00B5, 0x00B8, 0x00BB, 0x00C2, \r
+ 0x00C5, 0x00C6, 0x00CA, 0x00CE, \r
+ 0x00D4, 0x00D7, 0x00DB, 0x00DE, \r
+ 0x00DF, 0x00E2, 0x00E5, 0x00E6, \r
+ 0x00EA, 0x00EE, 0x00F4, 0x00FB, \r
+ 0x00FE, 0x0152, 0x0153, 0x02DC, \r
+ 0x0391, 0x0393, 0x0394, 0x0398, \r
+ 0x039A, 0x03A3, 0x03A9, 0x03B1, \r
+ 0x03B3, 0x03B4, 0x03B8, 0x03BA, \r
+ 0x03C3, 0x03C9, 0x03D2, 0x2013, \r
+ 0x2014, 0x2018, 0x2019, 0x201A, \r
+ 0x201C, 0x201D, 0x201E, 0x2032, \r
+ 0x2033, 0x203E, 0x2044, 0x2111, \r
+ 0x2122, 0x21B5, 0x2203, 0x2205, \r
+ 0x2207, 0x2209, 0x2212, 0x221A, \r
+ 0x221E, 0x2248, 0x2261, 0x2295, \r
+ 0x2308, 0x2309, 0x2663, 0x2666\r
+ };\r
+ for( size_t i = 0; i < entries; ++i )\r
+ {\r
+ if ( 0 == strncmp( const_cast<const char *>( c ), e5[i], 5 ) )\r
+ {\r
+ return c5[i];\r
+ }\r
+ }\r
+ }\r
+ else if ( 6 == len )\r
+ {\r
+ const int entries = 62;\r
+ static const char e6[entries][6] = {\r
+ {'c','u','r','r','e','n'}, {'b','r','v','b','a','r'}, {'p','l','u','s','m','n'}, {'m','i','d','d','o','t'}, \r
+ {'f','r','a','c','1','4'}, {'f','r','a','c','1','2'}, {'f','r','a','c','3','4'}, {'i','q','u','e','s','t'}, \r
+ {'A','g','r','a','v','e'}, {'A','a','c','u','t','e'}, {'A','t','i','l','d','e'}, {'C','c','e','d','i','l'}, \r
+ {'E','g','r','a','v','e'}, {'E','a','c','u','t','e'}, {'I','g','r','a','v','e'}, {'I','a','c','u','t','e'}, \r
+ {'N','t','i','l','d','e'}, {'O','g','r','a','v','e'}, {'O','a','c','u','t','e'}, {'O','t','i','l','d','e'}, \r
+ {'O','s','l','a','s','h'}, {'U','g','r','a','v','e'}, {'U','a','c','u','t','e'}, {'Y','a','c','u','t','e'}, \r
+ {'a','g','r','a','v','e'}, {'a','a','c','u','t','e'}, {'a','t','i','l','d','e'}, {'c','c','e','d','i','l'}, \r
+ {'e','g','r','a','v','e'}, {'e','a','c','u','t','e'}, {'i','g','r','a','v','e'}, {'i','a','c','u','t','e'}, \r
+ {'n','t','i','l','d','e'}, {'o','g','r','a','v','e'}, {'o','a','c','u','t','e'}, {'o','t','i','l','d','e'}, \r
+ {'d','i','v','i','d','e'}, {'o','s','l','a','s','h'}, {'u','g','r','a','v','e'}, {'u','a','c','u','t','e'}, \r
+ {'y','a','c','u','t','e'}, {'S','c','a','r','o','n'}, {'s','c','a','r','o','n'}, {'L','a','m','b','d','a'}, \r
+ {'l','a','m','b','d','a'}, {'s','i','g','m','a','f'}, {'t','h','i','n','s','p'}, {'d','a','g','g','e','r'}, \r
+ {'D','a','g','g','e','r'}, {'h','e','l','l','i','p'}, {'p','e','r','m','i','l'}, {'l','s','a','q','u','o'}, \r
+ {'r','s','a','q','u','o'}, {'w','e','i','e','r','p'}, {'f','o','r','a','l','l'}, {'l','o','w','a','s','t'}, \r
+ {'t','h','e','r','e','4'}, {'o','t','i','m','e','s'}, {'l','f','l','o','o','r'}, {'r','f','l','o','o','r'}, \r
+ {'s','p','a','d','e','s'}, {'h','e','a','r','t','s'}\r
+ };\r
+ static const wchar_t c6[entries] = {\r
+ 0x00A4, 0x00A6, 0x00B1, 0x00B7, \r
+ 0x00BC, 0x00BD, 0x00BE, 0x00BF, \r
+ 0x00C0, 0x00C1, 0x00C3, 0x00C7, \r
+ 0x00C8, 0x00C9, 0x00CC, 0x00CD, \r
+ 0x00D1, 0x00D2, 0x00D3, 0x00D5, \r
+ 0x00D8, 0x00D9, 0x00DA, 0x00DD, \r
+ 0x00E0, 0x00E1, 0x00E3, 0x00E7, \r
+ 0x00E8, 0x00E9, 0x00EC, 0x00ED, \r
+ 0x00F1, 0x00F2, 0x00F3, 0x00F5, \r
+ 0x00F7, 0x00F8, 0x00F9, 0x00FA, \r
+ 0x00FD, 0x0160, 0x0161, 0x039B, \r
+ 0x03BB, 0x03C2, 0x2009, 0x2020, \r
+ 0x2021, 0x2026, 0x2030, 0x2039, \r
+ 0x203A, 0x2118, 0x2200, 0x2217, \r
+ 0x2234, 0x2297, 0x230A, 0x230B, \r
+ 0x2660, 0x2665\r
+ };\r
+ for( size_t i = 0; i < entries; ++i )\r
+ {\r
+ if ( 0 == strncmp( const_cast<const char *>( c ), e6[i], 6 ) )\r
+ {\r
+ return c6[i];\r
+ }\r
+ }\r
+ }\r
+ else if ( 7 == len )\r
+ { \r
+ const int entries = 7;\r
+ static const char e7[entries][7] = {\r
+ {'E','p','s','i','l','o','n'}, {'O','m','i','c','r','o','n'}, \r
+ {'U','p','s','i','l','o','n'}, {'e','p','s','i','l','o','n'}, \r
+ {'o','m','i','c','r','o','n'}, {'u','p','s','i','l','o','n'}, \r
+ {'a','l','e','f','s','y','m'}\r
+ };\r
+ static const wchar_t c7[entries] = {\r
+ 0x0395, 0x039F, 0x03A5, 0x03B5, \r
+ 0x03BF, 0x03C5, 0x2135\r
+ };\r
+ for( size_t i = 0; i < entries; ++i )\r
+ {\r
+ if ( 0 == strncmp( const_cast<const char *>( c ), e7[i], 7 ) )\r
+ {\r
+ return c7[i];\r
+ }\r
+ }\r
+ }\r
+ else if ( 8 == len )\r
+ {\r
+ if ( 0 == strncmp( const_cast<const char *>( c ), "thetasym", 8 ) )\r
+ {\r
+ return 0x03D1;\r
+ }\r
+ }\r
+ return 0;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+#pragma once\r
+\r
+#define NOMINMAX\r
+#include <windows.h>\r
+\r
+namespace nsdfont\r
+{\r
+ class UnicodeString\r
+ {\r
+ public:\r
+ enum Codepage\r
+ {\r
+ SJIS = 932,\r
+ UTF8 = CP_UTF8,\r
+ };\r
+ private:\r
+ wchar_t *unicodeStr;\r
+ size_t length;\r
+ size_t position;\r
+\r
+ public:\r
+ UnicodeString( Codepage codepage, const char *str, size_t length = -1 );\r
+ ~UnicodeString( void );\r
+\r
+ unsigned int peek( void );\r
+ inline void rewind( void ){ position = 0; } \r
+ private:\r
+ /**\r
+ * \8c»\8dÝ\82Ì\88Ê\92u\82©\82ç\90\94\92l\95¶\8e\9a\8eQ\8fÆ\82ð\89ð\90Í\82µ\95¶\8e\9a\83R\81[\83h\82ð\95Ô\82·.\r
+ * @retrun \8eQ\8fÆ\82³\82ê\82Ä\82¢\82é\95¶\8e\9a\83R\81[\83h. \8e¸\94s\82µ\82½\8fê\8d\87\82Í\83[\83\8d\r
+ */\r
+ unsigned int parseNumericEntity( void );\r
+ /**\r
+ * \8c»\8dÝ\82Ì\88Ê\92u\82©\82ç\8eÀ\91Ì\95¶\8e\9a\8eQ\8fÆ\82ð\89ð\90Í\82µ\95¶\8e\9a\83R\81[\83h\82ð\95Ô\82·.\r
+ * @retrun \8eQ\8fÆ\82³\82ê\82Ä\82¢\82é\95¶\8e\9a\83R\81[\83h. \8e¸\94s\82µ\82½\8fê\8d\87\82Í\83[\83\8d\r
+ */\r
+ unsigned int parseCharacterEntity( void );\r
+ };\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Kimikage NScripter Plugins Project\r
+ *\r
+ * This software is distributed under a BSD-style license.\r
+ * See license.txt for more information.\r
+ */\r
+\r
+\r
+#define NOMINMAX\r
+#include <windows.h>\r
+#include <stdio.h>\r
+#include <lua.h>\r
+\r
+#include "nslua.h"\r
+#include "Glyph.h"\r
+#include "UnicodeString.h"\r
+#include "ArgbBitmap.h"\r
+#include "Decorator.h"\r
+#include "Typesetter.h"\r
+using namespace nsdfont;\r
+\r
+extern "C" {\r
+ __declspec(dllexport) void Font( unsigned char *bits, int w, int h, const char *param );\r
+ __declspec(dllexport) LUALIB_API int luaopen_nsdfont( lua_State *L );\r
+}\r
+\r
+static NL_gettablePtr NL_gettable = NULL;\r
+static NL_isstringPtr NL_isstring = NULL;\r
+static NL_istablePtr NL_istable = NULL;\r
+static NL_popPtr NL_pop = NULL;\r
+static NL_pushintegerPtr NL_pushinteger = NULL;\r
+static NL_pushstringPtr NL_pushstring = NULL;\r
+static NL_tobooleanPtr NL_toboolean = NULL;\r
+static NL_tointegerPtr NL_tointeger = NULL;\r
+static NL_tonumberPtr NL_tonumber = NULL;\r
+static NL_tostringPtr NL_tostring = NULL;\r
+\r
+static Decorator decorator;\r
+static Typesetter setter;\r
+\r
+\r
+BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )\r
+{\r
+ return TRUE;\r
+}\r
+\r
+static int setFont( lua_State *L )\r
+{\r
+ LOGFONT lf;\r
+ memset( &lf, 0, sizeof(lf) );\r
+ lf.lfCharSet = DEFAULT_CHARSET;\r
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
+ lf.lfEscapement = 0;\r
+ lf.lfItalic = 0;\r
+ lf.lfOrientation = 0;\r
+ lf.lfOutPrecision = OUT_DEFAULT_PRECIS;\r
+ lf.lfPitchAndFamily = DEFAULT_PITCH;\r
+ lf.lfQuality = DEFAULT_QUALITY;\r
+ lf.lfStrikeOut = 0;\r
+ lf.lfUnderline = 0;\r
+ lf.lfWidth = 0;\r
+ double expansion = 1.0;\r
+ double angleX = 0.0;\r
+ double angleY = 0.0;\r
+ const char *face = NULL;\r
+ if ( NL_istable( L, 1 ) )\r
+ {\r
+ NL_pushstring( L, "face" ); // 1:table, 2:"face"\r
+ NL_gettable( L, 1 ); // 1:table, 2:face\r
+ face = NL_tostring( L, 2 );\r
+ NL_pushstring( L, "size" );\r
+ NL_gettable( L, 1 );\r
+ lf.lfHeight = NL_tointeger( L, 3 ); // 1:table, 2:face, 3:size\r
+ NL_pushstring( L, "weight" );\r
+ NL_gettable( L, 1 );\r
+ lf.lfWeight = NL_tointeger( L, 4 ); \r
+ NL_pushstring( L, "italic" );\r
+ NL_gettable( L, 1 );\r
+ lf.lfItalic = static_cast<BYTE>( NL_toboolean( L, 5 ) ); \r
+ NL_pushstring( L, "expansion" );\r
+ NL_gettable( L, 1 );\r
+ expansion = NL_tonumber( L, 6 );\r
+ NL_pushstring( L, "angleX" );\r
+ NL_gettable( L, 1 );\r
+ angleX = NL_tonumber( L, 7 );\r
+ NL_pushstring( L, "angleY" );\r
+ NL_gettable( L, 1 );\r
+ angleY = NL_tonumber( L, 8 );\r
+ NL_pop( L, 7 ); // 1:table\r
+ }\r
+ else if ( NL_isstring( L, 1 ) )\r
+ {\r
+ face = NL_tostring( L, 1 ); // face\r
+ lf.lfHeight = NL_tointeger( L, 2 ); // size\r
+ lf.lfWeight = NL_tointeger( L, 3 ); // weight\r
+ lf.lfItalic = static_cast<BYTE>( NL_toboolean( L, 4 ) ); // italic\r
+ expansion = NL_tonumber( L, 5 ); // expansion\r
+ angleX = NL_tonumber( L, 6 ); // angleX\r
+ angleY = NL_tonumber( L, 7 ); // angleY\r
+ }\r
+ else\r
+ {\r
+ return 0;\r
+ }\r
+ if ( face ) strcpy_s( lf.lfFaceName, sizeof( lf.lfFaceName ), face );\r
+ if ( lf.lfFaceName[0] == 0 )\r
+ {\r
+ strcpy_s( lf.lfFaceName, sizeof( lf.lfFaceName ), "\82l\82r \82o\83S\83V\83b\83N" );\r
+ }\r
+ if ( lf.lfHeight == 0 ) lf.lfHeight = 24;\r
+ if ( lf.lfWeight == 0 ) lf.lfWeight = FW_NORMAL;\r
+ if ( expansion < 1e-20 ) expansion = 1.0;\r
+\r
+ Glyph::setFont( &lf );\r
+ Glyph::setTransformation( expansion, angleX, angleY );\r
+ return 0;\r
+}\r
+\r
+static int setFace( lua_State *L )\r
+{\r
+ const unsigned int color1 = static_cast<unsigned int>( NL_tointeger( L, 1 ) );;\r
+ decorator.setFace( Color( color1, 0xFF ) );\r
+ return 0;\r
+}\r
+\r
+static int setEdge( lua_State *L )\r
+{\r
+ const double width = NL_tonumber( L, 1 );\r
+ const unsigned int color1 = static_cast<unsigned int>( NL_tonumber( L, 2 ) );\r
+ decorator.setEdge( width, Color( color1 ) );\r
+ return 0;\r
+}\r
+\r
+static int calculateRect( lua_State *L )\r
+{\r
+ int width, height;\r
+ const char *str = NL_tostring( L, 1 );\r
+ UnicodeString unicodeStr( UnicodeString::SJIS, str );\r
+ setter.calculateRect( width, height, unicodeStr, decorator );\r
+ NL_pushinteger( L, width );\r
+ NL_pushinteger( L, height );\r
+ return 2;\r
+}\r
+\r
+LUALIB_API int luaopen_nsdfont( lua_State *L )\r
+{\r
+ HMODULE hMod = GetModuleHandleA( "nslua.dll" );\r
+ NL_registerPtr NL_register = NULL;\r
+ NL_register = reinterpret_cast<NL_registerPtr>( GetProcAddress( hMod, "NL_register" ) );\r
+ NL_gettable = reinterpret_cast<NL_gettablePtr>( GetProcAddress( hMod, "NL_gettable" ) );\r
+ NL_isstring = reinterpret_cast<NL_isstringPtr>( GetProcAddress( hMod, "NL_isstring" ) );\r
+ NL_istable = reinterpret_cast<NL_istablePtr>( GetProcAddress( hMod, "NL_istable" ) );\r
+ NL_pop = reinterpret_cast<NL_popPtr>( GetProcAddress( hMod, "NL_pop" ) );\r
+ NL_pushinteger = reinterpret_cast<NL_pushintegerPtr>( GetProcAddress( hMod, "NL_pushinteger" ) );\r
+ NL_pushstring = reinterpret_cast<NL_pushstringPtr>( GetProcAddress( hMod, "NL_pushstring" ) );\r
+ NL_toboolean = reinterpret_cast<NL_tobooleanPtr>( GetProcAddress( hMod, "NL_toboolean" ) );\r
+ NL_tostring = reinterpret_cast<NL_tostringPtr>( GetProcAddress( hMod, "NL_tostring" ) );\r
+ NL_tointeger = reinterpret_cast<NL_tointegerPtr>( GetProcAddress( hMod, "NL_tointeger" ) );\r
+ NL_tonumber = reinterpret_cast<NL_tonumberPtr>( GetProcAddress( hMod, "NL_tonumber" ) );\r
+ NL_register( "nsdfont_calcRect", &calculateRect );\r
+ NL_register( "nsdfont_setFont", &setFont );\r
+ NL_register( "nsdfont_setFace", &setFace );\r
+ NL_register( "nsdfont_setEdge", &setEdge );\r
+ return 0;\r
+}\r
+\r
+void Font(unsigned char *bits, int width, int height, const char *param )\r
+{\r
+ ArgbBitmap bmp( width, height, bits );\r
+ UnicodeString str( UnicodeString::SJIS, param );\r
+ //decorator.setEdge(0.1,Color(0xFF0000,255) );\r
+ setter.draw( bmp, str, decorator );\r
+ return;\r
+}\r
+\r
+\r
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsdfont", "nsdfont.vcproj", "{41D757BC-8A62-43E0-8F1D-7FBC28059DA9}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Win32 = Debug|Win32\r
+ Release|Win32 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {41D757BC-8A62-43E0-8F1D-7FBC28059DA9}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {41D757BC-8A62-43E0-8F1D-7FBC28059DA9}.Debug|Win32.Build.0 = Debug|Win32\r
+ {41D757BC-8A62-43E0-8F1D-7FBC28059DA9}.Release|Win32.ActiveCfg = Release|Win32\r
+ {41D757BC-8A62-43E0-8F1D-7FBC28059DA9}.Release|Win32.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>\r
+<VisualStudioProject\r
+ ProjectType="Visual C++"\r
+ Version="8.00"\r
+ Name="nsdfont"\r
+ ProjectGUID="{41D757BC-8A62-43E0-8F1D-7FBC28059DA9}"\r
+ RootNamespace="nsdfont"\r
+ >\r
+ <Platforms>\r
+ <Platform\r
+ Name="Win32"\r
+ />\r
+ </Platforms>\r
+ <ToolFiles>\r
+ </ToolFiles>\r
+ <Configurations>\r
+ <Configuration\r
+ Name="Debug|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ CharacterSet="2"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="0"\r
+ MinimalRebuild="true"\r
+ BasicRuntimeChecks="3"\r
+ RuntimeLibrary="1"\r
+ WarningLevel="4"\r
+ DebugInformationFormat="4"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ GenerateDebugInformation="true"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ CommandLine="echo $(OutDir)\$(ProjectName).dll
copy /Y "$(OutDir)\$(ProjectName).dll" "$(OutDir)/../../test/" /B
"\r
+ />\r
+ </Configuration>\r
+ <Configuration\r
+ Name="Release|Win32"\r
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+ IntermediateDirectory="$(ConfigurationName)"\r
+ ConfigurationType="2"\r
+ CharacterSet="2"\r
+ WholeProgramOptimization="1"\r
+ >\r
+ <Tool\r
+ Name="VCPreBuildEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCCustomBuildTool"\r
+ />\r
+ <Tool\r
+ Name="VCXMLDataGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebServiceProxyGeneratorTool"\r
+ />\r
+ <Tool\r
+ Name="VCMIDLTool"\r
+ />\r
+ <Tool\r
+ Name="VCCLCompilerTool"\r
+ Optimization="3"\r
+ EnableIntrinsicFunctions="true"\r
+ ExceptionHandling="1"\r
+ RuntimeLibrary="0"\r
+ EnableFunctionLevelLinking="true"\r
+ WarningLevel="4"\r
+ DebugInformationFormat="3"\r
+ />\r
+ <Tool\r
+ Name="VCManagedResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCResourceCompilerTool"\r
+ />\r
+ <Tool\r
+ Name="VCPreLinkEventTool"\r
+ />\r
+ <Tool\r
+ Name="VCLinkerTool"\r
+ GenerateDebugInformation="true"\r
+ OptimizeReferences="2"\r
+ EnableCOMDATFolding="2"\r
+ TargetMachine="1"\r
+ />\r
+ <Tool\r
+ Name="VCALinkTool"\r
+ />\r
+ <Tool\r
+ Name="VCManifestTool"\r
+ />\r
+ <Tool\r
+ Name="VCXDCMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCBscMakeTool"\r
+ />\r
+ <Tool\r
+ Name="VCFxCopTool"\r
+ />\r
+ <Tool\r
+ Name="VCAppVerifierTool"\r
+ />\r
+ <Tool\r
+ Name="VCWebDeploymentTool"\r
+ />\r
+ <Tool\r
+ Name="VCPostBuildEventTool"\r
+ />\r
+ </Configuration>\r
+ </Configurations>\r
+ <References>\r
+ </References>\r
+ <Files>\r
+ <Filter\r
+ Name="Sources"\r
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+ >\r
+ <File\r
+ RelativePath="..\src\ArgbBitmap.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\CharacterMap.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\ColorBlender.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\Decorator.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\Glyph.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\main.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\Typesetter.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\UnicodeString.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Headers"\r
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+ >\r
+ <File\r
+ RelativePath="..\src\ArgbArray.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\ArgbBitmap.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\CharacterMap.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\Color.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\ColorBlender.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\Decorator.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\Glyph.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\nslua.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\Typesetter.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\src\UnicodeString.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ <Filter\r
+ Name="Resources"\r
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"\r
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+ >\r
+ </Filter>\r
+ </Files>\r
+ <Globals>\r
+ </Globals>\r
+</VisualStudioProject>\r