IDrawStr.c
资源名称:ilib [点击查看]
上传用户:changbiao
上传日期:2007-01-13
资源大小:141k
文件大小:11k
源码类别:

图片显示

开发平台:

C/C++

  1. /*
  2.  * IDrawStr.c
  3.  *
  4.  * Image library
  5.  *
  6.  * Description:
  7.  * Portable routines to manipulate raster images.
  8.  *
  9.  * History:
  10.  * 21-Jan-00 Geovan Rodriguez <geovan@cigb.edu.cu>
  11.  * Added IDrawStringRotatedAngle()
  12.  * 23-Aug-99 Craig Knudsen cknudsen@radix.net
  13.  * Added support for text styles:
  14.  * ITEXT_NORMAL, ITEXT_ETCHED_IN, 
  15.  * ITEXT_ETCHED_OUT, ITEXT_SHADOWED
  16.  * 21-Aug-99 Craig Knudsen cknudsen@radix.net
  17.  * Added IDrawStringRotated()
  18.  * Removed anti-aliasing stuff since it didn't really
  19.  * work.  Eventually, true type fonts will be used
  20.  * for this (FreeType lib).
  21.  * 18-May-98 Craig Knudsen cknudsen@radix.net
  22.  * Added support for anti-aliasing fonts by using a
  23.  * font 2X bigger than we need.
  24.  * 20-May-96 Craig Knudsen cknudsen@radix.net
  25.  * Created
  26.  *
  27.  ****************************************************************************/
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <ctype.h>
  31. #include <memory.h>
  32. #include <math.h>
  33. #include "Ilib.h"
  34. #include "IlibP.h"
  35. #include "IFontBDF.h"
  36. #define SPACES_PER_TAB 8
  37. static IError draw_string_rotated_90 (
  38. #ifndef _NO_PROTO
  39.   IImage image,
  40.   IGC gc,
  41.   int x,
  42.   int y,
  43.   char *text,
  44.   unsigned int len,
  45.   ITextDirection direction
  46. #endif
  47. );
  48. IError IDrawString ( image, gc, x, y, text, len )
  49. IImage image;
  50. IGC gc;
  51. int x;
  52. int y;
  53. char *text;
  54. unsigned int len;
  55. {
  56.   return IDrawStringRotated ( image, gc, x, y, text, len, ITEXT_LEFT_TO_RIGHT );
  57. }
  58. /* calculate values for topshadow and bottomshadow */
  59. static void make_top_and_bottom_shadow ( incolorp, top, bottom )
  60. IColorP *incolorp;
  61. IColor *top, *bottom;
  62. {
  63.   unsigned int topr, topg, topb, bottomr, bottomg, bottomb;
  64.   if ( incolorp == NULL ) {
  65.     *top = 0;
  66.     *bottom = 1;
  67.   } else {
  68.     topr = incolorp->red > 205 ? 255 : incolorp->red + 50;
  69.     topg = incolorp->green > 205 ? 255 : incolorp->green + 50;
  70.     topb = incolorp->blue > 205 ? 255 : incolorp->blue + 50;
  71.     *top = IAllocColor ( topr, topg, topb );
  72.     bottomr = incolorp->red < 50 ? 0 : incolorp->red - 50;
  73.     bottomg = incolorp->green < 50 ? 0 : incolorp->green - 50;
  74.     bottomb = incolorp->blue < 50 ? 0 : incolorp->blue - 50;
  75.     *bottom = IAllocColor ( bottomr, bottomg, bottomb );
  76.   }
  77. }
  78. /* calculate values for shadows  */
  79. static void make_shadows ( incolorp, shadows, nshadows )
  80. IColorP *incolorp;
  81. IColor *shadows;
  82. int nshadows;
  83. {
  84.   unsigned int rinc, ginc, binc, rstart, gstart, bstart;
  85.   int loop;
  86.   rstart = ( incolorp->red / 2 );
  87.   gstart = ( incolorp->green / 2 );
  88.   bstart = ( incolorp->blue / 2 );
  89.   if ( incolorp != NULL ) {
  90.     rinc = ( incolorp->red - rstart ) / nshadows;
  91.     ginc = ( incolorp->green - gstart ) / nshadows;
  92.     binc = ( incolorp->blue - bstart ) / nshadows;
  93.     for ( loop = 0; loop < nshadows; loop++ )
  94.       shadows[loop] = IAllocColor ( rstart + rinc * loop,
  95.         gstart + ginc * loop, bstart + binc * loop );
  96.   }
  97. }
  98. IError IDrawStringRotated ( image, gc, x, y, text, len, direction )
  99. IImage image;
  100. IGC gc;
  101. int x;
  102. int y;
  103. char *text;
  104. unsigned int len;
  105. ITextDirection direction;
  106. {
  107.   IGCP *gcp = (IGCP *)gc;
  108.   IError ret = INoError;
  109.   IColor shadows[20], top, bottom;
  110.   IColorP *fgsave;
  111.   int loop, nshadows;
  112.   unsigned int font_height;
  113.   if ( ! gcp )
  114.     return ( IInvalidGC );
  115.   fgsave = gcp->foreground;
  116.   switch ( gcp->text_style ) {
  117.     case ITEXT_NORMAL:
  118.       ret = draw_string_rotated_90 ( image, gc, x, y, text, len, direction );
  119.       break;
  120.     case ITEXT_ETCHED_IN:
  121.     case ITEXT_ETCHED_OUT:
  122.       if ( gcp->background != NULL ) {
  123.         if ( gcp->text_style == ITEXT_ETCHED_OUT )
  124.           make_top_and_bottom_shadow ( gcp->background, &top, &bottom );
  125.         else
  126.           make_top_and_bottom_shadow ( gcp->background, &bottom, &top );
  127.         ISetForeground ( gc, top );
  128.         ret = draw_string_rotated_90 ( image, gc, x - 1, y - 1,
  129.           text, len, direction );
  130.         if ( ! ret ) {
  131.           ISetForeground ( gc, bottom );
  132.           ret = draw_string_rotated_90 ( image, gc, x + 1, y + 1,
  133.             text, len, direction );
  134.         }
  135.       }
  136.       if ( ! ret ) {
  137.         gcp->foreground = gcp->background;
  138.         ret = draw_string_rotated_90 ( image, gc, x, y,
  139.           text, len, direction );
  140.       }
  141.       break;
  142.     case ITEXT_SHADOWED:
  143.       if ( gcp->background != NULL ) {
  144.         IFontSize ( (IFont)gcp->font, &font_height );
  145.         nshadows = font_height / 5;
  146.         make_shadows ( gcp->background, shadows, nshadows );
  147.         gcp->foreground = fgsave;
  148.         for ( loop = nshadows; loop > 0; loop-- ) {
  149.           ISetForeground ( gc, shadows[loop-1] );
  150.           ret = draw_string_rotated_90 ( image, gc, x + loop, y + loop,
  151.             text, len, direction );
  152.         }
  153.         gcp->foreground = fgsave;
  154.       }
  155.       if ( ! ret )
  156.         ret = draw_string_rotated_90 ( image, gc, x, y, text, len, direction );
  157.       break;
  158.   }
  159.   gcp->foreground = fgsave;
  160.   return ( ret );
  161. }
  162. static IError draw_string_rotated_90 ( image, gc, x, y, text, len, direction )
  163. IImage image;
  164. IGC gc;
  165. int x;
  166. int y;
  167. char *text;
  168. unsigned int len;
  169. ITextDirection direction;
  170. {
  171.   IGCP *gcp = (IGCP *)gc;
  172.   IImageP *imagep = (IImageP *)image;
  173.   unsigned int *bitdata;
  174.   unsigned int height, width, actual_width, size, font_height;
  175.   int xoffset, yoffset, charx, chary;
  176.   char ch[256], *ptr;
  177.   int loop, loop2, loop3;
  178.   IError ret;
  179.   int myx, myy;
  180.   int char_num = 0;
  181.   if ( ! gcp )
  182.     return ( IInvalidGC );
  183.   if ( gcp->magic != IMAGIC_GC )
  184.     return ( IInvalidGC );
  185.   if ( ! imagep )
  186.     return ( IInvalidImage );
  187.   if ( imagep->magic != IMAGIC_IMAGE )
  188.     return ( IInvalidImage );
  189.   if ( ! gcp->font )
  190.     return ( INoFontSet );
  191.   charx = x;
  192.   chary = y;
  193.   IFontSize ( (IFont)gcp->font, &font_height );
  194.   for ( ptr = text, loop = 0; loop < len; loop++, ptr++ ) {
  195.     if ( *ptr == '12' ) {
  196.       switch ( direction ) {
  197.         case ITEXT_LEFT_TO_RIGHT:
  198.           charx = x;
  199.           chary += font_height;
  200.           break;
  201.         case ITEXT_TOP_TO_BOTTOM:
  202.           chary = y;
  203.           charx -= font_height;
  204.           break;
  205.         case ITEXT_BOTTOM_TO_TOP:
  206.           chary = y;
  207.           charx += font_height;
  208.           break;
  209.       }
  210.       char_num = 0;
  211.       continue;
  212.     }
  213.     else if ( *ptr == 't' ) {
  214.       ret = IFontBDFGetChar ( gcp->font->name, ch, &bitdata, &width, &height,
  215.         &actual_width, &size, &xoffset, &yoffset );
  216.       switch ( direction ) {
  217.         case ITEXT_LEFT_TO_RIGHT:
  218.           charx += ( 8 - ( char_num % 8 ) ) * actual_width;
  219.           break;
  220.         case ITEXT_TOP_TO_BOTTOM:
  221.           chary -= ( 8 - ( char_num % 8 ) ) * actual_width;
  222.           break;
  223.         case ITEXT_BOTTOM_TO_TOP:
  224.           chary += ( 8 - ( char_num % 8 ) ) * actual_width;
  225.           break;
  226.       }
  227.       continue;
  228.     }
  229.     else if ( *ptr != '33' ) {
  230.       ch[0] = *ptr;
  231.       ch[1] = '';
  232.     }
  233.     else {
  234.       loop2 = 0;
  235.       ptr++;
  236.       while ( *ptr != ';' && loop < len && loop2 < 256 ) {
  237.         ch[loop2] = *ptr;
  238.         ptr++;
  239.         loop++;
  240.         loop2++;
  241.       }
  242.       ch[loop2] = '';
  243.       if ( *ptr != ';' ) {
  244.         return ( IInvalidEscapeSequence );
  245.       }
  246.     }
  247.     ret = IFontBDFGetChar ( gcp->font->name, ch, &bitdata, &width, &height,
  248.       &actual_width, &size, &xoffset, &yoffset );
  249.     if ( ! ret ) {
  250.       for ( loop3 = 0; loop3 < height; loop3++ ) {
  251.         switch ( direction ) {
  252.           case ITEXT_LEFT_TO_RIGHT:
  253.             myy = chary - ( height + yoffset ) + loop3;
  254.             for ( loop2 = 0; loop2 < width; loop2++ ) {
  255.               if ( bitdata[loop3 * width + loop2] ) {
  256.                 myx = charx + xoffset + loop2;
  257.                 _ISetPoint ( imagep, gcp, myx, myy );
  258.               }
  259.             }
  260.             break;
  261.           case ITEXT_TOP_TO_BOTTOM:
  262.             myx = charx + ( height + yoffset ) - loop3;
  263.             for ( loop2 = 0; loop2 < width; loop2++ ) {
  264.               if ( bitdata[loop3 * width + loop2] ) {
  265.                 myy = chary + xoffset + loop2;
  266.                 _ISetPoint ( imagep, gcp, myx, myy );
  267.               }
  268.             }
  269.             break;
  270.           case ITEXT_BOTTOM_TO_TOP:
  271.             myx = charx - ( height + yoffset ) + loop3;
  272.             for ( loop2 = 0; loop2 < width; loop2++ ) {
  273.               if ( bitdata[loop3 * width + loop2] ) {
  274.                 myy = chary - xoffset - loop2;
  275.                 _ISetPoint ( imagep, gcp, myx, myy );
  276.               }
  277.             }
  278.             break;
  279.         }
  280.       }
  281.       switch ( direction ) {
  282.         case ITEXT_LEFT_TO_RIGHT:
  283.           charx += actual_width;
  284.           break;
  285.         case ITEXT_TOP_TO_BOTTOM:
  286.           chary += actual_width;
  287.           break;
  288.         case ITEXT_BOTTOM_TO_TOP:
  289.           chary -= actual_width;
  290.           break;
  291.       }
  292.       char_num++;
  293.     }
  294.   }
  295.   return ( INoError );
  296. }
  297. IError IDrawStringRotatedAngle ( image, gc, x, y, text, len, angle )
  298. IImage image;
  299. IGC gc;
  300. int x;
  301. int y;
  302. char *text;
  303. unsigned int len;
  304. double angle;
  305. {
  306.   IGCP *gcp = (IGCP *)gc;
  307.   IImageP *imagep = (IImageP *)image;
  308.   unsigned int *bitdata;
  309.   unsigned int height, width, actual_width, size, font_height;
  310.   int xoffset, yoffset, charx, chary;
  311.   char ch[256], *ptr;
  312.   int loop, loop2, loop3;
  313.   IError ret;
  314.   int myx, myy;
  315.   int char_num = 0;
  316.   double x1, y1, x2, y2;
  317.   int alpha;
  318.     
  319.   if ( ! gcp )
  320.     return ( IInvalidGC );
  321.   if ( gcp->magic != IMAGIC_GC )
  322.     return ( IInvalidGC );
  323.   if ( ! imagep )
  324.     return ( IInvalidImage );
  325.   if ( imagep->magic != IMAGIC_IMAGE )
  326.     return ( IInvalidImage );
  327.   if ( ! gcp->font )
  328.     return ( INoFontSet );
  329.   charx = x;
  330.   chary = y;
  331.   IFontSize ( (IFont)gcp->font, &font_height );
  332.   for ( ptr = text, loop = 0; loop < len; loop++, ptr++ ) {
  333.     
  334.     if ( *ptr == '12' ) {
  335.       chary += font_height;
  336.       charx = x;
  337.       char_num = 0;
  338.       continue;
  339.     }
  340.     else if ( *ptr == 't' ) {
  341.       ret = IFontBDFGetChar ( gcp->font->name, ch, &bitdata, &width, &height,
  342.         &actual_width, &size, &xoffset, &yoffset );
  343.       chary += ( 8 - ( char_num % 8 ) ) * actual_width;
  344.       continue;
  345.     }
  346.     else if ( *ptr != '33' ) {
  347.       ch[0] = *ptr;
  348.       ch[1] = '';
  349.     }
  350.     else {
  351.       loop2 = 0;
  352.       ptr++;
  353.       while ( *ptr != ';' && loop < len && loop2 < 256 ) {
  354.         ch[loop2] = *ptr;
  355.         ptr++;
  356.         loop++;
  357.         loop2++;
  358.       }
  359.       ch[loop2] = '';
  360.       
  361.       if ( *ptr != ';' ) {
  362.         return ( IInvalidEscapeSequence );
  363.       }
  364.     }
  365.     
  366.     ret = IFontBDFGetChar ( gcp->font->name, ch, &bitdata, &width, &height,
  367.       &actual_width, &size, &xoffset, &yoffset );
  368.     alpha=angle;
  369.           
  370.     if ( ! ret ) {
  371.       for ( loop3 = 0; loop3 < height; loop3++ ) {
  372.         for ( loop2 = 0; loop2 < width; loop2++ ) {
  373.           if ( bitdata[loop3 * width + loop2] ) {
  374.             x1 = loop2 + xoffset;
  375.             y1 = loop3 + size - height;
  376.             x2 = x1 * cos ( alpha * M_PI / 180 ) +
  377.               y1 * sin ( alpha * M_PI / 180 );
  378.             y2 = -1 * x1 * sin ( alpha * M_PI / 180 ) +
  379.               y1 * cos ( alpha * M_PI / 180 );
  380.             myy = chary - (size + yoffset ) + y2;
  381.             myx = charx + x2;
  382.             _ISetPoint ( imagep, gcp, myx, myy );
  383.           }
  384.         }  
  385.       }
  386.       x1 = actual_width+xoffset;      
  387.       y1 = 0;      
  388.       x2 = x1 * cos ( alpha * M_PI / 180 ) +
  389.         y1 * sin ( alpha * M_PI / 180 );      
  390.       y2 = -1 * x1 * sin ( alpha * M_PI / 180 ) +
  391.         y1 * cos ( alpha * M_PI / 180 );      
  392.       charx += x2;      
  393.       chary += y2;      
  394.       char_num++;
  395.     }
  396.   }
  397.   return ( INoError );
  398. }