The R Project SVN R-packages

Rev

Rev 7916 | Rev 8072 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7916 Rev 8070
Line 30... Line 30...
30
 *
30
 *
31
 *  Created by Hans-J. Bibiko on 01/03/2012.
31
 *  Created by Hans-J. Bibiko on 01/03/2012.
32
 *
32
 *
33
 */
33
 */
34
 
34
 
-
 
35
#import "RGUI.h"
35
#import "RScriptEditorGlyphGenerator.h"
36
#import "RScriptEditorGlyphGenerator.h"
36
#import "RScriptEditorTypesetter.h"
37
#import "RScriptEditorTypeSetter.h"
37
#import "RScriptEditorTextStorage.h"
38
#import "RScriptEditorTextStorage.h"
38
#import "RScriptEditorLayoutManager.h"
39
#import "RScriptEditorLayoutManager.h"
39
#import "PreferenceKeys.h"
40
#import "PreferenceKeys.h"
40
 
41
 
41
@implementation RScriptEditorGlyphGenerator
42
@implementation RScriptEditorGlyphGenerator
Line 74... Line 75...
74
#pragma mark -
75
#pragma mark -
75
#pragma mark NSGlyphStoragePrimitives
76
#pragma mark NSGlyphStoragePrimitives
76
 
77
 
77
- (void)insertGlyphs:(const NSGlyph *)glyphs length:(NSUInteger)length forStartingGlyphAtIndex:(NSUInteger)glyphIndex characterIndex:(NSUInteger)charIndex
78
- (void)insertGlyphs:(const NSGlyph *)glyphs length:(NSUInteger)length forStartingGlyphAtIndex:(NSUInteger)glyphIndex characterIndex:(NSUInteger)charIndex
78
{
79
{
-
 
80
	NSGlyph localBuffer[64]; /* stack-local buffer to avoid allocations */
79
	NSGlyph *buffer = NULL;
81
	NSGlyph *buffer = NULL;
80
	NSInteger folded = [theTextStorage foldedAtIndex: charIndex];
82
	NSInteger folded = [theTextStorage foldedAtIndex: charIndex];
81
 
83
 
-
 
84
	// SLog(@"%@ insertGlyphs: length:%d forStartingGlyphAtIndex:%d characterIndex:%d", self, (int) length, (int) glyphIndex, (int) charIndex);
-
 
85
 
-
 
86
	/* This part replaces the real glyphs with NSNullGlyph (empty) and/or NSControlGlyph (the symbol)
-
 
87
	   inside folded code.
-
 
88
 
-
 
89
	   FIXME: we only check whether the first glyph is inside a fold and then
-
 
90
	   replace the glyphs inside that fold. It is unclear if this can be called
-
 
91
	   with larger areas that include folds somewhere in the middle. Analogously,
-
 
92
	   it is unclear if there can be multiple folds in the requested glyph area.
-
 
93
	   Empirically, glyphs are inserted only for same attribues, so syntax highlighting
-
 
94
	   seems to help us here by splitting the text in a way that supports this
-
 
95
	   approach.
-
 
96
	 */
82
	if (folded > -1) {
97
	 if (folded > -1) {
83
		NSRange effectiveRange = [theTextStorage foldedRangeAtIndex:folded];
98
		NSRange effectiveRange = [theTextStorage foldedRangeAtIndex:folded];
-
 
99
		/* fold range includes the encloding { }, so we only care if we are actually inside and it's non-empty */
84
		if(effectiveRange.length) {
100
		if (effectiveRange.length &&
-
 
101
			charIndex + length > effectiveRange.location + 1 &&
-
 
102
			charIndex < NSMaxRange(effectiveRange) - 1) {
-
 
103
			SLog(@"insertGlyphs: glyphs [%d..%d] (@char %d, len %d), inside folded range %@ thus will replace glyphs",
-
 
104
				 (int) glyphIndex, (int) (glyphIndex + length - 1), (int) charIndex, (int) length,
-
 
105
				 NSStringFromRange(effectiveRange));
-
 
106
 
-
 
107
			/* we will be replacing something, so have to get a buffer for the glyphs we return */
85
			NSInteger size = sizeOfNSGlyph * length;
108
			NSUInteger size = sizeOfNSGlyph * length;
86
			buffer = NSZoneMalloc(NULL, size);
109
			buffer = (size > sizeof(localBuffer)) ? NSZoneMalloc(NULL, size) : localBuffer;
-
 
110
 
-
 
111
			NSUInteger nullEnd = NSMaxRange(effectiveRange) - charIndex - 1;
-
 
112
			if (nullEnd > length)
-
 
113
				nullEnd = length;
-
 
114
			NSUInteger nullStart = effectiveRange.location + 1 - charIndex;
-
 
115
			NSUInteger nullLength = nullEnd - nullStart;
-
 
116
			if (nullLength < length) /* some have to be retained, so copy all and then null */
-
 
117
				memcpy(buffer, glyphs, sizeOfNSGlyph * length);
-
 
118
			/* it is actually 4 but for safety include a fall-back ... */
-
 
119
			if (sizeOfNSGlyph == 4)
87
			memset_pattern4(buffer, &nullGlyph, size);
120
				memset_pattern4(buffer + nullStart, &nullGlyph, sizeOfNSGlyph * nullLength);
-
 
121
			else {
-
 
122
				size_t i = nullStart;
-
 
123
				while (i < nullLength) buffer[i++] = nullGlyph;
-
 
124
			}
-
 
125
			/* the first glyph just after the { (position 1) is the visible glyph */
-
 
126
			NSInteger ctrlLocation = effectiveRange.location + 1 - charIndex;
-
 
127
			if (ctrlLocation >= 0 && ctrlLocation < length)
88
			if ((effectiveRange.location+1) == charIndex) buffer[0] = NSControlGlyph;
128
				buffer[ctrlLocation] = NSControlGlyph;
89
			glyphs = buffer;
129
			glyphs = buffer;
90
		}
130
		}
91
	}
131
	}
92
 
132
 
93
	[_destination insertGlyphs:glyphs length:length forStartingGlyphAtIndex:glyphIndex characterIndex:charIndex];
133
	[_destination insertGlyphs:glyphs length:length forStartingGlyphAtIndex:glyphIndex characterIndex:charIndex];
94
 
134
 
-
 
135
	if (buffer && buffer != localBuffer)
95
	if (buffer) NSZoneFree(NULL, buffer);
136
		NSZoneFree(NULL, buffer);
96
}
137
}
97
 
138
 
98
- (void)setIntAttribute:(NSInteger)attributeTag value:(NSInteger)val forGlyphAtIndex:(NSUInteger)glyphIndex
139
- (void)setIntAttribute:(NSInteger)attributeTag value:(NSInteger)val forGlyphAtIndex:(NSUInteger)glyphIndex
99
{
140
{
100
	[_destination setIntAttribute:attributeTag value:val forGlyphAtIndex:glyphIndex];
141
	[_destination setIntAttribute:attributeTag value:val forGlyphAtIndex:glyphIndex];