OSDN Git Service

NSDフォントプラグイン登録
authorT2@kimikage <kimikage_ceo@hotmail.com>
Sun, 18 Jul 2010 11:32:56 +0000 (20:32 +0900)
committerT2@kimikage <kimikage_ceo@hotmail.com>
Sun, 18 Jul 2010 11:32:56 +0000 (20:32 +0900)
20 files changed:
common/src/nslua.h [new file with mode: 0755]
nsdfont/src/ArgbArray.h [new file with mode: 0755]
nsdfont/src/ArgbBitmap.cpp [new file with mode: 0755]
nsdfont/src/ArgbBitmap.h [new file with mode: 0755]
nsdfont/src/CharacterMap.cpp [new file with mode: 0755]
nsdfont/src/CharacterMap.h [new file with mode: 0755]
nsdfont/src/Color.h [new file with mode: 0755]
nsdfont/src/ColorBlender.cpp [new file with mode: 0755]
nsdfont/src/ColorBlender.h [new file with mode: 0755]
nsdfont/src/Decorator.cpp [new file with mode: 0755]
nsdfont/src/Decorator.h [new file with mode: 0755]
nsdfont/src/Glyph.cpp [new file with mode: 0755]
nsdfont/src/Glyph.h [new file with mode: 0755]
nsdfont/src/Typesetter.cpp [new file with mode: 0755]
nsdfont/src/Typesetter.h [new file with mode: 0755]
nsdfont/src/UnicodeString.cpp [new file with mode: 0755]
nsdfont/src/UnicodeString.h [new file with mode: 0755]
nsdfont/src/main.cpp [new file with mode: 0755]
nsdfont/vs2005/nsdfont.sln [new file with mode: 0755]
nsdfont/vs2005/nsdfont.vcproj [new file with mode: 0755]

diff --git a/common/src/nslua.h b/common/src/nslua.h
new file mode 100755 (executable)
index 0000000..dff6275
--- /dev/null
@@ -0,0 +1,18 @@
+/*\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
diff --git a/nsdfont/src/ArgbArray.h b/nsdfont/src/ArgbArray.h
new file mode 100755 (executable)
index 0000000..65ced82
--- /dev/null
@@ -0,0 +1,38 @@
+/*\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
diff --git a/nsdfont/src/ArgbBitmap.cpp b/nsdfont/src/ArgbBitmap.cpp
new file mode 100755 (executable)
index 0000000..717cbeb
--- /dev/null
@@ -0,0 +1,35 @@
+/*\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
diff --git a/nsdfont/src/ArgbBitmap.h b/nsdfont/src/ArgbBitmap.h
new file mode 100755 (executable)
index 0000000..d753a84
--- /dev/null
@@ -0,0 +1,42 @@
+/*\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
diff --git a/nsdfont/src/CharacterMap.cpp b/nsdfont/src/CharacterMap.cpp
new file mode 100755 (executable)
index 0000000..9277180
--- /dev/null
@@ -0,0 +1,313 @@
+/*\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\82\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
diff --git a/nsdfont/src/CharacterMap.h b/nsdfont/src/CharacterMap.h
new file mode 100755 (executable)
index 0000000..0106e7f
--- /dev/null
@@ -0,0 +1,129 @@
+/*\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
diff --git a/nsdfont/src/Color.h b/nsdfont/src/Color.h
new file mode 100755 (executable)
index 0000000..96fbcc6
--- /dev/null
@@ -0,0 +1,116 @@
+/*\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
diff --git a/nsdfont/src/ColorBlender.cpp b/nsdfont/src/ColorBlender.cpp
new file mode 100755 (executable)
index 0000000..6926ce1
--- /dev/null
@@ -0,0 +1,51 @@
+/*\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
diff --git a/nsdfont/src/ColorBlender.h b/nsdfont/src/ColorBlender.h
new file mode 100755 (executable)
index 0000000..cd68b6b
--- /dev/null
@@ -0,0 +1,135 @@
+/*\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
diff --git a/nsdfont/src/Decorator.cpp b/nsdfont/src/Decorator.cpp
new file mode 100755 (executable)
index 0000000..fff1586
--- /dev/null
@@ -0,0 +1,180 @@
+/*\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
diff --git a/nsdfont/src/Decorator.h b/nsdfont/src/Decorator.h
new file mode 100755 (executable)
index 0000000..d822958
--- /dev/null
@@ -0,0 +1,59 @@
+/*\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
diff --git a/nsdfont/src/Glyph.cpp b/nsdfont/src/Glyph.cpp
new file mode 100755 (executable)
index 0000000..0686456
--- /dev/null
@@ -0,0 +1,225 @@
+/*\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
diff --git a/nsdfont/src/Glyph.h b/nsdfont/src/Glyph.h
new file mode 100755 (executable)
index 0000000..b1b7e71
--- /dev/null
@@ -0,0 +1,115 @@
+/*\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
diff --git a/nsdfont/src/Typesetter.cpp b/nsdfont/src/Typesetter.cpp
new file mode 100755 (executable)
index 0000000..c6bcba5
--- /dev/null
@@ -0,0 +1,88 @@
+/*\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
diff --git a/nsdfont/src/Typesetter.h b/nsdfont/src/Typesetter.h
new file mode 100755 (executable)
index 0000000..dd10760
--- /dev/null
@@ -0,0 +1,29 @@
+/*\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
diff --git a/nsdfont/src/UnicodeString.cpp b/nsdfont/src/UnicodeString.cpp
new file mode 100755 (executable)
index 0000000..8c7d289
--- /dev/null
@@ -0,0 +1,340 @@
+/*\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
diff --git a/nsdfont/src/UnicodeString.h b/nsdfont/src/UnicodeString.h
new file mode 100755 (executable)
index 0000000..d5d6e34
--- /dev/null
@@ -0,0 +1,47 @@
+/*\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
diff --git a/nsdfont/src/main.cpp b/nsdfont/src/main.cpp
new file mode 100755 (executable)
index 0000000..419e7a8
--- /dev/null
@@ -0,0 +1,176 @@
+/*\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\82\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
diff --git a/nsdfont/vs2005/nsdfont.sln b/nsdfont/vs2005/nsdfont.sln
new file mode 100755 (executable)
index 0000000..4396021
--- /dev/null
@@ -0,0 +1,20 @@
+\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
diff --git a/nsdfont/vs2005/nsdfont.vcproj b/nsdfont/vs2005/nsdfont.vcproj
new file mode 100755 (executable)
index 0000000..62e1907
--- /dev/null
@@ -0,0 +1,259 @@
+<?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&#x0D;&#x0A;copy /Y &quot;$(OutDir)\$(ProjectName).dll&quot; &quot;$(OutDir)/../../test/&quot; /B&#x0D;&#x0A;"\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