diff options
Diffstat (limited to 'maccaml/graph.c')
-rw-r--r-- | maccaml/graph.c | 143 |
1 files changed, 81 insertions, 62 deletions
diff --git a/maccaml/graph.c b/maccaml/graph.c index d6c1700fe..59cf46cf7 100644 --- a/maccaml/graph.c +++ b/maccaml/graph.c @@ -40,15 +40,15 @@ RGBColor fgcolor; /* Convert from Caml coordinates to QD coordinates in the off-screen buffer. */ /* Note: these conversions are self-inverse (see gr_current_point). */ #define Bx(x) (x) -#define By(y) (h0 - (y)) +#define By(y) (h0-1 - (y)) /* Convert from Caml coordinates to QD coordinates in the window. */ -#define Wx(x) ((x) + x0) -#define Wy(y) ((h0 - (y)) + y0) +#define Wx(x) (Bx(x) + x0) +#define Wy(y) (By(y) + y0) /* Convert from QD window coordinates to Caml coordinates. */ #define Cx(x) ((x) - x0) -#define Cy(y) (h0 - ((y) - y0)) +#define Cy(y) (h0-1 - ((y) - y0)) /***********************************************************************/ @@ -237,20 +237,32 @@ static short cur_width, cur_font, cur_size; } \ } -/* Set up the current port to the off-screen buffer unconditionally. - This is for measurement functions that don't draw. */ -#define BeginSilent { \ +/* Set up the current port unconditionally. This is for functions that + don't draw (measurements and setting the graphport state). + Usage: BeginOffAlways / EndOffAlways + or BeginOffAlways / OnAlways / EndOffOnAlways + */ +#define BeginOffAlways { \ CGrafPtr _saveport_; \ GDHandle _savegdev_; \ GetGWorld (&_saveport_, &_savegdev_); \ LockPixels (GetGWorldPixMap (gworld)); \ SetGWorld ((CGrafPtr) gworld, NULL); -#define EndSilent \ +#define EndOffAlways \ SetGWorld (_saveport_, _savegdev_); \ UnlockPixels (GetGWorldPixMap (gworld)); \ } +#define OnAlways \ + SetGWorld (_saveport_, _savegdev_); \ + UnlockPixels (GetGWorldPixMap (gworld)); \ + SetPort (winGraphics); \ + +#define EndOffOnAlways \ + SetPort ((GrafPtr) _saveport_); \ +} + /* Convert a red, green, or blue value from 8 bits to 16 bits. */ #define RGB8to16(x) ((x) | ((x) << 8)) @@ -284,7 +296,7 @@ static void gr_check_open (void) in one major GC cycle. The GC will speed up to match this allocation speed. */ -#define Max_image_mem 1000000 /* XXX Should use user pref. */ +#define Max_image_mem 1000000 /*FIXME Should use user pref. */ #define Transparent (-1) @@ -425,12 +437,11 @@ value gr_sigio_handler (value unit) /* Not used on MacOS */ value gr_synchronize (value unit) { #pragma unused (unit) - GrafPtr port; + GrafPtr saveport; - GetPort (&port); - SetPort (winGraphics); + PushWindowPort (winGraphics); GraphUpdate (); - SetPort (port); + PopPort; return Val_unit; } @@ -480,11 +491,11 @@ value gr_set_color (value vrgb) fgcolor.red = RGB8to16 ((rgb >> 16) & 0xFF); fgcolor.green = RGB8to16 ((rgb >> 8) & 0xFF); fgcolor.blue = RGB8to16 (rgb & 0xFF); - BeginOff + BeginOffAlways RGBForeColor (&fgcolor); - On + OnAlways RGBForeColor (&fgcolor); - EndOffOn + EndOffOnAlways return Val_unit; } @@ -494,9 +505,9 @@ value gr_plot (value vx, value vy) gr_check_open (); BeginOff - SetCPixel (Bx (x), By (y+1), &fgcolor); + SetCPixel (Bx (x), By (y) - 1, &fgcolor); On - SetCPixel (Wx (x), Wy (y+1), &fgcolor); + SetCPixel (Wx (x), Wy (y) - 1, &fgcolor); EndOffOn return Val_unit; } @@ -508,9 +519,9 @@ value gr_point_color (value vx, value vy) gr_check_open (); if (x < 0 || x >= w0 || y < 0 || y >= h0) return Val_long (-1); - BeginSilent - GetCPixel (Bx (x), By (y+1), &c); - EndSilent + BeginOffAlways + GetCPixel (Bx (x), By (y) - 1, &c); + EndOffAlways return Val_long (((c.red & 0xFF00) << 8) | (c.green & 0xFF00) | ((c.blue & 0xFF00) >> 8)); @@ -521,11 +532,6 @@ value gr_moveto (value vx, value vy) XY; gr_check_open (); - BeginOff - MoveTo (Bx (x), By (y)); - On - MoveTo (Wx (x), Wy (y)); - EndOffOn cur_x = x; cur_y = y; return Val_unit; } @@ -549,12 +555,15 @@ value gr_current_y (value unit) value gr_lineto (value vx, value vy) { XY; + int delta = cur_width / 2; gr_check_open (); BeginOff - LineTo (Bx (x), By (y)); + MoveTo (Bx (cur_x) - delta, By (cur_y) - delta); + LineTo (Bx (x) - delta, By (y) - delta); On - LineTo (Wx (x), Wy (y)); + MoveTo (Wx (cur_x) - delta, Wy (cur_y) - delta); + LineTo (Wx (x) - delta, Wy (y) - delta); EndOffOn cur_x = x; cur_y = y; return Val_unit; @@ -565,13 +574,15 @@ value gr_draw_rect (value vx, value vy, value vw, value vh) XY; long w = Long_val (vw), h = Long_val (vh); Rect r; + int d1 = cur_width / 2; + int d2 = cur_width - d1; gr_check_open (); BeginOff - SetRect (&r, Bx (x), By (y+h), Bx (x+w), By (y)); + SetRect (&r, Bx (x) - d1, By (y+h) - d1, Bx (x+w) + d2, By (y) + d2); FrameRect (&r); On - SetRect (&r, Wx (x), Wy (y+h), Wx (x+w), Wy (y)); + SetRect (&r, Wx (x) - d1, Wy (y+h) - d1, Wx (x+w) + d2, Wy (y) + d2); FrameRect (&r); EndOffOn return Val_unit; @@ -591,13 +602,15 @@ value gr_draw_arc_nat (value vx, value vy, value vrx, value vry, value va1, long a1 = Long_val (va1), a2 = Long_val (va2); Rect r; long qda1 = 90 - a1, qda2 = 90 - a2; + int d1 = cur_width / 2; + int d2 = cur_width - d1; gr_check_open (); BeginOff - SetRect (&r, Bx (x-rx), By (y+ry), Bx (x+rx), By (y-ry)); + SetRect (&r, Bx(x-rx) - d1, By(y+ry) - d1, Bx(x+rx) + d2, By(y-ry) + d2); FrameArc (&r, qda1, qda2 - qda1); On - SetRect (&r, Wx (x-rx), Wy (y+ry), Wx (x+rx), Wy (y-ry)); + SetRect (&r, Wx(x-rx) - d1, Wy(y+ry) - d1, Wx(x+rx) + d2, Wy(y-ry) + d2); FrameArc (&r, qda1, qda2 - qda1); EndOffOn return Val_unit; @@ -609,11 +622,11 @@ value gr_set_line_width (value vwidth) if (width == 0) width = 1; gr_check_open (); - BeginOff + BeginOffAlways PenSize (width, width); - On + OnAlways PenSize (width, width); - EndOffOn + EndOffOnAlways cur_width = width; return Val_unit; } @@ -640,8 +653,8 @@ value gr_fill_poly (value vpoints) long i, n = Wosize_val (vpoints); PolyHandle p; - #define Bxx(i) Bx (Field (Field (vpoints, (i)), 0)) - #define Byy(i) By (Field (Field (vpoints, (i)), 1)) + #define Bxx(i) Bx (Int_val (Field (Field (vpoints, (i)), 0))) + #define Byy(i) By (Int_val (Field (Field (vpoints, (i)), 1))) gr_check_open (); if (n < 1) return Val_unit; @@ -686,19 +699,34 @@ value gr_fill_arc_nat (value vx, value vy, value vrx, value vry, value va1, return Val_unit; } -value gr_draw_char (value vchr) +static void draw_text (char *txt, unsigned long len) { - char c = Int_val (vchr); + FontInfo info; + unsigned long w; + + if (len > 32767) len = 32767; + + BeginOffAlways + GetFontInfo (&info); + w = TextWidth (txt, 0, len); + EndOffAlways gr_check_open (); BeginOff - DrawChar (c); + MoveTo (Bx (cur_x), By (cur_y) - info.descent); + DrawText (txt, 0, len); On - DrawChar (c); + MoveTo (Wx (cur_x), Wy (cur_y) - info.descent); + DrawText (txt, 0, len); EndOffOn - BeginSilent - cur_x += CharWidth (c); - EndSilent + cur_x += w; +} + +value gr_draw_char (value vchr) +{ + char c = Int_val (vchr); + + draw_text (&c, 1); return Val_unit; } @@ -707,16 +735,7 @@ value gr_draw_string (value vstr) mlsize_t len = string_length (vstr); char *str = String_val (vstr); - gr_check_open (); - if (len > 32767) len = 32767; - BeginOff - DrawText (str, 0, len); - On - DrawText (str, 0, len); - EndOffOn - BeginSilent - cur_x = TextWidth (str, 0, len); - EndSilent + draw_text (str, len); return Val_unit; } @@ -728,11 +747,11 @@ value gr_set_font (value vfontname) gr_check_open (); CopyCStringToPascal (String_val (vfontname), pfontname); GetFNum (pfontname, &fontnum); - BeginOff + BeginOffAlways TextFont (fontnum); - On + OnAlways TextFont (fontnum); - EndOffOn + EndOffOnAlways cur_font = fontnum; return Val_unit; } @@ -742,11 +761,11 @@ value gr_set_text_size (value vsz) short sz = Int_val (vsz); gr_check_open (); - BeginOff + BeginOffAlways TextSize (sz); - On + OnAlways TextSize (sz); - EndOffOn + EndOffOnAlways cur_size = sz; return Val_unit; } @@ -759,11 +778,11 @@ value gr_text_size (value vstr) FontInfo info; long w, h; - BeginSilent + BeginOffAlways GetFontInfo (&info); w = TextWidth (str, 0, len); h = info.ascent + info.descent; - EndSilent + EndOffAlways Field (result, 0) = Val_long (w); Field (result, 1) = Val_long (h); return result; |