mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 11:30:48 +00:00
Integrated patches from Frederic <frederic.chauvin@noos.fr> to
seed up drawing. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@9970 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
4c33646018
commit
d2948895d0
1 changed files with 111 additions and 24 deletions
|
@ -30,6 +30,8 @@
|
||||||
#include <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
#include <AppKit/NSStringDrawing.h>
|
#include <AppKit/NSStringDrawing.h>
|
||||||
#include <AppKit/AppKit.h>
|
#include <AppKit/AppKit.h>
|
||||||
|
#include "GSTextStorage.h"
|
||||||
|
|
||||||
// For the encoding functions
|
// For the encoding functions
|
||||||
#include <base/Unicode.h>
|
#include <base/Unicode.h>
|
||||||
|
|
||||||
|
@ -438,15 +440,14 @@ emptyChunk(GSTextChunk *chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setupChunk(GSTextChunk *chunk, NSAttributedString *str, NSRange range,
|
setupChunk(GSTextChunk *chunk, NSAttributedString *str, NSString* string,
|
||||||
GSGlyphArray *g, GSTextChunk *last)
|
NSRange range, GSGlyphArray *g, GSTextChunk *last)
|
||||||
{
|
{
|
||||||
GSTextRun *lastRun = 0;
|
GSTextRun *lastRun = 0;
|
||||||
NSDictionary *attr;
|
NSDictionary *attr;
|
||||||
unsigned start = range.location;
|
unsigned start = range.location;
|
||||||
unsigned loc = start;
|
unsigned loc = start;
|
||||||
unsigned end = NSMaxRange(range);
|
unsigned end = NSMaxRange(range);
|
||||||
NSString *string = [str string];
|
|
||||||
unichar chars[range.length];
|
unichar chars[range.length];
|
||||||
|
|
||||||
[string getCharacters: chars range: range];
|
[string getCharacters: chars range: range];
|
||||||
|
@ -645,11 +646,10 @@ drawLine(GSTextLine *line, NSGraphicsContext *ctxt, NSPoint origin, BOOL flip)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSTextChunk*
|
static GSTextChunk*
|
||||||
setupLine(GSTextLine *line, NSAttributedString *str, NSRange range,
|
setupLine(GSTextLine *line, NSAttributedString *str, NSString* string, NSRange range,
|
||||||
GSGlyphArray *g, NSParagraphStyle *style, float rMargin, BOOL first)
|
GSGlyphArray *g, NSParagraphStyle *style, float rMargin, BOOL first)
|
||||||
{
|
{
|
||||||
GSTextChunk *lastChunk = 0;
|
GSTextChunk *lastChunk = 0;
|
||||||
NSString *string = [str string];
|
|
||||||
NSArray *tabs = [style tabStops];
|
NSArray *tabs = [style tabStops];
|
||||||
float maxh = [style maximumLineHeight];
|
float maxh = [style maximumLineHeight];
|
||||||
unsigned start = range.location;
|
unsigned start = range.location;
|
||||||
|
@ -695,7 +695,7 @@ setupLine(GSTextLine *line, NSAttributedString *str, NSRange range,
|
||||||
*/
|
*/
|
||||||
if (lastChunk == 0)
|
if (lastChunk == 0)
|
||||||
{
|
{
|
||||||
setupChunk(&line->chunk0, str, chunkRange, g, 0);
|
setupChunk(&line->chunk0, str, string, chunkRange, g, 0);
|
||||||
lastChunk = &line->chunk0;
|
lastChunk = &line->chunk0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -703,7 +703,7 @@ setupLine(GSTextLine *line, NSAttributedString *str, NSRange range,
|
||||||
GSTextChunk *chunk;
|
GSTextChunk *chunk;
|
||||||
|
|
||||||
chunk = (GSTextChunk*)objc_malloc(sizeof(GSTextChunk));
|
chunk = (GSTextChunk*)objc_malloc(sizeof(GSTextChunk));
|
||||||
setupChunk(chunk, str, chunkRange, g, lastChunk);
|
setupChunk(chunk, str, string, chunkRange, g, lastChunk);
|
||||||
lastChunk = chunk;
|
lastChunk = chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,7 +851,7 @@ setupLine(GSTextLine *line, NSAttributedString *str, NSRange range,
|
||||||
NSRange newRange = NSMakeRange(chunkRange.location, pos-chunkRange.location);
|
NSRange newRange = NSMakeRange(chunkRange.location, pos-chunkRange.location);
|
||||||
end = pos;
|
end = pos;
|
||||||
empty_chunk(lastChunk);
|
empty_chunk(lastChunk);
|
||||||
setupChunk(lastChunk, str, newRange, g, lastChunk->last);
|
setupChunk(lastChunk, str, string, newRange, g, lastChunk->last);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -881,11 +881,10 @@ setupLine(GSTextLine *line, NSAttributedString *str, NSRange range,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drawAttributedString(NSAttributedString *str, NSRange aRange, NSPoint point, float width,
|
drawAttributedString(NSAttributedString *str, NSString *allText, NSRange aRange,
|
||||||
NSGraphicsContext *ctxt)
|
NSPoint point, float width, NSGraphicsContext *ctxt)
|
||||||
{
|
{
|
||||||
BOOL isFlipped = [[ctxt focusView] isFlipped];
|
BOOL isFlipped = [[ctxt focusView] isFlipped];
|
||||||
NSString *allText = [str string];
|
|
||||||
unsigned length = NSMaxRange(aRange);
|
unsigned length = NSMaxRange(aRange);
|
||||||
unsigned paraPos = aRange.location;
|
unsigned paraPos = aRange.location;
|
||||||
NSRange styleRange;
|
NSRange styleRange;
|
||||||
|
@ -944,7 +943,7 @@ drawAttributedString(NSAttributedString *str, NSRange aRange, NSPoint point, flo
|
||||||
garray.size = line.length;
|
garray.size = line.length;
|
||||||
garray.glyphs = info;
|
garray.glyphs = info;
|
||||||
|
|
||||||
setupLine(¤t, str, line, &garray, style, width, YES);
|
setupLine(¤t, str, allText, line, &garray, style, width, YES);
|
||||||
drawLine(¤t, ctxt, point, isFlipped);
|
drawLine(¤t, ctxt, point, isFlipped);
|
||||||
|
|
||||||
if (isFlipped)
|
if (isFlipped)
|
||||||
|
@ -962,9 +961,8 @@ drawAttributedString(NSAttributedString *str, NSRange aRange, NSPoint point, flo
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSSize
|
static NSSize
|
||||||
sizeAttributedString(NSAttributedString *str, NSRange aRange)
|
sizeAttributedString(NSAttributedString *str, NSString *allText, NSRange aRange)
|
||||||
{
|
{
|
||||||
NSString *allText = [str string];
|
|
||||||
unsigned length = NSMaxRange(aRange);
|
unsigned length = NSMaxRange(aRange);
|
||||||
unsigned paraPos = aRange.location;
|
unsigned paraPos = aRange.location;
|
||||||
NSParagraphStyle *style = nil;
|
NSParagraphStyle *style = nil;
|
||||||
|
@ -1021,7 +1019,7 @@ sizeAttributedString(NSAttributedString *str, NSRange aRange)
|
||||||
garray.used = 0;
|
garray.used = 0;
|
||||||
garray.glyphs = info;
|
garray.glyphs = info;
|
||||||
|
|
||||||
setupLine(¤t, str, line, &garray, style, rMargin, YES);
|
setupLine(¤t, str, allText, line, &garray, style, rMargin, YES);
|
||||||
if (current.width > size.width)
|
if (current.width > size.width)
|
||||||
size.width = current.width;
|
size.width = current.width;
|
||||||
size.height += current.height + current.leading;
|
size.height += current.height + current.leading;
|
||||||
|
@ -1045,8 +1043,8 @@ sizeAttributedString(NSAttributedString *str, NSRange aRange)
|
||||||
{
|
{
|
||||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||||
|
|
||||||
drawAttributedString(self, NSMakeRange(0, [self length]), point, NO_R_MARGIN,
|
drawAttributedString(self, [self string], NSMakeRange(0, [self length]),
|
||||||
ctxt);
|
point, NO_R_MARGIN, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawInRect: (NSRect)rect
|
- (void) drawInRect: (NSRect)rect
|
||||||
|
@ -1071,8 +1069,8 @@ sizeAttributedString(NSAttributedString *str, NSRange aRange)
|
||||||
else
|
else
|
||||||
point.y = rect.origin.y + rect.size.height;
|
point.y = rect.origin.y + rect.size.height;
|
||||||
|
|
||||||
drawAttributedString(self, NSMakeRange(0, [self length]), point, rect.size.width,
|
drawAttributedString(self, [self string], NSMakeRange(0, [self length]),
|
||||||
ctxt);
|
point, rect.size.width, ctxt);
|
||||||
|
|
||||||
/* Restore matching the DPSgsave used in the temporary workaround */
|
/* Restore matching the DPSgsave used in the temporary workaround */
|
||||||
DPSgrestore(ctxt);
|
DPSgrestore(ctxt);
|
||||||
|
@ -1080,20 +1078,20 @@ sizeAttributedString(NSAttributedString *str, NSRange aRange)
|
||||||
|
|
||||||
- (NSSize) size
|
- (NSSize) size
|
||||||
{
|
{
|
||||||
return sizeAttributedString(self, NSMakeRange(0, [self length]));
|
return sizeAttributedString(self, [self string], NSMakeRange(0, [self length]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// GNUstep extensions.
|
// GNUstep extensions.
|
||||||
- (NSSize) sizeRange: (NSRange) lineRange
|
- (NSSize) sizeRange: (NSRange) lineRange
|
||||||
{
|
{
|
||||||
return sizeAttributedString(self, lineRange);
|
return sizeAttributedString(self, [self string], lineRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) drawRange: (NSRange) lineRange atPoint: (NSPoint) point
|
- (void) drawRange: (NSRange) lineRange atPoint: (NSPoint) point
|
||||||
{
|
{
|
||||||
NSGraphicsContext *ctxt = GSCurrentContext();
|
NSGraphicsContext *ctxt = GSCurrentContext();
|
||||||
|
|
||||||
drawAttributedString(self, lineRange, point, NO_R_MARGIN,
|
drawAttributedString(self, [self string], lineRange, point, NO_R_MARGIN,
|
||||||
ctxt);
|
ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,7 +1117,96 @@ sizeAttributedString(NSAttributedString *str, NSRange aRange)
|
||||||
else
|
else
|
||||||
point.y = rect.origin.y + rect.size.height;
|
point.y = rect.origin.y + rect.size.height;
|
||||||
|
|
||||||
drawAttributedString(self, lineRange, point, rect.size.width,
|
drawAttributedString(self, [self string], lineRange, point, rect.size.width,
|
||||||
|
ctxt);
|
||||||
|
/* Restore matching the DPSgsave used in the temporary workaround */
|
||||||
|
DPSgrestore(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
ctxt);
|
||||||
/* Restore matching the DPSgsave used in the temporary workaround */
|
/* Restore matching the DPSgsave used in the temporary workaround */
|
||||||
DPSgrestore(ctxt);
|
DPSgrestore(ctxt);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue