Files
Arquivotheca.SunOS-4.1.4/usr.lib/libsuntool/menu/image.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

403 lines
9.1 KiB
C

#ifndef lint
#ifdef sccs
static char sccsid[] = "@(#)image.c 1.1 94/10/31 Copyright 1985 Sun Micro";
#endif
#endif
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
/*-
IMAGE PACKAGE
image.c, Fri Jul 12 12:11:18 1985
Craig Taylor,
Sun Microsystems
*/
/*
* Image layout:
*
* Image width = M, Lm, LPr, Pr, Rpr, Rm, M
* Image height = M, max(LPr, Pr, Rpr), M
*
* M = Margin,
* Lm = Left Margin,
* LPr = Left Pixrect,
* Pr = Pixrect or String,
* Rpr = Right Pixrect,
* Rm = Right Margin,
*
*/
#include <sys/types.h>
#include <stdio.h>
#include <varargs.h>
#include <pixrect/pixrect.h>
#include <pixrect/pixfont.h>
#include <sunwindow/sun.h> /* for LINT_CAST */
#include "sunwindow/sv_malloc.h"
#include <suntool/image_impl.h>
extern struct pixrect menu_gray50_pr;
static struct pixfont *image_font; /* Default to NULL */
#define IMAX(a, b) ((int)(b) > (int)(a) ? (int)(b) : (int)(a))
#define INHERIT_VALUE(f) im->f ? im->f : std_image ? std_image->f : 0
/* VARARGS */
Image
image_create(va_alist)
va_dcl
{
caddr_t avlist[ATTR_STANDARD_SIZE];
struct image *im = (struct image *)LINT_CAST(sv_calloc(
1, sizeof(struct image)));
va_list valist;
va_start(valist);
(void) attr_make(avlist, ATTR_STANDARD_SIZE, valist);
va_end(valist);
(void) image_set(im, ATTR_LIST, avlist, 0);
return (Image)im;
}
/* VARARGS1 */
int
image_set(im, va_alist)
register struct image *im;
va_dcl
{
Image_attribute avlist[ATTR_STANDARD_SIZE];
va_list valist;
register Image_attribute *attr;
if (!im) return FALSE;
va_start(valist);
(void) attr_make((char **)LINT_CAST(avlist), ATTR_STANDARD_SIZE, valist);
va_end(valist);
/* zero width/height if any size changes */
for (attr = avlist; *attr; attr = image_attr_next(attr)) {
switch (attr[0]) {
case IMAGE_ACTIVE:
im->inactive = FALSE;
break;
case IMAGE_BOXED:
im->boxed = (int)attr[1];
break;
case IMAGE_CENTER:
im->center = (int)attr[1];
break;
case IMAGE_FONT:
im->font = (struct pixfont *)attr[1];
im->width = im->height = 0;
break;
case IMAGE_INACTIVE:
im->inactive = TRUE;
break;
case IMAGE_INVERT:
im->invert = (int)attr[1];
break;
case IMAGE_LEFT_MARGIN:
im->left_margin = (int)attr[1];
im->width = im->height = 0;
break;
case IMAGE_MARGIN:
im->margin = (int)attr[1];
im->width = im->height = 0;
break;
case IMAGE_PIXRECT:
if (im->free_pr && im->pr) (void) pr_destroy(im->pr);
im->pr = (struct pixrect *)attr[1];
im->width = im->height = 0;
break;
case IMAGE_RELEASE:
im->free_image = TRUE;
break;
case IMAGE_RELEASE_STRING:
im->free_string = TRUE;
break;
case IMAGE_RELEASE_PR:
im->free_pr = TRUE;
break;
case IMAGE_RIGHT_MARGIN:
im->right_margin = (int)attr[1];
im->width = im->height = 0;
break;
case IMAGE_RIGHT_PIXRECT:
im->right_pr = (struct pixrect *)attr[1];
im->width = im->height = 0;
break;
case IMAGE_STRING:
if (im->free_string && im->string) free(im->string);
im->string = (char *)attr[1];
im->width = im->height = 0;
break;
case IMAGE_NOP:
break;
default:
if (ATTR_PKG_IMAGE == ATTR_PKG(attr[0]))
(void) fprintf(stderr,
"image_set: 0x%x not recognized as an image attribute.\n", attr[0]);
break;
}
}
return TRUE;
}
/* VARARGS2 */
void
image_render(im, std_image, va_alist)
struct image *im;
register struct image *std_image;
va_dcl
{
register Image_attribute *attr;
Image_attribute avlist[ATTR_STANDARD_SIZE];
struct pixrect *pr;
int top, left, mid, inactive = FALSE;
register int margin2;
int margin, left_margin, right_margin, width, height;
va_list valist;
struct pr_prpos where;
if (!im) return;
va_start(valist);
(void) attr_make((char **)LINT_CAST(avlist), ATTR_STANDARD_SIZE, valist);
va_end(valist);
for (attr = avlist; *attr; attr = image_attr_next(attr)) {
switch (attr[0]) {
case IMAGE_REGION:
pr = (struct pixrect *)attr[1];
left = (int)attr[2];
top = (int)attr[3];
break;
case IMAGE_INACTIVE:
inactive = TRUE;
break;
case IMAGE_NOP:
break;
default:
if (ATTR_PKG_IMAGE == ATTR_PKG(attr[0]))
(void) fprintf(stderr,
"image_render: 0x%x not recognized as a image attribute.\n", attr[0]);
break;
}
}
margin = INHERIT_VALUE(margin);
left_margin = INHERIT_VALUE(left_margin);
right_margin = INHERIT_VALUE(right_margin);
width = IMAX(im->width, std_image ? std_image->width : 0);
height = IMAX(im->height, std_image ? std_image->height : 0);
margin2 = margin << 1;
mid = top + height / 2;
left += margin, top += margin;
if (im->string) {
struct pixfont *font = image_get_font(im, std_image);
if (*im->string == '\0') return;
if (INHERIT_VALUE(center)) {
struct pr_size temp;
int pad;
temp = pf_textwidth(strlen(im->string), font, im->string);
pad = width - margin2 - temp.x;
left_margin = pad -
IMAX(pad/2, im->right_pr ?
im->right_pr->pr_width + right_margin + 1 : 0);
}
where.pr = pr;
where.pos.x = left+left_margin - font->pf_char[im->string[0]].pc_home.x,
where.pos.y = mid - font->pf_defaultsize.y / 2 -
font->pf_char[im->string[0]].pc_home.y,
(void) pf_text(where, PIX_SRC, font, im->string);
if (im->inactive || inactive) {
where.pos.x++;
(void) pf_text(where, PIX_SRC, font, im->string);
(void) pr_replrop(pr, left, top,
width - margin2, height - margin2,
PIX_SRC & PIX_DST, &menu_gray50_pr, 0, 0);
}
} else if (im->pr) {
(void) pr_rop(pr, left, top,
width - margin2, height - margin2,
PIX_SRC, im->pr, 0, 0);
/* Fixme: Add inactive mask for pixrects */
}
if (im->right_pr) {
(void) pr_rop(pr,
left + width - (im->right_pr->pr_width
+ (im->string ? right_margin:0) + margin2),
mid - im->right_pr->pr_height / 2,
im->right_pr->pr_width, im->right_pr->pr_height,
PIX_SRC, im->right_pr, 0, 0);
}
if (im->invert) {
(void) pr_rop(pr,
left, top, width - margin2, height - margin2,
PIX_NOT(PIX_DST), im->pr, 0, 0);
}
if (im->boxed || (std_image ? std_image->boxed : FALSE)) {
int x1 = left - 1;
int x2 = left + width - margin2;
int y1 = top - 1;
int y2 = top + height - margin2;
(void) pr_vector(pr, x1, y1, x2, y1, PIX_SET, 0);
(void) pr_vector(pr, x2, y1, x2, y2, PIX_SET, 0);
(void) pr_vector(pr, x2, y2, x1, y2, PIX_SET, 0);
(void) pr_vector(pr, x1, y2, x1, y1, PIX_SET, 0);
}
}
/* VARARGS2 */
caddr_t
image_get(im, std_image, attr)
struct image *im, *std_image;
Image_attribute attr;
{
caddr_t v = NULL;
if (!im) return NULL;
switch (attr) {
case IMAGE_FONT:
v = (caddr_t)image_get_font(im, std_image);
break;
case IMAGE_HEIGHT:
if (!im->height) compute_size(im, std_image);
v = (caddr_t)im->height;
break;
case IMAGE_PIXRECT:
v = (caddr_t)im->pr;
break;
case IMAGE_STRING:
v = (caddr_t)im->string;
break;
case IMAGE_WIDTH:
if (!im->width) compute_size(im, std_image);
v = (caddr_t)im->width;
break;
}
return v;
}
void
image_destroy(im)
struct image *im;
{
if (!im || !im->free_image) return;
if (im->free_string && im->string) free(im->string);
if (im->free_pr && im->pr) (void) pr_destroy(im->pr);
free((caddr_t)im);
}
static
compute_size(im, std_image)
register struct image *im, *std_image;
{
struct pixfont *font;
register int margin2;
int margin, left_margin, right_margin;
struct pr_size temp;
margin = INHERIT_VALUE(margin);
left_margin = INHERIT_VALUE(left_margin);
right_margin = INHERIT_VALUE(right_margin);
margin2 = margin << 1;
if (im->pr) {
im->width = margin2 + im->pr->pr_width;
im->height = margin2 + im->pr->pr_height;
if (im->right_pr) {
im->width += im->right_pr->pr_width;
im->height = IMAX(im->right_pr->pr_height, im->height);
}
} else if (im->string) {
font = image_get_font(im, std_image);
temp = pf_textwidth(strlen(im->string), font, im->string);
im->width = temp.x;
im->height = font->pf_defaultsize.y;
if (im->right_pr) {
im->width += im->right_pr->pr_width;
im->height = IMAX(im->right_pr->pr_height, im->height);
}
im->width += margin2 + left_margin + right_margin;
im->height += margin2;
} else {
im->height = im->width = 0;
}
im->width = IMAX(im->width, std_image->width);
im->height = IMAX(im->height, std_image->height);
}
static
struct pixfont *
image_get_font(im, std_image)
struct image *im;
register struct image *std_image;
{
struct pixfont *font;
if (im->font) font = im->font;
else if (std_image && std_image->font) font = std_image->font;
else if (image_font) font = image_font;
else if (image_font = pf_open(IMAGE_DEFAULT_FONT))
font = image_font;
else font = image_font = pw_pfsysopen();
return font;
}