diff options
author | mixedpuppy <devnull@localhost> | 2007-12-05 23:06:58 +0000 |
---|---|---|
committer | mixedpuppy <devnull@localhost> | 2007-12-05 23:06:58 +0000 |
commit | ffa2c5b99b0eb534498a550d11ac5debc1204c32 (patch) | |
tree | 7a56a2c74170e09c85b98ecdeebce310d001ad7d /macosx/PlatMacOSX.cxx | |
parent | a9e5e58a8d7875426b4d6d009254fc6ec191cbba (diff) | |
download | scintilla-mirror-ffa2c5b99b0eb534498a550d11ac5debc1204c32.tar.gz |
modified version of adobe OSX patches. Most of these patches are provided by Adobe, though I've
reorganized a lot of them
- improved drag/drop
- make copy/paste use modern pasteboard api's
- optimized textlayout usage
- reduce assertions for debug builds
- implement IME support
- other minor things
patches are available in openkomodo, which is a good test ground for scintilla osx (until someone
ports SCiTE).
Diffstat (limited to 'macosx/PlatMacOSX.cxx')
-rw-r--r-- | macosx/PlatMacOSX.cxx | 395 |
1 files changed, 164 insertions, 231 deletions
diff --git a/macosx/PlatMacOSX.cxx b/macosx/PlatMacOSX.cxx index 631e0d95e..f8282c5f8 100644 --- a/macosx/PlatMacOSX.cxx +++ b/macosx/PlatMacOSX.cxx @@ -109,29 +109,24 @@ void Font::Release() { SurfaceImpl::SurfaceImpl() { bitmapData = NULL; // Release will try and delete bitmapData if != NULL -#ifdef SUPPORT_PORT - port = NULL; -#endif gc = NULL; + textLayout = new QuartzTextLayout(NULL); Release(); } SurfaceImpl::~SurfaceImpl() { Release(); + delete textLayout; } void SurfaceImpl::Release() { + textLayout->setContext (NULL); if ( bitmapData != NULL ) { delete[] bitmapData; // We only "own" the graphics context if we are a bitmap context if ( gc != NULL ) CGContextRelease( gc ); } -#ifdef SUPPORT_PORT - if ( port != NULL && gc != NULL) { - QDEndCGContext(port, &gc); - } -#endif bitmapData = NULL; gc = NULL; @@ -155,20 +150,13 @@ void SurfaceImpl::Init(WindowID /*wid*/) { // aquire/release of the context. Release(); -#ifdef SUPPORT_PORT - // Note, this seems to be unecessary, I have not seen any functionality loss by - // doing nothing in this method. - - WindowRef window = GetControlOwner(reinterpret_cast<HIViewRef>(wid)); - port = GetWindowPort(window); - QDBeginCGContext(port, &gc); -#endif } void SurfaceImpl::Init(SurfaceID sid, WindowID /*wid*/) { Release(); gc = reinterpret_cast<CGContextRef>( sid ); CGContextSetLineWidth( gc, 1.0 ); + textLayout->setContext (gc); } void SurfaceImpl::InitPixMap(int width, int height, Surface* /*surface_*/, WindowID /*wid*/) { @@ -182,13 +170,12 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface* /*surface_*/, Windo // create an RGB color space CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - assert( colorSpace != NULL ); + if( colorSpace == NULL ) + return; // create the bitmap bitmapData = new uint8_t[ bitmapByteCount ]; - assert( bitmapData != NULL ); - if( bitmapData != NULL ) - { + if( bitmapData != NULL ) { // create the context gc = CGBitmapContextCreate( bitmapData, width, @@ -198,24 +185,25 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface* /*surface_*/, Windo colorSpace, kCGImageAlphaPremultipliedLast); - if( gc == NULL ) - { + if( gc == NULL ) { // the context couldn't be created for some reason, // and we have no use for the bitmap without the context delete[] bitmapData; bitmapData = NULL; - } } + textLayout->setContext (gc); + } // the context retains the color space, so we can release it CGColorSpaceRelease( colorSpace ); - assert( gc != NULL && bitmapData != NULL ); - - // "Erase" to white - CGContextClearRect( gc, CGRectMake( 0, 0, width, height ) ); - CGContextSetRGBFillColor( gc, 1.0, 1.0, 1.0, 1.0 ); - CGContextFillRect( gc, CGRectMake( 0, 0, width, height ) ); + if ( gc != NULL && bitmapData != NULL ) + { + // "Erase" to white + CGContextClearRect( gc, CGRectMake( 0, 0, width, height ) ); + CGContextSetRGBFillColor( gc, 1.0, 1.0, 1.0, 1.0 ); + CGContextFillRect( gc, CGRectMake( 0, 0, width, height ) ); + } } void SurfaceImpl::PenColour(ColourAllocated fore) { @@ -244,28 +232,30 @@ CGImageRef SurfaceImpl::GetImage() { // create an RGB color space CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - assert( colorSpace != NULL ); + if( colorSpace == NULL ) + return NULL; const int bitmapBytesPerRow = ((int) bitmapWidth * BYTES_PER_PIXEL); const int bitmapByteCount = (bitmapBytesPerRow * (int) bitmapHeight); // Create a data provider CGDataProviderRef dataProvider = CGDataProviderCreateWithData( NULL, bitmapData, bitmapByteCount, NULL ); - assert( dataProvider != NULL ); - - // create the CGImage - CGImageRef image = CGImageCreate( bitmapWidth, - bitmapHeight, - BITS_PER_COMPONENT, - BITS_PER_PIXEL, - bitmapBytesPerRow, - colorSpace, - kCGImageAlphaPremultipliedLast, - dataProvider, - NULL, - 0, - kCGRenderingIntentDefault ); - assert( image != NULL ); + CGImageRef image = NULL; + if ( dataProvider != NULL ) + { + // create the CGImage + image = CGImageCreate( bitmapWidth, + bitmapHeight, + BITS_PER_COMPONENT, + BITS_PER_PIXEL, + bitmapBytesPerRow, + colorSpace, + kCGImageAlphaPremultipliedLast, + dataProvider, + NULL, + 0, + kCGRenderingIntentDefault ); + } // the image retains the color space, so we can release it CGColorSpaceRelease( colorSpace ); @@ -379,8 +369,6 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { return; } - assert( image != NULL ); - const CGPatternCallbacks drawImageCallbacks = { 0, reinterpret_cast<CGPatternDrawPatternCallback>( drawImageRefCallback ), NULL }; CGPatternRef pattern = CGPatternCreate( image, @@ -392,30 +380,30 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { true, &drawImageCallbacks ); - assert( pattern != NULL ); - - // Create a pattern color space - CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern( NULL ); - assert( colorSpace != NULL ); - - CGContextSaveGState( gc ); - CGContextSetFillColorSpace( gc, colorSpace ); - - // Unlike the documentation, you MUST pass in a "components" parameter: - // For coloured patterns it is the alpha value. - const float alpha = 1.0; - CGContextSetFillPattern( gc, pattern, &alpha ); - CGContextFillRect( gc, PRectangleToCGRect( rc ) ); - - CGContextRestoreGState( gc ); - - // Free the color space, the pattern and image - CGColorSpaceRelease( colorSpace ); - colorSpace = NULL; - CGPatternRelease( pattern ); - pattern = NULL; - CGImageRelease( image ); - image = NULL; + if( pattern != NULL ) { + + // Create a pattern color space + CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern( NULL ); + if( colorSpace != NULL ) { + + CGContextSaveGState( gc ); + CGContextSetFillColorSpace( gc, colorSpace ); + + // Unlike the documentation, you MUST pass in a "components" parameter: + // For coloured patterns it is the alpha value. + const float alpha = 1.0; + CGContextSetFillPattern( gc, pattern, &alpha ); + CGContextFillRect( gc, PRectangleToCGRect( rc ) ); + CGContextRestoreGState( gc ); + // Free the color space, the pattern and image + CGColorSpaceRelease( colorSpace ); + } /* colorSpace != NULL */ + colorSpace = NULL; + CGPatternRelease( pattern ); + pattern = NULL; + CGImageRelease( image ); + image = NULL; + } /* pattern != NULL */ } void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { @@ -480,20 +468,16 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl CGContextDrawPath( gc, kCGPathFillStroke ); } -void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, - ColourAllocated outline, int alphaOutline, int flags) { - // XXX TODO +void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int /*cornerSize*/, ColourAllocated fill, int alphaFill, + ColourAllocated /*outline*/, int /*alphaOutline*/, int /*flags*/) +{ if ( gc ) { - CGContextBeginPath( gc ); - //FillColour(fill); - PenColour(outline); + ColourDesired colour( fill.AsLong() ); - // Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo) - // We subtract 1 from the Width() and Height() so that all our drawing is within the area defined - // by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom. - // TODO: Create some version of PRectangleToCGRect to do this conversion for us? - CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) ); - CGContextDrawPath( gc, kCGPathFill ); + // Set the Fill color to match + CGContextSetRGBFillColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, alphaFill / 100.0 ); + CGRect rect = PRectangleToCGRect( rc ); + CGContextFillRect( gc, rect ); } } @@ -597,8 +581,6 @@ void SurfaceImpl::Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSou return; } - assert( image != NULL ); - // Now draw the image on the surface // Some fancy clipping work is required here: draw only inside of rc @@ -616,29 +598,6 @@ void SurfaceImpl::Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSou image = NULL; } -QuartzTextLayout* SurfaceImpl::GetTextLayout( Font &font_, const char *s, int len ) -{ - // create the text layout - QuartzTextLayout* textLayout = new QuartzTextLayout( gc ); - OSStatus err = textLayout->setText( reinterpret_cast<const UInt8*>( s ), len, ( unicodeMode ? kCFStringEncodingUTF8 : kCFStringEncodingASCII ) ); - if (err != noErr) { - fprintf(stderr, "SurfaceImpl::GetTextLayout error calling textLayout->setText %d %s\n", err, unicodeMode?"Invalid UTF8":"Unknown error"); - if (unicodeMode) - err = textLayout->setText( reinterpret_cast<const UInt8*>( s ), len, kCFStringEncodingASCII ); - if (err != noErr) - return NULL; - } - - textLayout->setStyle( *reinterpret_cast<QuartzTextStyle*>( font_.GetID() ) ); - - // TODO: If I could modify Scintilla to use ATSUHighlightText, this would not be required. - // However, using this setting makes Scintilla's rendering match TextEdit's (except for the antialiasing rules) - ATSLineLayoutOptions rendering = kATSLineUseDeviceMetrics; - textLayout->setControl( kATSULineLayoutOptionsTag, sizeof( rendering ), &rendering ); - - return textLayout; -} - void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back) { @@ -656,89 +615,80 @@ void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const c } void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore) { - PLATFORM_ASSERT( gc != NULL ); - QuartzTextLayout* textLayout = GetTextLayout( font_, s, len ); - if (!textLayout) return; + textLayout->setText (reinterpret_cast<const UInt8*>(s), len, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); + // The Quartz RGB fill color influences the ATSUI color FillColour(fore); - // Draw the text, with the Y axis flipped textLayout->draw( rc.left, ybase, true ); - - // Get rid of the layout object - delete textLayout; - textLayout = NULL; } void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { // sample at http://developer.apple.com/samplecode/ATSUICurveAccessDemo/listing1.html // sample includes use of ATSUGetGlyphInfo which would be better for older // OSX systems. We should expand to using that on older systems as well. - QuartzTextLayout* textLayout = GetTextLayout( font_, s, len ); - if (!textLayout) return; - - // Get the UNICODE character length - UniCharCount unicodeLength, unicodePosition; - OSStatus err; - err = ATSUGetTextLocation( textLayout->getLayout(), NULL, NULL, NULL, &unicodeLength, NULL ); - assert( err == noErr ); - - ATSLayoutRecord *layoutRecords; - ItemCount numRecords; - // Get the arrays of glyph information - verify_noerr( ATSUDirectGetLayoutDataArrayPtrFromTextLayout( - textLayout->getLayout(), 0, - kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, - (void **)&layoutRecords, &numRecords) ); - - int i, count; - long position; - unsigned char uch; - unsigned char mask; - FontID fontid = font_.GetID(); - - for ( unicodePosition = 0, i = 0; i < len && unicodePosition < numRecords; unicodePosition ++ ) { - if (fontid) { - - // note: an extra layoutRecord is provided (eg. numRecords will be one - // more than unicodeLength). Each record contains the left x - // coordinate, but we need the right x coordinate, so we skip - // the first layoutRecord, thus unicodePosition+1. - position = Fix2Long( layoutRecords[unicodePosition+1].realPos ); - uch = s[i]; - positions[i++] = position; - - // If we are using unicode (UTF8), map the Unicode position back to the UTF8 characters, - // as 1 unicode character can map to multiple UTF8 characters. - // See: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF - // Or: http://www.cl.cam.ac.uk/~mgk25/unicode.html - if ( unicodeMode ) { - mask = 0xc0; - count = 1; - // Add one additonal byte for each extra high order one in the byte - while ( uch >= mask && count < 8 ) { - assert( i < len ); + for (int i = 0; i < len; i++) + positions [i] = 0; + + // We need the right X coords, so we have to append a char to get the left coord of thast extra char + char* buf = (char*) malloc (len+1); + if (!buf) + return; + + memcpy (buf, s, len); + buf [len] = '.'; + + textLayout->setText (reinterpret_cast<const UInt8*>(buf), len+1, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); + ATSUGlyphInfoArray* theGlyphInfoArrayPtr; + ByteCount theArraySize; + + // Get the GlyphInfoArray + ATSUTextLayout layout = textLayout->getLayout(); + if ( noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, NULL)) + { + theGlyphInfoArrayPtr = (ATSUGlyphInfoArray *) malloc (theArraySize + sizeof(ItemCount) + sizeof(ATSUTextLayout)); + if (theGlyphInfoArrayPtr) + { + if (noErr == ATSUGetGlyphInfo (layout, 0, textLayout->getLength(), &theArraySize, theGlyphInfoArrayPtr)) + { + // do not count the first item, which is at the beginning of the line + for ( UniCharCount unicodePosition = 1, i = 0; i < len && unicodePosition < theGlyphInfoArrayPtr->numGlyphs; unicodePosition ++ ) + { + // The ideal position is the x coordinate of the glyph, relative to the beginning of the line + int position = (int)( theGlyphInfoArrayPtr->glyphs[unicodePosition].idealX + 0.5 ); // These older APIs return float values + unsigned char uch = s[i]; positions[i++] = position; - count ++; - mask = mask >> 1 | 0x80; // add an additional one in the highest order position + + // If we are using unicode (UTF8), map the Unicode position back to the UTF8 characters, + // as 1 unicode character can map to multiple UTF8 characters. + // See: http://www.tbray.org/ongoing/When/200x/2003/04/26/UTF + // Or: http://www.cl.cam.ac.uk/~mgk25/unicode.html + if ( unicodeMode ) + { + unsigned char mask = 0xc0; + int count = 1; + // Add one additonal byte for each extra high order one in the byte + while ( uch >= mask && count < 8 ) + { + positions[i++] = position; + count ++; + mask = mask >> 1 | 0x80; // add an additional one in the highest order position + } + } } - assert( count <= 8 ); } - } else { - positions[i++] = (i == 0) ? 1 : positions[i-1] + 1; + + // Free the GlyphInfoArray + free (theGlyphInfoArrayPtr); } } - verify_noerr( ATSUDirectReleaseLayoutDataArrayPtr(NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void **)&layoutRecords) ); - // Get rid of the layout object - delete textLayout; - textLayout = NULL; + free (buf); } int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { if (font_.GetID()) { - QuartzTextLayout* textLayout = GetTextLayout( font_, s, len ); - if (!textLayout) return 0; + textLayout->setText (reinterpret_cast<const UInt8*>(s), len, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? unsigned long actualNumberOfBounds = 0; @@ -748,17 +698,10 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) { Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthText" ); - // Get rid of the layout object - delete textLayout; - textLayout = NULL; return 0; } //Platform::DebugPrintf( "WidthText: \"%*s\" = %ld\n", len, s, Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ) ); - - // Get rid of the layout object - delete textLayout; - textLayout = NULL; return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); } return 1; @@ -768,8 +711,7 @@ int SurfaceImpl::WidthChar(Font &font_, char ch) { char str[2] = { ch, '\0' }; if (font_.GetID()) { - QuartzTextLayout* textLayout = GetTextLayout( font_, str, 1 ); - if (!textLayout) return 0; + textLayout->setText (reinterpret_cast<const UInt8*>(str), 1, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); // TODO: Maybe I should add some sort of text measurement features to QuartzTextLayout? unsigned long actualNumberOfBounds = 0; @@ -779,15 +721,9 @@ int SurfaceImpl::WidthChar(Font &font_, char ch) { if ( ATSUGetGlyphBounds( textLayout->getLayout(), 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds ) != noErr || actualNumberOfBounds != 1 ) { Platform::DebugDisplay( "ATSUGetGlyphBounds failed in WidthChar" ); - // Get rid of the layout object - delete textLayout; - textLayout = NULL; return 0; } - // Get rid of the layout object - delete textLayout; - textLayout = NULL; return Fix2Long( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ); } else @@ -893,14 +829,15 @@ void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { } void SurfaceImpl::SetDBCSMode(int codePage) { - // TODO: Implement this + // TODO: Implement this for code pages != UTF-8 } Surface *Surface::Allocate() { return new SurfaceImpl( ); } -Window::~Window() {} +Window::~Window() { +} void Window::Destroy() { if (windowRef) { @@ -996,9 +933,7 @@ void Window::Show(bool show) { void Window::InvalidateAll() { if ( id ) { - OSStatus err; - err = HIViewSetNeedsDisplay( reinterpret_cast<HIViewRef>( id ), true ); - assert( err == noErr ); + HIViewSetNeedsDisplay( reinterpret_cast<HIViewRef>( id ), true ); } } @@ -1006,13 +941,10 @@ void Window::InvalidateRectangle(PRectangle rc) { if (id) { // Create a rectangular region RgnHandle region = NewRgn(); - assert( region != NULL ); SetRectRgn( region, rc.left, rc.top, rc.right, rc.bottom ); // Make that region invalid - OSStatus err; - err = HIViewSetNeedsDisplayInRegion( reinterpret_cast<HIViewRef>( id ), region, true ); - assert( err == noErr ); + HIViewSetNeedsDisplayInRegion( reinterpret_cast<HIViewRef>( id ), region, true ); DisposeRgn( region ); } } @@ -1041,6 +973,8 @@ void Window::SetCursor(Cursor curs) { cursor = kThemeResizeLeftRightCursor; break; case cursorVert: + cursor = kThemeResizeUpDownCursor; + break; case cursorReverseArrow: case cursorUp: default: @@ -1148,7 +1082,7 @@ private: int lineHeight; bool unicodeMode; int desiredVisibleRows; - unsigned int maxItemCharacters; + unsigned int maxItemWidth; unsigned int aveCharWidth; Font font; int maxWidth; @@ -1170,7 +1104,7 @@ public: void *doubleClickActionData; ListBoxImpl() : lb(NULL), lineHeight(10), unicodeMode(false), - desiredVisibleRows(5), maxItemCharacters(0), aveCharWidth(8), + desiredVisibleRows(5), maxItemWidth(0), aveCharWidth(8), doubleClickAction(NULL), doubleClickActionData(NULL) { if (kScrollBarWidth == 0) @@ -1223,7 +1157,7 @@ void ListBoxImpl::Create(Window &/*parent*/, int /*ctrlID*/, Scintilla::Point /* int lineHeight_, bool unicodeMode_) { lineHeight = lineHeight_; unicodeMode = unicodeMode_; - maxWidth = 1000; + maxWidth = 2000; WindowClass windowClass = kHelpWindowClass; WindowAttributes attributes = kWindowNoAttributes; @@ -1501,13 +1435,14 @@ void ListBoxImpl::SetFont(Font &font_) { #endif // !@&^#%$ we cant copy Font, but we need one for our custom drawing - Str255 fontName; - if (FMGetFontFamilyName(style.font, fontName) != kFMInvalidFontFamilyErr) { - // make sure we conver to a proper C string first. - char cFontName[255]; - CopyPascalStringToC(fontName, cFontName); - font.Create((const char *)cFontName, 0, style.size, false, false); - } + Str255 fontName255; + char fontName[256]; + FMGetFontFamilyName(style.font, fontName255); + + CFStringRef fontNameCF = ::CFStringCreateWithPascalString( kCFAllocatorDefault, fontName255, kCFStringEncodingMacRoman ); + ::CFStringGetCString( fontNameCF, fontName, (CFIndex)255, kCFStringEncodingMacRoman ); + + font.Create((const char *)fontName, 0, style.size, false, false); } void ListBoxImpl::SetAverageCharWidth(int width) { @@ -1545,17 +1480,14 @@ PRectangle ListBoxImpl::GetDesiredRect() { rows = desiredVisibleRows; rcDesired.bottom = itemHeight * rows; - int width = maxItemCharacters; - if (width < 12) - width = 12; - // XXX use the quartz text stuff to figure out the correct string width - rcDesired.right = rcDesired.left + width * (aveCharWidth+aveCharWidth/4); - if (rcDesired.right > maxWidth) { - rcDesired.right = maxWidth; - } - if (Length() > rows) + rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth; + + if (Length() > rows) rcDesired.right += kScrollBarWidth; rcDesired.right += IconWidth(); + + // Set the column width + ::SetDataBrowserTableViewColumnWidth (lb, UInt16 (rcDesired.right - rcDesired.left)); return rcDesired; } @@ -1578,7 +1510,7 @@ int ListBoxImpl::CaretFromEdge() { void ListBoxImpl::Clear() { // passing NULL to "items" arg 4 clears the list - maxItemCharacters = 0; + maxItemWidth = 0; ld.Clear(); AddDataBrowserItems (lb, kDataBrowserNoItem, 0, NULL, kDataBrowserItemNoProperty); } @@ -1588,15 +1520,15 @@ void ListBoxImpl::Append(char *s, int type) { CFStringRef r = CFStringCreateWithCString(NULL, s, kTextEncodingMacRoman); ld.Add(count, type, r); + Scintilla::SurfaceImpl surface; + unsigned int width = surface.WidthText (font, s, strlen (s)); + if (width > maxItemWidth) + maxItemWidth = width; + DataBrowserItemID items[1]; items[0] = count + 1; AddDataBrowserItems (lb, kDataBrowserNoItem, 1, items, kDataBrowserItemNoProperty); ShowHideScrollbar(); - - size_t len = strlen(s); - if (maxItemCharacters < len) - maxItemCharacters = len; - } void ListBoxImpl::SetList(const char* list, char separator, char typesep) { @@ -1721,7 +1653,6 @@ void Menu::CreatePopUp() { Destroy(); OSStatus err; err = CreateNewMenu( nextMenuID++, 0, reinterpret_cast<MenuRef*>( &id ) ); - assert( noErr == err && id != NULL ); } void Menu::Destroy() { @@ -1746,8 +1677,6 @@ void Menu::Show(Point pt, Window &) { &menuId, &menuItem ); - // The system should always handle the command for us, so we should get userCanceledErr - assert( /*noErr == err ||*/ userCanceledErr == err ); } // TODO: Consider if I should be using GetCurrentEventTime instead of gettimeoday @@ -1755,7 +1684,6 @@ ElapsedTime::ElapsedTime() { struct timeval curTime; int retVal; retVal = gettimeofday( &curTime, NULL ); - assert( retVal == 0 ); bigBit = curTime.tv_sec; littleBit = curTime.tv_usec; @@ -1765,7 +1693,6 @@ double ElapsedTime::Duration(bool reset) { struct timeval curTime; int retVal; retVal = gettimeofday( &curTime, NULL ); - assert( retVal == 0 ); long endBigBit = curTime.tv_sec; long endLittleBit = curTime.tv_usec; double result = 1000000.0 * (endBigBit - bigBit); @@ -1794,7 +1721,11 @@ static Str255 PlatformDefaultFontName; const char *Platform::DefaultFont() { long id = HighShortFromLong(GetScriptVariable(smCurrentScript, smScriptAppFondSize)); FMGetFontFamilyName(id, PlatformDefaultFontName); - return (const char *)PlatformDefaultFontName; + char* defaultFontName = (char*) PlatformDefaultFontName; + defaultFontName[defaultFontName[0]+1] = 0; + ++defaultFontName; + + return defaultFontName; } int Platform::DefaultFontSize() { @@ -1836,17 +1767,17 @@ long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, } bool Platform::IsDBCSLeadByte(int /*codePage*/, char /*ch*/) { - // TODO: Implement this + // TODO: Implement this for code pages != UTF-8 return false; } int Platform::DBCSCharLength(int /*codePage*/, const char* /*s*/) { - // TODO: Implement this + // TODO: Implement this for code pages != UTF-8 return 1; } int Platform::DBCSCharMaxLength() { - // TODO: Implement this + // TODO: Implement this for code pages != UTF-8 //return CFStringGetMaximumSizeForEncoding( 1, CFStringEncoding encoding ); return 2; } @@ -1906,11 +1837,13 @@ void Platform::Assert(const char *c, const char *file, int line) { sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); strcat(buffer, "\r\n"); Platform::DebugDisplay(buffer); - abort(); +#ifdef DEBUG + // Jump into debugger in assert on Mac (CL269835) + ::Debugger(); +#endif } int Platform::Clamp(int val, int minVal, int maxVal) { - assert( minVal <= maxVal ); if (val > maxVal) val = maxVal; if (val < minVal) |