This is ImageSFrame.m in view mode; [Download] [Up]
#import "../ImageOpr.h"
#import <appkit/Application.h>
#import <appkit/publicWraps.h>
#import <appkit/NXBitmapImageRep.h>
#import <appkit/Control.h>
#import <appkit/color.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import <libc.h>
#import "../TVController.h"
#import "../ToyWin.h"
#import "../ToyWinEPS.h"
#import "../ToyView.h"
#import "../common.h"
#import "../getpixel.h"
#import "imageOperation.h"
#define S_Rect 0
#define S_RoundRect 1
#define S_Oval 2
@implementation ImageOpr (SFrame)
static int sq_width, sq_x, sq_y;
static float t_rad = 0.0;
static float ov_x, ov_y;
static int background[3];
static void init_sftransp(float ratio, int shape, int color[], commonInfo *cinf)
{
int i, x;
for (i = 0; i < 3; i++)
background[i] = color[i];
if (t_rad <= 0.0) srandom(getpid());
x = (cinf->width > cinf->height) ? cinf->height : cinf->width;
if (shape == S_Oval) {
ov_x = cinf->width / 2.0;
ov_y = cinf->height / 2.0;
t_rad = 1.0 - ratio * 2.0;
}else {
if (shape == S_Rect) {
sq_width = x * ratio;
t_rad = 0.0;
}else { /* S_RoundRect */
if (ratio >= 0.25) {
sq_width = x * 0.5;
t_rad = 1.0 - ratio * 2.0;
}else {
sq_width = x * ratio * 2.0;
t_rad = 0.5;
}
}
sq_x = cinf->width - sq_width;
sq_y = cinf->height - sq_width;
}
}
static int sfTransp(int shape, BOOL useAlpha, int ax, int ay)
{
float v, w;
int x, y, n;
if (shape == S_Oval) {
w = (ax - ov_x) / ov_x;
v = (ay - ov_y) / ov_y;
v = w * w + v * v;
}else {
x = (ax < sq_width) ? (sq_width - 1 - ax) : (ax - sq_x);
y = (ay < sq_width) ? (sq_width - 1 - ay) : (ay - sq_y);
if (x < 0 && y < 0)
return AlphaOpaque;
if (shape == S_Rect)
v = (x >= y) ? (x * x) : (y * y);
else { /* S_RoundRect */
if (x < 0) x = 0;
else if (y < 0) y = 0;
v = x * x + y * y;
}
v /= (float)(sq_width * sq_width);
}
if ((v -= t_rad) < 0.0)
return AlphaOpaque;
v /= 1.0 - t_rad;
if (useAlpha)
return ((int)(v * 0xffff) > (random() & 0xffff))
? AlphaTransp : AlphaOpaque;
n = 255 * (1.0 - v);
return (n < 0) ? 0 : ((n > 255) ? 255 : n);
}
static commonInfo *makeSFrameMap(float ratio, int shape, int color[],
commonInfo *cinf, unsigned char *map[], unsigned char *newmap[])
{
commonInfo *newinf = NULL;
int pn, alp, cn;
int x, y, i;
BOOL useAlpha, beColor;
int elm[MAXPLANE], ptr, av = 0;
unsigned char *working[MAXPLANE];
init_sftransp(ratio, shape, color, cinf);
newmap[0] = NULL;
if ((newinf = (commonInfo *)malloc(sizeof(commonInfo))) == NULL)
goto ErrEXIT;
useAlpha = (color[ALPHA] != AlphaOpaque);
*newinf = *cinf;
newinf->palette = NULL;
newinf->palsteps = 0;
newinf->isplanar = YES;
if (!useAlpha && newinf->bits < 4)
newinf->bits = 4;
newinf->xbytes = byte_length(newinf->bits, newinf->width);
newinf->alpha = useAlpha;
beColor = (cinf->numcolors >= 3);
if (!beColor && !useAlpha) {
int d;
for (i = 0; i < 3; i++) {
d = color[i % 3] - color[(i+1) % 3];
if (d > 5 || d < -5) {
beColor = YES;
break;
}
}
}
if (beColor)
cn = 3;
else {
newinf->cspace = NX_OneIsWhiteColorSpace;
cn = 1;
}
cinf->numcolors = pn = cn;
if (useAlpha)
alp = pn++;
else alp = 0; /* not used */
if (allocImage(working, newinf->width, newinf->height, 8, pn))
goto ErrEXIT;
if (initGetPixel(cinf) != 0)
goto ErrEXIT;
resetPixel(map, 0);
if (useAlpha)
for (y = 0; y < newinf->height; y++) {
ptr = newinf->width * y;
for (x = 0; x < newinf->width; x++) {
getPixel(&elm[RED], &elm[GREEN], &elm[BLUE], &elm[ALPHA]);
if (elm[ALPHA] == AlphaTransp
|| (av = sfTransp(shape, YES, x, y)) == AlphaTransp) {
for (i = 0; i < cn; i++)
working[i][ptr + x] = 0xff;
working[alp][ptr + x] = AlphaTransp;
}else {
for (i = 0; i < cn; i++)
working[i][ptr + x] = elm[i];
working[alp][ptr + x] = (elm[ALPHA] < av) ? elm[ALPHA] : av;
}
}
}
else
for (y = 0; y < newinf->height; y++) {
ptr = newinf->width * y;
for (x = 0; x < newinf->width; x++) {
getPixel(&elm[RED], &elm[GREEN], &elm[BLUE], &elm[ALPHA]);
if ((av = sfTransp(shape, NO, x, y)) > elm[ALPHA])
av = elm[ALPHA];
compositeColors(elm, background, av);
for (i = 0; i < cn; i++)
working[i][ptr + x] = elm[i];
}
}
if (newinf->bits < 8) {
if (allocImage(newmap, newinf->width, newinf->height, newinf->bits, pn))
goto ErrEXIT;
packWorkingImage(newinf, pn, working, newmap);
free((void *)working[0]);
}else {
for (i = 0; i < MAXPLANE; i++)
newmap[i] = working[i];
}
return newinf;
ErrEXIT:
if (newinf)
free((void *)newinf);
if (working[0]) free((void *)working[0]);
return NULL;
}
- softFrame:(float)ratio shape:(int)shape color:(int *)color
{
ToyWin *tw, *newtw = nil;
ToyView *tv = nil;
commonInfo *cinf, *newinf;
const char *fnam;
char fn[256];
NXBitmapImageRep *rep;
unsigned char *map[MAXPLANE], *newmap[MAXPLANE];
if ((tw = [self keyParentWindow: SoftFrame]) == nil) {
NXBeep();
return self;
}
tv = [tw toyView];
cinf = [tv commonInfo];
fnam = [tw filename];
if (![self checkCommonInfo:cinf filename:fnam])
return self;
sprintf(fn, "%s(Frame)", fnam);
rep = (NXBitmapImageRep *)[[tv image] bestRepresentation];
[rep getDataPlanes: map];
newinf = makeSFrameMap(ratio, shape, color, cinf, map, newmap);
if (newinf == NULL) {
warnAlert(fnam, Err_MEMORY);
return self;
}
// [theController messageDisplay: "Making Soft Frame..."];
newtw = [[ToyWin alloc] init:tw by:SoftFrame];
[newtw initLocateWindow:fn width:newinf->width height:newinf->height];
[newtw makeComment: newinf from: cinf];
// [theController messageDisplay:NULL];
[newtw drawView:newmap info: newinf];
[theController newWindow: newtw];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.