diff --git a/widget/src/mac/Makefile.in b/widget/src/mac/Makefile.in index 95b8b0e952d8..8bf6346f4bc1 100644 --- a/widget/src/mac/Makefile.in +++ b/widget/src/mac/Makefile.in @@ -86,6 +86,7 @@ CPPSRCS = nsAppShell.cpp \ nsWidgetFactory.cpp \ nsWidgetSupport.cpp \ nsWindow.cpp \ + nsMacNativeUnicodeConverter.cpp \ $(GFX_LCPPSRCS) \ $(NULL) diff --git a/widget/src/mac/nsClipboard.cpp b/widget/src/mac/nsClipboard.cpp index 433e53f42d9a..c5e3da250eb9 100644 --- a/widget/src/mac/nsClipboard.cpp +++ b/widget/src/mac/nsClipboard.cpp @@ -60,9 +60,13 @@ #include "nsPrimitiveHelpers.h" #include "nsIImageMac.h" #include "nsMemory.h" +#include "nsMacNativeUnicodeConverter.h" +#include "nsICharsetConverterManager.h" #include "nsCRT.h" #include +#include +#include @@ -152,8 +156,22 @@ nsClipboard :: SetNativeClipboardData ( PRInt32 aWhichClipboard ) char* plainTextData = nsnull; PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, data); PRInt32 plainTextLen = 0; - nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, dataSize / 2, &plainTextData, &plainTextLen ); - if ( plainTextData ) { + errCode = nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, dataSize / 2, &plainTextData, &plainTextLen ); + + // if characters are not mapped from Unicode then try native API to convert to + // available script + if (errCode == NS_ERROR_UENC_NOMAPPING) { + if (plainTextData) { + nsMemory::Free(plainTextData); + plainTextData = nsnull; + } + errCode = nsMacNativeUnicodeConverter::ConvertUnicodetoScript(castedUnicode, + dataSize / 2, + &plainTextData, + &plainTextLen); + } + + if ( NS_SUCCEEDED(errCode) && plainTextData ) { errCode = PutOnClipboard ( 'TEXT', plainTextData, plainTextLen ); nsMemory::Free ( plainTextData ); } @@ -289,21 +307,55 @@ nsClipboard :: GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32 // if we are looking for text/unicode and we fail to find it on the clipboard first, // try again with text/plain. If that is present, convert it to unicode. if ( strcmp(flavorStr, kUnicodeMime) == 0 ) { - loadResult = GetDataOffClipboard ( 'TEXT', &clipboardData, &dataSize ); - if ( NS_SUCCEEDED(loadResult) && clipboardData ) { - const char* castedText = NS_REINTERPRET_CAST(char*, clipboardData); - PRUnichar* convertedText = nsnull; - PRInt32 convertedTextLen = 0; - nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize, - &convertedText, &convertedTextLen ); - if ( convertedText ) { - // out with the old, in with the new - nsMemory::Free(clipboardData); - clipboardData = convertedText; - dataSize = convertedTextLen * 2; - dataFound = PR_TRUE; + + // if 'styl' is available, we can get a script of the first run + // and use it for converting 'TEXT' + loadResult = GetDataOffClipboard ( 'styl', &clipboardData, &dataSize ); + if (NS_SUCCEEDED(loadResult) && + clipboardData && + (dataSize >= (sizeof(ScrpSTElement) + 2))) { + StScrpRec *scrpRecP = (StScrpRec *) clipboardData; + ScrpSTElement *styl = scrpRecP->scrpStyleTab; + ScriptCode script = styl ? ::FontToScript(styl->scrpFont) : smCurrentScript; + + // free 'styl' and get 'TEXT' + nsMemory::Free(clipboardData); + loadResult = GetDataOffClipboard ( 'TEXT', &clipboardData, &dataSize ); + if ( NS_SUCCEEDED(loadResult) && clipboardData ) { + PRUnichar* convertedText = nsnull; + PRInt32 convertedTextLen = 0; + errCode = nsMacNativeUnicodeConverter::ConvertScripttoUnicode( + script, + (const char *) clipboardData, + dataSize, + &convertedText, + &convertedTextLen); + if (NS_SUCCEEDED(errCode) && convertedText) { + nsMemory::Free(clipboardData); + clipboardData = convertedText; + dataSize = convertedTextLen * sizeof(PRUnichar); + dataFound = PR_TRUE; + } } - } // if plain text data on clipboard + } + + if (!dataFound) { + loadResult = GetDataOffClipboard ( 'TEXT', &clipboardData, &dataSize ); + if ( NS_SUCCEEDED(loadResult) && clipboardData ) { + const char* castedText = NS_REINTERPRET_CAST(char*, clipboardData); + PRUnichar* convertedText = nsnull; + PRInt32 convertedTextLen = 0; + nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize, + &convertedText, &convertedTextLen ); + if ( convertedText ) { + // out with the old, in with the new + nsMemory::Free(clipboardData); + clipboardData = convertedText; + dataSize = convertedTextLen * 2; + dataFound = PR_TRUE; + } + } // if plain text data on clipboard + } } // if looking for text/unicode } // else we try one last ditch effort to find our data diff --git a/widget/src/mac/nsDragService.cpp b/widget/src/mac/nsDragService.cpp index 5e7f6916b7e0..9ff8e0464f4c 100644 --- a/widget/src/mac/nsDragService.cpp +++ b/widget/src/mac/nsDragService.cpp @@ -80,6 +80,8 @@ #include "nsIDOMElement.h" #include "nsIImageMac.h" #include "nsIImage.h" +#include "nsMacNativeUnicodeConverter.h" +#include "nsICharsetConverterManager.h" // we need our own stuff for MacOS because of nsIDragSessionMac. @@ -495,22 +497,55 @@ printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const cha // if we are looking for text/unicode and we fail to find it on the clipboard first, // try again with text/plain. If that is present, convert it to unicode. if ( strcmp(flavorStr, kUnicodeMime) == 0 ) { - if ( ::GetFlavorFlags(mDragRef, itemRef, 'TEXT', &unused) == noErr ) { - nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, 'TEXT', &dataBuff, &dataSize); - if ( NS_SUCCEEDED(loadResult) && dataBuff ) { - const char* castedText = NS_REINTERPRET_CAST(char*, dataBuff); - PRUnichar* convertedText = nsnull; - PRInt32 convertedTextLen = 0; - nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize, - &convertedText, &convertedTextLen ); - if ( convertedText ) { - // out with the old, in with the new - nsMemory::Free(dataBuff); - dataBuff = convertedText; - dataSize = convertedTextLen * 2; - dataFound = PR_TRUE; + if ( ::GetFlavorFlags(mDragRef, itemRef, 'TEXT', &unused) == noErr ) { + + // if 'styl' is available, we can get a script of the first run + // and use it for converting 'TEXT' + nsresult loadResult = ExtractDataFromOS(mDragRef, itemRef, 'styl', &dataBuff, &dataSize); + if (NS_SUCCEEDED(loadResult) && + dataBuff && + (dataSize >= (sizeof(ScrpSTElement) + 2))) { + StScrpRec *scrpRecP = (StScrpRec *) dataBuff; + ScrpSTElement *styl = scrpRecP->scrpStyleTab; + ScriptCode script = styl ? ::FontToScript(styl->scrpFont) : smCurrentScript; + + // free 'styl' and get 'TEXT' + nsMemory::Free(dataBuff); + loadResult = ExtractDataFromOS(mDragRef, itemRef, 'TEXT', &dataBuff, &dataSize); + if ( NS_SUCCEEDED(loadResult) && dataBuff ) { + PRUnichar* convertedText = nsnull; + PRInt32 convertedTextLen = 0; + errCode = nsMacNativeUnicodeConverter::ConvertScripttoUnicode(script, + (const char *) dataBuff, + dataSize, + &convertedText, + &convertedTextLen); + if (NS_SUCCEEDED(errCode) && convertedText) { + nsMemory::Free(dataBuff); + dataBuff = convertedText; + dataSize = convertedTextLen * sizeof(PRUnichar); + dataFound = PR_TRUE; + } } - } // if plain text data on clipboard + } + + if (!dataFound) { + loadResult = ExtractDataFromOS(mDragRef, itemRef, 'TEXT', &dataBuff, &dataSize); + if ( NS_SUCCEEDED(loadResult) && dataBuff ) { + const char* castedText = NS_REINTERPRET_CAST(char*, dataBuff); + PRUnichar* convertedText = nsnull; + PRInt32 convertedTextLen = 0; + nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode ( castedText, dataSize, + &convertedText, &convertedTextLen ); + if ( convertedText ) { + // out with the old, in with the new + nsMemory::Free(dataBuff); + dataBuff = convertedText; + dataSize = convertedTextLen * 2; + dataFound = PR_TRUE; + } + } // if plain text data on clipboard + } } // if plain text flavor present } // if looking for text/unicode } // else we try one last ditch effort to find our data @@ -765,8 +800,22 @@ nsDragService :: GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference char* plainTextData = nsnull; PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, *outData); PRInt32 plainTextLen = 0; + nsresult rv = nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, *outDataSize / 2, &plainTextData, &plainTextLen ); - if ( *outData ) { + // if characters are not mapped from Unicode then try native API to convert to + // available script + if (rv == NS_ERROR_UENC_NOMAPPING) { + if (plainTextData) { + nsMemory::Free(plainTextData); + plainTextData = nsnull; + } + rv = nsMacNativeUnicodeConverter::ConvertUnicodetoScript(castedUnicode, + *outDataSize / sizeof(PRUnichar), + &plainTextData, + &plainTextLen); + } + + if ( plainTextData && *outData ) { nsMemory::Free(*outData); *outData = plainTextData; *outDataSize = plainTextLen; diff --git a/widget/src/mac/nsMacNativeUnicodeConverter.h b/widget/src/mac/nsMacNativeUnicodeConverter.h index 7a0ee46ed589..305b15d9c965 100644 --- a/widget/src/mac/nsMacNativeUnicodeConverter.h +++ b/widget/src/mac/nsMacNativeUnicodeConverter.h @@ -29,6 +29,7 @@ #include "prtypes.h" #include "nsError.h" #include "nscore.h" +#include class nsISupports;