1998-03-28 05:44:41 +03:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
** All the wonderful code for dealing with images
|
|
|
|
*/
|
|
|
|
#define JMC_INIT_PSIMGCB_ID
|
|
|
|
|
|
|
|
#include "xlate_i.h"
|
|
|
|
#include "libimg.h" /* Image Library public API. */
|
|
|
|
#include "il_util.h" /* Colormap/Colorspace API. */
|
|
|
|
|
|
|
|
/* Create and initialize the Image Library JMC callback interface.
|
|
|
|
Also create an IL_GroupContext for the current context. */
|
|
|
|
XP_Bool
|
|
|
|
psfe_init_image_callbacks(MWContext *cx)
|
|
|
|
{
|
|
|
|
IL_GroupContext *img_cx;
|
|
|
|
PSIMGCB* img_cb;
|
|
|
|
JMCException *exc = NULL;
|
|
|
|
|
|
|
|
if (!cx->img_cx) {
|
|
|
|
img_cb = PSIMGCBFactory_Create(&exc); /* JMC Module */
|
|
|
|
if (exc) {
|
|
|
|
JMC_DELETE_EXCEPTION(&exc); /* XXXM12N Should really return
|
|
|
|
exception */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create an Image Group Context. IL_NewGroupContext augments the
|
|
|
|
reference count for the JMC callback interface. The opaque argument
|
|
|
|
to IL_NewGroupContext is the Front End's display context, which will
|
|
|
|
be passed back to all the Image Library's FE callbacks. */
|
|
|
|
img_cx = IL_NewGroupContext((void*)cx, (IMGCBIF *)img_cb);
|
|
|
|
|
|
|
|
/* Attach the IL_GroupContext to the FE's display context. */
|
|
|
|
cx->img_cx = img_cx;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Image Library callbacks */
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
#define HOWMANY(x, r) (((x) + ((r) - 1)) / (r))
|
|
|
|
#define ROUNDUP(x, r) (HOWMANY(x, r) * (r))
|
|
|
|
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_init(struct PSIMGCB* self, JMCException* *exception)
|
|
|
|
{
|
|
|
|
/* Nothing to be done here. */
|
|
|
|
}
|
|
|
|
|
|
|
|
extern JMC_PUBLIC_API(void*)
|
|
|
|
_PSIMGCB_getBackwardCompatibleInterface(struct PSIMGCB* self,
|
|
|
|
const JMCInterfaceID* iid,
|
|
|
|
JMCException* *exception)
|
|
|
|
{
|
|
|
|
return NULL; /* Nothing to be done here. */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************************** Pixmap creation ********************************/
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_NewPixmap(PSIMGCB* img_cb, jint op, void *dpy_cx, jint width,
|
|
|
|
jint height, IL_Pixmap *image, IL_Pixmap *mask)
|
|
|
|
{
|
|
|
|
uint8 img_depth, pixmap_depth;
|
|
|
|
NI_PixmapHeader *img_header = &image->header;
|
|
|
|
NI_PixmapHeader *mask_header = mask ? &mask->header : NULL;
|
|
|
|
MWContext *context = (MWContext *)dpy_cx; /* XXXM12N This should be the
|
|
|
|
FE's display context. */
|
|
|
|
|
|
|
|
|
|
|
|
/* Determine the depth of the image. */
|
|
|
|
pixmap_depth = context->color_space->pixmap_depth;
|
|
|
|
|
|
|
|
/* Override the image colorspace with the display colorspace. This
|
|
|
|
instructs the image library to decode to the display colorspace
|
|
|
|
instead of decoding to the image's source colorspace. */
|
|
|
|
IL_ReleaseColorSpace(img_header->color_space);
|
|
|
|
img_header->color_space = context->color_space;
|
|
|
|
IL_AddRefToColorSpace(img_header->color_space);
|
|
|
|
|
|
|
|
/* Ask the image library to scale to the requested dimensions.
|
|
|
|
Context-specific scaling, however, will be handled by the PSFE. */
|
|
|
|
img_header->width = width;
|
|
|
|
img_header->height = height;
|
|
|
|
if (mask) {
|
|
|
|
mask_header->width = width;
|
|
|
|
mask_header->height = height;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Compute the number of bytes per scan line for the image and mask,
|
|
|
|
and make sure it is quadlet aligned. */
|
|
|
|
img_depth = img_header->color_space->pixmap_depth;
|
|
|
|
XP_ASSERT(img_depth == pixmap_depth);
|
|
|
|
img_header->widthBytes = (img_header->width * img_depth + 7) / 8;
|
|
|
|
img_header->widthBytes = ROUNDUP(img_header->widthBytes, 4);
|
|
|
|
if (mask) {
|
|
|
|
mask_header->widthBytes = (mask_header->width + 7) / 8;
|
|
|
|
mask_header->widthBytes = ROUNDUP(mask_header->widthBytes, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate memory for the image bits, and for the mask bits (if
|
|
|
|
required.) */
|
|
|
|
image->bits = calloc(img_header->widthBytes * img_header->height, 1);
|
|
|
|
if (!image->bits)
|
|
|
|
return;
|
|
|
|
if (mask) {
|
|
|
|
mask->bits = calloc(mask_header->widthBytes * mask_header->height, 1);
|
|
|
|
if (!mask->bits) {
|
|
|
|
free(image->bits);
|
|
|
|
image->bits = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************************** Pixmap update **********************************/
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_UpdatePixmap(PSIMGCB* img_cb, jint op, void* dpy_cx,
|
|
|
|
IL_Pixmap* pixmap, jint x_offset, jint y_offset,
|
|
|
|
jint width, jint height)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************** Pixmap memory management *************************/
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_ControlPixmapBits(PSIMGCB* img_cb, jint op, void* dpy_cx,
|
|
|
|
IL_Pixmap* pixmap, IL_PixmapControl message)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************************** Pixmap destruction *****************************/
|
|
|
|
/* XXXM12N The dpy_cx argument is not used in DestroyPixmap and should be
|
|
|
|
removed. */
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_DestroyPixmap(PSIMGCB* img_cb, jint op, void* dpy_cx,
|
|
|
|
IL_Pixmap* pixmap)
|
|
|
|
{
|
|
|
|
/* Free the pixmap's bits. */
|
|
|
|
if (pixmap->bits) {
|
|
|
|
free(pixmap->bits);
|
|
|
|
pixmap->bits = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************************** Pixmap display *********************************/
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_DisplayPixmap(PSIMGCB* img_cb, jint op, void* dpy_cx,
|
|
|
|
IL_Pixmap* image, IL_Pixmap* mask, jint x, jint y,
|
1998-05-28 23:32:00 +04:00
|
|
|
jint x_offset, jint y_offset, jint width, jint height,
|
|
|
|
jint req_w, jint req_h )
|
1998-03-28 05:44:41 +03:00
|
|
|
{
|
|
|
|
int32 img_x_offset, img_y_offset; /* Offset of image in drawable. */
|
|
|
|
int32 rect_x_offset, rect_y_offset; /* Offset of update rect in
|
|
|
|
drawable. */
|
|
|
|
NI_PixmapHeader *img_header = &image->header;
|
|
|
|
uint32 img_width = img_header->width; /* Image width. */
|
|
|
|
uint32 img_height = img_header->height; /* Image height. */
|
|
|
|
MWContext *context = (MWContext *)dpy_cx; /* XXX This should be the FE's
|
|
|
|
display context. */
|
|
|
|
XP_Bool tiling_required = FALSE;
|
|
|
|
|
|
|
|
/* Check for zero display area. */
|
|
|
|
if (width == 0 || height == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Perform context scaling. */
|
|
|
|
x *= context->convertPixX;
|
|
|
|
y *= context->convertPixY;
|
|
|
|
x_offset *= context->convertPixX;
|
|
|
|
y_offset *= context->convertPixY;
|
|
|
|
width *= context->convertPixX;
|
|
|
|
height *= context->convertPixY;
|
|
|
|
img_width *= context->convertPixX;
|
|
|
|
img_height *= context->convertPixY;
|
|
|
|
|
|
|
|
/* Determine whether tiling is required. */
|
|
|
|
if ((x_offset + width > img_width) || (y_offset + height > img_height))
|
|
|
|
tiling_required = TRUE;
|
|
|
|
|
|
|
|
/* Compute the offset into the drawable of the image origin. */
|
|
|
|
img_x_offset = x; /* + fe_drawable->x_origin; */
|
|
|
|
img_y_offset = y; /* + fe_drawable->y_origin; */
|
|
|
|
|
|
|
|
/* Check whether the image is ready to be displayed. */
|
|
|
|
if (!XP_CheckElementSpan(context, img_y_offset, img_height))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Draw the image. */
|
|
|
|
xl_colorimage(context, x, y, width, height, image, mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************************** Icon dimensions ********************************/
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_GetIconDimensions(PSIMGCB* img_cb, jint op, void* dpy_cx, int* width,
|
|
|
|
int* height, jint icon_number)
|
|
|
|
{
|
|
|
|
/* Call the screen FE to get the icon dimensions in pixels. */
|
|
|
|
FE_GetPSIconDimensions(icon_number, width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************************** Icon display ***********************************/
|
|
|
|
JMC_PUBLIC_API(void)
|
|
|
|
_PSIMGCB_DisplayIcon(PSIMGCB* img_cb, jint op, void* dpy_cx, jint x, jint y,
|
|
|
|
jint icon_number)
|
|
|
|
{
|
|
|
|
int width; /* Width of the icon in context scaled coordinates. */
|
|
|
|
int height; /* Height of the icon in context scaled coordinates. */
|
|
|
|
int img_depth; /* Depth of the image. */
|
|
|
|
MWContext *context = (MWContext *)dpy_cx;
|
|
|
|
IL_Pixmap image; /* Image pixmap. */
|
|
|
|
NI_PixmapHeader *img_header = &image.header;
|
|
|
|
|
|
|
|
/* Call the screen FE to get the icon dimensions in pixels. */
|
|
|
|
FE_GetPSIconDimensions(icon_number, &width, &height);
|
|
|
|
img_header->width = (int32)width;
|
|
|
|
img_header->height = (int32)height;
|
|
|
|
|
|
|
|
/* Apply context scaling to the dimensions. */
|
|
|
|
width *= context->convertPixX;
|
|
|
|
height *= context->convertPixY;
|
|
|
|
|
|
|
|
/* Check whether we are ready to display the icon. */
|
|
|
|
if (!XP_CheckElementSpan(context, y, height))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Don't attempt to display the icon if either dimension is zero. */
|
|
|
|
if (!width || !height)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get ourselves a colorspace. */
|
|
|
|
img_header->color_space = context->color_space;
|
|
|
|
IL_AddRefToColorSpace(img_header->color_space);
|
|
|
|
|
|
|
|
/* Allocate bits for the icon. We don't cache icons created for the
|
|
|
|
purpose of printing. */
|
|
|
|
img_depth = img_header->color_space->pixmap_depth;
|
|
|
|
img_header->widthBytes = (img_header->width * img_depth + 7) / 8;
|
|
|
|
img_header->widthBytes = ROUNDUP(img_header->widthBytes, 4);
|
|
|
|
|
|
|
|
/* Allocate memory for the image bits. */
|
|
|
|
image.bits = calloc(img_header->widthBytes * img_header->height, 1);
|
|
|
|
if (!image.bits) {
|
|
|
|
IL_ReleaseColorSpace(img_header->color_space);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the icon data from the screen FE and draw the icon. */
|
|
|
|
if (FE_GetPSIconData(icon_number, &image, NULL))
|
|
|
|
xl_colorimage(context, x, y, width, height, &image, NULL);
|
|
|
|
|
|
|
|
/* Clean up. */
|
|
|
|
free(image.bits);
|
|
|
|
IL_ReleaseColorSpace(img_header->color_space);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* End of Image Library callbacks */
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|