drawing.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
33 #ifndef __INCLUDE_MIST_DRAWING__
34 #define __INCLUDE_MIST_DRAWING__
35 
36 
37 #ifndef __INCLUDE_MIST_H__
38 #include "mist.h"
39 #endif
40 
41 #ifndef __INCLUDE_BITMAP_H__
42 #include "bitmap.h"
43 #endif
44 
45 #include <cmath>
46 
47 #ifdef MIST_USE_DRAW_TEXT
48 #include <ft2build.h>
49 #include FT_FREETYPE_H
50 #endif
51 
52 
53 // mist名前空間の始まり
55 
56 
57 
58 
66 
67 
68 
80 template < class T, class Allocator >
87 {
88  typedef typename array2< T, Allocator >::difference_type difference_type;
89  difference_type dx, dy;
90  difference_type sx, sy;
91  difference_type x, y, e, i;
92  difference_type w = static_cast< difference_type >( image.width( ) );
93  difference_type h = static_cast< difference_type >( image.height( ) );
94 
95  dx = std::abs( static_cast< int >( x2 - x1 ) );
96  dy = std::abs( static_cast< int >( y2 - y1 ) );
97  sx = ( x2 - x1 >= 0 ) ? 1 : -1;
98  sy = ( y2 - y1 >= 0 ) ? 1 : -1;
99  x = x1;
100  y = y1;
101  if( dx >= dy )
102  {
103  e = -dx;
104  for( i = 0 ; i <= dx ; i++ )
105  {
106  if( x >= 0 && x < w && y >= 0 && y < h )
107  {
108  image( x, y ) = color;
109  }
110  x += sx;
111  e += 2 * dy;
112 
113  if( e >= 0 )
114  {
115  y += sy;
116  e -= 2 * dx;
117  }
118  }
119  }
120  else
121  {
122  e = -dy;
123  for( i = 0 ; i <= dy ; i++ )
124  {
125  if( x >= 0 && x < w && y >= 0 && y < h )
126  {
127  image( x, y ) = color;
128  }
129  y += sy;
130  e += 2 * dx;
131  if( e >= 0 )
132  {
133  x += sx;
134  e -= 2 * dy;
135  }
136  }
137  }
138 }
139 
140 
141 
153 template < size_t BITS >
160 {
161  typedef typename bitmap< BITS >::difference_type difference_type;
162  difference_type dx, dy;
163  difference_type sx, sy;
164  difference_type x, y, e, i;
165  difference_type w = static_cast< difference_type >( image.width( ) );
166  difference_type h = static_cast< difference_type >( image.height( ) );
167 
168  dx = std::abs( static_cast< int >( x2 - x1 ) );
169  dy = std::abs( static_cast< int >( y2 - y1 ) );
170  sx = ( x2 - x1 >= 0 ) ? 1 : -1;
171  sy = ( y2 - y1 >= 0 ) ? 1 : -1;
172  x = x1;
173  y = y1;
174  if( dx >= dy )
175  {
176  e = -dx;
177  for( i = 0 ; i <= dx ; i++ )
178  {
179  if( x >= 0 && x < w && y >= 0 && y < h )
180  {
181  image( x, y ) = color;
182  }
183  x += sx;
184  e += 2 * dy;
185 
186  if( e >= 0 )
187  {
188  y += sy;
189  e -= 2 * dx;
190  }
191  }
192  }
193  else
194  {
195  e = -dy;
196  for( i = 0 ; i <= dy ; i++ )
197  {
198  if( x >= 0 && x < w && y >= 0 && y < h )
199  {
200  image( x, y ) = color;
201  }
202  y += sy;
203  e += 2 * dx;
204  if( e >= 0 )
205  {
206  x += sx;
207  e -= 2 * dy;
208  }
209  }
210  }
211 }
212 
213 
214 
228 template < class T, class Allocator >
237 {
238  typedef typename array3< T, Allocator >::difference_type difference_type;
239  difference_type dx, dy, dz;
240  difference_type sx, sy, sz;
241  difference_type x, y, z, e1, e2, i;
242  difference_type w = static_cast< difference_type >( image.width( ) );
243  difference_type h = static_cast< difference_type >( image.height( ) );
244  difference_type d = static_cast< difference_type >( image.depth( ) );
245 
246  dx = std::abs( static_cast< int >( x2 - x1 ) );
247  dy = std::abs( static_cast< int >( y2 - y1 ) );
248  dz = std::abs( static_cast< int >( z2 - z1 ) );
249  sx = ( x2 - x1 >= 0 ) ? 1 : -1;
250  sy = ( y2 - y1 >= 0 ) ? 1 : -1;
251  sz = ( z2 - z1 >= 0 ) ? 1 : -1;
252  x = x1;
253  y = y1;
254  z = z1;
255  if( dx >= dy && dx >= dz )
256  {
257  e1 = e2 = -dx;
258  for( i = 0 ; i <= dx ; i++ )
259  {
260  if( x >= 0 && x < w && y >= 0 && y < h && z >= 0 && z < d )
261  {
262  image( x, y, z ) = color;
263  }
264  x += sx;
265  e1 += 2 * dy;
266  e2 += 2 * dz;
267 
268  if( e1 >= 0 )
269  {
270  y += sy;
271  e1 -= 2 * dx;
272  }
273 
274  if( e2 >= 0 )
275  {
276  z += sz;
277  e2 -= 2 * dx;
278  }
279  }
280  }
281  else if( dy >= dx && dy >= dz )
282  {
283  e1 = e2 = -dy;
284  for( i = 0 ; i <= dy ; i++ )
285  {
286  if( x >= 0 && x < w && y >= 0 && y < h && z >= 0 && z < d )
287  {
288  image( x, y, z ) = color;
289  }
290  y += sy;
291  e1 += 2 * dx;
292  e2 += 2 * dz;
293 
294  if( e1 >= 0 )
295  {
296  x += sx;
297  e1 -= 2 * dy;
298  }
299 
300  if( e2 >= 0 )
301  {
302  z += sz;
303  e2 -= 2 * dy;
304  }
305  }
306  }
307  else
308  {
309  e1 = e2 = -dz;
310  for( i = 0 ; i <= dz ; i++ )
311  {
312  if( x >= 0 && x < w && y >= 0 && y < h && z >= 0 && z < d )
313  {
314  image( x, y, z ) = color;
315  }
316  z += sz;
317  e1 += 2 * dx;
318  e2 += 2 * dy;
319 
320  if( e1 >= 0 )
321  {
322  x += sx;
323  e1 -= 2 * dz;
324  }
325 
326  if( e2 >= 0 )
327  {
328  y += sy;
329  e2 -= 2 * dz;
330  }
331  }
332  }
333 }
334 
335 
336 
347 template < class T, class Allocator >
353 {
354  typedef typename array2< T, Allocator >::difference_type difference_type;
355 
356  difference_type is = x - radius;
357  difference_type ie = x + radius;
358  difference_type js = y - radius;
359  difference_type je = y + radius;
360 
361  difference_type w = static_cast< difference_type >( image.width( ) );
362  difference_type h = static_cast< difference_type >( image.height( ) );
363 
364  if( is < 0 )
365  {
366  is = 0;
367  }
368  if( is >= w )
369  {
370  is = w;
371  ie = w - 1;
372  }
373  if( ie < 0 )
374  {
375  is = 0;
376  ie = -1;
377  }
378  if( ie >= w )
379  {
380  ie = w - 1;
381  }
382 
383  if( js < 0 )
384  {
385  js = 0;
386  }
387  if( js >= h )
388  {
389  js = h;
390  je = h - 1;
391  }
392  if( je < 0 )
393  {
394  js = 0;
395  je = -1;
396  }
397  if( je >= h )
398  {
399  je = h - 1;
400  }
401 
402  for( difference_type j = js ; j <= je ; j++ )
403  {
404  for( difference_type i = is ; i <= ie ; i++ )
405  {
406  image( i, j ) = value;
407  }
408  }
409 }
410 
411 
423 template < class T, class Allocator >
430 {
431  typedef typename array3< T, Allocator >::difference_type difference_type;
432 
433  difference_type is = x - radius;
434  difference_type ie = x + radius;
435  difference_type js = y - radius;
436  difference_type je = y + radius;
437  difference_type ks = z - radius;
438  difference_type ke = z + radius;
439 
440  difference_type w = static_cast< difference_type >( image.width( ) );
441  difference_type h = static_cast< difference_type >( image.height( ) );
442  difference_type d = static_cast< difference_type >( image.depth( ) );
443 
444  if( is < 0 )
445  {
446  is = 0;
447  }
448  if( is >= w )
449  {
450  is = w;
451  ie = w - 1;
452  }
453  if( ie < 0 )
454  {
455  is = 0;
456  ie = -1;
457  }
458  if( ie >= w )
459  {
460  ie = w - 1;
461  }
462 
463  if( js < 0 )
464  {
465  js = 0;
466  }
467  if( js >= h )
468  {
469  js = h;
470  je = h - 1;
471  }
472  if( je < 0 )
473  {
474  js = 0;
475  je = -1;
476  }
477  if( je >= h )
478  {
479  je = h - 1;
480  }
481 
482  if( ks < 0 )
483  {
484  ks = 0;
485  }
486  if( ks >= d )
487  {
488  ks = d;
489  ke = d - 1;
490  }
491  if( ke < 0 )
492  {
493  ks = 0;
494  ke = -1;
495  }
496  if( ke >= d )
497  {
498  ke = d - 1;
499  }
500 
501  for( difference_type k = ks ; k <= ke ; k++ )
502  {
503  for( difference_type j = js ; j <= je ; j++ )
504  {
505  for( difference_type i = is ; i <= ie ; i++ )
506  {
507  image( i, j, k ) = value;
508  }
509  }
510  }
511 }
512 
518 template< typename T, typename Allocator >
522  const typename array2< T, Allocator >::value_type &value )
523 {
524  typedef typename array2< T, Allocator >::difference_type difference_type;
525 
526  // 範囲チェック
527  if( x < 0 || y < 0 || x >= static_cast< difference_type >( image.width( ) ) || y >= static_cast< difference_type >( image.height( ) ) )
528  {
529  return;
530  }
531 
532  image( x, y ) = value;
533 }
534 
541 template< typename T, typename Allocator >
546  const typename array2< T, Allocator >::value_type &value )
547 {
548  typename array2< T, Allocator >::difference_type d = 3 - 2 * r;
551 
552  // 開始点
553  set_pixel( image, cx, cy + r, value );
554  set_pixel( image, cx, cy - r, value );
555  set_pixel( image, cx + r, cy, value );
556  set_pixel( image, cx - r, cy, value );
557 
558  for( dx = 0 ; dx <= dy ; ++dx )
559  {
560  if( d < 0 )
561  {
562  d += 6 + 4 * dx;
563  }
564  else
565  {
566  d += 10 + 4 * dx - 4 * dy--;
567  }
568 
569  set_pixel( image, cx + dy, cy + dx, value );
570  set_pixel( image, cx + dx, cy + dy, value );
571  set_pixel( image, cx - dx, cy + dy, value );
572  set_pixel( image, cx - dy, cy + dx, value );
573  set_pixel( image, cx - dy, cy - dx, value );
574  set_pixel( image, cx - dx, cy - dy, value );
575  set_pixel( image, cx + dx, cy - dy, value );
576  set_pixel( image, cx + dy, cy - dx, value );
577  }
578 }
579 
587 template< typename T, typename Allocator >
593  const typename array2< T, Allocator >::value_type &value )
594 {
595  draw_line( image, x0, y0, x1, y0, value );
596  draw_line( image, x0, y0, x0, y1, value );
597  draw_line( image, x1, y0, x1, y1, value );
598  draw_line( image, x0, y1, x1, y1, value );
599 }
600 
608 template< typename T, typename Allocator >
614  const typename array2< T, Allocator >::value_type &value )
615 {
616  typedef typename array2< T, Allocator >::difference_type difference_type;
617 
618  x0 = ( 0 < x0 ) ? x0 : 0;
619  y0 = ( 0 < y0 ) ? y0 : 0;
620  x1 = ( x1 < static_cast< difference_type >( image.width() - 1 ) ) ? x1 : static_cast< difference_type >( image.width() - 1 );
621  y1 = ( y1 < static_cast< difference_type >( image.height() - 1 ) ) ? y1 : static_cast< difference_type >( image.height() - 1 );
622 
623  for( difference_type y = y0 ; y <= y1 ; ++y )
624  {
625  for( difference_type x = x0 ; x <= x1 ; ++x )
626  {
627  image( x, y ) = value;
628  }
629  }
630 }
631 
638 template< typename T, typename Allocator >
643  const typename array2< T, Allocator >::value_type &value )
644 {
645  draw_line( image, cx - size / 2, cy, cx + size / 2, cy, value );
646  draw_line( image, cx, cy - size / 2, cx, cy + size / 2, value );
647 }
648 
649 
650 
651 #ifdef MIST_USE_DRAW_TEXT
652 
653 
671 template < typename T, typename Allocator >
672 inline bool draw_text( array2< T, Allocator > &img,
673  char *filename,
674  int px,
675  int py,
676  int size,
677  typename array2< T, Allocator >::value_type color,
678  unsigned long *str,
679  int len )
680 {
681 
682  FT_Library library = NULL;
683  FT_Face face = NULL;
684  FT_Error error;
685 
686  try
687  {
688  error = FT_Init_FreeType( &library );
689  if ( error )
690  {
691  library = NULL;
692  throw error;
693  }
694 
695  error = FT_New_Face( library, filename, 0, &face );
696  if ( error )
697  {
698  face = NULL;
699  throw error;
700  }
701 
702  error = FT_Set_Pixel_Sizes( face, 0, size );
703  if ( error )
704  {
705  throw error;
706  }
707 
708  int pen_x = px;
709  int pen_y = py;
710  for ( int i = 0; i < len; i++)
711  {
712  FT_UInt glyph_index = FT_Get_Char_Index( face, (FT_ULong)str[i] );
713 
714  error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
715  if ( error )
716  {
717  throw error;
718  }
719 
720  error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
721  if ( error )
722  {
723  throw error;
724  }
725 
726  for (int x = 0; x < face->glyph->bitmap.width; x++)
727  {
728  for (int y = 0; y < face->glyph->bitmap.rows; y++)
729  {
730  int xx = x + pen_x + face->glyph->bitmap_left;
731  int yy = y + pen_y - face->glyph->bitmap_top;
732  if ( ( 0 <= xx ) && ( xx < (int)img.width() ) && ( 0 <= yy ) && ( yy < (int)img.height() ) )
733  {
734  // alpha blending
735  T img_value = img(xx, yy);
736  double str_value = static_cast< double > ( face->glyph->bitmap.buffer[ x + y * face->glyph->bitmap.width] ) / 255.0;
737  img(xx, yy) = static_cast< typename array2<T>::value_type > ( str_value * color + (1.0 - str_value) * img_value );
738  }
739  }
740  }
741  pen_x += face->glyph->advance.x >> 6;
742 
743  }
744 
745  FT_Done_Face(face);
746  FT_Done_FreeType(library);
747 
748  }
749  catch ( ... )
750  {
751  if (face != NULL)
752  {
753  FT_Done_Face(face);
754  }
755  if (library != NULL)
756  {
757  FT_Done_FreeType(library);
758  }
759  return false;
760  }
761 
762  return true;
763 
764 }
765 
766 
767 
784 template < typename T, typename Allocator >
785 inline bool draw_text( array2< T, Allocator > &img,
786  char *filename,
787  int px,
788  int py,
789  int size,
790  typename array2< T, Allocator >::value_type color,
791  char *str )
792 {
793  int len = strlen(str);
794 
795  unsigned long *str_ulong = new unsigned long[len];
796 
797  for (int i = 0; i < len; i++)
798  {
799  str_ulong[i] = (FT_ULong)str[i];
800  }
801 
802  bool result = draw_text( img, filename, px, py, size, color, str_ulong, len );
803 
804  delete []str_ulong;
805 
806  return result;
807 
808 }
809 
810 
811 #endif // MIST_USE_DRAW_TEXT
812 
813 
815 // 直線や円の描画グループの終わり
816 
817 
818 // mist名前空間の終わり
819 _MIST_END
820 
821 
822 #endif // __INCLUDE_MIST_DRAWING__
823 

Generated on Wed Nov 12 2014 19:44:14 for MIST by doxygen 1.8.1.2