Support for image copying, using nsImageClipboard helper object. r=saari, sr=sfraser.

This commit is contained in:
pinkerton%netscape.com 2001-01-23 01:09:58 +00:00
Родитель ef72f4906b
Коммит 6222a4419a
3 изменённых файлов: 90 добавлений и 132 удалений

Просмотреть файл

@ -23,7 +23,6 @@
*/
#include "nsClipboard.h"
#include <windows.h>
#include <OLE2.h>
#include <SHLOBJ.H>
#include <INTSHCUT.H>
@ -39,6 +38,7 @@
#include "nsXPIDLString.h"
#include "nsPrimitiveHelpers.h"
#include "nsIURL.h"
#include "nsImageClipboard.h"
#include "nsIWidget.h"
#include "nsIComponentManager.h"
@ -47,14 +47,9 @@
#include "nsVoidArray.h"
#include "nsFileSpec.h"
#include "nsGfxCIID.h"
#include "nsIImage.h"
#define DEBUG_PINK 0
static NS_DEFINE_IID(kCImageCID, NS_IMAGE_CID);
//-------------------------------------------------------------------------
//
// nsClipboard constructor
@ -95,9 +90,6 @@ UINT nsClipboard::GetFormat(const char* aMimeStr)
else
format = ::RegisterClipboardFormat(aMimeStr);
#if DEBUG_PINK
printf("nsClipboard::GetFormat [%s] 0x%x\n", aMimeStr, format);
#endif
return format;
}
@ -155,13 +147,10 @@ nsresult nsClipboard::SetupNativeDataObject(nsITransferable * aTransferable, IDa
currentFlavor->ToString(getter_Copies(flavorStr));
UINT format = GetFormat(flavorStr);
// check here to see if we can the data back from global member
// XXX need IStream support, or file support
// Now tell the native IDataObject about both our mime type and
// the native data format
FORMATETC fe;
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
// Now tell the native IDataObject about both the DataFlavor and
// the native data format
dObj->AddDataFlavor(flavorStr, &fe);
// Do various things internal to the implementation, like map one
@ -170,24 +159,31 @@ nsresult nsClipboard::SetupNativeDataObject(nsITransferable * aTransferable, IDa
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
// if we find text/unicode, also advertise text/plain (which we will convert
// on our own in nsDataObj::GetText().
FORMATETC fe2;
SET_FORMATETC(fe2, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
dObj->AddDataFlavor(kTextMime, &fe2);
FORMATETC textFE;
SET_FORMATETC(textFE, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
dObj->AddDataFlavor(kTextMime, &textFE);
}
if ( strcmp(flavorStr, kURLMime) == 0 ) {
else if ( strcmp(flavorStr, kURLMime) == 0 ) {
// if we're a url, in addition to also being text, we need to register
// the "file" flavors so that the win32 shell knows to create an internet
// shortcut when it sees one of these beasts.
FORMATETC fe2;
SET_FORMATETC(fe2, ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
dObj->AddDataFlavor(kURLMime, &fe2);
SET_FORMATETC(fe2, ::RegisterClipboardFormat(CFSTR_FILECONTENTS), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
dObj->AddDataFlavor(kURLMime, &fe2);
FORMATETC shortcutFE;
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
dObj->AddDataFlavor(kURLMime, &shortcutFE);
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILECONTENTS), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
dObj->AddDataFlavor(kURLMime, &shortcutFE);
#ifdef CFSTR_SHELLURL
SET_FORMATETC(fe2, ::RegisterClipboardFormat(CFSTR_SHELLURL), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
dObj->AddDataFlavor(kURLMime, &fe2);
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_SHELLURL), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
dObj->AddDataFlavor(kURLMime, &shortcutFE);
#endif
}
else if ( strcmp(flavorStr, kPNGImageMime) == 0 || strcmp(flavorStr, kJPEGImageMime) == 0 ||
strcmp(flavorStr, kGIFImageMime) == 0 ) {
// if we're an image, register the native bitmap flavor
FORMATETC imageFE;
SET_FORMATETC(imageFE, CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
dObj->AddDataFlavor(flavorStr, &imageFE);
}
}
}
@ -339,59 +335,6 @@ static HRESULT FillSTGMedium(IDataObject * aDataObject, UINT aFormat, LPFORMATET
return hres;
}
/*------------------------------------------------------------------
DibCopyFromPackedDib is generally used for pasting DIBs from the
clipboard.
------------------------------------------------------------------*/
PRUint8 * GetDIBBits(BITMAPINFO * aBitmapInfo)
{
BYTE * bits ;
DWORD headerSize;
DWORD maskSize;
DWORD colorSize;
// Get the size of the information header
headerSize = aBitmapInfo->bmiHeader.biSize ;
if (headerSize != sizeof (BITMAPCOREHEADER) &&
headerSize != sizeof (BITMAPINFOHEADER) &&
//headerSize != sizeof (BITMAPV5HEADER) &&
headerSize != sizeof (BITMAPV4HEADER)) {
return NULL ;
}
// Get the size of the color masks
if (headerSize == sizeof (BITMAPINFOHEADER) &&
aBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) {
maskSize = 3 * sizeof (DWORD);
} else {
maskSize = 0;
}
// Get the size of the color table
if (headerSize == sizeof (BITMAPCOREHEADER)) {
int iBitCount = ((BITMAPCOREHEADER *) aBitmapInfo)->bcBitCount;
if (iBitCount <= 8) {
colorSize = (1 << iBitCount) * sizeof (RGBTRIPLE);
} else {
colorSize = 0 ;
}
} else { // All non-OS/2 compatible DIBs
if (aBitmapInfo->bmiHeader.biClrUsed > 0) {
colorSize = aBitmapInfo->bmiHeader.biClrUsed * sizeof (RGBQUAD);
} else if (aBitmapInfo->bmiHeader.biBitCount <= 8) {
colorSize = (1 << aBitmapInfo->bmiHeader.biBitCount) * sizeof (RGBQUAD);
} else {
colorSize = 0;
}
}
bits = (BYTE *) aBitmapInfo + headerSize + maskSize + colorSize ;
return bits;
}
//-------------------------------------------------------------------------
nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT aIndex, UINT aFormat, void ** aData, PRUint32 * aLen)
@ -456,43 +399,20 @@ nsresult nsClipboard::GetNativeDataOffClipboard(IDataObject * aDataObject, UINT
case CF_DIB :
{
// This creates an nsIImage from
// the DIB info on the clipboard
HGLOBAL hGlobal = stm.hGlobal;
BYTE * pGlobal = (BYTE *)::GlobalLock (hGlobal) ;
BITMAPV4HEADER * header = (BITMAPV4HEADER *)pGlobal;
nsIImage * image;
nsresult rv = nsComponentManager::CreateInstance(kCImageCID, nsnull,
NS_GET_IID(nsIImage),
(void**) &image);
if (NS_OK == rv) {
// pull the size informat out of the BITMAPINFO header and
// initializew the image
PRInt32 width = header->bV4Width;
PRInt32 height = header->bV4Height;
PRInt32 depth = header->bV4BitCount;
PRUint8 * bits = GetDIBBits((BITMAPINFO *)pGlobal);
// BUG 44369 notes problems with the GFX image code handling
// depths other than 8 or 24 bits. Ensure that's what we have
// before we try to work with the image. (pinkerton)
if ( depth == 24 || depth == 8 ) {
image->Init(width, height, depth, nsMaskRequirements_kNoMask);
// Now, copy the image bits from the Dib into the nsIImage's buffer
PRUint8 * imageBits = image->GetBits();
depth = (depth >> 3);
PRUint32 size = width * height * depth;
CopyMemory(imageBits, bits, size);
// the data for this flavor is a ptr to the nsIImage
*aData = image;
*aLen = sizeof(nsIImage*);
result = NS_OK;
}
::GlobalUnlock (hGlobal) ;
nsImageFromClipboard converter ( header );
nsIImage* image;
converter.GetImage ( &image ); // addrefs for us, don't release
if ( image ) {
*aData = image;
*aLen = sizeof(nsIImage*);
result = NS_OK;
}
::GlobalUnlock (hGlobal) ;
} break;
case CF_HDROP :
@ -818,12 +738,12 @@ nsClipboard :: IsInternetShortcut ( const char* inFileName )
//-------------------------------------------------------------------------
NS_IMETHODIMP nsClipboard::GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32 aWhichClipboard )
NS_IMETHODIMP
nsClipboard::GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32 aWhichClipboard )
{
// make sure we have a good transferable
if ( !aTransferable || aWhichClipboard != kGlobalClipboard ) {
if ( !aTransferable || aWhichClipboard != kGlobalClipboard )
return NS_ERROR_FAILURE;
}
nsresult res;
@ -832,8 +752,10 @@ NS_IMETHODIMP nsClipboard::GetNativeClipboardData ( nsITransferable * aTransfera
if (S_OK == ::OleGetClipboard(&dataObj)) {
// Use OLE IDataObject for clipboard operations
res = GetDataFromDataObject(dataObj, 0, nsnull, aTransferable);
} else {
// do it the old manula way
dataObj->Release();
}
else {
// do it the old manual way
res = GetDataFromDataObject(nsnull, 0, mWindow, aTransferable);
}
return res;

Просмотреть файл

@ -30,6 +30,8 @@
#include "nsIComponentManager.h"
#include "nsPrimitiveHelpers.h"
#include "nsXPIDLString.h"
#include "nsIImage.h"
#include "nsImageClipboard.h"
#include "OLE2.h"
#include "URLMON.h"
@ -166,15 +168,20 @@ STDMETHODIMP nsDataObj::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
pSTM->pUnkForRelease = NULL;
CLIPFORMAT format = pFE->cfFormat;
switch(format) {
// Someone is asking for plain or unicode text
case CF_TEXT:
case CF_UNICODETEXT:
return GetText(df, *pFE, *pSTM);
break;
return GetText(*df, *pFE, *pSTM);
break;
// Someone is asking for an image
case CF_DIB:
return GetDib(*df, *pFE, *pSTM);
// ... not yet implemented ...
//case CF_BITMAP:
// return GetBitmap(*pFE, *pSTM);
//case CF_DIB:
// return GetDib(*pFE, *pSTM);
//case CF_METAFILEPICT:
// return GetMetafilePict(*pFE, *pSTM);
@ -186,7 +193,7 @@ STDMETHODIMP nsDataObj::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
return GetFileContents ( *pFE, *pSTM );
else {
PRNTDEBUG2("***** nsDataObj::GetData - Unknown format %x\n", format);
return GetText(df, *pFE, *pSTM);
return GetText(*df, *pFE, *pSTM);
}
break;
@ -333,17 +340,47 @@ HRESULT nsDataObj::AddGetFormat(FORMATETC& aFE)
}
//-----------------------------------------------------
HRESULT nsDataObj::GetBitmap(FORMATETC&, STGMEDIUM&)
HRESULT
nsDataObj::GetBitmap ( nsAReadableCString& , FORMATETC&, STGMEDIUM& )
{
PRNTDEBUG("nsDataObj::GetBitmap\n");
return ResultFromScode(E_NOTIMPL);
}
//-----------------------------------------------------
HRESULT nsDataObj::GetDib(FORMATETC&, STGMEDIUM&)
//
// GetDIB
//
// Someone is asking for a bitmap. The data in the transferable will be a straight
// nsIImage, so just QI it.
//
HRESULT
nsDataObj :: GetDib ( nsAReadableCString& inFlavor, FORMATETC &, STGMEDIUM & aSTG )
{
PRNTDEBUG("nsDataObj::GetDib\n");
return E_NOTIMPL;
ULONG result = E_FAIL;
PRUint32 len = 0;
nsCOMPtr<nsISupports> genericDataWrapper;
mTransferable->GetTransferData(nsPromiseFlatCString(inFlavor), getter_AddRefs(genericDataWrapper), &len);
nsCOMPtr<nsIImage> image ( do_QueryInterface(genericDataWrapper) );
if ( image ) {
// use a the helper class to build up a bitmap. The helper class owns the
// bits, so we don't want to free them. They'll be freed when it goes out
// of scope.
nsImageToClipboard converter ( image );
HANDLE bits = nsnull;
nsresult rv = converter.GetPicture ( &bits );
if ( NS_SUCCEEDED(rv) && bits ) {
aSTG.hGlobal = bits;
aSTG.tymed = TYMED_HGLOBAL;
result = S_OK;
}
} // if we have an image
else
NS_WARNING ( "Definately not an image on clipboard" );
return ResultFromScode(result);
}
@ -528,17 +565,17 @@ nsDataObj :: IsInternetShortcut ( )
//-----------------------------------------------------
HRESULT nsDataObj::GetText(nsCAutoString * aDataFlavor, FORMATETC& aFE, STGMEDIUM& aSTG)
HRESULT nsDataObj::GetText(nsAReadableCString & aDataFlavor, FORMATETC& aFE, STGMEDIUM& aSTG)
{
void* data;
PRUint32 len;
// if someone asks for text/plain, look up text/unicode instead in the transferable.
char* flavorStr;
if ( aDataFlavor->Equals("text/plain") )
const char* flavorStr;
if ( aDataFlavor.Equals("text/plain") )
flavorStr = kUnicodeMime;
else
flavorStr = *aDataFlavor;
flavorStr = nsPromiseFlatCString(aDataFlavor);
// NOTE: CreateDataFromPrimitive creates new memory, that needs to be deleted
nsCOMPtr<nsISupports> genericDataWrapper;
@ -546,7 +583,6 @@ HRESULT nsDataObj::GetText(nsCAutoString * aDataFlavor, FORMATETC& aFE, STGMEDIU
if ( !len )
return ResultFromScode(E_FAIL);
nsPrimitiveHelpers::CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, len );
HGLOBAL hGlobalMemory = NULL;
PSTR pGlobalMemory = NULL;

Просмотреть файл

@ -121,9 +121,9 @@ class nsDataObj : public IDataObject
virtual HRESULT AddSetFormat(FORMATETC& FE);
virtual HRESULT AddGetFormat(FORMATETC& FE);
virtual HRESULT GetText(nsCAutoString * aDF, FORMATETC& FE, STGMEDIUM& STM);
virtual HRESULT GetBitmap(FORMATETC& FE, STGMEDIUM& STM);
virtual HRESULT GetDib (FORMATETC& FE, STGMEDIUM& STM);
virtual HRESULT GetText ( nsAReadableCString& aDF, FORMATETC& aFE, STGMEDIUM & aSTG );
virtual HRESULT GetBitmap ( nsAReadableCString& inFlavor, FORMATETC& FE, STGMEDIUM& STM);
virtual HRESULT GetDib ( nsAReadableCString& inFlavor, FORMATETC &, STGMEDIUM & aSTG );
virtual HRESULT GetMetafilePict(FORMATETC& FE, STGMEDIUM& STM);
virtual HRESULT GetFileDescriptor ( FORMATETC& aFE, STGMEDIUM& aSTG ) ;