/******************************************************************************* * Copyright 1991-1996 by ORCA Software, Inc. * * * * All rights reserved. May not be reproduced or distributed, in printed or * * electronic form, without permission of ORCA Software, Inc. May not be * * distributed as object code, separately or linked with other object modules, * * without permission. * *******************************************************************************/ #define XI_INTERNAL #define XI_R3_COMPAT #include "xi.h" #include "xiutils.h" #if XIWS != XIWS_MAC && XIWS != XIWS_XM #include #endif XI_BITMAP * xi_bitmap_create( char *filename, XI_BITMAP_MODE mode ) { XI_BITMAP *bitmap; bitmap = XinMemoryZeroAlloc( sizeof( XI_BITMAP ) ); if ( filename != NULL ) { #if XIWS != XIWS_MAC if ( access( filename, 0 ) != -1 ) #endif bitmap->xin_bitmap = XinBitmapRead( filename ); if ( bitmap->xin_bitmap == NULL ) { XinMemoryFree( bitmap ); return NULL; } } bitmap->mode = mode; bitmap->ref_count = 1; return bitmap; } XI_BITMAP * xi_bitmap_create_res( short id, XI_BITMAP_MODE mode ) { XI_BITMAP *bitmap; bitmap = XinMemoryZeroAlloc( sizeof( XI_BITMAP ) ); if ( id != 0 ) { bitmap->xin_bitmap = XinBitmapReadRes( id ); if ( bitmap->xin_bitmap == NULL ) { XinMemoryFree( bitmap ); return NULL; } } bitmap->mode = mode; bitmap->ref_count = 1; return bitmap; } XI_BITMAP * xi_bitmap_copy( XI_BITMAP * bitmap ) { if ( bitmap != NULL ) bitmap->ref_count++; return bitmap; } void xi_bitmap_destroy( XI_BITMAP * bitmap ) { if ( bitmap != NULL && --bitmap->ref_count == 0 ) { if ( bitmap->xin_bitmap != NULL ) XinBitmapDestroy( bitmap->xin_bitmap ); XinMemoryFree( bitmap ); } } static void normal_bitmap( XI_BITMAP * bitmap, XinWindow win, XinRect * rct ) { short width, height; int x, y; XinRect src; XinRect dest; int full_width, full_height; XinBrush brush; if ( bitmap->xin_bitmap == NULL ) width = height = 0; else XinBitmapSizeGet( bitmap->xin_bitmap, &width, &height ); full_width = rct->right - rct->left; full_height = rct->bottom - rct->top; if ( bitmap->hcenter ) { if ( width > full_width ) x = 0; else x = ( full_width - width ) / 2; } else x = bitmap->x_offset; if ( bitmap->vcenter ) { if ( height > full_height ) y = 0; else y = ( full_height - height ) / 2; } else y = bitmap->y_offset; if ( x + width > full_width ) width = full_width - x; if ( y + height > full_height ) height = full_height - y; if ( bitmap->xin_bitmap != 0 ) { dest.top = rct->top + y; dest.left = rct->left + x; dest.bottom = dest.top + height; dest.right = dest.left + width; src.top = src.left = 0; src.right = width; src.bottom = height; XinWindowBitmapDraw( win, bitmap->xin_bitmap, &dest, &src ); } /* Draw background color around bitmap */ XinWindowPenSet( win, &hollow_cpen ); brush.pattern = XinBrushSolid; brush.fore_color = bitmap->background; XinWindowBrushSet( win, &brush ); if ( y > 0 ) { /* Draw top rectangle */ dest.top = rct->top; dest.left = rct->left; dest.bottom = rct->top + y; dest.right = rct->right; xi_draw_rect( win, &dest ); } if ( x > 0 ) { /* Draw left rectangle */ dest.top = rct->top + y; dest.left = rct->left; dest.bottom = dest.top + height; dest.right = rct->left + x; xi_draw_rect( win, &dest ); } if ( x + width < full_width ) { /* Draw right rectangle */ dest.top = rct->top + y; dest.left = rct->left + x + width; dest.bottom = dest.top + height; dest.right = rct->right; xi_draw_rect( win, &dest ); } if ( y + height < full_height ) { /* Draw bottom rectangle */ dest.top = rct->top + y + height; dest.left = rct->left; dest.bottom = rct->bottom; dest.right = rct->right; xi_draw_rect( win, &dest ); } } static void resize_bitmap( XI_BITMAP * bitmap, XinWindow win, XinRect * rct ) { short width, height; XinRect src; XinBitmapSizeGet( bitmap->xin_bitmap, &width, &height ); src.top = src.left = 0; src.right = width; src.bottom = height; XinWindowBitmapDraw( win, bitmap->xin_bitmap, rct, &src ); } static void tile_bitmap( XI_BITMAP * bitmap, XinWindow win, XinRect * rct, XinRect * clip_rct, BOOLEAN on_update ) { short width, height; XinRect src; XinRect dest; int full_width, full_height; int x, y; XinBitmapSizeGet( bitmap->xin_bitmap, &width, &height ); full_width = rct->right - rct->left; full_height = rct->bottom - rct->top; src.top = 0; src.left = 0; src.bottom = height; for ( y = 0; y < full_height; y += height ) { dest.top = rct->top + y; if ( clip_rct != NULL ) { if ( dest.top > clip_rct->bottom ) break; if ( dest.top + height < clip_rct->top ) continue; } if ( y + height > full_height ) src.bottom = full_height - y; src.right = width; for ( x = 0; x < full_width; x += width ) { if ( x + width > full_width ) src.right = full_width - x; dest.left = rct->left + x; dest.right = dest.left + src.right; dest.bottom = dest.top + src.bottom; if ( clip_rct != NULL ) { if ( dest.left > clip_rct->right ) break; if ( dest.right < clip_rct->left ) continue; } if ( !on_update || XinWindowPaintNeeds( win, &dest ) ) XinWindowBitmapDraw( win, bitmap->xin_bitmap, &dest, &src ); } } } void xi_bitmap_draw( XI_BITMAP * bitmap, XinWindow win, XinRect * rct, XinRect * clip_rct, BOOLEAN in_paint_event ) { XI_BITMAP_MODE mode; if ( bitmap == NULL ) return; if ( bitmap->xin_bitmap == NULL ) mode = XI_BITMAP_NORMAL; else mode = bitmap->mode; XinWindowClipSet( win, clip_rct ); switch ( mode ) { case XI_BITMAP_NORMAL: normal_bitmap( bitmap, win, rct ); break; case XI_BITMAP_RESIZE: resize_bitmap( bitmap, win, rct ); break; case XI_BITMAP_TILE: tile_bitmap( bitmap, win, rct, clip_rct, in_paint_event ); break; } } void xi_bitmap_size_get( XI_BITMAP * bitmap, short *width, short *height ) { if ( bitmap != NULL && bitmap->xin_bitmap != NULL ) XinBitmapSizeGet( bitmap->xin_bitmap, width, height ); } BOOLEAN xi_bitmap_draw_all_on_resize( XI_BITMAP * bitmap ) { if ( bitmap == NULL || bitmap->xin_bitmap == NULL ) return FALSE; return ( ( bitmap->mode == XI_BITMAP_NORMAL && ( bitmap->vcenter || bitmap->hcenter ) ) || bitmap->mode == XI_BITMAP_RESIZE ); }