mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 16:10:37 +00:00
Extended support for RTF
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@6697 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
69214d4cbe
commit
474b1eec6b
1 changed files with 329 additions and 129 deletions
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
Author: Stefan Bðhringer (stefan.boehringer@uni-bochum.de)
|
Author: Stefan Bðhringer (stefan.boehringer@uni-bochum.de)
|
||||||
Date: Dec 1999
|
Date: Dec 1999
|
||||||
|
Author: Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
Date: June 2000
|
||||||
|
|
||||||
This file is part of the GNUstep GUI Library.
|
This file is part of the GNUstep GUI Library.
|
||||||
|
|
||||||
|
@ -23,9 +25,10 @@
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
#import <AppKit/AppKit.h>
|
#include <AppKit/AppKit.h>
|
||||||
#import "Parsers/rtfConsumer.h"
|
#include "Parsers/rtfConsumer.h"
|
||||||
|
#include "Parsers/rtfConsumerFunctions.h"
|
||||||
|
|
||||||
/* we have to satisfy the scanner with a stream reading function */
|
/* we have to satisfy the scanner with a stream reading function */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -53,54 +56,77 @@ readNSString(StringContext *ctxt)
|
||||||
we must implement from the rtfConsumerSkeleton.h file (Supporting files)
|
we must implement from the rtfConsumerSkeleton.h file (Supporting files)
|
||||||
this includes the yacc error handling and output
|
this includes the yacc error handling and output
|
||||||
*/
|
*/
|
||||||
#define GSfontDictName @"fonts"
|
|
||||||
#define GScurrentTextPosition @"textPosition"
|
|
||||||
#define GSresultName @"result"
|
|
||||||
#define GSchanged @"changed"
|
|
||||||
|
|
||||||
#define GSparagraph @"paragraph"
|
// Hold the attributs of the current run
|
||||||
#define GSfontName @"fontName"
|
@interface RTFAttribute: NSObject <NSCopying>
|
||||||
#define GSfontSize @"fontSize"
|
|
||||||
#define GSbold @"bold"
|
|
||||||
#define GSitalic @"italic"
|
|
||||||
#define GSunderline @"underline"
|
|
||||||
#define GSscript @"script"
|
|
||||||
|
|
||||||
#define GSdocumentAttributes @"documentAttributes"
|
|
||||||
|
|
||||||
#define CTXT ((NSMutableDictionary *)ctxt)
|
|
||||||
#define FONTS [CTXT objectForKey: GSfontDictName]
|
|
||||||
#define RESULT [CTXT objectForKey: GSresultName]
|
|
||||||
#define CHANGED [[CTXT objectForKey: GSchanged] boolValue]
|
|
||||||
#define SETCHANGED(flag) [CTXT setObject: [NSNumber numberWithBool: flag] forKey: GSchanged]
|
|
||||||
#define PARAGRAPH [CTXT objectForKey: GSparagraph]
|
|
||||||
|
|
||||||
#define halfpoints2points(a) ((a)/2.0)
|
|
||||||
// FIXME: How to convert twips to points???
|
|
||||||
#define twips2points(a) ((a)/500.0)
|
|
||||||
|
|
||||||
|
|
||||||
static int textPosition(void *ctxt)
|
|
||||||
{
|
{
|
||||||
return [[CTXT objectForKey: GScurrentTextPosition] intValue];
|
@public
|
||||||
|
BOOL changed;
|
||||||
|
NSParagraphStyle *paragraph;
|
||||||
|
NSColor *fgColour;
|
||||||
|
NSColor *bgColour;
|
||||||
|
NSString *fontName;
|
||||||
|
float fontSize;
|
||||||
|
BOOL bold;
|
||||||
|
BOOL italic;
|
||||||
|
BOOL underline;
|
||||||
|
int script;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSFont *currentFont(void *ctxt)
|
- (NSFont*) currentFont;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation RTFAttribute
|
||||||
|
|
||||||
|
- (id) init
|
||||||
|
{
|
||||||
|
NSFont *font = [NSFont userFontOfSize:12];
|
||||||
|
|
||||||
|
ASSIGN(fontName, [font familyName]);
|
||||||
|
fontSize = 12.0;
|
||||||
|
italic = NO;
|
||||||
|
bold = NO;
|
||||||
|
underline = NO;
|
||||||
|
script = 0;
|
||||||
|
paragraph = [NSMutableParagraphStyle defaultParagraphStyle];
|
||||||
|
changed = YES;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
RELEASE(paragraph);
|
||||||
|
RELEASE(fontName);
|
||||||
|
RELEASE(fgColour);
|
||||||
|
RELEASE(bgColour);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) copyWithZone: (NSZone*)zone
|
||||||
|
{
|
||||||
|
RTFAttribute *new = [isa allocWithZone: zone];
|
||||||
|
|
||||||
|
new->paragraph = [paragraph copyWithZone: zone];
|
||||||
|
new->fontName = [fontName copyWithZone: zone];
|
||||||
|
new->fontSize = fontSize;
|
||||||
|
new->italic = italic;
|
||||||
|
new->bold = bold;
|
||||||
|
new->underline = underline;
|
||||||
|
new->script = script;
|
||||||
|
new->changed = NO;
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSFont*) currentFont
|
||||||
{
|
{
|
||||||
NSFont *font;
|
NSFont *font;
|
||||||
BOOL boldOn;
|
|
||||||
BOOL italicOn;
|
|
||||||
NSString *name;
|
|
||||||
float size;
|
|
||||||
NSFontTraitMask traits = 0;
|
NSFontTraitMask traits = 0;
|
||||||
int weight;
|
int weight;
|
||||||
|
|
||||||
name = [CTXT objectForKey: GSfontName];
|
if (bold)
|
||||||
size = [[CTXT objectForKey: GSfontSize] floatValue];
|
|
||||||
boldOn = [[CTXT objectForKey: GSbold] boolValue];
|
|
||||||
italicOn = [[CTXT objectForKey: GSitalic] boolValue];
|
|
||||||
|
|
||||||
if (boldOn)
|
|
||||||
{
|
{
|
||||||
weight = 9;
|
weight = 9;
|
||||||
traits |= NSBoldFontMask;
|
traits |= NSBoldFontMask;
|
||||||
|
@ -111,7 +137,7 @@ static NSFont *currentFont(void *ctxt)
|
||||||
traits |= NSUnboldFontMask;
|
traits |= NSUnboldFontMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (italicOn)
|
if (italic)
|
||||||
{
|
{
|
||||||
traits |= NSItalicFontMask;
|
traits |= NSItalicFontMask;
|
||||||
}
|
}
|
||||||
|
@ -120,12 +146,147 @@ static NSFont *currentFont(void *ctxt)
|
||||||
traits |= NSUnitalicFontMask;
|
traits |= NSUnitalicFontMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
font = [[NSFontManager sharedFontManager] fontWithFamily: name
|
font = [[NSFontManager sharedFontManager] fontWithFamily: fontName
|
||||||
traits: traits
|
traits: traits
|
||||||
weight: weight
|
weight: weight
|
||||||
size: size];
|
size: fontSize];
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface RTFConsumer: NSObject
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
NSMutableDictionary *documentAttributes;
|
||||||
|
NSMutableDictionary *fonts;
|
||||||
|
NSMutableArray *colours;
|
||||||
|
NSMutableArray *attrs;
|
||||||
|
NSMutableAttributedString *result;
|
||||||
|
int textPosition;
|
||||||
|
int ignore;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary*) documentAttributes;
|
||||||
|
- (RTFAttribute*) attr;
|
||||||
|
- (void) push;
|
||||||
|
- (void) pop;
|
||||||
|
- (NSAttributedString*) result;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation RTFConsumer
|
||||||
|
|
||||||
|
- (id) init
|
||||||
|
{
|
||||||
|
RTFAttribute *attr = [RTFAttribute new];
|
||||||
|
|
||||||
|
textPosition = 0;
|
||||||
|
ignore = 0;
|
||||||
|
result = [[NSMutableAttributedString alloc] init];
|
||||||
|
ASSIGN(documentAttributes, [NSMutableDictionary dictionary]);
|
||||||
|
ASSIGN(fonts, [NSMutableDictionary dictionary]);
|
||||||
|
ASSIGN(attrs, [NSMutableArray array]);
|
||||||
|
ASSIGN(colours, [NSMutableArray array]);
|
||||||
|
[attrs addObject: attr];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
RELEASE(fonts);
|
||||||
|
RELEASE(attrs);
|
||||||
|
RELEASE(colours);
|
||||||
|
RELEASE(result);
|
||||||
|
RELEASE(documentAttributes);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary*) documentAttributes
|
||||||
|
{
|
||||||
|
RETAIN(documentAttributes);
|
||||||
|
return AUTORELEASE(documentAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (RTFAttribute*) attr
|
||||||
|
{
|
||||||
|
return [attrs lastObject];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) push
|
||||||
|
{
|
||||||
|
[attrs addObject: [[attrs lastObject] copy]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) pop
|
||||||
|
{
|
||||||
|
[attrs removeLastObject];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSAttributedString*) result
|
||||||
|
{
|
||||||
|
RETAIN(result);
|
||||||
|
return AUTORELEASE(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSAttributedString*) parseRTF: (NSData *)rtfData
|
||||||
|
documentAttributes: (NSDictionary **)dict
|
||||||
|
{
|
||||||
|
CREATE_AUTORELEASE_POOL(pool);
|
||||||
|
RTFscannerCtxt scanner;
|
||||||
|
StringContext stringCtxt;
|
||||||
|
NSString *rtfString = [[NSString alloc]
|
||||||
|
initWithData: rtfData
|
||||||
|
encoding: NSASCIIStringEncoding];
|
||||||
|
|
||||||
|
// Has this RFTConsumer allready been used? Is so, reset!
|
||||||
|
if (textPosition)
|
||||||
|
[self init];
|
||||||
|
|
||||||
|
initStringContext(&stringCtxt, rtfString);
|
||||||
|
lexInitContext(&scanner, &stringCtxt, (int (*)(void*))readNSString);
|
||||||
|
NS_DURING
|
||||||
|
GSRTFparse((void *)self, &scanner);
|
||||||
|
NS_HANDLER
|
||||||
|
NSLog(@"Problem during RTF Parsing: %@",
|
||||||
|
[localException reason]);
|
||||||
|
//[localException raise];
|
||||||
|
NS_ENDHANDLER
|
||||||
|
|
||||||
|
RELEASE(pool);
|
||||||
|
// document attributes
|
||||||
|
if (dict)
|
||||||
|
*dict = [self documentAttributes];
|
||||||
|
|
||||||
|
return [self result];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#define FONTS ((RTFConsumer *)ctxt)->fonts
|
||||||
|
#define COLOURS ((RTFConsumer *)ctxt)->colours
|
||||||
|
#define RESULT ((RTFConsumer *)ctxt)->result
|
||||||
|
#define IGNORE ((RTFConsumer *)ctxt)->ignore
|
||||||
|
#define TEXTPOSITION ((RTFConsumer *)ctxt)->textPosition
|
||||||
|
#define DOCUMENTATTRIBUTES ((RTFConsumer*)ctxt)->documentAttributes
|
||||||
|
|
||||||
|
#define CTXT [((RTFConsumer *)ctxt) attr]
|
||||||
|
#define CHANGED CTXT->changed
|
||||||
|
#define PARAGRAPH CTXT->paragraph
|
||||||
|
#define FONTNAME CTXT->fontName
|
||||||
|
#define SCRIPT CTXT->script
|
||||||
|
#define ITALIC CTXT->italic
|
||||||
|
#define BOLD CTXT->bold
|
||||||
|
#define UNDERLINE CTXT->underline
|
||||||
|
#define FGCOLOUR CTXT->fgColour
|
||||||
|
#define BGCOLOUR CTXT->bgColour
|
||||||
|
|
||||||
|
#define PAPERSIZE @"PaperSize"
|
||||||
|
#define LEFTMARGIN @"LeftMargin"
|
||||||
|
#define RIGHTMARGIN @"RightMargin"
|
||||||
|
#define TOPMARGIN @"TopMargin"
|
||||||
|
#define BUTTOMMARGIN @"ButtomMargin"
|
||||||
|
|
||||||
/* handle errors (this is the yacc error mech) */
|
/* handle errors (this is the yacc error mech) */
|
||||||
void GSRTFerror(const char *msg)
|
void GSRTFerror(const char *msg)
|
||||||
|
@ -146,22 +307,6 @@ void GSRTFgenericRTFcommand(void *ctxt, RTFcmd cmd)
|
||||||
//Start: we're doing some initialization
|
//Start: we're doing some initialization
|
||||||
void GSRTFstart(void *ctxt)
|
void GSRTFstart(void *ctxt)
|
||||||
{
|
{
|
||||||
NSFont *font = [NSFont userFontOfSize:12];
|
|
||||||
|
|
||||||
[CTXT setObject: [NSNumber numberWithInt:0] forKey: GScurrentTextPosition];
|
|
||||||
[CTXT setObject: [NSMutableDictionary dictionary] forKey: GSfontDictName];
|
|
||||||
SETCHANGED(YES);
|
|
||||||
|
|
||||||
[CTXT setObject: [NSMutableParagraphStyle defaultParagraphStyle]
|
|
||||||
forKey: GSparagraph];
|
|
||||||
|
|
||||||
[CTXT setObject: [font familyName] forKey: GSfontName];
|
|
||||||
[CTXT setObject: [NSNumber numberWithFloat: 12.0] forKey: GSfontSize];
|
|
||||||
[CTXT setObject: [NSNumber numberWithBool: NO] forKey: GSbold];
|
|
||||||
[CTXT setObject: [NSNumber numberWithBool: NO] forKey: GSitalic];
|
|
||||||
[CTXT setObject: [NSNumber numberWithBool: NO] forKey: GSunderline];
|
|
||||||
[CTXT setObject: [NSNumber numberWithInt: 0] forKey: GSscript];
|
|
||||||
|
|
||||||
[RESULT beginEditing];
|
[RESULT beginEditing];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,44 +317,50 @@ void GSRTFstop(void *ctxt)
|
||||||
[RESULT endEditing];
|
[RESULT endEditing];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFopenBlock(void *ctxt)
|
void GSRTFopenBlock(void *ctxt, BOOL ignore)
|
||||||
{
|
{
|
||||||
// FIXME: Should push the current state on a stack
|
if (!IGNORE)
|
||||||
|
[(RTFConsumer *)ctxt push];
|
||||||
|
// Switch off any output for ignored block statements
|
||||||
|
if (ignore)
|
||||||
|
IGNORE++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFcloseBlock(void *ctxt)
|
void GSRTFcloseBlock(void *ctxt, BOOL ignore)
|
||||||
{
|
{
|
||||||
// FIXME: Should pop the current state from a stack
|
if (ignore)
|
||||||
|
IGNORE--;
|
||||||
|
if (!IGNORE)
|
||||||
|
[(RTFConsumer *)ctxt pop];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFmangleText(void *ctxt, const char *text)
|
void GSRTFmangleText(void *ctxt, const char *text)
|
||||||
{
|
{
|
||||||
int oldPosition = textPosition(ctxt);
|
int oldPosition = TEXTPOSITION;
|
||||||
int textlen = strlen(text);
|
int textlen = strlen(text);
|
||||||
int newPosition = oldPosition + textlen;
|
int newPosition = oldPosition + textlen;
|
||||||
NSRange insertionRange = NSMakeRange(oldPosition,0);
|
NSRange insertionRange = NSMakeRange(oldPosition,0);
|
||||||
NSDictionary *attributes;
|
NSDictionary *attributes;
|
||||||
NSFont *font;
|
NSFont *font;
|
||||||
|
|
||||||
if (textlen)
|
if (!IGNORE && textlen)
|
||||||
{
|
{
|
||||||
[CTXT setObject:[NSNumber numberWithInt: newPosition]
|
TEXTPOSITION = newPosition;
|
||||||
forKey: GScurrentTextPosition];
|
|
||||||
|
|
||||||
[RESULT replaceCharactersInRange: insertionRange
|
[RESULT replaceCharactersInRange: insertionRange
|
||||||
withString: [NSString stringWithCString:text]];
|
withString: [NSString stringWithCString:text]];
|
||||||
|
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
font = currentFont(ctxt);
|
font = [CTXT currentFont];
|
||||||
attributes = [NSDictionary dictionaryWithObjectsAndKeys:
|
attributes = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
font, NSFontAttributeName,
|
font, NSFontAttributeName,
|
||||||
[CTXT objectForKey: GSscript], NSSuperscriptAttributeName,
|
SCRIPT, NSSuperscriptAttributeName,
|
||||||
PARAGRAPH, NSParagraphStyleAttributeName,
|
PARAGRAPH, NSParagraphStyleAttributeName,
|
||||||
nil];
|
nil];
|
||||||
[RESULT setAttributes: attributes range:
|
[RESULT setAttributes: attributes range:
|
||||||
NSMakeRange(oldPosition, textlen)];
|
NSMakeRange(oldPosition, textlen)];
|
||||||
SETCHANGED(NO);
|
CHANGED = NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +375,7 @@ void GSRTFregisterFont(void *ctxt, const char *fontName,
|
||||||
{
|
{
|
||||||
[NSException raise:NSInvalidArgumentException
|
[NSException raise:NSInvalidArgumentException
|
||||||
format:@"Error in RTF (font omitted?), position:%d",
|
format:@"Error in RTF (font omitted?), position:%d",
|
||||||
textPosition(ctxt)];
|
TEXTPOSITION];
|
||||||
}
|
}
|
||||||
// exclude trailing ';' from fontName
|
// exclude trailing ';' from fontName
|
||||||
fontNameString = [NSString stringWithCString: fontName
|
fontNameString = [NSString stringWithCString: fontName
|
||||||
|
@ -243,14 +394,14 @@ void GSRTFfontNumber(void *ctxt, int fontNumber)
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
format: @"Error in RTF (referring to undefined font \\f%d), position:%d",
|
format: @"Error in RTF (referring to undefined font \\f%d), position:%d",
|
||||||
fontNumber,
|
fontNumber,
|
||||||
textPosition(ctxt)];
|
TEXTPOSITION];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (![fontName isEqual: [CTXT objectForKey: GSfontName]])
|
if (![fontName isEqual: FONTNAME])
|
||||||
{
|
{
|
||||||
[CTXT setObject: fontName forKey: GSfontName];
|
ASSIGN(FONTNAME, fontName);
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,28 +411,77 @@ void GSRTFfontSize(void *ctxt, int fontSize)
|
||||||
{
|
{
|
||||||
float size = halfpoints2points(fontSize);
|
float size = halfpoints2points(fontSize);
|
||||||
|
|
||||||
if (size != [[CTXT objectForKey: GSfontSize] floatValue])
|
if (size != CTXT->fontSize)
|
||||||
{
|
{
|
||||||
[CTXT setObject: [NSNumber numberWithFloat: size]
|
CTXT->fontSize = size;
|
||||||
forKey: GSfontSize];
|
CHANGED = YES;
|
||||||
SETCHANGED(YES);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFpaperWidth(void *ctxt, int width)
|
void GSRTFpaperWidth(void *ctxt, int width)
|
||||||
{
|
{
|
||||||
|
float fwidth = twips2points(width);
|
||||||
|
NSMutableDictionary *dict = DOCUMENTATTRIBUTES;
|
||||||
|
NSValue *val = [dict objectForKey: PAPERSIZE];
|
||||||
|
NSSize size;
|
||||||
|
|
||||||
|
if (val == nil)
|
||||||
|
size = NSMakeSize(fwidth, 792);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = [val sizeValue];
|
||||||
|
size.width = fwidth;
|
||||||
|
}
|
||||||
|
[dict setObject: [NSValue valueWithSize: size] forKey: PAPERSIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFpaperHeight(void *ctxt, int height)
|
void GSRTFpaperHeight(void *ctxt, int height)
|
||||||
{
|
{
|
||||||
|
float fheight = twips2points(height);
|
||||||
|
NSMutableDictionary *dict = DOCUMENTATTRIBUTES;
|
||||||
|
NSValue *val = [dict objectForKey: PAPERSIZE];
|
||||||
|
NSSize size;
|
||||||
|
|
||||||
|
if (val == nil)
|
||||||
|
size = NSMakeSize(612, fheight);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = [val sizeValue];
|
||||||
|
size.height = fheight;
|
||||||
|
}
|
||||||
|
[dict setObject: [NSValue valueWithSize: size] forKey: PAPERSIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFmarginLeft(void *ctxt, int margin)
|
void GSRTFmarginLeft(void *ctxt, int margin)
|
||||||
{
|
{
|
||||||
|
float fmargin = twips2points(margin);
|
||||||
|
NSMutableDictionary *dict = DOCUMENTATTRIBUTES;
|
||||||
|
|
||||||
|
[dict setObject: [NSNumber numberWithFloat: fmargin] forKey: LEFTMARGIN];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFmarginRight(void *ctxt, int margin)
|
void GSRTFmarginRight(void *ctxt, int margin)
|
||||||
{
|
{
|
||||||
|
float fmargin = twips2points(margin);
|
||||||
|
NSMutableDictionary *dict = DOCUMENTATTRIBUTES;
|
||||||
|
|
||||||
|
[dict setObject: [NSNumber numberWithFloat: fmargin] forKey: RIGHTMARGIN];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSRTFmarginTop(void *ctxt, int margin)
|
||||||
|
{
|
||||||
|
float fmargin = twips2points(margin);
|
||||||
|
NSMutableDictionary *dict = DOCUMENTATTRIBUTES;
|
||||||
|
|
||||||
|
[dict setObject: [NSNumber numberWithFloat: fmargin] forKey: TOPMARGIN];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSRTFmarginButtom(void *ctxt, int margin)
|
||||||
|
{
|
||||||
|
float fmargin = twips2points(margin);
|
||||||
|
NSMutableDictionary *dict = DOCUMENTATTRIBUTES;
|
||||||
|
|
||||||
|
[dict setObject: [NSNumber numberWithFloat: fmargin] forKey: BUTTOMMARGIN];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFfirstLineIndent(void *ctxt, int indent)
|
void GSRTFfirstLineIndent(void *ctxt, int indent)
|
||||||
|
@ -289,10 +489,11 @@ void GSRTFfirstLineIndent(void *ctxt, int indent)
|
||||||
NSMutableParagraphStyle *para = PARAGRAPH;
|
NSMutableParagraphStyle *para = PARAGRAPH;
|
||||||
float findent = twips2points(indent);
|
float findent = twips2points(indent);
|
||||||
|
|
||||||
if ([para firstLineHeadIndent] != findent)
|
// for attributed strings only positiv indent is allowed
|
||||||
|
if ((findent >= 0.0) && ([para firstLineHeadIndent] != findent))
|
||||||
{
|
{
|
||||||
[para setFirstLineHeadIndent: findent];
|
[para setFirstLineHeadIndent: findent];
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,10 +502,11 @@ void GSRTFleftIndent(void *ctxt, int indent)
|
||||||
NSMutableParagraphStyle *para = PARAGRAPH;
|
NSMutableParagraphStyle *para = PARAGRAPH;
|
||||||
float findent = twips2points(indent);
|
float findent = twips2points(indent);
|
||||||
|
|
||||||
if ([para headIndent] != findent)
|
// for attributed strings only positiv indent is allowed
|
||||||
|
if ((findent >= 0.0) && ([para headIndent] != findent))
|
||||||
{
|
{
|
||||||
[para setHeadIndent: findent];
|
[para setHeadIndent: findent];
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +517,7 @@ void GSRTFalignCenter(void *ctxt)
|
||||||
if ([para alignment] != NSCenterTextAlignment)
|
if ([para alignment] != NSCenterTextAlignment)
|
||||||
{
|
{
|
||||||
[para setAlignment: NSCenterTextAlignment];
|
[para setAlignment: NSCenterTextAlignment];
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +528,7 @@ void GSRTFalignLeft(void *ctxt)
|
||||||
if ([para alignment] != NSLeftTextAlignment)
|
if ([para alignment] != NSLeftTextAlignment)
|
||||||
{
|
{
|
||||||
[para setAlignment: NSLeftTextAlignment];
|
[para setAlignment: NSLeftTextAlignment];
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +539,7 @@ void GSRTFalignRight(void *ctxt)
|
||||||
if ([para alignment] != NSRightTextAlignment)
|
if ([para alignment] != NSRightTextAlignment)
|
||||||
{
|
{
|
||||||
[para setAlignment: NSRightTextAlignment];
|
[para setAlignment: NSRightTextAlignment];
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,23 +547,39 @@ void GSRTFstyle(void *ctxt, int style)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSRTFaddColor(void *ctxt, int red, int green, int blue)
|
||||||
|
{
|
||||||
|
NSColor *colour = [NSColor colorWithCalibratedRed: red/255.0
|
||||||
|
green: green/255.0
|
||||||
|
blue: blue/255.0
|
||||||
|
alpha: 1.0];
|
||||||
|
|
||||||
|
[COLOURS addObject: colour];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSRTFaddDefaultColor(void *ctxt)
|
||||||
|
{
|
||||||
|
[COLOURS addObject: [NSColor textColor]];
|
||||||
|
}
|
||||||
|
|
||||||
void GSRTFcolorbg(void *ctxt, int color)
|
void GSRTFcolorbg(void *ctxt, int color)
|
||||||
{
|
{
|
||||||
|
ASSIGN(BGCOLOUR, [COLOURS objectAtIndex: color]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFcolorfg(void *ctxt, int color)
|
void GSRTFcolorfg(void *ctxt, int color)
|
||||||
{
|
{
|
||||||
|
ASSIGN(FGCOLOUR, [COLOURS objectAtIndex: color]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFsubscript(void *ctxt, int script)
|
void GSRTFsubscript(void *ctxt, int script)
|
||||||
{
|
{
|
||||||
script = (int) (-halfpoints2points(script) / 3.0);
|
script = (int) (-halfpoints2points(script) / 3.0);
|
||||||
|
|
||||||
if (script != [[CTXT objectForKey: GSscript] intValue])
|
if (script != SCRIPT)
|
||||||
{
|
{
|
||||||
[CTXT setObject: [NSNumber numberWithInt: script]
|
SCRIPT = script;
|
||||||
forKey: GSscript];
|
CHANGED = YES;
|
||||||
SETCHANGED(YES);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,68 +587,50 @@ void GSRTFsuperscript(void *ctxt, int script)
|
||||||
{
|
{
|
||||||
script = (int) (halfpoints2points(script) / 3.0);
|
script = (int) (halfpoints2points(script) / 3.0);
|
||||||
|
|
||||||
if (script != [[CTXT objectForKey: GSscript] intValue])
|
if (script != SCRIPT)
|
||||||
{
|
{
|
||||||
[CTXT setObject: [NSNumber numberWithInt: script]
|
SCRIPT = script;
|
||||||
forKey: GSscript];
|
CHANGED = YES;
|
||||||
SETCHANGED(YES);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFitalic(void *ctxt, BOOL state)
|
void GSRTFitalic(void *ctxt, BOOL state)
|
||||||
{
|
{
|
||||||
if (state != [[CTXT objectForKey: GSitalic] boolValue])
|
if (state != ITALIC)
|
||||||
{
|
{
|
||||||
[CTXT setObject: [NSNumber numberWithBool: state] forKey: GSitalic];
|
ITALIC = state;
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFbold(void *ctxt, BOOL state)
|
void GSRTFbold(void *ctxt, BOOL state)
|
||||||
{
|
{
|
||||||
if (state != [[CTXT objectForKey: GSbold] boolValue])
|
if (state != BOLD)
|
||||||
{
|
{
|
||||||
[CTXT setObject: [NSNumber numberWithBool: state] forKey: GSbold];
|
BOLD = state;
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSRTFunderline(void *ctxt, BOOL state)
|
void GSRTFunderline(void *ctxt, BOOL state)
|
||||||
{
|
{
|
||||||
if (state != [[CTXT objectForKey: GSunderline] boolValue])
|
if (state != UNDERLINE)
|
||||||
{
|
{
|
||||||
[CTXT setObject: [NSNumber numberWithBool: state] forKey: GSunderline];
|
UNDERLINE = state;
|
||||||
SETCHANGED(YES);
|
CHANGED = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL parseRTFintoAttributedString(NSString *rtfString,
|
NSAttributedString *parseRTFintoAttributedString(NSData *rtfData,
|
||||||
NSMutableAttributedString *result,
|
NSDictionary **dict)
|
||||||
NSDictionary **dict)
|
|
||||||
{
|
{
|
||||||
RTFscannerCtxt scanner;
|
RTFConsumer *consumer = [RTFConsumer new];
|
||||||
StringContext stringCtxt;
|
NSAttributedString *result;
|
||||||
NSMutableDictionary *myDict = [NSMutableDictionary dictionary];
|
|
||||||
|
|
||||||
[myDict setObject: result forKey: GSresultName];
|
|
||||||
initStringContext(&stringCtxt, rtfString);
|
|
||||||
lexInitContext(&scanner, &stringCtxt, (int (*)(void*))readNSString);
|
|
||||||
GSRTFparse(myDict, &scanner);
|
|
||||||
|
|
||||||
// document attributes
|
result = [consumer parseRTF: rtfData documentAttributes: dict];
|
||||||
if (dict)
|
RELEASE(consumer);
|
||||||
(*dict)=[myDict objectForKey: GSdocumentAttributes];
|
|
||||||
|
|
||||||
return YES;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
NSMutableAttributedString *attributedStringFromRTF(NSString *rtfString)
|
|
||||||
{
|
|
||||||
NSMutableAttributedString *result = [[NSMutableAttributedString alloc] init];
|
|
||||||
|
|
||||||
parseRTFintoAttributedString(rtfString, result, NULL);
|
|
||||||
|
|
||||||
return AUTORELEASE(result);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue