2 * $Id: aquaterm.trm,v 1.31.2.2 2009/07/03 05:36:28 sfeam Exp $
6 /* GNUPLOT - aquaTerm.trm */
10 * This file is included by ../term.c via ../term.h.
12 * This terminal driver supports:
13 * Aqua (Mac OS X/Cocoa)
16 * Per Persson from openstep.trm by Robert Lutwak
18 * Homepage: http://aquaterm.sourceforge.net
19 * send your comments or suggestions to (persquare@users.sourceforge.net).
21 * This terminal attempts to connect, via the Mac OS X Distributed
22 * Objects system, to the "aquatermServer." If there is no such
23 * service registered with the OS, the terminal attempts to fire
24 * up AquaTerm.app. If the user has not set the environment variable
25 * AQUATERM_PATH, the terminal searches for AquaTerm.app in standard
26 * locations like /Applications, ~/Applications, etc.
27 * In order to use this filter, you MUST have AquaTerm.app installed
30 * Once connected to the server, all gnuplot graphs are sent,
31 * via the D.O. system, to AquaTerm.app, which produces renders graphs,
32 * manages the windows, takes care of printing etc.
43 /* Required entries */
44 TERM_PUBLIC void AQUA_options __PROTO((void));
45 TERM_PUBLIC void AQUA_init __PROTO((void));
46 TERM_PUBLIC void AQUA_reset __PROTO((void));
47 TERM_PUBLIC void AQUA_text __PROTO((void));
48 TERM_PUBLIC void AQUA_graphics __PROTO((void));
49 TERM_PUBLIC void AQUA_move __PROTO((unsigned int x, unsigned int y));
50 TERM_PUBLIC void AQUA_vector __PROTO((unsigned int x, unsigned int y));
51 TERM_PUBLIC void AQUA_linetype __PROTO((int linetype));
52 TERM_PUBLIC void AQUA_put_text __PROTO((unsigned int x, unsigned int y,const char *str));
53 /* Optional entries */
54 TERM_PUBLIC int AQUA_text_angle __PROTO((int));
55 TERM_PUBLIC int AQUA_justify_text __PROTO((enum JUSTIFY));
56 TERM_PUBLIC int AQUA_set_font __PROTO((const char *font)); /* "font,size" */
57 TERM_PUBLIC void AQUA_set_pointsize __PROTO((double size)); /* notification of set pointsize */
58 TERM_PUBLIC void AQUA_point __PROTO((unsigned int, unsigned int, int));
59 TERM_PUBLIC int flags; /* various flags */
60 TERM_PUBLIC void AQUA_suspend __PROTO((void)); /* after one plot of multiplot */
61 TERM_PUBLIC void AQUA_resume __PROTO((void)); /* before subsequent plot of multiplot */
62 TERM_PUBLIC void AQUA_boxfill __PROTO((int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height)); /* clear part of multiplot */
63 TERM_PUBLIC void AQUA_linewidth __PROTO((double linewidth));
64 TERM_PUBLIC void AQUA_pointsize __PROTO((double pointsize));
65 TERM_PUBLIC int AQUA_make_palette __PROTO((t_sm_palette *palette));
66 TERM_PUBLIC void AQUA_previous_palette __PROTO((void));
67 TERM_PUBLIC void AQUA_set_color __PROTO((t_colorspec *));
68 TERM_PUBLIC void AQUA_filled_polygon __PROTO((int points, gpiPoint *corners));
70 TERM_PUBLIC void AQUA_image __PROTO((unsigned, unsigned, coordval *, gpiPoint *, t_imagecolor));
72 TERM_PUBLIC void ENHAQUA_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
73 TERM_PUBLIC void ENHAQUA_open __PROTO((char * fontname, double fontsize,
74 double base, TBOOLEAN widthflag, TBOOLEAN showflag,
76 TERM_PUBLIC void ENHAQUA_flush __PROTO((void));
77 TERM_PUBLIC void ENHAQUA_writec __PROTO((int c));
80 #define AQUA_RESOLUTION (20.0) /* Increase resolution */
81 #define AQUA_XMAX (11.75 * 72 * AQUA_RESOLUTION) /* = paper width (in) times screen resolution */
82 #define AQUA_YMAX (8.25 * 72 * AQUA_RESOLUTION) /* = paper height (in) times screen resolution */
83 #define AQUA_VTIC (8.0*AQUA_RESOLUTION)
84 #define AQUA_HTIC (8.0*AQUA_RESOLUTION)
85 #define AQUA_VCHAR (16.0*AQUA_RESOLUTION) /* default font is Times at 14 points */
86 #define AQUA_HCHAR (AQUA_VCHAR*6.0/10.0)
87 #define AQUA_DASH_PATTERNS 8
88 #define AQUA_DEFAULT_DASHLENGTH_FACTOR 0.5
90 #define SPECIAL_COLORS 4
91 #define CYCLIC_COLORS 9
93 #define GOT_AQUA_PROTO
94 #endif /* TERM_PROTO */
96 #ifndef TERM_PROTO_ONLY
99 #import <aquaterm/AQTAdapter.h>
101 #import <Foundation/NSAutoreleasePool.h>
102 #import <Foundation/NSArray.h>
103 #import <Foundation/NSDictionary.h>
104 #import <Foundation/NSAttributedString.h>
107 /* Debugging extras */
108 static inline void NOOP_(id x, ...) {;}
116 /* AquaTerm specific */
117 static NSAutoreleasePool *arpool;
118 static NSAutoreleasePool *loopPool;
119 static AQTAdapter *adapter;
122 static int AQUA_plotRef = 0; /* A ref to the current plot */
123 static char AQUA_title[MAX_LINE_LEN + 1] = "Figure 0"; /* Plot title (in windowbar) */
125 static unsigned int AQUA_xSize = AQUA_XMAX; /* plot horizontal size */
126 static unsigned int AQUA_ySize = AQUA_YMAX; /* plot vertical size*/
128 static int AQUA_LineType = -3; /* current line type*/
129 static float AQUA_LineWidth = 1.0; /* current line width*/
130 static float AQUA_TextAngle = 0.0; /* current text orientation*/
131 static enum JUSTIFY AQUA_TextJust = LEFT; /* current text justification*/
133 /* default text font family: */
134 static char AQUA_fontNameDef[MAX_ID_LEN + 1] = "Times-Roman";
135 static double AQUA_fontSizeDef = 14; /* default text size*/
136 /* current text font family: */
137 static char AQUA_fontNameCur[MAX_ID_LEN + 1] = "Times-Roman";
138 static double AQUA_fontSizeCur = 14; /* current text size*/
141 static TBOOLEAN AQUA_dashedlines = FALSE;
142 static float AQUA_dashlength_factor = AQUA_DEFAULT_DASHLENGTH_FACTOR;
143 static int AQUA_dashPatternLengths[AQUA_DASH_PATTERNS] = {0, 2, 2, 2, 4, 4, 4, 6};
144 static int AQUA_dashPatterns[AQUA_DASH_PATTERNS][6] = {
155 /* Helper functions */
156 static NSString* AQUA_convert_using_encoding __PROTO((const char *string));
159 * ----------------------------------------------------------------
160 * Aquaterm driver implementation
161 * ----------------------------------------------------------------
163 * Current options are:
164 * <n> title "theTitle" size <x> <y> fname "fontface" fsize <fontsize>
171 TBOOLEAN set_number = FALSE;
173 AQUA_title[0] = '\0'; /* Force re-interpretation of title string */
175 while (!END_OF_COMMAND) {
177 if (almost_equals(c_token, "ti$tle")) {
180 if (!(s = try_to_get_string()))
181 int_error(c_token,"fname: expecting plot title");
182 strncpy(AQUA_title,s,sizeof(AQUA_title));
187 if (almost_equals(c_token, "s$ize")) {
193 int_error(c_token,"expecting x size");
194 value = real(const_express (&a));
195 if (value < 2 || value > 2048)
196 int_error(c_token,"x size out of range");
197 AQUA_xSize = (unsigned int) value * AQUA_RESOLUTION;
200 int_error(c_token,"expecting y size");
201 if (equals(c_token, ","))
203 value = real(const_express (&a));
204 if (value < 2 || value > 2048)
205 int_error(c_token,"y size out of range");
206 AQUA_ySize = (unsigned int) value * AQUA_RESOLUTION;
210 if (almost_equals(c_token, "fn$ame") || almost_equals(c_token, "font")) {
214 if (!(s = try_to_get_string()))
215 int_error(c_token,"expecting font specifier");
216 comma = strrchr(s, ',');
217 if (comma && (1 == sscanf(comma+1, "%lf", &AQUA_fontSizeCur)))
220 strncpy(AQUA_fontNameCur, s, sizeof(AQUA_fontNameCur));
225 if (almost_equals(c_token, "fs$ize")) {
229 int_error(c_token,"expecting font size");
230 AQUA_fontSizeCur = real (const_express (&a));
234 if (equals(c_token, "solid")) {
236 AQUA_dashedlines = FALSE;
240 if (almost_equals(c_token, "dash$ed")) {
242 AQUA_dashedlines = TRUE;
246 if (equals(c_token, "dl") || almost_equals(c_token, "dashl$ength")) {
249 int_error(c_token, "expecting dashlength multiplier");
250 AQUA_dashlength_factor = real(const_express(&a));
251 if (AQUA_dashlength_factor < 0.0)
252 AQUA_dashlength_factor = AQUA_DEFAULT_DASHLENGTH_FACTOR;
256 if (almost_equals(c_token, "enh$anced")) {
257 term->put_text = ENHAQUA_put_text;
259 term->flags |= TERM_ENHANCED_TEXT;
263 if (almost_equals(c_token, "noenh$anced")) {
264 term->put_text = AQUA_put_text;
266 term->flags &= ~TERM_ENHANCED_TEXT;
270 if (!set_number) { /* plot ref number */
271 AQUA_plotRef = (int) real (const_express (&a));
276 int_error(c_token, "unexpected text at end of command");
279 if (AQUA_title[0]=='\0') /* always set title */
280 sprintf(AQUA_title, "Figure %d", AQUA_plotRef);
281 /* Save options back into options string in normalized format */
282 sprintf(term_options, "%d title \"%s\" size %d,%d font \"%s,%g\" %s %s",
285 (unsigned int) (AQUA_xSize/AQUA_RESOLUTION), (unsigned int) (AQUA_ySize/AQUA_RESOLUTION),
286 AQUA_fontNameCur, AQUA_fontSizeCur,
287 term->put_text == ENHAQUA_put_text?"enhanced":"noenhanced",
288 AQUA_dashedlines?"dashed":"solid");
289 if (AQUA_dashedlines)
290 sprintf(&(term_options[strlen(term_options)]), " dl %3.1f", AQUA_dashlength_factor);
294 AQUA_convert_using_encoding(const char *string)
296 static bool didCheckEncodingSupport = false;
297 static bool hasStringEncodingSupport = false;
298 NSStringEncoding currentEncoding;
299 NSString *translatedString;
301 /* Check encoding support in system on first call */
302 if(!didCheckEncodingSupport) {
303 didCheckEncodingSupport = true;
304 hasStringEncodingSupport = [NSString respondsToSelector:@selector(stringWithCString:encoding:)];
306 /* Set encoding as requested by user via "set encoding" */
308 case S_ENC_ISO8859_1:
309 currentEncoding = NSISOLatin1StringEncoding;
311 case S_ENC_ISO8859_2:
312 currentEncoding = NSISOLatin2StringEncoding;
315 currentEncoding = NSWindowsCP1250StringEncoding;
317 /* FIXME: Add more encodings... */
318 case S_ENC_DEFAULT: /* Fallthrough */
320 /* UTF8 is 'default' */
321 currentEncoding = NSUTF8StringEncoding;
324 /* Perform translation (into UTF8 encoding used by Mac OS X) */
325 if (hasStringEncodingSupport) {
326 translatedString = [NSString stringWithCString:string encoding:currentEncoding];
328 translatedString = [NSString stringWithCString:string];
330 /* Check for nil result before returning */
331 return translatedString?translatedString:@"";
337 float fontSize, fontWHRatio;
340 LOG(@"Aqua Init (open plot)");
341 if (arpool == NULL) {
342 /* FIXME: This should be removed when pools are handled in gnuplot proper */
343 arpool = [[NSAutoreleasePool alloc] init];
345 if (adapter == NULL) {
346 adapter = [[AQTAdapter alloc] init];
347 if (!adapter) { /* server could be invalid (=nil) for several reasons */
348 /* FIXME: Issue warning here? */
352 /* Must open plot before all other commands */
353 [adapter openPlotWithIndex:AQUA_plotRef];
356 term->xmax = AQUA_xSize;
357 term->ymax = AQUA_ySize;
358 /* set current font*/
359 [adapter setFontname:AQUA_convert_using_encoding(AQUA_fontNameCur)];
360 [adapter setFontsize:AQUA_fontSizeCur];
361 /* set h_char, v_char*/
362 term->h_char = (int) (AQUA_fontSizeCur * 0.6 * AQUA_RESOLUTION);
363 term->v_char = (int) (AQUA_fontSizeCur * 1.5 * AQUA_RESOLUTION);
364 /* set h_tic, v_tic*/
365 term->h_tic = term->v_char / 3;
366 term->v_tic = term->v_char / 3;
368 [adapter setPlotSize:NSMakeSize(AQUA_xSize/AQUA_RESOLUTION, AQUA_ySize/AQUA_RESOLUTION)];
369 [adapter setPlotTitle:AQUA_convert_using_encoding(AQUA_title)];
372 * Set up the basic indexed colormap for gnuplot
375 [adapter setColormapEntry:0 red:0.1 green:0.1 blue:0.1]; /* linetype -4 */
376 [adapter setColormapEntry:1 red:0.9 green:0.9 blue:0.9]; /* linetype -3 (xor;interactive) light gray */
377 [adapter setColormapEntry:2 red:0.0 green:0.0 blue:0.0]; /* linetype -2 (border) black */
378 [adapter setColormapEntry:3 red:0.8 green:0.8 blue:0.8]; /* linetype -1 (gridlines) light grey */
380 [adapter setColormapEntry:4 red:1.0 green:0.0 blue:0.0]; /* red */
381 [adapter setColormapEntry:5 red:0.0 green:1.0 blue:0.0]; /* green */
382 [adapter setColormapEntry:6 red:0.0 green:0.0 blue:1.0]; /* blue */
383 [adapter setColormapEntry:7 red:1.0 green:0.0 blue:1.0]; /* magenta */
384 [adapter setColormapEntry:8 red:0.0 green:1.0 blue:1.0]; /* cyan */
385 [adapter setColormapEntry:9 red:0.6275 green:0.3216 blue:0.1765]; /* sienna */
386 [adapter setColormapEntry:10 red:1.0 green:0.6471 blue:0.0]; /* orange */
387 [adapter setColormapEntry:11 red:0.5 green:0.4980 blue:0.3137]; /* coral */
388 [adapter setColormapEntry:12 red:0.25 green:0.25 blue:0.25]; /* grey */
401 LOG(@"Aqua text (render)");
402 [adapter renderPlot];
409 /* Keep the compiler quiet when not debugging */
410 LOG(@"Pre: (arpool + loopPool, loopPool) =(%d, %d)", [NSAutoreleasePool autoreleasedObjectCount],
411 [NSAutoreleasePool topAutoreleasePoolCount]);
413 /* Avoid buildup of objects in the autoreleasepools */
415 loopPool = [[NSAutoreleasePool alloc] init];
417 /* Keep the compiler quiet when not debugging */
418 LOG(@"Post: (arpool + loopPool, loopPool) =(%d, %d)",[NSAutoreleasePool autoreleasedObjectCount],
419 [NSAutoreleasePool topAutoreleasePoolCount]);
421 [adapter eraseRect:NSMakeRect(0.0, 0.0, AQUA_xSize/AQUA_RESOLUTION, AQUA_ySize/AQUA_RESOLUTION)];
425 AQUA_move(unsigned int x, unsigned int y)
427 [adapter moveToPoint:NSMakePoint(x/AQUA_RESOLUTION, y/AQUA_RESOLUTION)];
431 AQUA_vector(unsigned int x, unsigned int y)
433 [adapter addLineToPoint:NSMakePoint(x/AQUA_RESOLUTION, y/AQUA_RESOLUTION)];
437 AQUA_linetype(int linetype)
441 LOG(@"AQUA_linetype(%d) ---> entry: %d", linetype, (linetype%CYCLIC_COLORS)+SPECIAL_COLORS);
442 if (linetype != AQUA_LineType) {
443 /* Note: this operation maps linestyle -4 to -1 onto colormap entries 0 to 3 */
444 AQUA_LineType = linetype;
445 [adapter takeColorFromColormapEntry:(linetype%CYCLIC_COLORS)+SPECIAL_COLORS];
447 if (AQUA_dashedlines) {
448 style = linetype%AQUA_DASH_PATTERNS;
450 [adapter setLinestyleSolid];
452 // Set up a dash array
453 for(i = 0; i<AQUA_dashPatternLengths[style]; i++) {
454 dash[i] = AQUA_dashPatterns[style][i] * AQUA_dashlength_factor;
456 [adapter setLinestylePattern:dash count:AQUA_dashPatternLengths[style] phase:0.0];
462 AQUA_put_text(unsigned int x, unsigned int y, const char *str)
466 [adapter addLabel:AQUA_convert_using_encoding(str)
467 atPoint:NSMakePoint(x/AQUA_RESOLUTION, y/AQUA_RESOLUTION)
469 align:(AQUA_TextJust | AQTAlignMiddle)];
473 AQUA_justify_text (enum JUSTIFY mode)
475 AQUA_TextJust = mode;
480 AQUA_text_angle (int angle)
482 AQUA_TextAngle = (float)angle;
487 AQUA_set_font(const char *font) /* "font,size" */
489 /* Obtain default fontname and fontsize. If these are invalid, AquaTerm will handle it. */
490 NSString *fontFace = AQUA_convert_using_encoding(AQUA_fontNameCur);
491 float fontSize = AQUA_fontSizeCur;
493 if (strlen(font) > 0) {
494 /* Try to split the non-empty string into array parts (as string objects) */
495 NSArray *parts = [AQUA_convert_using_encoding(font) componentsSeparatedByString:@","];
496 /* Check that we have both non-empty name and size, otherwise stay with defaults */
497 if ([parts count] > 0 && ![[parts objectAtIndex:0] isEqualToString:@""] ) {
498 fontFace = [parts objectAtIndex:0]; /* fontname */
499 if ([parts count] > 1 && ![[parts objectAtIndex:1] isEqualToString:@""] ) {
500 fontSize = [[parts objectAtIndex:1] floatValue]; /* Convert (optional) 2nd string object (fontsize) to float */
505 LOG(@"Setting:(%@,%f)", fontFace, fontSize);
506 [adapter setFontname:fontFace];
507 [adapter setFontsize:fontSize];
509 term->h_char = (int) (fontSize * 0.6 * AQUA_RESOLUTION);
510 term->v_char = (int) (fontSize * 1.5 * AQUA_RESOLUTION);
516 AQUA_set_pointsize(double size) /* notification of set pointsize */
518 LOG(@"AQUA_set_pointsize(%f)", size);
522 AQUA_point(unsigned int x, unsigned int y, int number)
524 /* The default dot-routine doesn't work with AQT */
525 [adapter setLinestyleSolid]; /* Symbols should never be dashed */
526 [adapter setLinewidth:1.0];
527 [adapter setLineCapStyle:AQTRoundLineCapStyle]; /* Set line cap style to round to create a dot */
528 [adapter moveToPoint:NSMakePoint(x/AQUA_RESOLUTION-0.005, y/AQUA_RESOLUTION)];
529 [adapter addLineToPoint:NSMakePoint(x/AQUA_RESOLUTION+0.005, y/AQUA_RESOLUTION)];
530 [adapter moveToPoint:NSMakePoint(0,0)]; /* Force a path end to work around a bug in AquaTerm 1.0.0 */
531 /* Round caps results in nicer symbols too */
533 do_point(x, y, number);
535 [adapter moveToPoint:NSMakePoint(0,0)]; /* Force a path end to work around a bug in AquaTerm 1.0.0 */
536 [adapter setLineCapStyle:AQTButtLineCapStyle]; /* Reset line capstyle */
539 /* after one plot of multiplot */
543 [adapter renderPlot];
546 /* before subsequent plot of multiplot */
552 /* clear part of multiplot */
554 AQUA_boxfill(int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height)
558 LOG(@"\nstyle=%d\nstyle & 0xf = %d\nfillpar=%d\n", style, style & 0xf, style >> 4);
559 /* Save current color */
560 [adapter getColorRed:&r green:&g blue:&b];
564 * - pattern : 0 - 100
566 int fillpar = style >> 4;
571 case 0: /* fill with background color */
574 [adapter getBackgroundColorRed:&rb green:&gb blue:&bb];
575 [adapter setColorRed:rb green:gb blue:bb];
578 case FS_SOLID: /* solid fill */
580 /* Alpha channel? RGB -> HSV -> R'G'B'? */
581 float density = (100 - fillpar)*0.01;
582 [adapter setColorRed:r*(1-density) + density
583 green:g*(1-density) + density
584 blue:b*(1-density) + density];
587 case FS_PATTERN: /* pattern fill */
588 /* Can't do pattern easily, using colors. */
589 [adapter takeColorFromColormapEntry:(fillpar%CYCLIC_COLORS)+SPECIAL_COLORS];
595 NSRect scaledRect = NSMakeRect(x1/AQUA_RESOLUTION, y1/AQUA_RESOLUTION, width/AQUA_RESOLUTION, height/AQUA_RESOLUTION);
596 [adapter eraseRect:scaledRect];
597 [adapter addFilledRect:scaledRect];
599 [adapter setColorRed:r green:g blue:b];
603 AQUA_linewidth(double linewidth)
605 [adapter setLinewidth:linewidth];
609 AQUA_pointsize(double pointsize)
611 LOG(@"AQUA_pointsize(%f)", pointsize);
612 term_pointsize = pointsize;
616 AQUA_make_palette(t_sm_palette *palette)
618 if (palette == NULL) {
619 /* AquaTerm can do continuous colors */
626 AQUA_set_color(t_colorspec *colorspec)
630 switch (colorspec->type) {
632 rgb1maxcolors_from_gray(colorspec->value, &color);
633 [adapter setColorRed:color.r green:color.g blue:color.b];
636 color.r = (double)((colorspec->lt >> 16 ) & 255) / 255.;
637 color.g = (double)((colorspec->lt >> 8 ) & 255) / 255.;
638 color.b = (double)(colorspec->lt & 255) / 255.;
639 [adapter setColorRed:color.r green:color.g blue:color.b];
642 [adapter takeColorFromColormapEntry:((colorspec->lt)%CYCLIC_COLORS)+SPECIAL_COLORS];
647 AQUA_LineType = LT_UNDEFINED;
651 AQUA_filled_polygon(int pc, gpiPoint *corners)
654 [adapter moveToVertexPoint:NSMakePoint(corners[0].x/AQUA_RESOLUTION,
655 corners[0].y/AQUA_RESOLUTION)];
656 for (i=1; i<pc; i++) {
657 [adapter addEdgeToVertexPoint:NSMakePoint(corners[i].x/AQUA_RESOLUTION,
658 corners[i].y/AQUA_RESOLUTION)];
663 AQUA_previous_palette()
670 AQUA_image (unsigned int M, unsigned int N, coordval *image, gpiPoint *corner, t_imagecolor color_mode)
672 float width = (corner[1].x - corner[0].x)/AQUA_RESOLUTION;
673 float height = (corner[0].y - corner[1].y)/AQUA_RESOLUTION;
674 float xPos = corner[0].x/AQUA_RESOLUTION;
675 float yPos = corner[1].y/AQUA_RESOLUTION;
676 int bitmapSize = M*N;
677 int targetSize = 3 * bitmapSize;
679 unsigned char *bitmap;
682 bitmap = malloc(targetSize*sizeof(unsigned char));
684 if (color_mode == IC_RGB) {
685 srcSize = targetSize;
686 for (i=0;i<srcSize;i++) {
687 bitmap[i] = (unsigned char)(255*image[i]);
689 } else if (color_mode == IC_PALETTE) {
691 unsigned char *bitmapPtr = bitmap;
692 srcSize = bitmapSize;
693 for (i=0;i<srcSize;i++) {
694 rgb1maxcolors_from_gray(image[i], &color);
695 *bitmapPtr = (unsigned char)(255*color.r);
697 *bitmapPtr = (unsigned char)(255*color.g);
699 *bitmapPtr = (unsigned char)(255*color.b);
703 NSLog(@"Unknown bitmap format");
705 [adapter addImageWithBitmap:bitmap
706 size:NSMakeSize(M, N)
707 bounds:NSMakeRect(xPos, yPos, width, height)];
713 #endif /* WITH_IMAGE */
716 * Per Persson 20041019
717 * Support for enhanced text mode
720 * - Overprinting not implemented
721 * - The sub/superscript level is determined from relative fontsize,
722 * it may break if fontsize is changed for individual characters.
725 static NSMutableAttributedString *enhString;
726 static NSMutableDictionary *attributes;
729 ENHAQUA_put_text(unsigned int x, unsigned int y, const char str[])
731 if (!strpbrk(str, "{}^_@&~"))
733 AQUA_put_text(x,y,str);
736 /* set up the global variables needed by enhanced_recursion() */
737 enhanced_max_height = -1000;
738 enhanced_min_height = 1000;
739 enhanced_fontscale = 1;
740 strncpy(enhanced_escape_format,"\\%o",sizeof(enhanced_escape_format));
742 /* Clear the attributed string */
744 enhString = [[NSMutableAttributedString alloc] init];
745 [enhString setAttributedString:[[NSAttributedString alloc] initWithString:@""]];
747 while (*(str = enhanced_recursion((char *)str, TRUE, AQUA_fontNameCur,
748 (double)(AQUA_fontSizeCur), 0.0, TRUE, TRUE, 0))) {
749 /* I think we can only get here if *str == '}' */
753 break; /* end of string */
754 /* else carry on and process the rest of the string */
757 /* Now, send the attributed string to the adapter */
758 [adapter addLabel:enhString
759 atPoint:NSMakePoint(x/AQUA_RESOLUTION, y/AQUA_RESOLUTION)
761 align:(AQUA_TextJust | AQTAlignMiddle)];
766 ENHAQUA_open(char * fontname, double fontsize,
767 double base, TBOOLEAN widthflag, TBOOLEAN showflag,
770 LOG(@"%s %.1f %.1f %s %s %d", fontname, fontsize, base,
771 widthflag ? "true" : "false",
772 showflag ? "true" : "false",
778 [attributes release];
779 attributes = [[NSMutableDictionary alloc] initWithCapacity:16];
780 [attributes setObject:AQUA_convert_using_encoding(fontname) forKey:@"AQTFontname"];
782 if (abs(base)>0.01) {
783 /* consider this as super/subscript, and compute subscript level */
784 int n = (int)round(log(fontsize/AQUA_fontSizeCur)/log(0.8));
785 [attributes setObject:[NSNumber numberWithInt:(base > 0)?n:-n]
786 forKey:@"NSSuperScript"];
787 } else if (abs(fontsize - AQUA_fontSizeCur)>0.01) {
788 /* Fontsize was set explicitly */
789 [attributes setObject:[NSNumber numberWithFloat:fontsize] forKey:@"AQTFontsize"];
793 [attributes setObject:[NSNumber numberWithInt:1]
794 forKey:@"AQTNonPrintingChar"];
797 /* Local buffer used in encoding conversion */
798 #define ENHAQUA_CSTRBUFLEN 1023
799 static char cStrBuf[ENHAQUA_CSTRBUFLEN + 1];
800 static unsigned int cStrBufIndex = 0;
805 /* Convert cStrBuf UTF8 according to encoding, use convert_using_encoding()
806 and apply attributes before adding to enhString
808 NSAttributedString *aStr;
809 cStrBuf[cStrBufIndex] = '\0';
811 aStr = [[NSAttributedString alloc] initWithString:AQUA_convert_using_encoding(cStrBuf) attributes:attributes];
812 [enhString appendAttributedString:aStr];
817 ENHAQUA_writec(int c)
819 /* Buffer byte sequence into cStrBuf */
820 LOG(@"int c = 0x%04x", c);
821 cStrBuf[cStrBufIndex] = (char)(c+0x100) & 0xFF; /* FIXME: Sometimes c is overflowed */
822 if (cStrBufIndex < ENHAQUA_CSTRBUFLEN)
825 #endif /* TERM_BODY */
829 TERM_TABLE_START(aqua_driver)
831 "Interface to graphics terminal server for Mac OS X",
832 0 /* xmax */ , 0 /* ymax */ , 0 /* vchar */ , 0 /* hchar */ ,
833 0 /* vtic */ , 0 /* htic */ ,
834 AQUA_options, AQUA_init, AQUA_reset,
835 AQUA_text, null_scale, AQUA_graphics, AQUA_move, AQUA_vector,
836 AQUA_linetype, AQUA_put_text,
839 AQUA_justify_text, AQUA_point, do_arrow, AQUA_set_font,
840 AQUA_pointsize, TERM_CAN_MULTIPLOT|TERM_NO_OUTPUTFILE,
841 AQUA_suspend, AQUA_resume,
842 AQUA_boxfill, AQUA_linewidth
845 #endif /* USE_MOUSE */
847 AQUA_previous_palette,
853 , ENHAQUA_open, ENHAQUA_flush, ENHAQUA_writec
854 TERM_TABLE_END(aqua_driver)
857 #define LAST_TERM aqua_driver
859 #endif /* TERM_TABLE */
860 #endif /* TERM_PROTO_ONLY */
865 "?commands set terminal aqua",
866 "?set terminal aqua",
872 " This terminal relies on AquaTerm.app for display on Mac OS X.",
875 " set terminal aqua {<n>} {title \"<wintitle>\"} {size <x> <y>}",
876 " {font \"<fontname>{,<fontsize>}\"}",
877 " {{no}enhanced} {solid|dashed} {dl <dashlength>}}",
879 " where <n> is the number of the window to draw in (default is 0),",
880 " <wintitle> is the name shown in the title bar (default \"Figure <n>\"),",
881 " <x> <y> is the size of the plot (default is 846x594 pt = 11.75x8.25 in).",
883 " Use <fontname> to specify the font to use (default is \"Times-Roman\"),",
884 " and <fontsize> to specify the font size (default is 14.0 pt). The old syntax",
885 " {fname \"<fontname>\"} {fsize <fontsize>} is still supported.",
887 " The aqua terminal supports enhanced text mode (see `enhanced`), except for",
888 " overprint. Font support is limited to the fonts available on the system.",
889 " Character encoding can be selected by `set encoding` and currently supports",
890 " iso_latin_1, iso_latin_2, cp1250, and default which equals UTF8.",
892 " Lines can be drawn either solid or dashed, (default is solid) and the dash",
893 " spacing can be modified by <dashlength> which is a multiplier > 0.",
896 #endif /* TERM_HELP */