OSDN Git Service

NSDフォントプラグイン登録
[kimikage-nscr/kimikage-nscr.git] / nsdfont / src / Decorator.cpp
1 /*\r
2  *      Kimikage NScripter Plugins Project\r
3  *\r
4  *      This software is distributed under a BSD-style license.\r
5  *      See license.txt for more information.\r
6  */\r
7 \r
8 #include "Decorator.h"\r
9 #include <cmath>\r
10 \r
11 namespace nsdfont\r
12 {\r
13         Decorator::Decorator( void )\r
14         {\r
15                 face1 = Color( 0xFFFFFFFF );\r
16         }\r
17 \r
18         Decorator::~Decorator( void )\r
19         {\r
20         }\r
21 \r
22         void Decorator::setFace( const Color color )\r
23         {\r
24                 face1 = color;\r
25                 face2 = color;\r
26         }\r
27 \r
28         void Decorator::setEdge( const double width, const Color color )\r
29         {\r
30                 //  \r
31                 //     :\r
32                 //   l : l   l2,2l\r
33                 //   +-+-+---+---+\r
34                 //   l : l1,1l2,1l\r
35                 //   +-+-+---+---+---+\r
36                 // --+0,0+1,0+2,0+3,0+---->\r
37                 //   +-:-+---+---+---+\r
38                 //   | : l   l   l   |\r
39                 //     :\r
40                 \r
41                 // \83e\81[\83u\83\8b\8f\89\8aú\89»\r
42                 // \90³\95û\8c`\82Å\82 \82é\82±\82Æ\82ð\91O\92ñ\r
43                 const size_t tableSize = sizeof( edgePower ) / sizeof( edgePower[0] );\r
44                 for( size_t j = 0; j < tableSize; ++j )\r
45                 {\r
46                         for( size_t i = 0; i < tableSize; ++i )\r
47                         {\r
48                                 edgePower[j][i] = 0;\r
49                         }\r
50                 }\r
51 \r
52                 if ( width <= 1e-20 )\r
53                 {\r
54                         edgeWidth = 0.0;\r
55                         return;\r
56                 }\r
57 \r
58                 edge1 = color;\r
59                 exTop = exBottom = exLeft = exRight = static_cast<unsigned int>( std::ceil( edgeWidth ) );\r
60 \r
61                 const double r = width + rEqu; // \89~\82Ì\94¼\8ca\r
62                 const double s = rPi * r * r; // \89~\82Ì\96Ê\90Ï\r
63                 const double scale( edge1.getA() );\r
64                 if ( r <= rSqrt0_5 ) // (0.5,0.5)\93\9e\92B\82Ü\82Å\r
65                 {\r
66                         // a0 = SQRT(r^2-0.5^2) * 2   + 2*r^2*(\r
67                         //                                                  ASIN(0.5/r)-ACOS(0.5/r) \r
68                         //                                                                      + 0.5*SIN(2*ASIN(0.5/r))-0.5*SIN(2*ACOS(0.5/r))\r
69                         //                                            )\r
70                         const double a0 = 1.0 - 4.333 * (r - rSqrt0_5) * (r - rSqrt0_5); //2\8e\9f\8bß\8e\97\r
71                         const double a1 = 0.25 * (s - a0);\r
72                         edgePower[0][0] = static_cast<int>( a0 * scale );\r
73                         edgePower[1][0] = static_cast<int>( a1 * scale );\r
74                         edgePower[1][1] = 0;\r
75                         return;\r
76                 }\r
77                 if ( r <= 1.5 ) // (1.5,0.0)\93\9e\92B\82Ü\82Å\r
78                 {\r
79                         // b0 = 0.5*SQRT(r^2-0.5^2)-0.5+r^2*ASIN(0.5/r)\r
80 \r
81                         const double b0 = 1.0422359371 * r - 0.5878914747; //1\8e\9f\8bß\8e\97\r
82                         const double b1 = 0.25 * (s - 1.0) - b0;\r
83                         edgePower[0][0] = static_cast<int>( scale );\r
84                         edgePower[1][0] = static_cast<int>( b0 * scale );\r
85                         edgePower[1][1] = static_cast<int>( b1 * scale );\r
86                         return;\r
87                 }\r
88                 \r
89         }\r
90 \r
91         void Decorator::drawFace( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const\r
92         {\r
93                 if ( glyph.getBufferSize() <= 0 ) return;\r
94 \r
95                 drawCoreSimple( x, y, bmp, glyph, face1 );\r
96         }\r
97 \r
98         void Decorator::drawCoreSimple( int x, int y, ArgbBitmap &bmp, const Glyph &glyph, const Color color ) const\r
99         {\r
100                 // \8a®\91S\82É\93§\96¾\82È\82ç\95`\89æ\82µ\82È\82¢\r
101                 if ( color.getA() == 0 ) return;\r
102 \r
103                 x += exLeft;\r
104                 y += exTop;\r
105                 \r
106                 int width, height;\r
107                 unsigned char *src = clip( x, y, width, height, bmp, glyph );\r
108 \r
109                 for( int j = 0; j < height; ++j )\r
110                 {\r
111                         ArgbArray dest = bmp.getArray( x, y + j );\r
112                         for( int i = 0; i < width; ++i )\r
113                         {\r
114                                 if ( src[i] == 0 ) continue;\r
115                                 const Color face( color.getArgb(), blend.mul( color.getA(), src[i] ) );\r
116                                 dest[i] = blend.merge( dest[i], face );\r
117                         }\r
118                         src += glyph.getPitch();\r
119                 }\r
120         }\r
121 \r
122         void Decorator::drawEdge( int x, int y, ArgbBitmap &bmp, const Glyph &glyph ) const\r
123         {\r
124                 if ( glyph.getBufferSize() <= 0 ) return;\r
125 \r
126                 const Color c00( edge1.getArgb(), edgePower[0][0] );\r
127                 const Color c10( edge1.getArgb(), edgePower[1][0] );\r
128                 const Color c11( edge1.getArgb(), edgePower[1][1] );\r
129 \r
130                 drawCoreSimple( x-1, y-1, bmp, glyph, c11 ); // \8d\8fã\r
131                 drawCoreSimple( x+0, y-1, bmp, glyph, c10 ); // \92\86\8fã\r
132                 drawCoreSimple( x+1, y-1, bmp, glyph, c11 ); // \89E\8fã\r
133                 drawCoreSimple( x-1, y+0, bmp, glyph, c10 ); // \8d\92\86\r
134                 drawCoreSimple( x+0, y+0, bmp, glyph, c00 ); // \92\86\92\86\r
135                 drawCoreSimple( x+1, y+0, bmp, glyph, c10 ); // \89E\92\86\r
136                 drawCoreSimple( x-1, y+1, bmp, glyph, c11 ); // \8d\89º\r
137                 drawCoreSimple( x+0, y+1, bmp, glyph, c10 ); // \92\86\89º\r
138                 drawCoreSimple( x+1, y+1, bmp, glyph, c11 ); // \89E\89º\r
139                 if ( edgePower[2][0] > 0 )\r
140                 {\r
141                         \r
142                 }\r
143                 return;\r
144         }\r
145 \r
146         unsigned char *Decorator::clip( int &x, int &y, int &width, int &height, \r
147                                         const ArgbBitmap &bmp, const Glyph&glyph ) const\r
148         {\r
149                 width = glyph.getWidth();\r
150                 height = glyph.getHeight();\r
151                 unsigned char *src = glyph.getBuffer();\r
152 \r
153                 if ( x < 0 ) //(\8d\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
154                 {\r
155                         width += x;\r
156                         src -= x;\r
157                         x = 0;\r
158                 }\r
159                 if ( y < 0 ) //(\8fã\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
160                 {\r
161                         height += y;\r
162                         src -= y * glyph.getPitch();\r
163                         y = 0;\r
164                 }\r
165                 if ( x + width > bmp.getWidth() ) //(\89E\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
166                 {\r
167                         width = bmp.getWidth() - x;\r
168                 }\r
169                 if ( y + height > bmp.getHeight() ) //(\89º\82É\82Í\82Ý\8fo\82Ä\82¢\82é)\r
170                 {\r
171                         height = bmp.getHeight() - y;\r
172                 }\r
173                 return src;\r
174         }\r
175 \r
176 \r
177         const double Decorator::rPi( 3.14159265358979323846 ); // pi\r
178         const double Decorator::rEqu( 0.564189583547756286948 ); // sqrt( 1 / pi )\r
179         const double Decorator::rSqrt0_5( 0.7071067811865475244 ); // sqrt( 0.5 )\r
180 }\r