]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/core/strconv_cf.cpp
implementing canBecomeKeyView for user panes, native focus support, fixes #15070
[wxWidgets.git] / src / osx / core / strconv_cf.cpp
index be04c8a881aa8683675a0b7fc70898eff051ed42..f4bd30f334d036910551af628fd152c920d66b3a 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        src/osx/corefoundation/strconv.cpp
+// Name:        src/osx/core/strconv_cf.cpp
 // Purpose:     Unicode conversion classes
 // Author:      David Elliott
 // Modified by:
@@ -33,6 +33,7 @@
  * assume ABI compatibility even within a given wxWidgets release.
  */
 
+#if wxUSE_FONTMAP
 WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf( const char* name)
 {
     wxMBConv_cf *result = new wxMBConv_cf(name);
@@ -44,6 +45,7 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf( const char* name)
     else
         return result;
 }
+#endif // wxUSE_FONTMAP
 
 WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
 {
@@ -85,7 +87,16 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
                                                 false //no BOM/external representation
                                                 ));
 
-        wxCHECK(theString != NULL, wxCONV_FAILED);
+        if ( theString == NULL )
+            return wxCONV_FAILED;
+
+        // Ensure that the string is in canonical composed form (NFC): this is
+        // important because Darwin uses decomposed form (NFD) for e.g. file
+        // names but we want to use NFC internally.
+        wxCFRef<CFMutableStringRef>
+            cfMutableString(CFStringCreateMutableCopy(NULL, 0, theString));
+        CFStringNormalize(cfMutableString, kCFStringNormalizationFormC);
+        theString = cfMutableString;
 
         /* NOTE: The string content includes the NULL element if the source string did
          * That means we have to do nothing special because the destination will have
@@ -114,8 +125,7 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
                     dstSize * sizeof(wchar_t),
                     &usedBufLen);
 
-            // charsConverted is > 0 iff conversion succeeded
-            if(charsConverted <= 0)
+            if(charsConverted < CFStringGetLength(theString))
                 return wxCONV_FAILED;
 
             /* usedBufLen is the number of bytes written, so we divide by
@@ -130,11 +140,11 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
         else
         {
             // NOTE: Includes NULL iff source did
-            /* NOTE: This is an approximation.  The eventual UTF-32 will    
+            /* NOTE: This is an approximation.  The eventual UTF-32 will
              * possibly have less elements but certainly not more.
              */
             size_t returnSize = CFStringGetLength(theString);
-    
+
             if (dstSize == 0 || dst == NULL)
             {
                 return returnSize;
@@ -144,13 +154,13 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
             // for an undersized UTF-32 destination buffer.
             CFRange fullStringRange = CFRangeMake(0, CFStringGetLength(theString));
             UniChar *szUniCharBuffer = new UniChar[fullStringRange.length];
-    
+
             CFStringGetCharacters(theString, fullStringRange, szUniCharBuffer);
-    
+
             wxMBConvUTF16 converter;
             returnSize = converter.ToWChar( dst, dstSize, (const char*)szUniCharBuffer, fullStringRange.length );
             delete [] szUniCharBuffer;
-    
+
             return returnSize;
         }
         // NOTREACHED
@@ -205,19 +215,20 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
         CFIndex usedBufLen;
 
         CFIndex charsConverted = CFStringGetBytes(
-                theString, 
+                theString,
                 CFRangeMake(0, CFStringGetLength(theString)),
                 m_encoding,
                 0, // FAIL on unconvertible characters
                 false, // not an external representation
-                // if dstSize is 0 then pass NULL to get required length in usedBufLen
-                (dstSize != 0)?(UInt8*)dst:NULL,
+                (UInt8*)dst,
                 dstSize,
                 &usedBufLen
             );
 
-        // charsConverted is > 0 iff conversion succeeded
-        if(charsConverted <= 0)
+        // when dst is non-NULL, we check usedBufLen against dstSize as
+        // CFStringGetBytes sometimes treats dst as being NULL when dstSize==0
+        if( (charsConverted < CFStringGetLength(theString)) ||
+                (dst && (size_t) usedBufLen > dstSize) )
             return wxCONV_FAILED;
 
         return usedBufLen;