HBITMAP PSBMBLTToSize( HAB hab, HPS hps, HBITMAP hbm, float fScale, ULONG ulOptions ) { BITMAPINFOHEADER2 bif2Before; BITMAPINFOHEADER2 bif2After; SIZEL slAfter; ULONG ulScreenWidth; ULONG ulScreenHeight; HDC hdcAfter; HPS hpsAfter; HBITMAP hbmAfter; POINTL aptl[ 4 ]; float fAspect; HBITMAP hbmOld; if( ( hbmOld = GpiSetBitmap( hps, hbm ) ) == HBM_ERROR ) { return( NULLHANDLE ); } memset( &bif2Before, 0, sizeof( bif2Before ) ); // get current info bif2Before.cbFix = sizeof( bif2Before ); if( GpiQueryBitmapInfoHeader( hbm, &bif2Before ) != TRUE ) { GpiSetBitmap( hps, hbmOld ); return( NULLHANDLE ); } ulScreenWidth = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); // screen width ulScreenHeight = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); // screen height fAspect = ( bif2Before.cx * 1.0 ) / ( bif2Before.cy * 1.0 ); // calculate aspect ratio if( ulOptions & SCALE_LARGEST ) { if( bif2Before.cx > bif2Before.cy ) { slAfter.cx = ( LONG )( ulScreenWidth * fScale ); slAfter.cy = ( LONG )( slAfter.cx / fAspect ); } else { slAfter.cy = ( LONG )( ulScreenHeight * fScale ); slAfter.cx = ( LONG )( slAfter.cy * fAspect ); } } else if( ulOptions & SCALE_SMALLEST ) { if( bif2Before.cx < bif2Before.cy ) { slAfter.cx = ( LONG )( ulScreenWidth * fScale ); slAfter.cy = ( LONG )( slAfter.cx / fAspect ); } else { slAfter.cy = ( LONG )( ulScreenHeight * fScale ); slAfter.cx = ( LONG )( slAfter.cy * fAspect ); } } else if( ulOptions & SCALE_HORIZONTAL ) { slAfter.cx = ( LONG )( ulScreenWidth * fScale ); if( ulOptions & SCALE_VERTICAL ) // basically, screw the aspect { slAfter.cy = ( LONG )( ulScreenHeight * fScale ); } else { slAfter.cy = ( LONG )( slAfter.cx / fAspect ); } } else if( ulOptions & SCALE_VERTICAL ) { slAfter.cy = ( LONG )( ulScreenHeight * fScale ); slAfter.cx = ( LONG )( slAfter.cy * fAspect ); } else { GpiSetBitmap( hps, hbmOld ); return( NULLHANDLE ); } if( ( hdcAfter = DevOpenDC( hab, OD_MEMORY, "*", 0L, ( PDEVOPENDATA )NULL, NULLHANDLE ) ) == NULLHANDLE ) { GpiSetBitmap( hps, hbmOld ); return( NULLHANDLE ); } if( ( hpsAfter = GpiCreatePS( hab, hdcAfter, &slAfter, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC ) ) == NULLHANDLE ) { DevCloseDC( hdcAfter ); GpiSetBitmap( hps, hbmOld ); return( NULLHANDLE ); } memset( &bif2After, 0, sizeof( bif2After ) ); bif2After.cbFix = sizeof( bif2After ); bif2After.cx = slAfter.cx; bif2After.cy = slAfter.cy; bif2After.cBitCount = bif2Before.cBitCount; bif2After.cPlanes = bif2Before.cPlanes; if( ( hbmAfter = GpiCreateBitmap( hpsAfter, // create bitmap ( PBITMAPINFOHEADER2 )&( bif2After ), ( ULONG )FALSE, NULL, NULL ) ) == NULLHANDLE ) { GpiDestroyPS( hpsAfter ); DevCloseDC( hdcAfter ); GpiSetBitmap( hps, hbmOld ); return( NULLHANDLE ); } if( GpiSetBitmap( hpsAfter, hbmAfter ) == HBM_ERROR ) { GpiDeleteBitmap( hbmAfter ); GpiDestroyPS( hpsAfter ); DevCloseDC( hdcAfter ); GpiSetBitmap( hps, hbmOld ); return( NULLHANDLE ); } aptl[ 0 ].x = 0; aptl[ 0 ].y = 0; aptl[ 1 ].x = slAfter.cx; aptl[ 1 ].y = slAfter.cy; aptl[ 2 ].x = 0; aptl[ 2 ].y = 0; aptl[ 3 ].x = bif2Before.cx; aptl[ 3 ].y = bif2Before.cy; if( GpiBitBlt( hpsAfter, hps, 4L, aptl, ROP_SRCCOPY, BBO_IGNORE ) == GPI_ERROR ) { GpiSetBitmap( hpsAfter, NULLHANDLE ); GpiDeleteBitmap( hbmAfter ); GpiDestroyPS( hpsAfter ); DevCloseDC( hdcAfter ); GpiSetBitmap( hps, hbmOld ); return( NULLHANDLE ); } GpiSetBitmapDimension( hbmAfter, &slAfter ); GpiSetBitmap( hpsAfter, NULLHANDLE ); GpiDestroyPS( hpsAfter ); DevCloseDC( hdcAfter ); GpiSetBitmap( hps, hbmOld ); return( hbmAfter ); }
static grPMSurface* init_surface( grPMSurface* surface, grBitmap* bitmap ) { PBITMAPINFO2 bit; SIZEL sizl = { 0, 0 }; LONG palette[256]; LOG(( "Os2PM: init_surface( %08lx, %08lx )\n", (long)surface, (long)bitmap )); LOG(( " -- input bitmap =\n" )); LOG(( " -- mode = %d\n", bitmap->mode )); LOG(( " -- grays = %d\n", bitmap->grays )); LOG(( " -- width = %d\n", bitmap->width )); LOG(( " -- height = %d\n", bitmap->rows )); /* create the bitmap - under OS/2, we support all modes as PM */ /* handles all conversions automatically.. */ if ( grNewBitmap( bitmap->mode, bitmap->grays, bitmap->width, bitmap->rows, bitmap ) ) return 0; LOG(( " -- output bitmap =\n" )); LOG(( " -- mode = %d\n", bitmap->mode )); LOG(( " -- grays = %d\n", bitmap->grays )); LOG(( " -- width = %d\n", bitmap->width )); LOG(( " -- height = %d\n", bitmap->rows )); bitmap->pitch = -bitmap->pitch; surface->root.bitmap = *bitmap; /* create the image and event lock */ DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE ); DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE ); /* create the image's presentation space */ surface->image_dc = DevOpenDC( gr_anchor, OD_MEMORY, (PSZ)"*", 0L, 0L, 0L ); surface->image_ps = GpiCreatePS( gr_anchor, surface->image_dc, &sizl, PU_PELS | GPIT_MICRO | GPIA_ASSOC | GPIF_DEFAULT ); GpiSetBackMix( surface->image_ps, BM_OVERPAINT ); /* create the image's PM bitmap */ bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) ); surface->bitmap_header = bit; bit->cbFix = sizeof( BITMAPINFOHEADER2 ); bit->cx = surface->root.bitmap.width; bit->cy = surface->root.bitmap.rows; bit->cPlanes = 1; bit->argbColor[0].bBlue = 255; bit->argbColor[0].bGreen = 0; bit->argbColor[0].bRed = 0; bit->argbColor[1].bBlue = 0; bit->argbColor[1].bGreen = 255; bit->argbColor[1].bRed = 0; bit->cBitCount = (bitmap->mode == gr_pixel_mode_gray ? 8 : 1 ); if (bitmap->mode == gr_pixel_mode_gray) { RGB2* color = bit->argbColor; int x, count; count = bitmap->grays; for ( x = 0; x < count; x++, color++ ) { color->bBlue = color->bGreen = color->bRed = (((count-x)*255)/count); } } else { RGB2* color = bit->argbColor; color[0].bBlue = color[0].bGreen = color[0].bRed = 0; color[1].bBlue = color[1].bGreen = color[1].bRed = 255; } surface->os2_bitmap = GpiCreateBitmap( surface->image_ps, (PBITMAPINFOHEADER2)bit, 0L, NULL, NULL ); GpiSetBitmap( surface->image_ps, surface->os2_bitmap ); bit->cbFix = sizeof( BITMAPINFOHEADER2 ); GpiQueryBitmapInfoHeader( surface->os2_bitmap, (PBITMAPINFOHEADER2)bit ); surface->bitmap_header = bit; /* for gr_pixel_mode_gray, create a gray-levels logical palette */ if ( bitmap->mode == gr_pixel_mode_gray ) { int x, count; count = bitmap->grays; for ( x = 0; x < count; x++ ) palette[x] = (((count-x)*255)/count) * 0x010101; /* create logical color table */ GpiCreateLogColorTable( surface->image_ps, (ULONG) LCOL_PURECOLOR, (LONG) LCOLF_CONSECRGB, (LONG) 0L, (LONG) count, (PLONG) palette ); /* now, copy the color indexes to surface->shades */ for ( x = 0; x < count; x++ ) surface->shades[x] = GpiQueryColorIndex( surface->image_ps, 0, palette[x] ); } /* set up the blit points array */ surface->blit_points[1].x = surface->root.bitmap.width; surface->blit_points[1].y = surface->root.bitmap.rows; surface->blit_points[3] = surface->blit_points[1]; /* Finally, create the event handling thread for the surface's window */ DosCreateThread( &surface->message_thread, (PFNTHREAD) RunPMWindow, (ULONG) surface, 0UL, 32920 ); /* wait for the window creation */ LOCK(surface->image_lock); UNLOCK(surface->image_lock); surface->root.done = (grDoneSurfaceFunc) done_surface; surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle; surface->root.set_title = (grSetTitleFunc) set_title; surface->root.listen_event = (grListenEventFunc) listen_event; /* convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows ); */ return surface; }
// ******************************************************************************* // FUNCTION: DuplicateBitmap // // FUNCTION USE: Duplicates a bitmap // // DESCRIPTION: Uses GpiBitBlt to make a copy of a bitmap by bit-bliting the // contents of the source PS containing the bitmap, to the target // presentation space. // // PARAMETERS: HBITMAP source bitmap handle to copy // // RETURNS: HBITMAP target bitmap handle // // HISTORY: // // ******************************************************************************* HBITMAP DuplicateBitmap (HBITMAP hbmSource) { HAB hab; HBITMAP hbmTarget; HDC hdcSource; HDC hdcTarget; HPS hpsSource; HPS hpsTarget; SIZEL sizl; POINTL aptl[3]; BOOL bError = FALSE; BITMAPINFOHEADER2 bmp2; // -------------------------------------------------------------------------- // Get an anchor block handle // -------------------------------------------------------------------------- hab = WinQueryAnchorBlock(HWND_DESKTOP); // -------------------------------------------------------------------------- // Create memory device context handles and presentation space handles // -------------------------------------------------------------------------- hdcSource = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE); hdcTarget = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULLHANDLE); // -------------------------------------------------------------------------- // Set presentation space size // -------------------------------------------------------------------------- sizl.cx = 0; sizl.cy = 0; // -------------------------------------------------------------------------- // Create our source presentation space // -------------------------------------------------------------------------- hpsSource = GpiCreatePS (hab, hdcSource, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC); // -------------------------------------------------------------------------- // Create our target presentation space // -------------------------------------------------------------------------- hpsTarget = GpiCreatePS (hab, hdcTarget, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC); // -------------------------------------------------------------------------- // Initialize the bitmap info header structure // -------------------------------------------------------------------------- // memset(&bmp2, NULL, sizeof(BITMAPINFOHEADER2)); // -------------------------------------------------------------------------- // Set the size of the structure // -------------------------------------------------------------------------- bmp2.cbFix = sizeof (BITMAPINFOHEADER2); // -------------------------------------------------------------------------- // Get the bitmap information header from the source bitmap // -------------------------------------------------------------------------- GpiQueryBitmapInfoHeader (hbmSource, &bmp2); // -------------------------------------------------------------------------- // Create our target bitmap using the bitmap information header from // our source bitmap. // -------------------------------------------------------------------------- hbmTarget = GpiCreateBitmap (hpsTarget, &bmp2, 0L, NULL, NULL); // -------------------------------------------------------------------------- // If everything is cool, set the bitmaps into our presentation spaces. // -------------------------------------------------------------------------- if (hbmTarget != GPI_ERROR) { GpiSetBitmap (hpsSource, hbmSource); GpiSetBitmap (hpsTarget, hbmTarget); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = bmp2.cx; aptl[1].y = bmp2.cy; aptl[2].x = 0; aptl[2].y = 0; // -------------------------------------------------------------------------- // Bit blit the contents of the source presentation space into our target // presentation space. This is how we copy the bitmap from the source to // the target. // -------------------------------------------------------------------------- bError = GpiBitBlt (hpsTarget, // Target presentation space handle hpsSource, // Source presentation space handle 3L, // Number of Points aptl, // Array of Points ROP_SRCCOPY, // Mixing function (source copy) BBO_IGNORE); // Options // -------------------------------------------------------------------------- // If we get an error copying from our source PS to our target PS // set the error flag to TRUE so that we can return GPI_ERROR back // to the caller. // -------------------------------------------------------------------------- if (bError == GPI_ERROR) { bError = TRUE; } // -------------------------------------------------------------------------- // If we got a value back from GpiBitBlt reset our error flag since // bError would be TRUE. // -------------------------------------------------------------------------- else { bError = FALSE; } } // -------------------------------------------------------------------------- // If we get an error creating the bitmap set the bError flag to TRUE // so we can return GPI_ERROR telling the caller that the function failed. // -------------------------------------------------------------------------- else { bError = TRUE; } // -------------------------------------------------------------------------- // Regardless of what happens, we will free all of our graphics engine // resources by destroying our presentation spaces and device context // handles. // -------------------------------------------------------------------------- GpiDestroyPS (hpsSource); GpiDestroyPS (hpsTarget); DevCloseDC (hdcSource); DevCloseDC (hdcTarget); // -------------------------------------------------------------------------- // If we get an error trying to duplicate the bitmap, return GPI_ERROR. // -------------------------------------------------------------------------- if (bError) { return GPI_ERROR; } // -------------------------------------------------------------------------- // If everthing worked like a champ, return the bitmap handle. // -------------------------------------------------------------------------- else { return hbmTarget; } }
nsresult nsIconChannel::MakeInputStream(nsIInputStream **_retval, bool nonBlocking) { // get some details about this icon nsCOMPtr<nsIFile> localFile; uint32_t desiredImageSize; nsXPIDLCString contentType; nsAutoCString filePath; nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(localFile), &desiredImageSize, contentType, filePath); NS_ENSURE_SUCCESS(rv, rv); // if the file exists, get its path bool fileExists = false; if (localFile) { localFile->GetNativePath(filePath); localFile->Exists(&fileExists); } // get the file's icon from either the WPS or PM bool fWpsIcon = false; HPOINTER hIcon = GetIcon(filePath, fileExists, desiredImageSize <= 16, &fWpsIcon); if (hIcon == NULLHANDLE) return NS_ERROR_FAILURE; // get the color & mask bitmaps used by the icon POINTERINFO IconInfo; if (!WinQueryPointerInfo(hIcon, &IconInfo)) { DestroyIcon(hIcon, fWpsIcon); return NS_ERROR_FAILURE; } // if we need a mini-icon, use those bitmaps if present; // otherwise, signal that the icon needs to be shrunk bool fShrink = FALSE; if (desiredImageSize <= 16) { if (IconInfo.hbmMiniPointer) { IconInfo.hbmColor = IconInfo.hbmMiniColor; IconInfo.hbmPointer = IconInfo.hbmMiniPointer; } else { fShrink = TRUE; } } // various resources to be allocated PBITMAPINFO2 pBMInfo = 0; uint8_t* pInBuf = 0; uint8_t* pOutBuf = 0; HDC hdc = 0; HPS hps = 0; // using this dummy do{...}while(0) "loop" guarantees that resources will // be deallocated, but eliminates the need for nesting, and generally makes // testing for & dealing with errors pretty painless (just 'break') do { rv = NS_ERROR_FAILURE; // get the details for the color bitmap; if there isn't one // or this is 1-bit color, exit BITMAPINFOHEADER2 BMHeader; BMHeader.cbFix = sizeof(BMHeader); if (!IconInfo.hbmColor || !GpiQueryBitmapInfoHeader(IconInfo.hbmColor, &BMHeader) || BMHeader.cBitCount == 1) break; // alloc space for the color bitmap's info, including its color table uint32_t cbBMInfo = sizeof(BITMAPINFO2) + (sizeof(RGB2) * 255); pBMInfo = (PBITMAPINFO2)nsMemory::Alloc(cbBMInfo); if (!pBMInfo) break; // alloc space for the color bitmap data uint32_t cbInRow = ALIGNEDBPR(BMHeader.cx, BMHeader.cBitCount); uint32_t cbInBuf = cbInRow * BMHeader.cy; pInBuf = (uint8_t*)nsMemory::Alloc(cbInBuf); if (!pInBuf) break; memset(pInBuf, 0, cbInBuf); // alloc space for the BGRA32 bitmap we're creating uint32_t cxOut = fShrink ? BMHeader.cx / 2 : BMHeader.cx; uint32_t cyOut = fShrink ? BMHeader.cy / 2 : BMHeader.cy; uint32_t cbOutBuf = 2 + ALIGNEDBPR(cxOut, 32) * cyOut; pOutBuf = (uint8_t*)nsMemory::Alloc(cbOutBuf); if (!pOutBuf) break; memset(pOutBuf, 0, cbOutBuf); // create a DC and PS DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL}; hdc = DevOpenDC((HAB)0, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE); if (!hdc) break; SIZEL sizel = {0,0}; hps = GpiCreatePS((HAB)0, hdc, &sizel, GPIA_ASSOC | PU_PELS | GPIT_MICRO); if (!hps) break; // get the color bits memset(pBMInfo, 0, cbBMInfo); *((PBITMAPINFOHEADER2)pBMInfo) = BMHeader; GpiSetBitmap(hps, IconInfo.hbmColor); if (GpiQueryBitmapBits(hps, 0L, (LONG)BMHeader.cy, (BYTE*)pInBuf, pBMInfo) <= 0) break; // The first 2 bytes are the width & height of the icon in pixels, // the remaining bytes are BGRA32 (B in first byte, A in last) uint8_t* outPtr = pOutBuf; *outPtr++ = (uint8_t)cxOut; *outPtr++ = (uint8_t)cyOut; // convert the color bitmap pBMInfo->cbImage = cbInBuf; ConvertColorBitMap(pInBuf, pBMInfo, outPtr, fShrink); // now we need to tack on the alpha data, so jump back to the first // pixel in the output buffer outPtr = pOutBuf+2; // Get the mask info BMHeader.cbFix = sizeof(BMHeader); if (!GpiQueryBitmapInfoHeader(IconInfo.hbmPointer, &BMHeader)) break; // if the existing input buffer isn't large enough, reallocate it cbInRow = ALIGNEDBPR(BMHeader.cx, BMHeader.cBitCount); if ((cbInRow * BMHeader.cy) > cbInBuf) // Need more for mask { cbInBuf = cbInRow * BMHeader.cy; nsMemory::Free(pInBuf); pInBuf = (uint8_t*)nsMemory::Alloc(cbInBuf); memset(pInBuf, 0, cbInBuf); } // get the mask/alpha bits memset(pBMInfo, 0, cbBMInfo); *((PBITMAPINFOHEADER2)pBMInfo) = BMHeader; GpiSetBitmap(hps, IconInfo.hbmPointer); if (GpiQueryBitmapBits(hps, 0L, (LONG)BMHeader.cy, (BYTE*)pInBuf, pBMInfo) <= 0) break; // convert the mask/alpha bitmap pBMInfo->cbImage = cbInBuf; ConvertMaskBitMap(pInBuf, pBMInfo, outPtr, fShrink); // create a pipe nsCOMPtr<nsIInputStream> inStream; nsCOMPtr<nsIOutputStream> outStream; rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream), cbOutBuf, cbOutBuf, nonBlocking); if (NS_FAILED(rv)) break; // put our data into the pipe uint32_t written; rv = outStream->Write(reinterpret_cast<const char*>(pOutBuf), cbOutBuf, &written); if (NS_FAILED(rv)) break; // success! so addref the pipe NS_ADDREF(*_retval = inStream); } while (0); // free all the resources we allocated if (pOutBuf) nsMemory::Free(pOutBuf); if (pInBuf) nsMemory::Free(pInBuf); if (pBMInfo) nsMemory::Free(pBMInfo); if (hps) { GpiAssociate(hps, NULLHANDLE); GpiDestroyPS(hps); } if (hdc) DevCloseDC(hdc); if (hIcon) DestroyIcon(hIcon, fWpsIcon); return rv; }
BOOL CreateImages(PLUGINSHARE *pPluginData) { int i; HBITMAP hbmTemp; HAB hab = WinQueryAnchorBlock(HWND_DESKTOP); HDC hdcSrc, hdcDest; HPS hpsSrc, hpsDest; SIZEL slHPS; BITMAPINFOHEADER2 bif2Src, bif2Dest; POINTL aptl[4]; if (pPluginData == NULL) return (FALSE); hbmTemp = SetupBitmapFromFile(HWND_DESKTOP, pPluginData->szImageFile/*, 22*/); if (hbmTemp == NULLHANDLE) return FALSE; memset(&bif2Src, 0, sizeof(bif2Src)); bif2Src.cbFix = sizeof(bif2Src); GpiQueryBitmapInfoHeader(hbmTemp, &bif2Src); hdcSrc = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, NULLHANDLE); slHPS.cx = bif2Src.cx; slHPS.cy = bif2Src.cy; pPluginData->ulCx=slHPS.cx; pPluginData->ulCy=slHPS.cy; hpsSrc = GpiCreatePS(hab, hdcSrc, &slHPS, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC); GpiSetBitmap(hpsSrc, hbmTemp); hdcDest = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, NULLHANDLE); slHPS.cx = bif2Src.cx / 2; slHPS.cy = bif2Src.cy / 5; hpsDest = GpiCreatePS(hab, hdcDest, &slHPS, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC); memset(&bif2Dest, 0, sizeof(bif2Dest)); bif2Dest.cbFix = sizeof(bif2Dest); bif2Dest.cx = slHPS.cx; bif2Dest.cy = slHPS.cy; bif2Dest.cBitCount = 24; bif2Dest.cPlanes = 1; //Close Button pPluginData->hbmActiveClose = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmActiveClose); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = 0; aptl[2].y = 0; aptl[3].x = slHPS.cx; aptl[3].y = slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Minimize Button pPluginData->hbmActiveMinimize = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmActiveMinimize); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = 0; aptl[2].y = slHPS.cy * 1; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Maximize Button pPluginData->hbmActiveMaximize = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmActiveMaximize); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = 0; aptl[2].y = slHPS.cy * 2; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Restore Button pPluginData->hbmActiveRestore = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmActiveRestore); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = 0; aptl[2].y = slHPS.cy * 3; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Hide Button pPluginData->hbmActiveHide = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmActiveHide); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = 0; aptl[2].y = slHPS.cy * 4; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); /* Inactive... */ //Close Button pPluginData->hbmInactiveClose = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmInactiveClose); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = slHPS.cx ; aptl[2].y = 0; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Minimize Button pPluginData->hbmInactiveMinimize = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmInactiveMinimize); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = slHPS.cx; aptl[2].y = slHPS.cy * 1; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Maximize Button pPluginData->hbmInactiveMaximize = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmInactiveMaximize); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = slHPS.cx; aptl[2].y = slHPS.cy * 2; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Restore Button pPluginData->hbmInactiveRestore = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmInactiveRestore); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = slHPS.cx; aptl[2].y = slHPS.cy * 3; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); //Hide Button pPluginData->hbmInactiveHide = GpiCreateBitmap(hpsDest, &bif2Dest, 0L, NULL, NULL); GpiSetBitmap(hpsDest, pPluginData->hbmInactiveHide); aptl[0].x = 0; aptl[0].y = 0; aptl[1].x = slHPS.cx; aptl[1].y = slHPS.cy; aptl[2].x = slHPS.cx; aptl[2].y = slHPS.cy * 4; aptl[3].x = aptl[2].x + slHPS.cx; aptl[3].y = aptl[2].y + slHPS.cy; GpiBitBlt(hpsDest, hpsSrc, 4, aptl, ROP_SRCCOPY, BBO_IGNORE); GpiSetBitmap(hpsSrc, NULLHANDLE); if (hbmTemp != NULLHANDLE) GpiDeleteBitmap(hbmTemp); if (hpsSrc != NULLHANDLE) GpiDestroyPS(hpsSrc); if (hdcSrc != NULLHANDLE) DevCloseDC(hdcSrc); GpiSetBitmap(hpsDest, NULLHANDLE); if (hpsDest != NULLHANDLE) GpiDestroyPS(hpsDest); if (hdcDest != NULLHANDLE) DevCloseDC(hdcDest); return TRUE; }
XBitmap XBitmap::operator = (const XBitmap & b) { /**** BITMAPINFOHEADER2 * head; head = (BITMAPINFOHEADER2 *) malloc( sizeof(BITMAPINFOHEADER2)); owner = b.owner; if (owner && hps == 0) hps = WinGetPS(owner->GetHandle()); if (hbm != 0) GpiDeleteBitmap(hbm); head->cbFix = sizeof(BITMAPINFOHEADER2); GpiSetBitmap(b.hps, b.hbm); if( GpiQueryBitmapInfoHeader(b.hbm, head) == FALSE) OOLThrow("error copying bitmap", 3); LONG offBits = sizeof(BITMAPINFO2) + (sizeof(RGB2) * (1 << head->cBitCount)); LONG size = (((head->cBitCount * head->cx) + 31) / 32) * 4 * head->cPlanes * head->cy; head = (BITMAPINFOHEADER2 *) realloc(head, offBits); void * buffer = malloc(size); if( GpiQueryBitmapBits(b.hps, 0, head->cy, (PBYTE) buffer, (BITMAPINFO2 *) head) == GPI_ALTERROR) OOLThrow("error query bitmap data", 3); // hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) &p->bmp, CBM_INIT, (PBYTE) p + p->offBits, (PBITMAPINFO2) &p->bmp); hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) head, CBM_INIT, (PBYTE) buffer, (PBITMAPINFO2) head); if(hbm == 0) XProcess::Beep(300,300); GpiSetBitmap(hps, hbm); XSize s; b.GetDimensions(&s); cx = s.GetWidth(); cy = s.GetHeight(); width = b.width; height = b.height; p = b.p; free(head); free(buffer); return *this; ****/ BITMAPFILEHEADER2 * head; owner = b.owner; if (owner && hps == 0) hps = WinGetPS(owner->GetHandle()); if (hbm != 0) GpiDeleteBitmap(hbm); head = (BITMAPFILEHEADER2 *) malloc(sizeof(BITMAPFILEHEADER2)); head->bmp2.cbFix = sizeof(BITMAPINFOHEADER2); GpiQueryBitmapInfoHeader(b.hbm, &head->bmp2); head->offBits = sizeof(BITMAPFILEHEADER2) + (sizeof(RGB2) * (1 << head->bmp2.cBitCount)); LONG size = head->offBits + (((head->bmp2.cBitCount * head->bmp2.cx) + 31) / 32) * 4 * head->bmp2.cPlanes * head->bmp2.cy; head = (BITMAPFILEHEADER2 *) realloc(head, size); head->usType = BFT_BMAP; head->xHotspot = head->yHotspot = 0; head->cbSize = sizeof(BITMAPFILEHEADER2); GpiSetBitmap(hps, b.hbm); /*** head->bmp2.cbFix=16; head->bmp2.cPlanes =1; head->bmp2.cBitCount = 1; ****/ GpiQueryBitmapBits(hps, 0, head->bmp2.cy, (PBYTE) head + head->offBits, (BITMAPINFO2 *) &head->bmp2); hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) &head->bmp2, CBM_INIT, (PBYTE) head + head->offBits, (PBITMAPINFO2) &head->bmp2); GpiSetBitmap(hps, hbm); XSize s; b.GetDimensions(&s); cx = s.GetWidth(); cy = s.GetHeight(); width = b.width; height = b.height; p = b.p; free(head); return *this; }
// static QPixmap QPixmap::fromPmHBITMAP(HBITMAP hbm, HBITMAP hbmMask) { QPixmap res; if (hbm == NULLHANDLE) return res; // bitmap header + 2 palette entries (for the monochrome bitmap) char bmi[sizeof(BITMAPINFOHEADER2) + 4 * 2]; memset(bmi, 0, sizeof(bmi)); PBITMAPINFOHEADER2 bmh = (PBITMAPINFOHEADER2)bmi; bmh->cbFix = sizeof(BITMAPINFOHEADER2); PULONG pal = (PULONG)(bmi + sizeof(BITMAPINFOHEADER2)); if (!GpiQueryBitmapInfoHeader(hbm, bmh)) return res; HPS hps = qt_alloc_mem_ps(bmh->cx, bmh->cy * 2); if (hps == NULLHANDLE) return res; GpiSetBitmap(hps, hbm); QImage img; bool succeeded = false; if (bmh->cPlanes == 1 && bmh->cBitCount == 1) { // monochrome bitmap img = QImage(bmh->cx, bmh->cy, QImage::Format_Mono); if (GpiQueryBitmapBits(hps, 0, img.height(), (PBYTE)img.bits(), (PBITMAPINFO2)&bmi) != GPI_ALTERROR) { succeeded = true; // take the palette QVector<QRgb> colors(2); colors[0] = QRgb(pal[0]); colors[1] = QRgb(pal[1]); img.setColorTable(colors); } } else { // always convert to 32-bit otherwise img = QImage(bmh->cx, bmh->cy, QImage::Format_RGB32); bmh->cPlanes = 1; bmh->cBitCount = 32; if (GpiQueryBitmapBits(hps, 0, img.height(), (PBYTE)img.bits(), (PBITMAPINFO2)&bmi) != GPI_ALTERROR) { succeeded = true; // try to auto-detect if there is a real alpha channel bool allZero = true; for (int i = 0; i < img.numBytes(); ++i) { if (img.bits()[i] & 0xFF000000) { allZero = false; break; } } if (!allZero) { // assume we've got the alpha channel QImage alphaImg = QImage(bmh->cx, bmh->cy, QImage::Format_ARGB32); memcpy(alphaImg.bits(), img.bits(), img.numBytes()); img = alphaImg; } // flip the bitmap top to bottom to cancel PM inversion img = img.mirrored(); } } QImage mask; if (hbmMask != NULLHANDLE && GpiQueryBitmapInfoHeader(hbmMask, bmh)) { // get the AND+XOR mask if ((int)bmh->cx == img.width() && (int)bmh->cy == img.height() * 2 && bmh->cPlanes == 1 && bmh->cBitCount == 1) { GpiSetBitmap(hps, hbmMask); mask = QImage(bmh->cx, bmh->cy, QImage::Format_Mono); if (GpiQueryBitmapBits(hps, 0, mask.height(), (PBYTE)mask.bits(), (PBITMAPINFO2)&bmi) != GPI_ALTERROR) { // take the palette QVector<QRgb> colors(2); colors[0] = QRgb(pal[0]); colors[1] = QRgb(pal[1]); mask.setColorTable(colors); // flip the bitmap top to bottom to cancel PM inversion mask = mask.mirrored(false, true); // drop the XOR mask mask = mask.copy(0, 0, mask.width(), mask.height() / 2); // create a normal mask from the AND mask mask.invertPixels(); } else { mask = QImage(); } GpiSetBitmap(hps, NULLHANDLE); } else { Q_ASSERT(false); } } qt_free_mem_ps(hps); if (succeeded) { res = QPixmap::fromImage(img); if (!mask.isNull()) res.setMask(QBitmap::fromImage(mask)); } return res; }
// tiles an image across preview window BOOL DrawImage(PSPAINT * pPaint, HBITMAP hbm, HBITMAP hbmMask) { SIZEL slHps; BITMAPINFOHEADER2 bif2; BITMAPINFOHEADER2 bif; POINTL aptl[3]; HDC hdc; HPS hps; HAB hab = WinQueryAnchorBlock(pPaint->hwnd); long starty; RECTL rectl; rectl.xLeft = pPaint->rectlWindow.xLeft; /* if ( pPaint->rectlWindow.xRight < (pPaint->rectlWindow.xLeft + 16) ) rectl.xRight = pPaint->rectlWindow.xRight; else rectl.xRight = pPaint->rectlWindow.xLeft + 16; */ if ( (pPaint->rectlWindow.yTop - pPaint->rectlWindow.yBottom) < 16) { rectl.yTop = pPaint->rectlWindow.yTop; rectl.yBottom = pPaint->rectlWindow.yBottom; } else { rectl.yBottom = ((pPaint->rectlWindow.yTop + pPaint->rectlWindow.yBottom + 1) / 2) - 8; rectl.yTop = rectl.yBottom + 16; } // setup source bitmap hdc = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, NULLHANDLE); // get bitmap info memset(&bif2, 0, sizeof(bif2)); bif2.cbFix = sizeof(bif2); GpiQueryBitmapInfoHeader(hbm, &bif2); // create source hps slHps.cx = bif2.cx; slHps.cy = bif2.cy; hps = GpiCreatePS(hab, hdc, &slHps, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC); if ( pPaint->rectlWindow.xRight < (pPaint->rectlWindow.xLeft + slHps.cx) ) rectl.xRight = pPaint->rectlWindow.xRight; else rectl.xRight = pPaint->rectlWindow.xLeft + slHps.cx; // initial blt location aptl[0].x = rectl.xLeft; aptl[0].y = rectl.yBottom; aptl[1].x = rectl.xRight; aptl[1].y = rectl.yTop; aptl[2].x = 0; aptl[2].y = 0; if(hbmMask) { // set mask bmp into hps GpiSetBitmap(hps, hbmMask); GpiBitBlt(pPaint->hps, hps, 3L, aptl, ROP_MERGEPAINT, BBO_IGNORE); // set bmp into hps GpiSetBitmap(hps, hbm); GpiBitBlt(pPaint->hps, hps, 3L, aptl, ROP_SRCAND, BBO_IGNORE); } else { // set bmp into hps GpiSetBitmap(hps, hbm); GpiBitBlt(pPaint->hps, hps, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE); } // clean up GpiSetBitmap(hps, NULLHANDLE); GpiDestroyPS(hps); DevCloseDC(hdc); return (TRUE); }