From ceb2323c0ba751c28346d18f78c4d757e02433da Mon Sep 17 00:00:00 2001 From: fedor Date: Mon, 24 Mar 2003 18:15:56 +0000 Subject: [PATCH] Merge from 0.8.5 branch git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@16250 72102866-910b-0410-8b05-ffd578937521 --- ANNOUNCE | 9 +- ChangeLog | 35 + Documentation/news.texi | 4 + Headers/gnustep/gui/GMAppKit.h | 2 +- Headers/gnustep/gui/GMArchiver.h | 12 +- Headers/gnustep/gui/IMConnectors.h | 6 +- Headers/gnustep/gui/IMCustomObject.h | 8 +- Headers/gnustep/gui/IMLoading.h | 6 +- Headers/gnustep/gui/NSNibConnector.h | 6 +- Headers/gnustep/gui/NSStringDrawing.h | 4 - Model/Controller.h | 2 +- Model/Controller.m | 2 +- Model/GMAppKit.m | 2 - Model/GMArchiveObjects.m | 6 +- Model/GMArchiver.m | 24 +- Model/IBClasses.h | 6 +- Model/IBClasses.m | 17 +- Model/IMConnectors.h | 6 +- Model/IMLoading.m | 14 +- Model/Translator.h | 6 +- Model/Translator.m | 11 +- Model/nib2gmodel.m | 7 +- Model/test.m | 4 +- NEWS | 7 +- README | 2 +- Source/NSBox.m | 2 +- Source/NSFont.m | 8 +- Source/NSStringDrawing.m | 1376 ++--------------- .../gsnd/portaudio/pa_unix_oss/pa_unix_oss.c | 6 + Version | 2 +- 30 files changed, 321 insertions(+), 1281 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index acc289661..3c60290ed 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,7 +1,7 @@ ANNOUNCE ******** -This is version 0.8.4 of the GNUstep GUI library (`gnustep-gui'). +This is version 0.8.5 of the GNUstep GUI library (`gnustep-gui'). What is the GNUstep GUI Library? ================================ @@ -28,6 +28,11 @@ systems. GNUstep Base Library, the TIFF Graphics library, and a back-end component like the GNUstep 'Back' Backend. +Noteworthy changes in version `0.8.5' +===================================== + + Bug fixes. NSStringDrawing now uses text system implementation. + Noteworthy changes in version `0.8.4' ===================================== @@ -45,7 +50,7 @@ Alexander Malmberg. Other improvements include: Where can you get it? How can you compile it? ============================================== - The gstep-gui-0.8.4.tar.gz distribution file has been placed on + The gstep-gui-0.8.5.tar.gz distribution file has been placed on `ftp.gnustep.org' in `pub/gnustep/core'. the TIFF Graphics library version 3.4 is required. diff --git a/ChangeLog b/ChangeLog index 83f760441..dae897cd7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2003-03-24 Adam Fedor + + * Merge from 0.8.5 branch + 2003-03-23 Serg Stoyan * Source/NSMenuView.m: Removed horizontal menu related code. (setHorizontal:): Removed. @@ -275,6 +279,37 @@ (-textStorage:edited:range:changeInLength:invalidatedRange:): Fix handling of trailing text containers when soft-invalidating. +2003-03-24 Adam Fedor + + * Version: 0.8.5 + +2003-03-24 Adam Fedor + + * Source/NSBox.m (-sizeToFit): Set frame to calculated size when + content view has no subviews. + +2003-03-18 17:54 Alexander Malmberg + + * Source/NSFont.m, Source/NSStringDrawing.m, + Headers/gnustep/gui/NSStringDrawing.h: Change to an implementation + that uses the text system. + +2003-03-07 Richard Frith-Macdonald + + * Source/NSWindow: ([-miniaturise:]) order the counterpart window + in so that it gets drawn properly. + +2003-03-04 Adam Fedor + + * Headers/gnustep/gui/GMAppKit.h, GMArchiver.h, IMConnectors.h, + IMCustomObject.h, IMLoading.h, NSNibConnector.h: Change #import to + #include + * Model/Controller.[h,m], GMAppKit.m, GMArchiveObjects.m, + GMArchiver.m, IBClasses.[hm], IMConnectors.h, IMLoading.m, + Translator.[hm], nib2gmodel.m, test.m: Idem. + + * Tools/gsnd/portaudio/pa_unix_oss/pa_unix_oss.c: Fixes for FreeBSD. + 2003-02-24 Adam Fedor * Version: 0.8.4 diff --git a/Documentation/news.texi b/Documentation/news.texi index 41f782887..d576ddb55 100644 --- a/Documentation/news.texi +++ b/Documentation/news.texi @@ -9,6 +9,10 @@ The currently released version of the library is @samp{@value{GNUSTEP-GUI-VERSION}}. @end ifclear +@section Noteworthy changes in version @samp{0.8.5} + +Bug fixes. NSStringDrawing now uses text system implementation. + @section Noteworthy changes in version @samp{0.8.4} This release features a brand new text and layout system thanks diff --git a/Headers/gnustep/gui/GMAppKit.h b/Headers/gnustep/gui/GMAppKit.h index d36ab9a93..794815268 100644 --- a/Headers/gnustep/gui/GMAppKit.h +++ b/Headers/gnustep/gui/GMAppKit.h @@ -27,7 +27,7 @@ #define _GNUstep_H_GMAppKit #include -#import +#include @interface NSApplication (GMArchiverMethods) @end diff --git a/Headers/gnustep/gui/GMArchiver.h b/Headers/gnustep/gui/GMArchiver.h index 0c997bae7..11bb49131 100644 --- a/Headers/gnustep/gui/GMArchiver.h +++ b/Headers/gnustep/gui/GMArchiver.h @@ -29,10 +29,14 @@ #ifndef __GMArchiver_h__ #define __GMArchiver_h__ -#import -#import -#import -#import +#ifndef GNUSTEP +#include +#else +#include +#include +#include +#include +#endif @class NSString; @class NSData; diff --git a/Headers/gnustep/gui/IMConnectors.h b/Headers/gnustep/gui/IMConnectors.h index 9c510dda0..70b6c0164 100644 --- a/Headers/gnustep/gui/IMConnectors.h +++ b/Headers/gnustep/gui/IMConnectors.h @@ -30,7 +30,11 @@ #ifndef _GNUstep_H_IMConnectors #define _GNUstep_H_IMConnectors -#import +#ifndef GNUSTEP +#include +#else +#include +#endif @interface IMConnector : NSObject { diff --git a/Headers/gnustep/gui/IMCustomObject.h b/Headers/gnustep/gui/IMCustomObject.h index 4cb9e48dd..422ac6a24 100644 --- a/Headers/gnustep/gui/IMCustomObject.h +++ b/Headers/gnustep/gui/IMCustomObject.h @@ -30,8 +30,12 @@ #ifndef _GNUstep_H_IMCustomObject #define _GNUstep_H_IMCustomObject -#import -#import +#ifndef GNUSTEP +#include +#else +#include +#include +#endif /* Add an archiving category to object so every object can respond to -nibInstantiate diff --git a/Headers/gnustep/gui/IMLoading.h b/Headers/gnustep/gui/IMLoading.h index 0ce266e89..40158967f 100644 --- a/Headers/gnustep/gui/IMLoading.h +++ b/Headers/gnustep/gui/IMLoading.h @@ -26,7 +26,11 @@ #ifndef _GNUstep_H_IMLoading #define _GNUstep_H_IMLoading -#import +#ifndef GNUSTEP +#include +#else +#include +#endif @interface NSObject (NibAwaking) - (void)awakeFromModel; diff --git a/Headers/gnustep/gui/NSNibConnector.h b/Headers/gnustep/gui/NSNibConnector.h index 2972f2d6d..a109d49e6 100644 --- a/Headers/gnustep/gui/NSNibConnector.h +++ b/Headers/gnustep/gui/NSNibConnector.h @@ -26,7 +26,11 @@ #ifndef _GNUstep_H_NSNibConnector #define _GNUstep_H_NSNibConnector -#import +#ifndef GNUSTEP +#include +#else +#include +#endif @interface NSNibConnector : NSObject { diff --git a/Headers/gnustep/gui/NSStringDrawing.h b/Headers/gnustep/gui/NSStringDrawing.h index 2762f11ad..4a1686516 100644 --- a/Headers/gnustep/gui/NSStringDrawing.h +++ b/Headers/gnustep/gui/NSStringDrawing.h @@ -51,10 +51,6 @@ - (void) drawAtPoint: (NSPoint)point; - (void) drawInRect: (NSRect)rect; --(NSSize) sizeRange:(NSRange) aRange; --(void) drawRange:(NSRange) aRange atPoint:(NSPoint) aPoint; --(void) drawRange:(NSRange) aRange inRect:(NSRect) aRect; - @end #endif /* _GNUstep_H_NSStringDrawing */ diff --git a/Model/Controller.h b/Model/Controller.h index 6e8f8aeef..26e4e887a 100644 --- a/Model/Controller.h +++ b/Model/Controller.h @@ -1,4 +1,4 @@ -#import +#include @interface Controller : NSObject { diff --git a/Model/Controller.m b/Model/Controller.m index 1c8174071..dcde9f4f2 100644 --- a/Model/Controller.m +++ b/Model/Controller.m @@ -1,4 +1,4 @@ -#import "Controller.h" +#include "Controller.h" @implementation Controller diff --git a/Model/GMAppKit.m b/Model/GMAppKit.m index 4da6ddba7..aa3649230 100644 --- a/Model/GMAppKit.m +++ b/Model/GMAppKit.m @@ -23,8 +23,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#import -#import #include "gnustep/gui/GMAppKit.h" #ifndef AUTORELEASE diff --git a/Model/GMArchiveObjects.m b/Model/GMArchiveObjects.m index a8a6314b8..a313bf3a7 100644 --- a/Model/GMArchiveObjects.m +++ b/Model/GMArchiveObjects.m @@ -34,7 +34,11 @@ symbol from the category's file in order to force it link. */ -#import +#ifndef GNUSTEP +#include +#else +#include +#endif @implementation NSObject (ModelArchivingMethods) diff --git a/Model/GMArchiver.m b/Model/GMArchiver.m index d82d8e133..a8e24d43e 100644 --- a/Model/GMArchiver.m +++ b/Model/GMArchiver.m @@ -26,16 +26,20 @@ /* Portions of the code are based on NSArchiver from libFoundation. See the COPYING file from libFoundation for copyright information. */ -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import +#ifndef GNUSTEP +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif #ifndef AUTORELEASE #define AUTORELEASE(object) [object autorelease] diff --git a/Model/IBClasses.h b/Model/IBClasses.h index 7bb819eb6..ba5eb5ba1 100644 --- a/Model/IBClasses.h +++ b/Model/IBClasses.h @@ -29,7 +29,11 @@ #ifndef _GNUstep_H_IBClasses #define _GNUstep_H_IBClasses -#import +#ifndef GNUSTEP +#include +#else +#include +#endif @class NSString; diff --git a/Model/IBClasses.m b/Model/IBClasses.m index ecebd30af..0ff253362 100644 --- a/Model/IBClasses.m +++ b/Model/IBClasses.m @@ -25,10 +25,11 @@ #include -#import -#import -#import -#import +#ifdef GNUSTEP +#include +#include +#endif +#include #ifdef __APPLE__ #import @@ -36,10 +37,10 @@ #import #endif -#import "IBClasses.h" -#import "Translator.h" -#import "IMConnectors.h" -#import "gnustep/gui/IMCustomObject.h" +#include "IBClasses.h" +#include "Translator.h" +#include "IMConnectors.h" +#include "gnustep/gui/IMCustomObject.h" //#define DEBUG diff --git a/Model/IMConnectors.h b/Model/IMConnectors.h index 9c510dda0..70b6c0164 100644 --- a/Model/IMConnectors.h +++ b/Model/IMConnectors.h @@ -30,7 +30,11 @@ #ifndef _GNUstep_H_IMConnectors #define _GNUstep_H_IMConnectors -#import +#ifndef GNUSTEP +#include +#else +#include +#endif @interface IMConnector : NSObject { diff --git a/Model/IMLoading.m b/Model/IMLoading.m index 6c1036bb5..3114651d3 100644 --- a/Model/IMLoading.m +++ b/Model/IMLoading.m @@ -23,10 +23,14 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#import -#import -#import -#import +#ifndef GNUSTEP +#include +#else +#include +#include +#include +#include +#endif #include "gnustep/gui/GMArchiver.h" #include "gnustep/gui/IMLoading.h" @@ -204,7 +208,7 @@ BOOL _fileOwnerDecoded = NO; #if GNU_RUNTIME -#import "IMConnectors.h" +#include "IMConnectors.h" static void __dummyFunctionForLinking (void) { diff --git a/Model/Translator.h b/Model/Translator.h index cc1b1eca1..eba92c4ee 100644 --- a/Model/Translator.h +++ b/Model/Translator.h @@ -26,7 +26,11 @@ #ifndef _GNUstep_H_Translator #define _GNUstep_H_Translator -#import +#ifndef GNUSTEP +#include +#else +#include +#endif @class NSMutableArray; diff --git a/Model/Translator.m b/Model/Translator.m index e696d48e0..a4b1b2c79 100644 --- a/Model/Translator.m +++ b/Model/Translator.m @@ -30,12 +30,11 @@ Imran Qureshi. */ -#import -#import -#import "gnustep/gui/GMArchiver.h" -#import "gnustep/gui/IMLoading.h" -#import "IBClasses.h" -#import "Translator.h" +#include +#include "gnustep/gui/GMArchiver.h" +#include "gnustep/gui/IMLoading.h" +#include "IBClasses.h" +#include "Translator.h" NSMutableArray* objects; NSMutableArray* connections; diff --git a/Model/nib2gmodel.m b/Model/nib2gmodel.m index cb2521f7f..6292a4178 100644 --- a/Model/nib2gmodel.m +++ b/Model/nib2gmodel.m @@ -25,11 +25,8 @@ #include -#import -#import -#import -#import -#import "Translator.h" +#include +#include "Translator.h" int main () { diff --git a/Model/test.m b/Model/test.m index e4104b71c..7370d45f7 100644 --- a/Model/test.m +++ b/Model/test.m @@ -1,5 +1,5 @@ -#import -#import +#include +#include int main (int argc, char** argv, char** env) { diff --git a/NEWS b/NEWS index 3b4243e69..e459f679f 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,12 @@ NEWS **** -The currently released version of the library is `0.8.4'. +The currently released version of the library is `0.8.5'. + +Noteworthy changes in version `0.8.5' +===================================== + + Bug fixes. NSStringDrawing now uses text system implementation. Noteworthy changes in version `0.8.4' ===================================== diff --git a/README b/README index 5d931c444..dc0bf2ff5 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ README ****** -This is version 0.8.4 of the GNUstep GUI library (`gnustep-gui'). +This is version 0.8.5 of the GNUstep GUI library (`gnustep-gui'). Here is some introductory info to get you started: diff --git a/Source/NSBox.m b/Source/NSBox.m index 715dd3f0b..2e65686a1 100644 --- a/Source/NSBox.m +++ b/Source/NSBox.m @@ -301,7 +301,7 @@ } else // _content_view has no subviews { - [_content_view setFrame: NSZeroRect]; + [_content_view setFrame: [self calcSizesAllowingNegative: NO]]; } } diff --git a/Source/NSFont.m b/Source/NSFont.m index 28e612109..c1a8909f5 100644 --- a/Source/NSFont.m +++ b/Source/NSFont.m @@ -749,6 +749,12 @@ setNSFont(NSString* key, NSFont* font) screenFont: screenFont]); } +static BOOL flip_hack; ++(void) _setFontFlipHack: (BOOL)flip +{ + flip_hack = flip; +} + // // Setting the Font // @@ -760,7 +766,7 @@ setNSFont(NSString* key, NSFont* font) { NSGraphicsContext *ctxt = GSCurrentContext(); - if (matrixExplicitlySet == NO && [[NSView focusView] isFlipped]) + if (matrixExplicitlySet == NO && ([[NSView focusView] isFlipped] || flip_hack)) [ctxt GSSetFont: [[self _flippedViewFont] fontRef]]; else [ctxt GSSetFont: [self fontRef]]; diff --git a/Source/NSStringDrawing.m b/Source/NSStringDrawing.m index 2cd180943..e304b564e 100644 --- a/Source/NSStringDrawing.m +++ b/Source/NSStringDrawing.m @@ -3,11 +3,14 @@ Categories which add drawing capabilities to NSAttributedString and NSString. - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2003 Free Software Foundation, Inc. Author: Richard Frith-Macdonald Date: Mar 1999 - rewrite from scratch + Author: Alexander Malmberg + Date: November 2002 - February 2003 (rewrite to use NSLayoutManager et al) + This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or @@ -26,1270 +29,203 @@ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include -#include -#include -#include + +#include +#include +#include #include #include "GSTextStorage.h" -// For the encoding functions -#include - -#define NO_R_MARGIN 1.0E8 - /* - * A function called by NSApplication to ensure that this file is linked - * when it should be. - */ -void -GSStringDrawingDummyFunction() -{ -} +TODO: -static NSCharacterSet *newlines; -static NSFont *defFont; -static NSParagraphStyle *defStyle; -static NSColor *defFgCol; -static NSColor *defBgCol; -static SEL advSel; +these methods are _not_ reentrant. should they be? -/* - * Thne 'checkInit()' function is called to ensure that any static - * variables required by the string drawing code are initialised. - */ -static void -checkInit() -{ - static BOOL beenHere = NO; - - if (beenHere == NO) - { - NSMutableCharacterSet *ms; - NSCharacterSet *whitespace; - - advSel = @selector(advancementForGlyph:); - - whitespace = RETAIN([NSCharacterSet whitespaceCharacterSet]); - - /* - * Build a character set containing only newline characters. - */ - ms = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy]; - [ms formIntersectionWithCharacterSet: [whitespace invertedSet]]; - newlines = [ms copy]; - RELEASE(ms); - - defStyle = [NSParagraphStyle defaultParagraphStyle]; - RETAIN(defStyle); - defBgCol = nil; - beenHere = YES; - } - - /* - * These defaults could change during the running of the program if the - * user defaults are changed. - */ - defFont = [NSFont userFontOfSize: 0]; - defFgCol = [NSColor textColor]; -} - -/* - * A GSGlyphInfo is used to maintain information about a single glyph - */ -typedef struct { - NSGlyph glyph; // The glyph to be drawn. - NSSize adv; // How far to move to draw next glyph. -} GSGlyphInfo; - -/* - * A GSGlyphArray structure is used to keep track of how many slots in an - * array of GSGlyphInfo structures have been allocated to GSTextRuns - */ -typedef struct { - unsigned size; - unsigned used; - GSGlyphInfo *glyphs; -} GSGlyphArray; - -typedef struct { - NSFont *font; // Last font used. - NSStringEncoding enc; // The encoding of the font - NSColor *color; // Last color used. - NSGraphicsContext *ctxt; // Drawing context. - BOOL flip; // If view is flipped. -} GSDrawInfo; - -/* - * A GSTextRun structure is used to hold information about a run of characters - * identical attributes. - */ -typedef struct GSTextRunStruct { - unsigned glyphCount; // Number of glyphs in run. - GSGlyphInfo *glyphs; // Starting glyph. - float width; // Width of entire run. - float height; // Height of entire run. - float baseline; // Where to draw glyphs. - // These fields are for normal glyphs - NSFont *font; - NSColor *bg; - NSColor *fg; - int underline; - int superscript; - float base; - float kern; - int ligature; - // Fields for special glyphs - id cell; - unsigned charIndex; - - // Forward and backward link - struct GSTextRunStruct *last; - struct GSTextRunStruct *next; -} GSTextRun; - -static void -drawSpecialRun(GSTextRun *run, NSPoint origin, GSDrawInfo *draw) -{ - // Currently this is only used for attachments - id cell = run->cell; - unsigned charIndex = run->charIndex; - NSRect cellFrame = NSMakeRect(origin.x, (draw->flip ? - origin.y - run->glyphs[0].adv.height : - origin.y), - run->glyphs[0].adv.width, - run->glyphs[0].adv.height); - NSView *controlView = [draw->ctxt focusView]; - - [cell drawWithFrame: cellFrame - inView: controlView - characterIndex: charIndex - layoutManager: nil]; -} - -static void -drawRun(GSTextRun *run, NSPoint origin, GSDrawInfo *draw) -{ - /* - * Adjust the drawing origin so that the y coordinate is at the baseline - * of the font. - */ - if (draw->flip) - { - origin.y -= run->base; - } - else - { - origin.y += run->base; - } - - if (run->glyphs[0].glyph == NSControlGlyph) - { - drawSpecialRun(run, origin, draw); - return; - } - - /* - * Set current font and color if necessary. - */ - if (draw->color != run->fg) - { - [run->fg set]; - draw->color = run->fg; - } - - if (draw->font != run->font) - { - [run->font set]; - draw->font = run->font; - draw->enc = [run->font mostCompatibleStringEncoding]; - } - - /* - * Now draw the text. - * FIXME - should actually draw glyphs - at present we just use ascii. - */ - if (run->kern == 0) - { - unsigned i; - NSStringEncoding enc = draw->enc; - - // glyph is an unicode char value - // if the font has non-standard encoding we need to remap it. - unichar u[run->glyphCount]; - char *r = NULL; - unsigned l = run->glyphCount; - unsigned s = 0; - - for (i = 0; i < run->glyphCount; i++) - u[i] = run->glyphs[i].glyph; - - if (GSFromUnicode((unsigned char**)&r, &s, u, l, enc, - NSDefaultMallocZone(), GSUniTerminate | GSUniTemporary) == NO) - { - [NSException raise: NSCharacterConversionException - format: @"Can't convert to/from Unicode string."]; - } - - DPSmoveto(draw->ctxt, origin.x, origin.y); - if (l) - DPSshow(draw->ctxt, r); - } - else - { - char buf[2]; - unsigned i; - NSStringEncoding enc = draw->enc; - - buf[1] = '\0'; - for (i = 0; i < run->glyphCount; i++) - { - // glyph is an unicode char value - // if the font has non-standard encoding we need to remap it. - if ((enc != NSASCIIStringEncoding) && - (enc != NSUnicodeStringEncoding)) - { - unsigned int size = 1; - unsigned char *dst = buf; - unichar glyph = run->glyphs[i].glyph; - - GSFromUnicode(&dst, &size, &glyph, 1, enc, 0, 0); - } - else - { - buf[0] = (char)run->glyphs[i].glyph; - } - DPSmoveto(draw->ctxt, origin.x, origin.y); - DPSshow(draw->ctxt, buf); - origin.x += run->glyphs[i].adv.width; - } - } - - if (run->underline) - { - DPSmoveto(draw->ctxt, origin.x, origin.y); - DPSlineto(draw->ctxt, origin.x + run->width, origin.y); - DPSstroke(draw->ctxt); - } -} - -static void -setupSpecialRun(GSTextRun *run, unsigned length, unichar *chars, unsigned pos, - NSDictionary *attr) -{ - NSTextAttachment *attachment = [attr objectForKey: NSAttachmentAttributeName]; - - run->cell = [attachment attachmentCell]; - run->charIndex = pos; - run->glyphs[0].glyph = NSControlGlyph; - // We should better call the cellFrameForTextContainer:... method here - run->glyphs[0].adv = [run->cell cellSize]; - - run->baseline = [run->cell cellBaselineOffset].y; - run->height = run->glyphs[0].adv.height; - run->width = run->glyphs[0].adv.width; - run->base = 0; - // Unset the normale fields - run->font = nil; - run->bg = nil; - run->fg = nil; -} - -static void -setupRun(GSTextRun *run, unsigned length, unichar *chars, unsigned pos, - NSDictionary *attr, GSGlyphArray *g, GSTextRun *last) -{ - NSNumber *num; - unsigned i; - float above; - float below; - - /* - * Add run to linked list after the previous run. - */ - run->next = 0; - run->last = last; - if (last != 0) - last->next = run; - - /* - * Assign a section of the glyphs array to hold info for this run. - */ - run->glyphCount = length; - run->glyphs = &g->glyphs[g->used]; - g->used += run->glyphCount; - - if (chars[0] == NSAttachmentCharacter) - { - setupSpecialRun(run, length, chars, pos, attr); - return; - } - - // Get font to be used by characters in run. - run->font = (NSFont*)[attr objectForKey: NSFontAttributeName]; - if (run->font == nil) - run->font = defFont; - - // Get background color - run->bg = (NSColor*)[attr objectForKey: NSBackgroundColorAttributeName]; - if (run->bg == nil) - run->bg = defBgCol; - - // Get foreground color - run->fg = (NSColor*)[attr objectForKey: NSForegroundColorAttributeName]; - if (run->fg == nil) - run->fg = defFgCol; - - // Get underline style - num = (NSNumber*)[attr objectForKey: NSUnderlineStyleAttributeName]; - if (num == nil) - run->underline = GSNoUnderlineStyle; // No underline - else - run->underline = [num intValue]; - - // Get superscript - num = (NSNumber*)[attr objectForKey: NSSuperscriptAttributeName]; - if (num == nil) - run->base = 0.0; - else - // interprete as a baseline change without font change - run->base = 3.0 * [num intValue]; - - // Get baseline offset - num = (NSNumber*)[attr objectForKey: NSBaselineOffsetAttributeName]; - if (num != nil) - run->base = [num floatValue]; - // Else, use value from superscript! - - // Get kern attribute - num = (NSNumber*)[attr objectForKey: NSKernAttributeName]; - if (num == nil) - run->kern = 0.0; - else - run->kern = [num floatValue]; - - // Get ligature attribute - num = (NSNumber*)[attr objectForKey: NSLigatureAttributeName]; - if (num == nil) - run->ligature = 1; - else - run->ligature = [num intValue]; - - /* - * Calculate height of line from font information and base offset. - */ - below = -([run->font descender]); - above = [run->font pointSize]; - if (run->base > 0) - above += run->base; // Character is above baseline. - else if (run->base < 0) - below -= run->base; // Character is below baseline. - run->baseline = below; - run->height = below + above; - - /* - * Get the characters for this run from the string and set up the - * array of glyphs, allong with their advancement information. - * As we build the array, we keep a total of the run width. - * FIXME This code should really look at the string and determine - * glyphs properly rather than assuming that the unicode character - * is the same as the glyph (which will not always be true). - * At the moment, we are ignoring unicode character composition and - * are ignoring ligatures. - */ - if (length > 0) - { - NSSize (*advImp)(NSFont*, SEL, NSGlyph); - NSFont *font = run->font; - float kern = run->kern; - float width = 0; - - advImp = (NSSize (*)(NSFont*, SEL, NSGlyph)) - [run->font methodForSelector: advSel]; - - if (kern == 0) - { - /* Special case - if no kerning, we can do things a bit quicker. */ - for (i = 0; i < length; i++) - { - GSGlyphInfo *gi = &run->glyphs[i]; - - gi->glyph = (NSGlyph)chars[i]; - gi->adv = (*advImp)(font, advSel, gi->glyph); - width += gi->adv.width; - } - } - else - { - for (i = 0; i < length; i++) - { - GSGlyphInfo *gi = &run->glyphs[i]; - - gi->glyph = (NSGlyph)chars[i]; - gi->adv = (*advImp)(font, advSel, gi->glyph); - gi->adv.width += kern; - width += gi->adv.width; - } - } - - run->width = width; - } - else - { - run->width = 0; - } -} - -/* - * A GSTextChunk structure is used to maintain a list of GSTextRuns that make - * up the text between two tabstops. - */ -typedef struct GSTextChunkStruct { - GSTextRun run0; // Starting run in chunk. - float width; // Width of entire chunk. - float height; // Height of entire chunk. - float baseline; // Baseline for characters. - float xpos; // Position of chunk in line. - float decimal; // Position of decimal point. - struct GSTextChunkStruct *last; - struct GSTextChunkStruct *next; -} GSTextChunk; - -static void -drawChunk(GSTextChunk *chunk, NSPoint origin, GSDrawInfo *draw) -{ - GSTextRun *run = &chunk->run0; - - origin.x += chunk->xpos; - if (draw->flip) - { - origin.y += (chunk->height - chunk->baseline); - } - else - { - origin.y -= (chunk->height - chunk->baseline); - } - while (run) - { - drawRun(run, origin, draw); - origin.x += run->width; - run = run->next; - } -} - -/* - * emptyChunk() - release memory used by all chunks after this one, - * and release all dynamically allocated runs in this chunk (ie all - * but 'run0'). - */ -static void -emptyChunk(GSTextChunk *chunk) -{ - while (chunk->run0.next != 0) - { - GSTextRun *tmp = chunk->run0.next; - - chunk->run0.next = tmp->next; - objc_free(tmp); - } - if (chunk->next != 0) - { - emptyChunk(chunk->next); - objc_free(chunk->next); - chunk->next = 0; - } -} - -static void -setupChunk(GSTextChunk *chunk, NSAttributedString *str, NSString* string, - NSRange range, GSGlyphArray *g, GSTextChunk *last) -{ - GSTextRun *lastRun = 0; - NSDictionary *attr; - unsigned start = range.location; - unsigned loc = start; - unsigned end = NSMaxRange(range); - unichar chars[range.length]; - - [string getCharacters: chars range: range]; - - /* - * Add chunk to linked list after the previous chunk. - */ - chunk->next = 0; - chunk->last = last; - if (last != 0) - last->next = chunk; - - chunk->xpos = 0; - chunk->width = 0; - chunk->height = 0; - chunk->baseline = 0; - chunk->decimal = -1; // Not yet valid. - - /* - * Build up all the runs in this chunk - a run is a sequence of characters - * with the same attributes. - */ - do - { - unsigned where; - unsigned length; - - attr = [str attributesAtIndex: loc effectiveRange: &range]; - if (range.location < loc) - { - range.length -= (loc - range.location); - range.location = loc; - } - if (NSMaxRange(range) > end) - range.length = end - range.location; - - where = loc - start; - length = range.length; - if (lastRun == 0) - { - setupRun(&chunk->run0, length, &chars[where], loc, attr, g, 0); - lastRun = &chunk->run0; - } - else - { - GSTextRun *run = (GSTextRun*)objc_malloc(sizeof(GSTextRun)); - - setupRun(run, length, &chars[where], loc, attr, g, lastRun); - lastRun = run; - } - - chunk->width += lastRun->width; - if (lastRun->baseline > chunk->baseline) - chunk->baseline = lastRun->baseline; - if (lastRun->height > chunk->height) - chunk->height = lastRun->height; - - loc = NSMaxRange(range); - } - while (loc < end); - - if (lastRun == 0) - setupRun(&chunk->run0, 0, 0, start, nil, g, 0); -} - -/* - * The chunkDecimal() function searches a chunk of text for the first decimal - * point and returns it's position within the chunk. This is used for decimal - * tabs. - */ -static float -chunkDecimal(GSTextChunk *chunk) -{ - if (chunk->decimal < 0) - { - GSTextRun *run = &chunk->run0; - - chunk->decimal = 0; - while (run != 0) - { - unsigned i; - GSGlyphInfo *gi = run->glyphs; - - for (i = 0; i < run->glyphCount; i++) - { - if (gi[i].glyph == (NSGlyph)'.') - break; - chunk->decimal += gi[i].adv.width; - } - run = run->next; - } - } - return chunk->decimal; -} - -/* - * The GSTextLine structure is used to maintain information about a - * complete line of text consisting of one or more GSTextChunks. - */ -typedef struct GSTextLine { - GSTextChunk chunk0; // Starting run in chunk. - float width; // Width of entire chunk. - float height; // Height of entire chunk. - NSArray *tabs; // Tabstops in line. - float indent; // Position of start of line. - float rmargin; // Position of end of line. - float leading; // Space below line. - NSTextAlignment alignment; // Alignment for entire line. - NSLineBreakMode lineBreakMode; // How to deal with long lines. -} GSTextLine; - -static void -emptyLine(GSTextLine *line) -{ - emptyChunk(&line->chunk0); -} - -/* - * The backLine() function draws the text background for a line of text. - * FIXME - is this behavior what we want? - * We actually fill the entire line including the inter-line space (leading) - * with whatever background color is used by the text at any point. - */ -static void -backLine(GSTextLine *line, NSGraphicsContext *ctxt, NSPoint origin, BOOL flip) -{ - NSRect fillrect; - GSTextChunk *chunk = &line->chunk0; - NSColor *bg; - float offset = origin.x; - - fillrect.origin.y = origin.y; - fillrect.size.height = line->height + line->leading; - if (flip == NO) - fillrect.origin.y -= fillrect.size.height; - - fillrect.origin.x = line->chunk0.xpos; - - bg = line->chunk0.run0.bg; - while (chunk != 0) - { - GSTextRun *run = &chunk->run0; - - fillrect.size.width = chunk->xpos - fillrect.origin.x; - - while (run != 0) - { - if (run->bg == bg) - { - fillrect.size.width += run->width; - } - else - { - if (bg != nil) - { - [bg set]; - fillrect.origin.x += offset; - NSRectFill(fillrect); - fillrect.origin.x -= offset; - } - bg = run->bg; - fillrect.origin.x += fillrect.size.width; - fillrect.size.width = 0; - } - run = run->next; - } - chunk = chunk->next; - } - - if (bg != nil && fillrect.size.width > 0) - { - [bg set]; - fillrect.origin.x += offset; - NSRectFill(fillrect); - } -} - -static void -drawLine(GSTextLine *line, NSGraphicsContext *ctxt, NSPoint origin, BOOL flip) -{ - GSTextChunk *chunk = &line->chunk0; - GSDrawInfo draw; - - backLine(line, ctxt, origin, flip); - - draw.font = nil; - draw.color = nil; - draw.ctxt = ctxt; - draw.flip = flip; - - while (chunk != 0) - { - drawChunk(chunk, origin, &draw); - chunk = chunk->next; - } -} - -static GSTextChunk* -setupLine(GSTextLine *line, NSAttributedString *str, NSString* string, NSRange range, - GSGlyphArray *g, NSParagraphStyle *style, float rMargin, BOOL first) -{ - GSTextChunk *lastChunk = 0; - NSArray *tabs = [style tabStops]; - float maxh = [style maximumLineHeight]; - unsigned start = range.location; - unsigned end = NSMaxRange(range); - unsigned numTabs = [tabs count]; - unsigned nextTab = 0; - - line->alignment = [style alignment]; - line->lineBreakMode = [style lineBreakMode]; - line->height = [style minimumLineHeight]; - line->rmargin = [style tailIndent]; - if (line->rmargin <= 0.0) - line->rmargin += rMargin; - - if (first) - line->indent = [style firstLineHeadIndent]; - else - line->indent = [style headIndent]; - line->width = line->indent; - - line->leading = [style lineSpacing]; - - do - { - NSRange tabRange; - NSRange chunkRange; - - /* - * Locate a tab or end-of-line and set the chunk range to be the range - * up to (but not including) the tab. - */ - tabRange = [string rangeOfString: @"\t" - options: NSLiteralSearch - range: range]; - if (tabRange.length == 0) - tabRange.location = end; - chunkRange.location = range.location; - chunkRange.length = tabRange.location - range.location; - - /* - * Load information about the text chunk upto the tabstop into a - * GSTextChunk structure. - */ - if (lastChunk == 0) - { - setupChunk(&line->chunk0, str, string, chunkRange, g, 0); - lastChunk = &line->chunk0; - } - else - { - GSTextChunk *chunk; - - chunk = (GSTextChunk*)objc_malloc(sizeof(GSTextChunk)); - setupChunk(chunk, str, string, chunkRange, g, lastChunk); - lastChunk = chunk; - } - - /* - * Advance our range past the tab we found, or to the end-of-line - */ - range.location = NSMaxRange(tabRange); - range.length = end - range.location; - - if (chunkRange.location > start) - { - float offset; - BOOL found = NO; - - /* - * We have had a tab before this chunk, try to align at a tabstop - */ - while (found == NO && nextTab < numTabs) - { - NSTextTab *tab = [tabs objectAtIndex: nextTab++]; - float loc = [tab location]; - - if (loc > line->width) - { - NSTextTabType type = [tab tabStopType]; - - if (type == NSLeftTabStopType) - { - lastChunk->xpos = loc; - found = YES; - } - else if (type == NSRightTabStopType - && loc - (offset = lastChunk->width) > line->width) - { - lastChunk->xpos = loc - offset; - found = YES; - } - else if (type == NSCenterTabStopType - && loc - (offset = lastChunk->width/2.0) > line->width) - { - lastChunk->xpos = loc - offset; - found = YES; - } - else if (type == NSDecimalTabStopType - && loc - (offset = chunkDecimal(lastChunk)) > line->width) - { - lastChunk->xpos = loc - offset; - found = YES; - } - } - } - if (found == NO) - { - /* - * No more tabs - run this chunk on directly from last. - */ - lastChunk->xpos = line->width; - } - } - else if (range.location >= end) - { - /* - * There are no tabs in this line - align by paragraph style. - * FIXME - NSNaturalTextAlignment should have different effects - * depending on script in use. - */ - if (line->alignment == NSLeftTextAlignment - || line->alignment == NSNaturalTextAlignment - || line->rmargin == NO_R_MARGIN) - { - /* - * Simple left alignment. - */ - lastChunk->xpos = line->width; - } - else if (line->alignment == NSRightTextAlignment) - { - lastChunk->xpos = line->rmargin - lastChunk->width; - } - else if (line->alignment == NSCenterTextAlignment) - { - lastChunk->xpos = line->rmargin - line->width - lastChunk->width; - lastChunk->xpos = (lastChunk->xpos / 2.0) + line->width; - } - else if (line->alignment == NSJustifiedTextAlignment) - { - // FIXME - need to support justified text. - lastChunk->xpos = line->width; - } - else - { - lastChunk->xpos = line->width; - } - } - else - { - /* - * First chunk on a line with tabs - simply align to left. - */ - lastChunk->xpos = line->width; - } - - /* - * FIXME - should check for line-break and handle long lines here. - * If we break a line, we should return the first chunk of the next line. - */ -/* - if (lastChunk->xpos + lastChunk->width > line->rmargin) - { - NSLineBreakMode lbm = line->lineBreakMode; - unsigned pos = 0; - unisgned i; - float xpos = lastChunk->xpos; - - // find the first character that does not fit on the line - for (i = chunkRange.location; i < NSMaxRange(chunkRange); i++) - { - float adv = g[i].adv.width; - - if (xpos + adv > line->rmargin) - break; - xpos += adv; - } - - if (lbm == NSLineBreakByWordWrapping) - { - // Get break position from string - pos = [str lineBreakBeforeIndex: i - withinRange: chunkRange]; - } - else if (lbm == NSLineBreakByCharWrapping) - { - // Simply do a linebreak at the current character position. - pos = i; - } - else - { - // Truncate line. - //pos = NSMaxRange(chunkRange); - } - // Break up the last chunk - // FIXME We should try to reuse as much as possible - if (pos) - { - NSRange newRange = NSMakeRange(chunkRange.location, pos-chunkRange.location); - end = pos; - empty_chunk(lastChunk); - setupChunk(lastChunk, str, string, newRange, g, lastChunk->last); - } - - } +We could save time by trying to avoid changing the text storage and +container size if the new rect and text are the same as the previous. +This might be a common case if lots of calls to -size... and -draw... +are paired. */ - /* - * Now extend line width to add the new chunk and adjust the line - * height if necessary. - */ - line->width = lastChunk->xpos + lastChunk->width; - if (lastChunk->height > line->height) - { - line->height = lastChunk->height; - if (maxh > 0 && line->height > maxh) - line->height = maxh; - } - } - while (range.location < end); +static NSTextStorage *textStorage; +static NSLayoutManager *layoutManager; +static NSTextContainer *textContainer; - /* - * If we got here, we are on the last line in the paragraph, so we use the - * paragraph spacing rather than line spacing as our leading. - */ - line->leading = [style paragraphSpacing]; - - return 0; -} - -static void -drawAttributedString(NSAttributedString *str, NSString *allText, NSRange aRange, - NSPoint point, float width, NSGraphicsContext *ctxt) +static void init_string_drawing(void) { - BOOL isFlipped = [[ctxt focusView] isFlipped]; - unsigned length = NSMaxRange(aRange); - unsigned paraPos = aRange.location; - NSRange styleRange; - NSParagraphStyle *style = nil; - GSTextLine current; + if (textStorage) + return; - checkInit(); - - /* - * Now produce output on a per-line basis. - */ - while (paraPos < length) - { - NSRange para; // Range of current paragraph. - NSRange line; // Range of current line. - NSRange eol; // Range of newline character. - unsigned position; // Position in NSString. - - /* - * Determine the range of the next paragraph of text (in 'para') and set - * 'paraPos' to point after the terminating newline character (if any). - */ - para = NSMakeRange(paraPos, length - paraPos); - eol = [allText rangeOfCharacterFromSet: newlines - options: NSLiteralSearch - range: para]; - - if (eol.length == 0) - eol.location = length; - else - para.length = eol.location - para.location; - paraPos = NSMaxRange(eol); - position = para.location; - - do - { - if (style == nil || NSMaxRange(styleRange) > position) - { - style = (NSParagraphStyle*)[str - attribute: NSParagraphStyleAttributeName - atIndex: position - effectiveRange: &styleRange]; - if (style == nil) - style = defStyle; - } - - /* - * Assemble drawing information for the entire line. - */ - line = para; - { - GSGlyphInfo info[line.length]; - GSGlyphArray garray; - - garray.used = 0; - garray.size = line.length; - garray.glyphs = info; - - setupLine(¤t, str, allText, line, &garray, style, width, YES); - drawLine(¤t, ctxt, point, isFlipped); - - if (isFlipped) - point.y += current.height + current.leading; - else - point.y -= current.height + current.leading; - - emptyLine(¤t); - } - para.length -= line.length; - para.location += line.length; - } - while (para.location < eol.location); - } + textStorage = [[NSTextStorage alloc] init]; + layoutManager = [[NSLayoutManager alloc] init]; + [textStorage addLayoutManager: layoutManager]; + [layoutManager release]; + textContainer = [[NSTextContainer alloc] + initWithContainerSize: NSMakeSize(10,10)]; + [layoutManager addTextContainer: textContainer]; + [textContainer release]; } -static NSSize -sizeAttributedString(NSAttributedString *str, NSString *allText, NSRange aRange) -{ - unsigned length = NSMaxRange(aRange); - unsigned paraPos = aRange.location; - NSParagraphStyle *style = nil; - GSTextLine current; - NSSize size = NSMakeSize(0,0); - float rMargin = NO_R_MARGIN; +/* +This is an ugly hack to get text to display correctly in non-flipped views. - checkInit(); - - while (paraPos < length) - { - NSRange para; // Range of current paragraph. - NSRange line; // Range of current line. - NSRange eol; // Range of newline character. - unsigned position; // Position in NSString. - BOOL firstLine = YES; - - /* - * Determine the range of the next paragraph of text (in 'para') and set - * 'paraPos' to point after the terminating newline character (if any). - */ - para = NSMakeRange(paraPos, length - paraPos); - eol = [allText rangeOfCharacterFromSet: newlines - options: NSLiteralSearch - range: para]; - - if (eol.length == 0) - eol.location = length; - else - para.length = eol.location - para.location; - paraPos = NSMaxRange(eol); - position = para.location; - - do - { - if (firstLine == YES) - { - style = (NSParagraphStyle*)[str - attribute: NSParagraphStyleAttributeName - atIndex: position - effectiveRange: 0]; - if (style == nil) - style = defStyle; - } - - /* - * Assemble drawing information for the entire line. - */ - line = para; - { - GSGlyphInfo info[line.length]; - GSGlyphArray garray; - - garray.used = 0; - garray.glyphs = info; - - setupLine(¤t, str, allText, line, &garray, style, rMargin, YES); - if (current.width > size.width) - size.width = current.width; - size.height += current.height + current.leading; - - emptyLine(¤t); - } - para.length -= line.length; - para.location += line.length; - } - while (para.location < eol.location); - } - - return size; -} - - +The text system always has positive y down, so we flip the coordinate +system when drawing (if the view isn't flipped already). This causes the +glyphs to be drawn upside-down, so we need to tell NSFont to flip the fonts. +*/ +@interface NSFont (font_flip_hack) ++(void) _setFontFlipHack: (BOOL)flip; +@end @implementation NSAttributedString (NSStringDrawing) - (void) drawAtPoint: (NSPoint)point { - NSGraphicsContext *ctxt = GSCurrentContext(); + NSRange r; + NSGraphicsContext *ctxt = GSCurrentContext(); - drawAttributedString(self, [self string], NSMakeRange(0, [self length]), - point, NO_R_MARGIN, ctxt); + init_string_drawing(); + + [textStorage replaceCharactersInRange: NSMakeRange(0, [textStorage length]) + withString: @""]; + + [textContainer setContainerSize: NSMakeSize(1e8, 1e8)]; + + [textStorage replaceCharactersInRange: NSMakeRange(0, 0) + withAttributedString: self]; + + r = NSMakeRange(0, [layoutManager numberOfGlyphs]); + + if (![[NSView focusView] isFlipped]) + { + DPSscale(ctxt, 1, -1); + point.y = -point.y; + [NSFont _setFontFlipHack: YES]; + } + + [layoutManager drawBackgroundForGlyphRange: r + atPoint: point]; + + [layoutManager drawGlyphsForGlyphRange: r + atPoint: point]; + + if (![[NSView focusView] isFlipped]) + { + DPSscale(ctxt, 1, -1); + [NSFont _setFontFlipHack: NO]; + } } - (void) drawInRect: (NSRect)rect { - NSPoint point; - NSView *view = [NSView focusView]; - - /* FIXME: This is an extremely lossy and temporary workaround for - the fact that we should draw only inside rect. */ + NSRange r; + BOOL need_clip; + NSRect used; NSGraphicsContext *ctxt = GSCurrentContext(); - DPSgsave(ctxt); - NSRectClip (rect); + + init_string_drawing(); + + [textStorage replaceCharactersInRange: NSMakeRange(0, [textStorage length]) + withString: @""]; /* - * Since [-drawAtPoint:] positions the top-left corner of the text at - * the point, we locate the top-left corner of the rectangle to do the - * drawing. - */ - point.x = rect.origin.x; - if ([view isFlipped]) - point.y = rect.origin.y; + TODO: Use rect.size.heigth instead of 1e8? Should make things faster, + since we'll only typeset what fits, but lines that used to fit partially + won't fit at all. + */ + [textContainer setContainerSize: NSMakeSize(rect.size.width, 1e8)]; + + [textStorage replaceCharactersInRange: NSMakeRange(0, 0) + withAttributedString: self]; + + used = [layoutManager usedRectForTextContainer: textContainer]; + + /* + If the used rect fits completely in the rect we draw in, we save time + by avoiding the DPSrectclip (and the state save and restore). + + This isn't completely safe; the used rect isn't guaranteed to contain + all parts of all glyphs. + */ + if (used.origin.x >= 0 && used.origin.y <= 0 && + NSMaxX(used) <= rect.size.width && NSMaxY(used) <= rect.size.height) + { + need_clip = NO; + } else - point.y = rect.origin.y + rect.size.height; + { + need_clip = YES; + DPSgsave(ctxt); + DPSrectclip(ctxt, rect.origin.x, rect.origin.y, + rect.size.width, rect.size.height); + } - drawAttributedString(self, [self string], NSMakeRange(0, [self length]), - point, rect.size.width, ctxt); + r = [layoutManager + glyphRangeForBoundingRect: NSMakeRect(0, 0, rect.size.width, rect.size.height) + inTextContainer: textContainer]; - /* Restore matching the DPSgsave used in the temporary workaround */ - DPSgrestore(ctxt); + if (![[NSView focusView] isFlipped]) + { + DPSscale(ctxt, 1, -1); + rect.origin.y = -NSMaxY(rect); + [NSFont _setFontFlipHack: YES]; + } + + [layoutManager drawBackgroundForGlyphRange: r + atPoint: rect.origin]; + + [layoutManager drawGlyphsForGlyphRange: r + atPoint: rect.origin]; + + [NSFont _setFontFlipHack: NO]; + if (![[NSView focusView] isFlipped]) + { + DPSscale(ctxt, 1, -1); + } + + if (need_clip) + { + /* Restore the original clipping path. */ + DPSgrestore(ctxt); + } } - (NSSize) size { - return sizeAttributedString(self, [self string], NSMakeRange(0, [self length])); -} + NSRange r; + NSRect rect; -// GNUstep extensions. -- (NSSize) sizeRange: (NSRange)aRange -{ - return sizeAttributedString(self, [self string], aRange); -} + init_string_drawing(); -- (void) drawRange: (NSRange)aRange atPoint: (NSPoint)aPoint -{ - NSGraphicsContext *ctxt = GSCurrentContext(); + [textStorage replaceCharactersInRange: NSMakeRange(0, [textStorage length]) + withString: @""]; - drawAttributedString(self, [self string], aRange, aPoint, NO_R_MARGIN, ctxt); -} + [textContainer setContainerSize: NSMakeSize(1e8, 1e8)]; -- (void) drawRange: (NSRange)aRange inRect: (NSRect)aRect -{ - NSPoint point; - NSView *view = [NSView focusView]; + [textStorage replaceCharactersInRange: NSMakeRange(0, 0) + withAttributedString: self]; - /* FIXME: This is an extremely lossy and temporary workaround for - the fact that we should draw only inside aRect. */ - NSGraphicsContext *ctxt = GSCurrentContext(); - DPSgsave(ctxt); - NSRectClip (aRect); + r = NSMakeRange(0, [layoutManager numberOfGlyphs]); - /* - * Since [-drawAtPoint:] positions the top-left corner of the text at - * the point, we locate the top-left corner of the rectangle to do the - * drawing. - */ - point.x = aRect.origin.x; - if ([view isFlipped]) - point.y = aRect.origin.y; - else - point.y = aRect.origin.y + aRect.size.height; - - drawAttributedString(self, [self string], aRange, point, aRect.size.width, - ctxt); - /* Restore matching the DPSgsave used in the temporary workaround */ - DPSgrestore(ctxt); + rect = [layoutManager usedRectForTextContainer: textContainer]; + return rect.size; } @end - -@implementation GSTextStorage (NSStringDrawing) - -- (void) drawAtPoint: (NSPoint)point -{ - NSGraphicsContext *ctxt = GSCurrentContext(); - - drawAttributedString(self, _textChars, NSMakeRange(0, [self length]), - point, NO_R_MARGIN, ctxt); -} - -- (void) drawInRect: (NSRect)rect -{ - NSPoint point; - NSView *view = [NSView focusView]; - - /* FIXME: This is an extremely lossy and temporary workaround for - the fact that we should draw only inside rect. */ - NSGraphicsContext *ctxt = GSCurrentContext(); - DPSgsave(ctxt); - NSRectClip (rect); - - /* - * Since [-drawAtPoint:] positions the top-left corner of the text at - * the point, we locate the top-left corner of the rectangle to do the - * drawing. - */ - point.x = rect.origin.x; - if ([view isFlipped]) - point.y = rect.origin.y; - else - point.y = rect.origin.y + rect.size.height; - - drawAttributedString(self, _textChars, NSMakeRange(0, [self length]), - point, rect.size.width, ctxt); - - /* Restore matching the DPSgsave used in the temporary workaround */ - DPSgrestore(ctxt); -} - -- (NSSize) size -{ - return sizeAttributedString(self, _textChars, NSMakeRange(0, [self length])); -} - -// GNUstep extensions. -- (NSSize) sizeRange: (NSRange)lineRange -{ - return sizeAttributedString(self, _textChars, lineRange); -} - -- (void) drawRange: (NSRange) lineRange atPoint: (NSPoint) point -{ - NSGraphicsContext *ctxt = GSCurrentContext(); - - drawAttributedString(self, _textChars, lineRange, point, NO_R_MARGIN, - ctxt); -} - -- (void) drawRange: (NSRange) lineRange inRect: (NSRect)rect -{ - NSPoint point; - NSView *view = [NSView focusView]; - - /* FIXME: This is an extremely lossy and temporary workaround for - the fact that we should draw only inside rect. */ - NSGraphicsContext *ctxt = GSCurrentContext(); - DPSgsave(ctxt); - NSRectClip (rect); - - /* - * Since [-drawAtPoint:] positions the top-left corner of the text at - * the point, we locate the top-left corner of the rectangle to do the - * drawing. - */ - point.x = rect.origin.x; - if ([view isFlipped]) - point.y = rect.origin.y; - else - point.y = rect.origin.y + rect.size.height; - - drawAttributedString(self, _textChars, lineRange, point, rect.size.width, - ctxt); - /* Restore matching the DPSgsave used in the temporary workaround */ - DPSgrestore(ctxt); -} - -@end - - /* - * I know it's severely sub-optimal, but the NSString methods just - * use NSAttributes string to do the job. - */ +TODO: It's severely sub-optimal, but the NSString methods just use +NSAttributedString to do the job. +*/ @implementation NSString (NSStringDrawing) - (void) drawAtPoint: (NSPoint)point withAttributes: (NSDictionary *)attrs { NSAttributedString *a; - a = [[NSAttributedString allocWithZone: NSDefaultMallocZone()] - initWithString: self attributes: attrs]; + a = [[NSAttributedString allocWithZone: NSDefaultMallocZone()] + initWithString: self + attributes: attrs]; [a drawAtPoint: point]; RELEASE(a); } @@ -1299,7 +235,8 @@ sizeAttributedString(NSAttributedString *str, NSString *allText, NSRange aRange) NSAttributedString *a; a = [[NSAttributedString allocWithZone: NSDefaultMallocZone()] - initWithString: self attributes: attrs]; + initWithString: self + attributes: attrs]; [a drawInRect: rect]; RELEASE(a); } @@ -1310,9 +247,16 @@ sizeAttributedString(NSAttributedString *str, NSString *allText, NSRange aRange) NSSize s; a = [[NSAttributedString allocWithZone: NSDefaultMallocZone()] - initWithString: self attributes: attrs]; + initWithString: self + attributes: attrs]; s = [a size]; RELEASE(a); return s; } @end + + +void GSStringDrawingDummyFunction(void) +{ +} + diff --git a/Tools/gsnd/portaudio/pa_unix_oss/pa_unix_oss.c b/Tools/gsnd/portaudio/pa_unix_oss/pa_unix_oss.c index 8d337c9e5..47d755118 100644 --- a/Tools/gsnd/portaudio/pa_unix_oss/pa_unix_oss.c +++ b/Tools/gsnd/portaudio/pa_unix_oss/pa_unix_oss.c @@ -95,7 +95,9 @@ PaDriverInfo; #include #include +#ifndef __FreeBSD__ #include +#endif #include #include #include @@ -110,8 +112,12 @@ PaDriverInfo; #ifdef __linux__ #include #else +#ifdef __FreeBSD__ +#include +#else #include /* JH20010905 */ #endif +#endif #include "portaudio.h" #include "pa_host.h" diff --git a/Version b/Version index 590bde478..dd62d4be2 100644 --- a/Version +++ b/Version @@ -11,7 +11,7 @@ GNUSTEP_GUI_LIBTIFF=3.4 # The version number of this release. GNUSTEP_GUI_MAJOR_VERSION=0 GNUSTEP_GUI_MINOR_VERSION=8 -GNUSTEP_GUI_SUBMINOR_VERSION=4 +GNUSTEP_GUI_SUBMINOR_VERSION=5 GNUSTEP_GUI_VERSION=${GNUSTEP_GUI_MAJOR_VERSION}.${GNUSTEP_GUI_MINOR_VERSION}.${GNUSTEP_GUI_SUBMINOR_VERSION} VERSION=${GNUSTEP_GUI_VERSION}