pjs/cmd/qtfe/image.cpp

254 строки
7.4 KiB
C++

/* $Id: image.cpp,v 1.1 1998-09-25 18:01:34 ramiro%netscape.com Exp $
*
* 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. Portions
* created by Warwick Allison, Kalle Dalheimer, Eirik Eng, Matthias
* Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav Tvete are
* Copyright (C) 1998 Warwick Allison, Kalle Dalheimer, Eirik Eng,
* Matthias Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav
* Tvete. All Rights Reserved.
*/
#define JMC_INIT_IMGCB_ID
#include "xp_core.h"
#include "structs.h"
#include "ntypes.h"
#include "libimg.h"
#include "il_util.h"
#include "prtypes.h"
#include "QtContext.h"
#include "icons.h"
#include <qimage.h>
#include <qpainter.h>
class QtImageData {
public:
QtImageData( MWContext *context, IL_Pixmap *ilpm, int w, int h, int d )
{
header = &ilpm->header;
header->width = w;
header->height = h;
IL_ReleaseColorSpace(header->color_space);
header->color_space = context->color_space;
IL_AddRefToColorSpace(header->color_space);
if ( d == 1 ) {
image = QImage( w, h, 1, 2, QImage::BigEndian );
image.setColor( 0, qRgb(0xff,0xff,0xff) );
image.setColor( 1, qRgb(0,0,0) );
header->widthBytes = ((w+31)/32)*4;
} else {
image = QImage( w, h, 32 );
int img_depth = header->color_space->pixmap_depth;
header->widthBytes = ((w * img_depth + 31)/32)*4;
}
ilpm->bits = image.bits();
ilpm->client_data = this;
}
void update(int x, int y, int w, int h)
{
if ( pixmap.isNull() ) {
pixmap = QPixmap( header->width, header->height,
image.depth() > 1 ? -1 : 1 );
//debug("IMG: ??: create %dx%d",header->width, header->height);
}
bitBlt( &pixmap, x, y, &image, x, y, w, h );
}
void message( IL_PixmapControl m )
{
if ( m == IL_RELEASE_BITS )
image = QImage();
}
NI_PixmapHeader* header;
QPixmap pixmap;
QImage image;
};
static void useArgs( const char *fn, ... )
{
if (0&&fn) printf( "%s\n", fn );
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_init(struct IMGCB* self, JMCException* *exception)
{
useArgs("_IMGCB_init", self, exception);
}
extern "C"
JMC_PUBLIC_API(void*)
_IMGCB_getBackwardCompatibleInterface(struct IMGCB* self,
const JMCInterfaceID* iid,
JMCException* *exception)
{
useArgs("_IMGCB_getBackwardCompatibleInterface", self, iid, exception);
return 0;
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_NewPixmap(IMGCB* img_cb, jint op, void *dpy_cx, jint width, jint height,
IL_Pixmap *image, IL_Pixmap *mask)
{
useArgs( 0, img_cb, op );
ASSERT( width > 0 && height > 0 );
new QtImageData( (MWContext*)dpy_cx, image, width, height, 32 );
if ( mask )
new QtImageData( (MWContext*)dpy_cx, mask, width, height, 1 );
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_UpdatePixmap(IMGCB* img_cb, jint op, void* dpy_cx, IL_Pixmap* pixmap,
jint x_offset, jint y_offset, jint width, jint height)
{
//debug("IMG: %p: update %d,%d %dx%d",pixmap,x_offset,y_offset,width,height);
useArgs(0,img_cb, op, dpy_cx );
((QtImageData *)pixmap->client_data)->
update(x_offset,y_offset,width,height);
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_ControlPixmapBits(IMGCB* img_cb, jint op, void* dpy_cx,
IL_Pixmap* pixmap, IL_PixmapControl message)
{
((QtImageData *)pixmap->client_data)->message( message );
useArgs( 0, img_cb, op, dpy_cx, pixmap, message );
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_DestroyPixmap(IMGCB* img_cb, jint op, void* dpy_cx, IL_Pixmap* pixmap)
{
useArgs( 0, img_cb, op, dpy_cx, pixmap );
QtImageData *qt_pixmap = (QtImageData *)pixmap->client_data;
delete qt_pixmap;
pixmap->client_data = 0;
pixmap->bits = 0;
}
static void internalDisplayPixmap( void* dpy_cx, QPixmap pix,
QPixmap *mask, jint x, jint y, jint x_offset,
jint y_offset, jint width, jint height)
{
MWContext *context = (MWContext *)dpy_cx;
if ( !pix.isNull() ) {
QtContext *c = QtContext::qt(context);
if ( c && c->contentWidget() ) {
if ( mask && !mask->isNull() )
pix.setMask( *((QBitmap*)mask) );
QPixmap pm = pix;
/* BUG - while not using backingstore
Sometimes width and height look like region-style sizes,
which are one more than IMGCBIF_DisplayPixmap expects.
Attempt to detect and correct this case.
Should be fixed in the backend.
*/
if ( x_offset+width == pm.width() + 1 ) width--;
if ( y_offset+height == pm.height() + 1 ) height--;
int img_x_offset = x - c->documentXOffset() + c->getXOrigin();
int img_y_offset = y - c->documentYOffset() + c->getYOrigin();
int rect_x_offset = img_x_offset + x_offset;
int rect_y_offset = img_y_offset + y_offset;
if ( x_offset + width > pm.width()
|| y_offset + height > pm.height() )
{
c->painter()->drawTiledPixmap(
rect_x_offset, rect_y_offset,
width, height, pm, x_offset, y_offset
);
} else {
c->painter()->drawPixmap(
rect_x_offset, rect_y_offset, pm,
x_offset, y_offset, width, height
);
}
}
}
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_DisplayPixmap(IMGCB* img_cb, jint op, void* dpy_cx, IL_Pixmap* image,
IL_Pixmap* mask, jint x, jint y, jint x_offset,
jint y_offset, jint width, jint height, jint /*req_w*/, jint /*req_h*/)
{
if ( width <= 0 || height <= 0 )
return;
QtImageData *qt_image = (QtImageData *)image->client_data;
QtImageData *qt_mask = mask ? (QtImageData *)mask->client_data : 0;
if ( qt_image )
internalDisplayPixmap( dpy_cx, qt_image->pixmap,
qt_mask ? &(qt_mask->pixmap) : 0,
x, y, x_offset,
y_offset, width, height);
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_GetIconDimensions(IMGCB* img_cb, jint op, void* dpy_cx, int* width,
int* height, jint icon_number)
{
Pixmap pm( icon_number );
*width = pm.width();
*height = pm.height();
// if ( *width <= 0 || *height <= 0 )
// *width = *height = 50;
}
extern "C"
JMC_PUBLIC_API(void)
_IMGCB_DisplayIcon(IMGCB* img_cb, jint op, void* dpy_cx, jint x, jint y,
jint icon_number)
{
Pixmap pm( icon_number );
int width = pm.width();
int height = pm.height();
internalDisplayPixmap( dpy_cx, pm, 0,
x, y, 0, 0, //##### offset???
width, height );
// useArgs("_IMGCB_DisplayIcon", img_cb, op, dpy_cx, x, y, icon_number);
}
/* Mocha image group observer callback. */
extern "C"
void
FE_MochaImageGroupObserver(XP_Observable observable, XP_ObservableMsg message,
void *message_data, void *closure)
{
useArgs("FE_MochaImageGroupObserver", observable, message, message_data, closure);
}