home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / ImageOpr.bproj / ImageSFrame.m < prev    next >
Encoding:
Text File  |  1996-10-04  |  5.6 KB  |  232 lines

  1. #import "../ImageOpr.h"
  2. #import <appkit/Application.h>
  3. #import <appkit/publicWraps.h>
  4. #import <appkit/NXBitmapImageRep.h>
  5. #import <appkit/Control.h>
  6. #import <appkit/color.h>
  7. #import <stdio.h>
  8. #import <stdlib.h>
  9. #import <string.h>
  10. #import <libc.h>
  11. #import "../TVController.h"
  12. #import "../ToyWin.h"
  13. #import "../ToyWinEPS.h"
  14. #import "../ToyView.h"
  15. #import "../common.h"
  16. #import "../getpixel.h"
  17. #import "imageOperation.h"
  18.  
  19. #define  S_Rect        0
  20. #define  S_RoundRect    1
  21. #define  S_Oval        2
  22.  
  23. @implementation ImageOpr (SFrame)
  24.  
  25.  
  26. static int sq_width, sq_x, sq_y;
  27. static float t_rad = 0.0;
  28. static float ov_x, ov_y;
  29. static int background[3];
  30.  
  31. static void init_sftransp(float ratio, int shape, int color[], commonInfo *cinf)
  32. {
  33.     int i, x;
  34.  
  35.     for (i = 0; i < 3; i++)
  36.         background[i] = color[i];
  37.     if (t_rad <= 0.0) srandom(getpid());
  38.     x = (cinf->width > cinf->height) ? cinf->height : cinf->width;
  39.     if (shape == S_Oval) {
  40.         ov_x = cinf->width / 2.0;
  41.         ov_y = cinf->height / 2.0;
  42.         t_rad = 1.0 - ratio * 2.0;
  43.     }else {
  44.         if (shape == S_Rect) {
  45.             sq_width = x * ratio;
  46.             t_rad = 0.0;
  47.         }else { /* S_RoundRect */
  48.             if (ratio >= 0.25) {
  49.                 sq_width = x * 0.5;
  50.                 t_rad = 1.0 - ratio * 2.0;
  51.             }else {
  52.                 sq_width = x * ratio * 2.0;
  53.                 t_rad = 0.5;
  54.             }
  55.         }
  56.         sq_x = cinf->width - sq_width;
  57.         sq_y = cinf->height - sq_width;
  58.     }
  59. }
  60.  
  61. static int sfTransp(int shape, BOOL useAlpha, int ax, int ay)
  62. {
  63.     float v, w;
  64.     int x, y, n;
  65.  
  66.     if (shape == S_Oval) {
  67.         w = (ax - ov_x) / ov_x;
  68.         v = (ay - ov_y) / ov_y;
  69.         v = w * w + v * v;
  70.     }else {
  71.         x = (ax < sq_width) ? (sq_width - 1 - ax) : (ax - sq_x);
  72.         y = (ay < sq_width) ? (sq_width - 1 - ay) : (ay - sq_y);
  73.         if (x < 0 && y < 0)
  74.             return AlphaOpaque;
  75.         if (shape == S_Rect)
  76.             v = (x >= y) ? (x * x) : (y * y);
  77.         else { /* S_RoundRect */
  78.             if (x < 0) x = 0;
  79.             else if (y < 0) y = 0;
  80.             v = x * x + y * y;
  81.         }
  82.         v /= (float)(sq_width * sq_width);
  83.     }
  84.     if ((v -= t_rad) < 0.0)
  85.         return AlphaOpaque;
  86.     v /= 1.0 - t_rad;
  87.     if (useAlpha)
  88.         return ((int)(v * 0xffff) > (random() & 0xffff))
  89.             ? AlphaTransp : AlphaOpaque;
  90.     n = 255 * (1.0 - v);
  91.     return (n < 0) ? 0 : ((n > 255) ? 255 : n);
  92. }
  93.  
  94. static commonInfo *makeSFrameMap(float ratio, int shape, int color[],
  95.     commonInfo *cinf, unsigned char *map[], unsigned char *newmap[])
  96. {
  97.     commonInfo *newinf = NULL;
  98.     int pn, alp, cn;
  99.     int x, y, i;
  100.     BOOL useAlpha, beColor;
  101.     int elm[MAXPLANE], ptr, av = 0;
  102.     unsigned char *working[MAXPLANE];
  103.  
  104.     init_sftransp(ratio, shape, color, cinf);
  105.     newmap[0] = NULL;
  106.     if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL)
  107.         goto ErrEXIT;
  108.     useAlpha = (color[ALPHA] != AlphaOpaque);
  109.     *newinf = *cinf;
  110.     newinf->palette = NULL;
  111.     newinf->palsteps = 0;
  112.     newinf->isplanar = YES;
  113.     if (!useAlpha && newinf->bits < 4)
  114.         newinf->bits = 4;
  115.     newinf->xbytes = byte_length(newinf->bits, newinf->width);
  116.     newinf->alpha = useAlpha;
  117.     beColor = (cinf->numcolors >= 3);
  118.     if (!beColor && !useAlpha) {
  119.         int d;
  120.         for (i = 0; i < 3; i++) {
  121.             d = color[i % 3] - color[(i+1) % 3];
  122.             if (d > 5 || d < -5) {
  123.                 beColor = YES;
  124.                 break;
  125.             }
  126.         }
  127.     }
  128.     if (beColor)
  129.         cn = 3;
  130.     else {
  131.         newinf->cspace = NX_OneIsWhiteColorSpace;
  132.         cn = 1;
  133.     }
  134.     cinf->numcolors = pn = cn;
  135.     if (useAlpha)
  136.         alp = pn++;
  137.     else alp = 0;    /* not used */
  138.  
  139.     if (allocImage(working, newinf->width, newinf->height, 8, pn))
  140.         goto ErrEXIT;
  141.     if (initGetPixel(cinf) != 0)
  142.         goto ErrEXIT;
  143.     resetPixel(map, 0);
  144.     if (useAlpha)
  145.         for (y = 0; y < newinf->height; y++) {
  146.         ptr = newinf->width * y;
  147.         for (x = 0; x < newinf->width; x++) {
  148.             getPixel(&elm[RED], &elm[GREEN], &elm[BLUE], &elm[ALPHA]);
  149.             if (elm[ALPHA] == AlphaTransp
  150.                 || (av = sfTransp(shape, YES, x, y)) == AlphaTransp) {
  151.             for (i = 0; i < cn; i++)
  152.                 working[i][ptr + x] = 0xff;
  153.             working[alp][ptr + x] = AlphaTransp;
  154.             }else {
  155.             for (i = 0; i < cn; i++)
  156.                 working[i][ptr + x] = elm[i];
  157.             working[alp][ptr + x] = (elm[ALPHA] < av) ? elm[ALPHA] : av;
  158.             }
  159.         }
  160.         }
  161.     else
  162.         for (y = 0; y < newinf->height; y++) {
  163.         ptr = newinf->width * y;
  164.         for (x = 0; x < newinf->width; x++) {
  165.             getPixel(&elm[RED], &elm[GREEN], &elm[BLUE], &elm[ALPHA]);
  166.             if ((av = sfTransp(shape, NO, x, y)) > elm[ALPHA])
  167.                 av = elm[ALPHA];
  168.             compositeColors(elm, background, av);
  169.             for (i = 0; i < cn; i++)
  170.             working[i][ptr + x] = elm[i];
  171.         }
  172.         }
  173.  
  174.     if (newinf->bits < 8) {
  175.         if (allocImage(newmap, newinf->width, newinf->height, newinf->bits, pn))
  176.             goto ErrEXIT;
  177.         packWorkingImage(newinf, pn, working, newmap);
  178.         free((void *)working[0]);
  179.     }else {
  180.         for (i = 0; i < MAXPLANE; i++)
  181.             newmap[i] = working[i];
  182.     }
  183.     return newinf;
  184.  
  185. ErrEXIT:
  186.     if (newinf)
  187.         free((void *)newinf);
  188.     if (working[0]) free((void *)working[0]);
  189.     return NULL;
  190. }
  191.  
  192.  
  193. - softFrame:(float)ratio shape:(int)shape color:(int *)color
  194. {
  195.     ToyWin    *tw, *newtw = nil;
  196.     ToyView    *tv = nil;
  197.     commonInfo    *cinf, *newinf;
  198.     const char *fnam;
  199.     char fn[256];
  200.     NXBitmapImageRep *rep;
  201.     unsigned char *map[MAXPLANE], *newmap[MAXPLANE];
  202.  
  203.     if ((tw = [self keyParentWindow: SoftFrame]) == nil) {
  204.         NXBeep();
  205.         return self;
  206.     }
  207.     tv = [tw toyView];
  208.     cinf = [tv commonInfo];
  209.     fnam = [tw filename];
  210.     if (![self checkCommonInfo:cinf filename:fnam])
  211.         return self;
  212.     sprintf(fn, "%s(Frame)", fnam);
  213.     rep = (NXBitmapImageRep *)[[tv image] bestRepresentation];
  214.     [rep getDataPlanes: map];
  215.     newinf = makeSFrameMap(ratio, shape, color, cinf, map, newmap);
  216.     if (newinf == NULL) {
  217.         warnAlert(fnam, Err_MEMORY);
  218.         return self;
  219.     }
  220. //    [theController messageDisplay: "Making Soft Frame..."];
  221.     newtw = [[ToyWin alloc] init:tw by:SoftFrame];
  222.     [newtw initLocateWindow:fn width:newinf->width height:newinf->height];
  223.     [newtw makeComment: newinf from: cinf];
  224. //    [theController messageDisplay:NULL];
  225.     [newtw drawView:newmap info: newinf];
  226.  
  227.     [theController newWindow: newtw];
  228.     return self;
  229. }
  230.  
  231. @end
  232.