My favorites | Sign in
Project Home Downloads Wiki Issues Source
Repository:
Checkout   Browse   Changes   Clones  
Changes to /AppKit/RTF.subproj/NSRichTextReader.m
e5277a40a7e8 vs. 2470bd80abf4 Compare: vs.  Format:
Revision 2470bd80abf4
Go to: 
Project members, sign in to write a code review
/AppKit/RTF.subproj/NSRichTextReader.m   e5277a40a7e8 /AppKit/RTF.subproj/NSRichTextReader.m   2470bd80abf4
1 /* Copyright (c) 2006 Christopher J. W. Lloyd 1 /* Copyright (c) 2006-2007 Christopher J. W. Lloyd
2 2
3 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 3 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 4
5 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 6
7 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 7 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
8 8
9 // Original - Christopher Lloyd <cjwl@objc.net> 9 // Original - Christopher Lloyd <cjwl@objc.net>
10 #import <AppKit/NSRichTextReader.h> 10 #import <AppKit/NSRichTextReader.h>
11 #import <AppKit/NSFont.h> 11 #import <AppKit/NSFont.h>
12 #import <AppKit/NSFontManager.h> 12 #import <AppKit/NSFontManager.h>
13 #import <AppKit/NSAttributedString.h> 13 #import <AppKit/NSAttributedString.h>
14 #import <AppKit/NSTextAttachment.h> 14 #import <AppKit/NSTextAttachment.h>
15 15
16 enum { 16 enum {
17 STATE_SKIPLAST, 17 STATE_SKIPLAST,
18 STATE_SCANNING, 18 STATE_SCANNING,
19 STATE_CONTROL, 19 STATE_CONTROL,
20 STATE_CONTROL_ALPHA, 20 STATE_CONTROL_ALPHA,
21 STATE_CONTROL_DIGIT, 21 STATE_CONTROL_DIGIT,
22 STATE_UNICODE, 22 STATE_UNICODE,
23 STATE_UNICODE_X, 23 STATE_UNICODE_X,
24 STATE_UNICODE_XX, 24 STATE_UNICODE_XX,
25 STATE_UNICODE_XXX, 25 STATE_UNICODE_XXX,
26 STATE_UNICODE_XXXX, 26 STATE_UNICODE_XXXX,
27 }; 27 };
28 28
29 @implementation NSRichTextReader 29 @implementation NSRichTextReader
30 30
31 -initWithData:(NSData *)data { 31 -initWithData:(NSData *)data {
32 _data=[data copy]; 32 _data=[data copy];
33 _bytes=[_data bytes]; 33 _bytes=[_data bytes];
34 _length=[_data length]; 34 _length=[_data length];
35 _range=NSMakeRange(0,0); 35 _range=NSMakeRange(0,0);
36 _state=STATE_SCANNING; 36 _state=STATE_SCANNING;
37 _fontTable=[NSMutableDictionary new]; 37 _fontTable=[NSMutableDictionary new];
38 _currentFontInfo=nil; 38 _currentFontInfo=nil;
39 _currentAttributes=[NSMutableDictionary new]; 39 _currentAttributes=[NSMutableDictionary new];
40 [_currentAttributes setObject:[NSFont systemFontOfSize:0] 40 [_currentAttributes setObject:[NSFont systemFontOfSize:0]
41 forKey:NSFontAttributeName]; 41 forKey:NSFontAttributeName];
42 _attributedString=[NSMutableAttributedString new]; 42 _attributedString=[NSMutableAttributedString new];
43 return self; 43 return self;
44 } 44 }
45 45
46 -initWithContentsOfFile:(NSString *)path { 46 -initWithContentsOfFile:(NSString *)path {
47 NSString *type=[path pathExtension]; 47 NSString *type=[path pathExtension];
48 48
49 if([type isEqualToString:@"rtf"]){ 49 if([type isEqualToString:@"rtf"]){
50 NSData *data=[NSData dataWithContentsOfFile:path]; 50 NSData *data=[NSData dataWithContentsOfFile:path];
51 51
52 if(data!=nil) 52 if(data!=nil)
53 return [self initWithData:data]; 53 return [self initWithData:data];
54 } 54 }
55 else if([type isEqualToString:@"rtfd"]){ 55 else if([type isEqualToString:@"rtfd"]){
56 NSString *txt=[[path stringByAppendingPathComponent:@"TXT"] stringByAppendingPathExtension:@"rtf"]; 56 NSString *txt=[[path stringByAppendingPathComponent:@"TXT"] stringByAppendingPathExtension:@"rtf"];
57 NSData *data=[NSData dataWithContentsOfFile:txt]; 57 NSData *data=[NSData dataWithContentsOfFile:txt];
58 58
59 if(data!=nil) 59 if(data!=nil)
60 return [self initWithData:data]; 60 return [self initWithData:data];
61 61
62 _imageDirectory=[path copy]; 62 _imageDirectory=[path copy];
63 } 63 }
64 64
65 [self dealloc]; 65 [self dealloc];
66 return nil; 66 return nil;
67 } 67 }
68 68
69 -(void)dealloc { 69 -(void)dealloc {
70 [_imageDirectory release]; 70 [_imageDirectory release];
71 [_data release]; 71 [_data release];
72 [_currentAttributes release]; 72 [_currentAttributes release];
73 [_attributedString release]; 73 [_attributedString release];
74 [super dealloc]; 74 [super dealloc];
75 } 75 }
76 76
77 +(NSAttributedString *)attributedStringWithData:(NSData *)data { 77 +(NSAttributedString *)attributedStringWithData:(NSData *)data {
78 NSRichTextReader *reader=[[self alloc] initWithData:data]; 78 NSRichTextReader *reader=[[self alloc] initWithData:data];
79 NSAttributedString *result=[[[reader parseAttributedString] retain] autorelease]; 79 NSAttributedString *result=[[[reader parseAttributedString] retain] autorelease];
80 80
81 [reader release]; 81 [reader release];
82 82
83 return result; 83 return result;
84 } 84 }
85 85
86 +(NSAttributedString *)attributedStringWithContentsOfFile:(NSString *)path { 86 +(NSAttributedString *)attributedStringWithContentsOfFile:(NSString *)path {
87 NSRichTextReader *reader=[[self alloc] initWithContentsOfFile:path]; 87 NSRichTextReader *reader=[[self alloc] initWithContentsOfFile:path];
88 NSAttributedString *result=[[[reader parseAttributedString] retain] autorelease]; 88 NSAttributedString *result=[[[reader parseAttributedString] retain] autorelease];
89 89
90 [reader release]; 90 [reader release];
91 91
92 return result; 92 return result;
93 } 93 }
94 94
95 -(unsigned)length { 95 -(unsigned)length {
96 return _range.length; 96 return _range.length;
97 } 97 }
98 98
99 -(unichar)characterAtIndex:(unsigned)index { 99 -(unichar)characterAtIndex:(unsigned)index {
100 return _bytes[_range.location+index]; 100 return _bytes[_range.location+index];
101 } 101 }
102 102
103 -(void)getCharacters:(unichar *)buffer { 103 -(void)getCharacters:(unichar *)buffer {
104 unsigned i; 104 unsigned i;
105 105
106 for(i=0;i<_range.length;i++) 106 for(i=0;i<_range.length;i++)
107 buffer[i]=_bytes[_range.location+i]; 107 buffer[i]=_bytes[_range.location+i];
108 } 108 }
109 109
110 -(void)getCharacters:(unichar *)buffer range:(NSRange)range { 110 -(void)getCharacters:(unichar *)buffer range:(NSRange)range {
111 unsigned location=range.location,max=NSMaxRange(range); 111 unsigned location=range.location,max=NSMaxRange(range);
112 unsigned i; 112 unsigned i;
113 113
114 for(i=0;location<max;i++,location++) 114 for(i=0;location<max;i++,location++)
115 buffer[i]=_bytes[_range.location+location]; 115 buffer[i]=_bytes[_range.location+location];
116 } 116 }
117 117
118 -(void)appendStringWithCurrentAttributes:(NSString *)string { 118 -(void)appendStringWithCurrentAttributes:(NSString *)string {
119 unsigned length=[_attributedString length]; 119 unsigned length=[_attributedString length];
120 NSRange append=NSMakeRange(length,0); 120 NSRange append=NSMakeRange(length,0);
121 NSRange range=NSMakeRange(length,[string length]); 121 NSRange range=NSMakeRange(length,[string length]);
122 122
123 [_attributedString replaceCharactersInRange:append withString:string]; 123 [_attributedString replaceCharactersInRange:append withString:string];
124 [_attributedString setAttributes:_currentAttributes range:range]; 124 [_attributedString setAttributes:_currentAttributes range:range];
125 } 125 }
126 126
127 static inline void flushPreviousString(NSRichTextReader *self) { 127 static inline void flushPreviousString(NSRichTextReader *self) {
128 self->_range.length--; 128 self->_range.length--;
129 if(self->_range.length>0){ 129 if(self->_range.length>0){
130 [self appendStringWithCurrentAttributes:self]; 130 [self appendStringWithCurrentAttributes:self];
131 } 131 }
132 132
133 self->_range.location=NSMaxRange(self->_range); 133 self->_range.location=NSMaxRange(self->_range);
134 self->_range.length=1; 134 self->_range.length=1;
135 } 135 }
136 136
137 -(void)flushFontName { 137 -(void)flushFontName {
138 _range.length--; 138 _range.length--;
139 if(_range.length>0){ 139 if(_range.length>0){
140 [_currentFontInfo setObject:[NSString stringWithString:self] forKey:@"fontname"]; 140 [_currentFontInfo setObject:[NSString stringWithString:self] forKey:@"fontname"];
141 } 141 }
142 142
143 _range.location=NSMaxRange(_range); 143 _range.location=NSMaxRange(_range);
144 _range.length=1; 144 _range.length=1;
145 } 145 }
146 146
147 -(BOOL)activeFontInfo { 147 -(BOOL)activeFontInfo {
148 return (_currentFontInfo!=nil)?YES:NO; 148 return (_currentFontInfo!=nil)?YES:NO;
149 } 149 }
150 150
151 -(void)flushFontInfo { 151 -(void)flushFontInfo {
152 NSString *key=[_currentFontInfo objectForKey:@"fontnum"]; 152 NSString *key=[_currentFontInfo objectForKey:@"fontnum"];
153 153
154 if(key!=nil) 154 if(key!=nil)
155 [_fontTable setObject:_currentFontInfo forKey:key]; 155 [_fontTable setObject:_currentFontInfo forKey:key];
156 [_currentFontInfo release]; 156 [_currentFontInfo release];
157 _currentFontInfo=nil; 157 _currentFontInfo=nil;
158 } 158 }
159 159
160 -(void)createFontInfo { 160 -(void)createFontInfo {
161 _currentFontInfo=[NSMutableDictionary new]; 161 _currentFontInfo=[NSMutableDictionary new];
162 } 162 }
163 163
164 -(BOOL)activeColorTable { 164 -(BOOL)activeColorTable {
165 return _activeColorTable; 165 return _activeColorTable;
166 } 166 }
167 167
168 -(void)processControlWithArgValue:(int)argument { 168 -(void)processControlWithArgValue:(int)argument {
169 NSRange save=_range; 169 NSRange save=_range;
170 170
171 _range=_letterRange; 171 _range=_letterRange;
172 //NSLog(@"%s %@ %d",SELNAME(_cmd),self,argument); 172 //NSLog(@"%s %@ %d",SELNAME(_cmd),self,argument);
173 173
174 if([self isEqualToString:@"b"]){ 174 if([self isEqualToString:@"b"]){
175 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName]; 175 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName];
176 176
177 font=[[NSFontManager sharedFontManager] convertFont:font toHaveTrait:argument?NSBoldFontMask:NSUnboldFontMask]; 177 font=[[NSFontManager sharedFontManager] convertFont:font toHaveTrait:argument?NSBoldFontMask:NSUnboldFontMask];
178 [_currentAttributes setObject:font forKey:NSFontAttributeName]; 178 [_currentAttributes setObject:font forKey:NSFontAttributeName];
179 } 179 }
180 else if([self isEqualToString:@"i"]){ 180 else if([self isEqualToString:@"i"]){
181 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName]; 181 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName];
182 182
183 font=[[NSFontManager sharedFontManager] convertFont:font toHaveTrait:argument?NSItalicFontMask:NSUnitalicFontMask]; 183 font=[[NSFontManager sharedFontManager] convertFont:font toHaveTrait:argument?NSItalicFontMask:NSUnitalicFontMask];
184 [_currentAttributes setObject:font forKey:NSFontAttributeName]; 184 [_currentAttributes setObject:font forKey:NSFontAttributeName];
185 } 185 }
186 else if([self isEqualToString:@"fs"]){ 186 else if([self isEqualToString:@"fs"]){
187 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName]; 187 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName];
188 188
189 font=[[NSFontManager sharedFontManager] convertFont:font toSize:argument/2]; 189 font=[[NSFontManager sharedFontManager] convertFont:font toSize:argument/2];
190 [_currentAttributes setObject:font forKey:NSFontAttributeName]; 190 [_currentAttributes setObject:font forKey:NSFontAttributeName];
191 } 191 }
192 else if([self isEqualToString:@"fonttbl"]){ 192 else if([self isEqualToString:@"fonttbl"]){
193 _currentFontInfo=[NSMutableDictionary new]; 193 _currentFontInfo=[NSMutableDictionary new];
194 } 194 }
195 else if([self isEqualToString:@"f"]){ 195 else if([self isEqualToString:@"f"]){
196 NSString *key=[NSString stringWithFormat:@"%d",argument]; 196 NSString *key=[NSString stringWithFormat:@"%d",argument];
197 197
198 if([self activeFontInfo]){ 198 if([self activeFontInfo]){
199 [_currentFontInfo setObject:key forKey:@"fontnum"]; 199 [_currentFontInfo setObject:key forKey:@"fontnum"];
200 } 200 }
201 else { 201 else {
202 NSDictionary *info=[_fontTable objectForKey:key]; 202 NSDictionary *info=[_fontTable objectForKey:key];
203 NSString *family=[info objectForKey:@"fontfamily"]; 203 NSString *family=[info objectForKey:@"fontfamily"];
204 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName]; 204 NSFont *font=[_currentAttributes objectForKey:NSFontAttributeName];
205 205
206 if([family isEqualToString:@"roman"]) 206 if([family isEqualToString:@"roman"])
207 font=[NSFont fontWithName:@"Times New Roman" size:12]; 207 font=[NSFont fontWithName:@"Times New Roman" size:12];
208 else if([family isEqualToString:@"modern"]) 208 else if([family isEqualToString:@"modern"])
209 font=[NSFont fontWithName:@"Courier New" size:12]; 209 font=[NSFont fontWithName:@"Courier New" size:12];
210 else if([family isEqualToString:@"swiss"]) 210 else if([family isEqualToString:@"swiss"])
211 font=[NSFont fontWithName:@"Arial" size:12]; 211 font=[NSFont fontWithName:@"Arial" size:12];
212 else if([family isEqualToString:@"nil"]){ 212 else if([family isEqualToString:@"nil"]){
213 font=[NSFont fontWithName:[info objectForKey:@"fontname"] size:12]; 213 font=[NSFont fontWithName:[info objectForKey:@"fontname"] size:12];
214 } 214 }
215 [_currentAttributes setObject:font forKey:NSFontAttributeName]; 215 [_currentAttributes setObject:font forKey:NSFontAttributeName];
216 216
217 } 217 }
218 } 218 }
219 else if([self isEqualToString:@"fnil"]) 219 else if([self isEqualToString:@"fnil"])
220 [_currentFontInfo setObject:@"nil" forKey:@"fontfamily"]; 220 [_currentFontInfo setObject:@"nil" forKey:@"fontfamily"];
221 else if([self isEqualToString:@"froman"]) 221 else if([self isEqualToString:@"froman"])
222 [_currentFontInfo setObject:@"roman" forKey:@"fontfamily"]; 222 [_currentFontInfo setObject:@"roman" forKey:@"fontfamily"];
223 else if([self isEqualToString:@"fswiss"]) 223 else if([self isEqualToString:@"fswiss"])
224 [_currentFontInfo setObject:@"swiss" forKey:@"fontfamily"]; 224 [_currentFontInfo setObject:@"swiss" forKey:@"fontfamily"];
225 else if([self isEqualToString:@"fmodern"]) 225 else if([self isEqualToString:@"fmodern"])
226 [_currentFontInfo setObject:@"modern" forKey:@"fontfamily"]; 226 [_currentFontInfo setObject:@"modern" forKey:@"fontfamily"];
227 else if([self isEqualToString:@"fscript"]) 227 else if([self isEqualToString:@"fscript"])
228 [_currentFontInfo setObject:@"script" forKey:@"fontfamily"]; 228 [_currentFontInfo setObject:@"script" forKey:@"fontfamily"];
229 else if([self isEqualToString:@"fdecor"]) 229 else if([self isEqualToString:@"fdecor"])
230 [_currentFontInfo setObject:@"decor" forKey:@"fontfamily"]; 230 [_currentFontInfo setObject:@"decor" forKey:@"fontfamily"];
231 else if([self isEqualToString:@"ftech"]) 231 else if([self isEqualToString:@"ftech"])
232 [_currentFontInfo setObject:@"tech" forKey:@"fontfamily"]; 232 [_currentFontInfo setObject:@"tech" forKey:@"fontfamily"];
233 else if([self isEqualToString:@"fbidi"]) 233 else if([self isEqualToString:@"fbidi"])
234 [_currentFontInfo setObject:@"bidi" forKey:@"fontfamily"]; 234 [_currentFontInfo setObject:@"bidi" forKey:@"fontfamily"];
235 else if([self isEqualToString:@"colortbl"]){ 235 else if([self isEqualToString:@"colortbl"]){
236 _activeColorTable=YES; 236 _activeColorTable=YES;
237 } 237 }
238 else if([self isEqualToString:@"NeXTGraphic"]){ 238 else if([self isEqualToString:@"NeXTGraphic"]){
239 239
240 _range.location=NSMaxRange(save); 240 _range.location=NSMaxRange(save);
241 _range.length=0; 241 _range.length=0;
242 242
243 for(;NSMaxRange(_range)<_length;){ 243 for(;NSMaxRange(_range)<_length;){
244 if(_bytes[NSMaxRange(_range)]=='\\') 244 if(_bytes[NSMaxRange(_range)]=='\\')
245 break; 245 break;
246 _range.length++; 246 _range.length++;
247 } 247 }
248 _range.length--; 248 _range.length--;
249 { 249 {
250 NSString *path=[_imageDirectory stringByAppendingPathComponent:self]; 250 NSString *path=[_imageDirectory stringByAppendingPathComponent:self];
251 NSTextAttachment *attachment=[[[NSTextAttachment alloc] initWithContentsOfFile:path] autorelease]; 251 NSTextAttachment *attachment=[[[NSTextAttachment alloc] initWithContentsOfFile:path] autorelease];
252 unichar attachChar=NSAttachmentCharacter; 252 unichar attachChar=NSAttachmentCharacter;
253 253
254 //NSLog(@"path=[%@],attachment=%@",path,attachment); 254 //NSLog(@"path=[%@],attachment=%@",path,attachment);
255 255
256 if(attachment!=nil){ 256 if(attachment!=nil){
257 [_currentAttributes setObject:attachment forKey:NSAttachmentAttributeName]; 257 [_currentAttributes setObject:attachment forKey:NSAttachmentAttributeName];
258 258
259 [self appendStringWithCurrentAttributes:[NSString stringWithCharacters:&attachChar length:1]]; 259 [self appendStringWithCurrentAttributes:[NSString stringWithCharacters:&attachChar length:1]];
260 260
261 [_currentAttributes removeObjectForKey:NSAttachmentAttributeName]; 261 [_currentAttributes removeObjectForKey:NSAttachmentAttributeName];
262 } 262 }
263 } 263 }
264 _range.length++; 264 _range.length++;
265 save=_range; 265 save=_range;
266 } 266 }
267 _range=save; 267 _range=save;
268 } 268 }
269 269
270 270
271 -(void)tokenize { 271 -(void)tokenize {
272 for(;NSMaxRange(_range)<_length;){ 272 for(;NSMaxRange(_range)<_length;){
273 unsigned position=NSMaxRange(_range); 273 unsigned position=NSMaxRange(_range);
274 unsigned char code=_bytes[position]; 274 unsigned char code=_bytes[position];
275 275
276 _range.length++; 276 _range.length++;
277 277
278 switch(_state){ 278 switch(_state){
279 279
280 case STATE_SKIPLAST: 280 case STATE_SKIPLAST:
281 _range.location=position; 281 _range.location=position;
282 _range.length=1; 282 _range.length=1;
283 _state=STATE_SCANNING; 283 _state=STATE_SCANNING;
284 // fall thru 284 // fall thru
285 case STATE_SCANNING: 285 case STATE_SCANNING:
286 if(code=='\\'){ 286 if(code=='\\'){
287 flushPreviousString(self); 287 flushPreviousString(self);
288 _state=STATE_CONTROL; 288 _state=STATE_CONTROL;
289 _range.location=NSMaxRange(_range); 289 _range.location=NSMaxRange(_range);
290 _range.length=0; 290 _range.length=0;
291 } 291 }
292 else if(code=='{'){ 292 else if(code=='{'){
293 flushPreviousString(self); 293 flushPreviousString(self);
294 _state=STATE_SKIPLAST; 294 _state=STATE_SKIPLAST;
295 } 295 }
296 else if(code=='}'){ 296 else if(code=='}'){
297 if([self activeFontInfo]) 297 if([self activeFontInfo])
298 [self flushFontInfo]; 298 [self flushFontInfo];
299 else if([self activeColorTable]) 299 else if([self activeColorTable])
300 _activeColorTable=NO; 300 _activeColorTable=NO;
301 else 301 else
302 flushPreviousString(self); 302 flushPreviousString(self);
303 _state=STATE_SKIPLAST; 303 _state=STATE_SKIPLAST;
304 } 304 }
305 else if(code=='\r' || code=='\n'){ 305 else if(code=='\r' || code=='\n'){
306 flushPreviousString(self); 306 flushPreviousString(self);
307 _state=STATE_SKIPLAST; 307 _state=STATE_SKIPLAST;
308 } 308 }
309 else if(code==';'){ 309 else if(code==';'){
310 if([self activeFontInfo]){ 310 if([self activeFontInfo]){
311 [self flushFontName]; 311 [self flushFontName];
312 [self flushFontInfo]; 312 [self flushFontInfo];
313 [self createFontInfo]; 313 [self createFontInfo];
314 _state=STATE_SKIPLAST; 314 _state=STATE_SKIPLAST;
315 } 315 }
316 if([self activeColorTable]){ 316 if([self activeColorTable]){
317 _state=STATE_SKIPLAST; 317 _state=STATE_SKIPLAST;
318 } 318 }
319 } 319 }
320 break; 320 break;
321 321
322 case STATE_CONTROL: 322 case STATE_CONTROL:
323 if(code=='\''){ 323 if(code=='\''){
324 _state=STATE_SKIPLAST; 324 _state=STATE_SKIPLAST;
325 break; 325 break;
326 } 326 }
327 else if(code=='*'){ 327 else if(code=='*'){
328 _state=STATE_SKIPLAST; 328 _state=STATE_SKIPLAST;
329 break; 329 break;
330 } 330 }
331 else if(code=='-'){ 331 else if(code=='-'){
332 _state=STATE_SKIPLAST; 332 _state=STATE_SKIPLAST;
333 break; 333 break;
334 } 334 }
335 else if(code=='\\'){ 335 else if(code=='\\'){
336 _state=STATE_SKIPLAST; 336 _state=STATE_SKIPLAST;
337 break; 337 break;
338 } 338 }
339 else if(code=='_'){ 339 else if(code=='_'){
340 _state=STATE_SKIPLAST; 340 _state=STATE_SKIPLAST;
341 break; 341 break;
342 } 342 }
343 else if(code=='{'){ 343 else if(code=='{'){
344 _state=STATE_SKIPLAST; 344 _state=STATE_SKIPLAST;
345 break; 345 break;
346 } 346 }
347 else if(code=='|'){ 347 else if(code=='|'){
348 _state=STATE_SKIPLAST; 348 _state=STATE_SKIPLAST;
349 break; 349 break;
350 } 350 }
351 else if(code=='}'){ 351 else if(code=='}'){
352 _state=STATE_SKIPLAST; 352 _state=STATE_SKIPLAST;
353 break; 353 break;
354 } 354 }
355 else if(code=='~'){ 355 else if(code=='~'){
356 _state=STATE_SKIPLAST; 356 _state=STATE_SKIPLAST;
357 break; 357 break;
358 } 358 }
359 else if(code=='\r' || code=='\n'){ 359 else if(code=='\r' || code=='\n'){
360 _state=STATE_SKIPLAST; 360 _state=STATE_SKIPLAST;
361 [self appendStringWithCurrentAttributes:@"\n"]; 361 [self appendStringWithCurrentAttributes:@"\n"];
362 break; 362 break;
363 } 363 }
364 else if(code=='U'){ 364 else if(code=='U'){
365 _state=STATE_UNICODE; 365 _state=STATE_UNICODE;
366 _univalue=0; 366 _univalue=0;
367 break; 367 break;
368 } 368 }
369 369
370 // fallthru 370 // fallthru
371 case STATE_CONTROL_ALPHA: 371 case STATE_CONTROL_ALPHA:
372 if((code>='a' && code<='z') || (code>='A' && code<='Z')) 372 if((code>='a' && code<='z') || (code>='A' && code<='Z'))
373 _state=STATE_CONTROL_ALPHA; 373 _state=STATE_CONTROL_ALPHA;
374 else if(code=='-'){ 374 else if(code=='-'){
375 _argSign=-1; 375 _argSign=-1;
376 _argValue=0; 376 _argValue=0;
377 _letterRange=_range; 377 _letterRange=_range;
378 _letterRange.length--; 378 _letterRange.length--;
379 _state=STATE_CONTROL_DIGIT; 379 _state=STATE_CONTROL_DIGIT;
380 } 380 }
381 else if(code>='0' && code<='9'){ 381 else if(code>='0' && code<='9'){
382 _argSign=1; 382 _argSign=1;
383 _argValue=code-'0'; 383 _argValue=code-'0';
384 _letterRange=_range; 384 _letterRange=_range;
385 _letterRange.length--; 385 _letterRange.length--;
386 _state=STATE_CONTROL_DIGIT; 386 _state=STATE_CONTROL_DIGIT;
387 } 387 }
388 else if(code==' '){ 388 else if(code==' '){
389 _letterRange=_range; 389 _letterRange=_range;
390 _letterRange.length--; 390 _letterRange.length--;
391 _state=STATE_SKIPLAST; 391 _state=STATE_SKIPLAST;
392 [self processControlWithArgValue:1]; 392 [self processControlWithArgValue:1];
393 } 393 }
394 else { 394 else {
395 _range.length--; 395 _range.length--;
396 _letterRange=_range; 396 _letterRange=_range;
397 _state=STATE_SCANNING; 397 _state=STATE_SCANNING;
398 [self processControlWithArgValue:1]; 398 [self processControlWithArgValue:1];
399 _range.location=position; 399 _range.location=position;
400 _range.length=0; 400 _range.length=0;
401 } 401 }
402 break; 402 break;
403 403
404 case STATE_CONTROL_DIGIT: 404 case STATE_CONTROL_DIGIT:
405 if(code>='0' && code<='9'){ 405 if(code>='0' && code<='9'){
406 _argValue*=10; 406 _argValue*=10;
407 _argValue+=code-'0'; 407 _argValue+=code-'0';
408 _state=STATE_CONTROL_DIGIT; 408 _state=STATE_CONTROL_DIGIT;
409 } 409 }
410 else if(code==' '){ 410 else if(code==' '){
411 _state=STATE_SKIPLAST; 411 _state=STATE_SKIPLAST;
412 [self processControlWithArgValue:_argSign*_argValue]; 412 [self processControlWithArgValue:_argSign*_argValue];
413 } 413 }
414 else { 414 else {
415 _range.length--; 415 _range.length--;
416 _state=STATE_SCANNING; 416 _state=STATE_SCANNING;
417 [self processControlWithArgValue:_argSign*_argValue]; 417 [self processControlWithArgValue:_argSign*_argValue];
418 _range.location=position; 418 _range.location=position;
419 _range.length=0; 419 _range.length=0;
420 } 420 }
421 break; 421 break;
422 422
423 case STATE_UNICODE: 423 case STATE_UNICODE:
424 case STATE_UNICODE_X: 424 case STATE_UNICODE_X:
425 case STATE_UNICODE_XX: 425 case STATE_UNICODE_XX:
426 case STATE_UNICODE_XXX: 426 case STATE_UNICODE_XXX:
427 if(code>='0' && code<='9'){ 427 if(code>='0' && code<='9'){
428 _univalue*=16; 428 _univalue*=16;
429 _univalue+=code-'0'; 429 _univalue+=code-'0';
430 _state++; 430 _state++;
431 } 431 }
432 else if(code>='A' && code<='F'){ 432 else if(code>='A' && code<='F'){
433 _univalue*=16; 433 _univalue*=16;
434 _univalue+=code-'A'+10; 434 _univalue+=code-'A'+10;
435 _state++; 435 _state++;
436 } 436 }
437 else { 437 else {
438 NSLog(@"error parsing unicode control in RTF"); 438 NSLog(@"error parsing unicode control in RTF");
439 _state=STATE_SCANNING; 439 _state=STATE_SCANNING;
440 } 440 }
441 if(_state==STATE_UNICODE_XXXX){ 441 if(_state==STATE_UNICODE_XXXX){
442 [self appendStringWithCurrentAttributes:[NSString stringWithCharacters:&_univalue length:1]]; 442 [self appendStringWithCurrentAttributes:[NSString stringWithCharacters:&_univalue length:1]];
443 _state=STATE_SKIPLAST; 443 _state=STATE_SKIPLAST;
444 } 444 }
445 break; 445 break;
446 } 446 }
447 } 447 }
448 } 448 }
449 449
450 -(NSAttributedString *)parseAttributedString { 450 -(NSAttributedString *)parseAttributedString {
451 [self tokenize]; 451 [self tokenize];
452 return _attributedString; 452 return _attributedString;
453 } 453 }
454 454
455 @end 455 @end
Powered by Google Project Hosting