Graphics.c revision cbc4e2be
1eaef79e5Smrg/* 2eaef79e5Smrg 3eaef79e5SmrgCopyright 1989, 1998 The Open Group 4eaef79e5Smrg 5eaef79e5SmrgPermission to use, copy, modify, distribute, and sell this software and its 6eaef79e5Smrgdocumentation for any purpose is hereby granted without fee, provided that 7eaef79e5Smrgthe above copyright notice appear in all copies and that both that 8eaef79e5Smrgcopyright notice and this permission notice appear in supporting 9eaef79e5Smrgdocumentation. 10eaef79e5Smrg 11eaef79e5SmrgThe above copyright notice and this permission notice shall be included 12eaef79e5Smrgin all copies or substantial portions of the Software. 13eaef79e5Smrg 14eaef79e5SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15eaef79e5SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16eaef79e5SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17eaef79e5SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18eaef79e5SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19eaef79e5SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20eaef79e5SmrgOTHER DEALINGS IN THE SOFTWARE. 21eaef79e5Smrg 22eaef79e5SmrgExcept as contained in this notice, the name of The Open Group shall 23eaef79e5Smrgnot be used in advertising or otherwise to promote the sale, use or 24eaef79e5Smrgother dealings in this Software without prior written authorization 25eaef79e5Smrgfrom The Open Group. 26eaef79e5Smrg 27eaef79e5Smrg*/ 28eaef79e5Smrg 29eaef79e5Smrg/* 30eaef79e5Smrg * Author: Davor Matic, MIT X Consortium 31eaef79e5Smrg */ 32eaef79e5Smrg 33cbc4e2beSmrg#ifdef HAVE_CONFIG_H 34cbc4e2beSmrg# include "config.h" 35cbc4e2beSmrg#endif 36cbc4e2beSmrg 37eaef79e5Smrg#include <X11/IntrinsicP.h> 38eaef79e5Smrg#include <X11/StringDefs.h> 39eaef79e5Smrg#include <X11/Xfuncs.h> 40eaef79e5Smrg#include "BitmapP.h" 41eaef79e5Smrg#include "Bitmap.h" 42eaef79e5Smrg#include "Requests.h" 43cbc4e2beSmrg 44eaef79e5Smrg#include <stdio.h> 45eaef79e5Smrg#include <math.h> 46eaef79e5Smrg 47eaef79e5Smrg#ifndef abs 48eaef79e5Smrg#define abs(x) (((x) > 0) ? (x) : -(x)) 49eaef79e5Smrg#endif 50eaef79e5Smrg#define min(x, y) (((int)(x) < (int)(y)) ? (x) : (y)) 51eaef79e5Smrg#define max(x, y) (((int)(x) > (int)(y)) ? (x) : (y)) 52eaef79e5Smrg#ifndef rint 53cbc4e2beSmrg# if HAVE_LRINT 54cbc4e2beSmrg# define rint(x) lrint(x) 55cbc4e2beSmrg# else 56cbc4e2beSmrg# define rint(x) floor(x + 0.5) 57cbc4e2beSmrg# endif 58eaef79e5Smrg#endif 59eaef79e5Smrg 60eaef79e5Smrg/*****************************************************************************\ 61eaef79e5Smrg * Graphics * 62eaef79e5Smrg\*****************************************************************************/ 63eaef79e5Smrg 64eaef79e5Smrg#define GetBit(image, x, y)\ 65eaef79e5Smrg ((bit)((*(image->data + (x) / 8 + (y) * image->bytes_per_line) &\ 66eaef79e5Smrg (1 << ((x) % 8))) ? 1 : 0)) 67eaef79e5Smrg 68eaef79e5Smrg#if 0 69cbc4e2beSmrgbit 70eaef79e5SmrgBWGetBit(Widget w, Position x, Position y) 71eaef79e5Smrg{ 72eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 73cbc4e2beSmrg 74eaef79e5Smrg if (QueryInBitmap(BW, x, y)) 75eaef79e5Smrg return GetBit(BW->bitmap.image, x, y); 76eaef79e5Smrg else 77eaef79e5Smrg return NotSet; 78eaef79e5Smrg} 79eaef79e5Smrg#endif 80eaef79e5Smrg 81eaef79e5Smrg#define InvertBit(image, x, y)\ 82eaef79e5Smrg (*(image->data + (x) / 8 + (y) * image->bytes_per_line) ^=\ 83eaef79e5Smrg (bit) (1 << ((x) % 8))) 84eaef79e5Smrg 85eaef79e5Smrg 86eaef79e5Smrg#define SetBit(image, x, y)\ 87eaef79e5Smrg (*(image->data + (x) / 8 + (y) * image->bytes_per_line) |=\ 88eaef79e5Smrg (bit) (1 << ((x) % 8))) 89eaef79e5Smrg 90eaef79e5Smrg#define ClearBit(image, x, y)\ 91eaef79e5Smrg (*(image->data + (x) / 8 + (y) * image->bytes_per_line) &=\ 92eaef79e5Smrg (bit)~(1 << ((x) % 8))) 93eaef79e5Smrg 94eaef79e5Smrg 95eaef79e5Smrg#define HighlightSquare(BW, x, y)\ 96eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW),\ 97eaef79e5Smrg BW->bitmap.highlighting_gc,\ 98eaef79e5Smrg InWindowX(BW, x), InWindowY(BW, y),\ 99eaef79e5Smrg BW->bitmap.squareW, BW->bitmap.squareH) 100eaef79e5Smrg/* 101cbc4e2beSmrgvoid 102eaef79e5SmrgHighlightSquare(BitmapWidget BW, Position x, Position y) 103eaef79e5Smrg{ 104eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW), 105eaef79e5Smrg BW->bitmap.highlighting_gc, 106eaef79e5Smrg InWindowX(BW, x), InWindowY(BW, y), 107eaef79e5Smrg BW->bitmap.squareW, BW->bitmap.squareH); 108eaef79e5Smrg} 109eaef79e5Smrg*/ 110eaef79e5Smrg 111eaef79e5Smrg#define DrawSquare(BW, x, y)\ 112eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW),\ 113eaef79e5Smrg BW->bitmap.drawing_gc,\ 114eaef79e5Smrg InWindowX(BW, x), InWindowY(BW, y),\ 115cbc4e2beSmrg BW->bitmap.squareW, BW->bitmap.squareH) 116eaef79e5Smrg 117eaef79e5Smrg/* 118cbc4e2beSmrgvoid 119eaef79e5SmrgDrawSquare(BitmapWidget BW, Position x, Position y) 120eaef79e5Smrg{ 121eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW), 122eaef79e5Smrg BW->bitmap.drawing_gc, 123eaef79e5Smrg InWindowX(BW, x), InWindowY(BW, y), 124eaef79e5Smrg BW->bitmap.squareW, BW->bitmap.squareH); 125eaef79e5Smrg} 126eaef79e5Smrg*/ 127eaef79e5Smrg 128eaef79e5Smrg#define InvertPoint(BW, x, y)\ 129eaef79e5Smrg {InvertBit(BW->bitmap.image, x, y); DrawSquare(BW, x, y);} 130eaef79e5Smrg 131eaef79e5Smrg#define DrawPoint(BW, x, y, value)\ 132eaef79e5Smrg if (GetBit(BW->bitmap.image, x, y) != value)\ 133eaef79e5Smrg InvertPoint(BW, x, y) 134eaef79e5Smrg 135cbc4e2beSmrgvoid 136eaef79e5SmrgBWDrawPoint(Widget w, Position x, Position y, bit value) 137eaef79e5Smrg{ 138eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 139cbc4e2beSmrg 140eaef79e5Smrg if (QueryInBitmap(BW, x, y)) { 141eaef79e5Smrg if (value == Highlight) 142eaef79e5Smrg HighlightSquare(BW, x, y); 143eaef79e5Smrg else 144eaef79e5Smrg DrawPoint(BW, x, y, value); 145eaef79e5Smrg } 146eaef79e5Smrg} 147eaef79e5Smrg 148eaef79e5Smrgstatic XPoint * 149eaef79e5SmrgHotSpotShape(BitmapWidget BW, Position x, Position y) 150eaef79e5Smrg{ 151eaef79e5Smrg static XPoint points[5]; 152cbc4e2beSmrg 153eaef79e5Smrg points[0].x = InWindowX(BW, x); 154eaef79e5Smrg points[0].y = InWindowY(BW, y + 1.0/2); 155eaef79e5Smrg points[1].x = InWindowX(BW, x + 1.0/2); 156eaef79e5Smrg points[1].y = InWindowY(BW, y + 1); 157eaef79e5Smrg points[2].x = InWindowX(BW, x + 1); 158eaef79e5Smrg points[2].y = InWindowY(BW, y + 1.0/2); 159eaef79e5Smrg points[3].x = InWindowX(BW, x + 1.0/2); 160eaef79e5Smrg points[3].y = InWindowY(BW, y); 161eaef79e5Smrg points[4].x = InWindowX(BW, x); 162eaef79e5Smrg points[4].y = InWindowY(BW, y + 1.0/2); 163cbc4e2beSmrg 164eaef79e5Smrg return points; 165eaef79e5Smrg} 166eaef79e5Smrg 167eaef79e5Smrg#define DrawHotSpot(BW, x, y)\ 168eaef79e5Smrg XFillPolygon(XtDisplay(BW), XtWindow(BW), BW->bitmap.drawing_gc,\ 169eaef79e5Smrg HotSpotShape(BW, x, y), 5, Convex, CoordModeOrigin) 170eaef79e5Smrg 171eaef79e5Smrg#define HighlightHotSpot(BW, x, y)\ 172eaef79e5Smrg XFillPolygon(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc,\ 173eaef79e5Smrg HotSpotShape(BW, x, y), 5, Convex, CoordModeOrigin) 174eaef79e5Smrg 175eaef79e5Smrg/* 176eaef79e5SmrgXImage *CreateBitmapImage(); 177eaef79e5Smrgvoid DestroyBitmapImage(); 178eaef79e5Smrg*/ 179eaef79e5Smrg 180cbc4e2beSmrgvoid 181eaef79e5SmrgBWRedrawHotSpot(Widget w) 182eaef79e5Smrg{ 183eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 184eaef79e5Smrg 185eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) 186eaef79e5Smrg DrawHotSpot(BW, BW->bitmap.hot.x, BW->bitmap.hot.y); 187eaef79e5Smrg} 188eaef79e5Smrg 189cbc4e2beSmrgvoid 190eaef79e5SmrgBWClearHotSpot(Widget w) 191eaef79e5Smrg{ 192eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 193cbc4e2beSmrg 194eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) { 195eaef79e5Smrg DrawHotSpot(BW, BW->bitmap.hot.x, BW->bitmap.hot.y); 196eaef79e5Smrg BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet; 197eaef79e5Smrg } 198eaef79e5Smrg} 199eaef79e5Smrg 200cbc4e2beSmrgvoid 201eaef79e5SmrgBWDrawHotSpot(Widget w, Position x, Position y, int value) 202eaef79e5Smrg{ 203eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 204cbc4e2beSmrg 205eaef79e5Smrg if (QueryInBitmap(BW, x, y)) { 206eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) && 207eaef79e5Smrg ((BW->bitmap.hot.x == x) && (BW->bitmap.hot.y == y))) { 208eaef79e5Smrg if ((value == Clear) || (value == Invert)) { 209eaef79e5Smrg BWClearHotSpot(w); 210eaef79e5Smrg } 211eaef79e5Smrg } 212eaef79e5Smrg else 213eaef79e5Smrg if ((value == Set) || (value == Invert)) { 214eaef79e5Smrg BWClearHotSpot(w); 215eaef79e5Smrg DrawHotSpot(BW, x, y); 216eaef79e5Smrg BW->bitmap.hot.x = x; 217eaef79e5Smrg BW->bitmap.hot.y = y; 218eaef79e5Smrg } 219cbc4e2beSmrg 220eaef79e5Smrg if (value == Highlight) 221cbc4e2beSmrg HighlightHotSpot(BW, x, y); 222eaef79e5Smrg } 223eaef79e5Smrg} 224eaef79e5Smrg 225cbc4e2beSmrgvoid 226eaef79e5SmrgBWSetHotSpot(Widget w, Position x, Position y) 227eaef79e5Smrg{ 228eaef79e5Smrg if (QuerySet(x, y)) 229eaef79e5Smrg BWDrawHotSpot(w, x, y, Set); 230eaef79e5Smrg else 231eaef79e5Smrg BWClearHotSpot(w); 232eaef79e5Smrg} 233eaef79e5Smrg 234eaef79e5Smrg/* high level procedures */ 235eaef79e5Smrg 236cbc4e2beSmrgvoid 237cbc4e2beSmrgBWRedrawSquares(Widget w, 238cbc4e2beSmrg Position x, Position y, 239eaef79e5Smrg Dimension width, Dimension height) 240eaef79e5Smrg{ 241eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 242eaef79e5Smrg Position from_x = InBitmapX(BW, x); 243eaef79e5Smrg Position from_y = InBitmapY(BW, y); 244eaef79e5Smrg Position to_x = InBitmapX(BW, x + width); 245eaef79e5Smrg Position to_y = InBitmapY(BW, y + height); 246eaef79e5Smrg 247eaef79e5Smrg QuerySwap(from_x, to_x); 248eaef79e5Smrg QuerySwap(from_y, to_y); 249eaef79e5Smrg from_x = max(0, from_x); 250eaef79e5Smrg from_y = max(0, from_y); 251eaef79e5Smrg to_x = min(BW->bitmap.image->width - 1, to_x); 252eaef79e5Smrg to_y = min(BW->bitmap.image->height - 1, to_y); 253cbc4e2beSmrg 254eaef79e5Smrg for (x = from_x; x <= to_x; x++) 255eaef79e5Smrg for (y = from_y; y <= to_y; y++) 256eaef79e5Smrg if (GetBit(BW->bitmap.image, x, y)) DrawSquare(BW, x, y); 257eaef79e5Smrg} 258eaef79e5Smrg 259cbc4e2beSmrgvoid 260cbc4e2beSmrgBWDrawGrid(Widget w, 261cbc4e2beSmrg Position from_x, Position from_y, 262eaef79e5Smrg Position to_x, Position to_y) 263eaef79e5Smrg{ 264eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 265eaef79e5Smrg int i; 266cbc4e2beSmrg 267eaef79e5Smrg QuerySwap(from_x, to_x); 268eaef79e5Smrg QuerySwap(from_y, to_y); 269eaef79e5Smrg from_x = max(0, from_x); 270eaef79e5Smrg from_y = max(0, from_y); 271eaef79e5Smrg to_x = min(BW->bitmap.image->width - 1, to_x); 272eaef79e5Smrg to_y = min(BW->bitmap.image->height - 1, to_y); 273cbc4e2beSmrg 274eaef79e5Smrg for(i = from_x + (from_x == 0); i <= to_x; i++) 275cbc4e2beSmrg XDrawLine(XtDisplay(BW), XtWindow(BW), 276eaef79e5Smrg BW->bitmap.frame_gc, 277eaef79e5Smrg InWindowX(BW, i), InWindowY(BW, from_y), 278eaef79e5Smrg InWindowX(BW, i), InWindowY(BW, to_y + 1)); 279cbc4e2beSmrg 280eaef79e5Smrg for(i = from_y + (from_y == 0); i <= to_y; i++) 281cbc4e2beSmrg XDrawLine(XtDisplay(BW), XtWindow(BW), 282eaef79e5Smrg BW->bitmap.frame_gc, 283eaef79e5Smrg InWindowX(BW, from_x), InWindowY(BW, i), 284eaef79e5Smrg InWindowX(BW, to_x + 1), InWindowY(BW, i)); 285eaef79e5Smrg} 286eaef79e5Smrg 287eaef79e5Smrg 288cbc4e2beSmrgvoid 289cbc4e2beSmrgBWRedrawGrid(Widget w, 290cbc4e2beSmrg Position x, Position y, 291eaef79e5Smrg Dimension width, Dimension height) 292eaef79e5Smrg{ 293eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 294eaef79e5Smrg Position from_x = InBitmapX(BW, x); 295eaef79e5Smrg Position from_y = InBitmapY(BW, y); 296eaef79e5Smrg Position to_x = InBitmapX(BW, x + width); 297eaef79e5Smrg Position to_y = InBitmapY(BW, y + height); 298eaef79e5Smrg 299eaef79e5Smrg if (BW->bitmap.grid) 300eaef79e5Smrg BWDrawGrid(w, from_x, from_y, to_x, to_y); 301eaef79e5Smrg} 302eaef79e5Smrg 303cbc4e2beSmrgvoid 304cbc4e2beSmrgBWDrawLine(Widget w, 305cbc4e2beSmrg Position from_x, Position from_y, 306eaef79e5Smrg Position to_x, Position to_y, int value) 307eaef79e5Smrg{ 308eaef79e5Smrg Position i; 309eaef79e5Smrg register double x, y; 310eaef79e5Smrg double dx, dy, delta; 311eaef79e5Smrg 312eaef79e5Smrg dx = to_x - from_x; 313eaef79e5Smrg dy = to_y - from_y; 314eaef79e5Smrg x = from_x + 0.5; 315eaef79e5Smrg y = from_y + 0.5; 316eaef79e5Smrg delta = max(abs(dx), abs(dy)); 317eaef79e5Smrg if (delta > 0) { 318eaef79e5Smrg dx /= delta; 319eaef79e5Smrg dy /= delta; 320eaef79e5Smrg for(i = 0; i <= delta; i++) { 321eaef79e5Smrg BWDrawPoint(w, (Position) x, (Position) y, value); 322eaef79e5Smrg x += dx; 323eaef79e5Smrg y += dy; 324eaef79e5Smrg } 325eaef79e5Smrg } 326eaef79e5Smrg else 327eaef79e5Smrg BWDrawPoint(w, from_x, from_y, value); 328eaef79e5Smrg} 329eaef79e5Smrg 330cbc4e2beSmrgvoid 331cbc4e2beSmrgBWBlindLine(Widget w, 332cbc4e2beSmrg Position from_x, Position from_y, 333eaef79e5Smrg Position to_x, Position to_y, int value) 334eaef79e5Smrg{ 335eaef79e5Smrg Position i; 336eaef79e5Smrg register double x, y; 337eaef79e5Smrg double dx, dy, delta; 338eaef79e5Smrg 339eaef79e5Smrg dx = to_x - from_x; 340eaef79e5Smrg dy = to_y - from_y; 341eaef79e5Smrg x = from_x + 0.5; 342eaef79e5Smrg y = from_y + 0.5; 343eaef79e5Smrg delta = max(abs(dx), abs(dy)); 344eaef79e5Smrg if (delta > 0) { 345eaef79e5Smrg dx /= delta; 346eaef79e5Smrg dy /= delta; 347eaef79e5Smrg x += dx; 348eaef79e5Smrg y += dy; 349eaef79e5Smrg for(i = 1; i <= delta; i++) { 350eaef79e5Smrg BWDrawPoint(w, (Position) x, (Position) y, value); 351eaef79e5Smrg x += dx; 352eaef79e5Smrg y += dy; 353eaef79e5Smrg } 354eaef79e5Smrg } 355eaef79e5Smrg else 356eaef79e5Smrg BWDrawPoint(w, from_x, from_y, value); 357eaef79e5Smrg} 358eaef79e5Smrg 359cbc4e2beSmrgvoid 360cbc4e2beSmrgBWDrawRectangle(Widget w, 361cbc4e2beSmrg Position from_x, Position from_y, 362eaef79e5Smrg Position to_x, Position to_y, int value) 363eaef79e5Smrg{ 364eaef79e5Smrg register Position i; 365eaef79e5Smrg Dimension delta, width, height; 366cbc4e2beSmrg 367eaef79e5Smrg QuerySwap(from_x, to_x); 368eaef79e5Smrg QuerySwap(from_y, to_y); 369cbc4e2beSmrg 370eaef79e5Smrg width = to_x - from_x; 371eaef79e5Smrg height = to_y - from_y; 372eaef79e5Smrg 373eaef79e5Smrg delta = max(width, height); 374cbc4e2beSmrg 375eaef79e5Smrg if (!QueryZero(width, height)) { 376eaef79e5Smrg for (i = 0; (int)i < (int)delta; i++) { 377eaef79e5Smrg if ((int)i < (int)width) { 378eaef79e5Smrg BWDrawPoint(w, from_x + i, from_y, value); 379eaef79e5Smrg BWDrawPoint(w, to_x - i, to_y, value); 380eaef79e5Smrg } 381eaef79e5Smrg if ((int)i < (int)height) { 382eaef79e5Smrg BWDrawPoint(w, from_x, to_y - i, value); 383eaef79e5Smrg BWDrawPoint(w, to_x, from_y + i, value); 384eaef79e5Smrg } 385eaef79e5Smrg } 386eaef79e5Smrg } 387eaef79e5Smrg else 388cbc4e2beSmrg BWDrawLine(w, 389cbc4e2beSmrg from_x, from_y, 390eaef79e5Smrg to_x, to_y, value); 391eaef79e5Smrg} 392cbc4e2beSmrg 393cbc4e2beSmrgvoid 394cbc4e2beSmrgBWDrawFilledRectangle(Widget w, 395cbc4e2beSmrg Position from_x, Position from_y, 396eaef79e5Smrg Position to_x, Position to_y, int value) 397eaef79e5Smrg{ 398eaef79e5Smrg register Position x, y; 399eaef79e5Smrg 400eaef79e5Smrg QuerySwap(from_x, to_x); 401eaef79e5Smrg QuerySwap(from_y, to_y); 402cbc4e2beSmrg 403eaef79e5Smrg for (x = from_x; x <= to_x; x++) 404eaef79e5Smrg for (y = from_y; y <= to_y; y++) 405eaef79e5Smrg BWDrawPoint(w, x, y, value); 406eaef79e5Smrg} 407eaef79e5Smrg 408cbc4e2beSmrgvoid 409cbc4e2beSmrgBWDrawCircle(Widget w, 410cbc4e2beSmrg Position origin_x, Position origin_y, 411eaef79e5Smrg Position point_x, Position point_y, int value) 412eaef79e5Smrg{ 413eaef79e5Smrg register Position i, delta; 414eaef79e5Smrg Dimension dx, dy, half; 415eaef79e5Smrg double radius; 416cbc4e2beSmrg 417eaef79e5Smrg dx = abs(point_x - origin_x); 418eaef79e5Smrg dy = abs(point_y - origin_y); 419eaef79e5Smrg radius = sqrt((double) ((int)dx * (int)dx + (int)dy * (int)dy)); 420eaef79e5Smrg if (radius < 1.0) { 421eaef79e5Smrg BWDrawPoint(w, origin_x, origin_y, value); 422eaef79e5Smrg } 423eaef79e5Smrg else { 424eaef79e5Smrg BWDrawPoint(w, origin_x - (Position) floor(radius), origin_y, value); 425eaef79e5Smrg BWDrawPoint(w, origin_x + (Position) floor(radius), origin_y, value); 426eaef79e5Smrg BWDrawPoint(w, origin_x, origin_y - (Position) floor(radius), value); 427eaef79e5Smrg BWDrawPoint(w, origin_x, origin_y + (Position) floor(radius), value); 428eaef79e5Smrg } 429eaef79e5Smrg half = radius / sqrt(2.0); 430eaef79e5Smrg for(i = 1; (int)i <= (int)half; i++) { 431eaef79e5Smrg delta = sqrt(radius * radius - i * i); 432eaef79e5Smrg BWDrawPoint(w, origin_x - delta, origin_y - i, value); 433eaef79e5Smrg BWDrawPoint(w, origin_x - delta, origin_y + i, value); 434eaef79e5Smrg BWDrawPoint(w, origin_x + delta, origin_y - i, value); 435eaef79e5Smrg BWDrawPoint(w, origin_x + delta, origin_y + i, value); 436eaef79e5Smrg if (i != delta) { 437eaef79e5Smrg BWDrawPoint(w, origin_x - i, origin_y - delta, value); 438eaef79e5Smrg BWDrawPoint(w, origin_x - i, origin_y + delta, value); 439eaef79e5Smrg BWDrawPoint(w, origin_x + i, origin_y - delta, value); 440eaef79e5Smrg BWDrawPoint(w, origin_x + i, origin_y + delta, value); 441eaef79e5Smrg } 442eaef79e5Smrg } 443eaef79e5Smrg} 444eaef79e5Smrg 445cbc4e2beSmrgvoid 446cbc4e2beSmrgBWDrawFilledCircle(Widget w, 447cbc4e2beSmrg Position origin_x, Position origin_y, 448eaef79e5Smrg Position point_x, Position point_y, int value) 449eaef79e5Smrg{ 450eaef79e5Smrg register Position i, j, delta; 451eaef79e5Smrg Dimension dx, dy; 452eaef79e5Smrg double radius; 453cbc4e2beSmrg 454eaef79e5Smrg dx = abs(point_x - origin_x); 455eaef79e5Smrg dy = abs(point_y - origin_y); 456eaef79e5Smrg radius = sqrt((double) ((int)dx * (int)dx + (int)dy * (int)dy)); 457cbc4e2beSmrg for(j = origin_x - (Position) floor(radius); 458eaef79e5Smrg j <= origin_x + (Position) floor(radius); j++) 459eaef79e5Smrg BWDrawPoint(w, j, origin_y, value); 460eaef79e5Smrg for(i = 1; i <= (Position) floor(radius); i++) { 461eaef79e5Smrg delta = sqrt(radius * radius - i * i); 462eaef79e5Smrg for(j = origin_x - delta; j <= origin_x + delta; j++) { 463eaef79e5Smrg BWDrawPoint(w, j, origin_y - i, value); 464eaef79e5Smrg BWDrawPoint(w, j, origin_y + i, value); 465eaef79e5Smrg } 466eaef79e5Smrg } 467eaef79e5Smrg} 468eaef79e5Smrg 469eaef79e5Smrg#define QueryFlood(BW, x, y, value)\ 470eaef79e5Smrg ((GetBit(BW->bitmap.image, x, y) !=\ 471eaef79e5Smrg (value & 1)) && QueryInBitmap(BW, x, y)) 472eaef79e5Smrg 473eaef79e5Smrg#define Flood(BW, x, y, value)\ 474eaef79e5Smrg {if (value == Highlight) HighlightSquare(BW, x, y);\ 475eaef79e5Smrg else InvertPoint(BW, x, y);} 476eaef79e5Smrg 477eaef79e5Smrg/* 478cbc4e2beSmrgstatic void 479eaef79e5SmrgFloodLoop(BitmapWidget BW, Position x, Position y, int value) 480eaef79e5Smrg{ 481eaef79e5Smrg if (QueryFlood(BW, x, y, value)) { 482eaef79e5Smrg Flood(BW, x, y, value); 483eaef79e5Smrg FloodLoop(BW, x, y - 1, value); 484eaef79e5Smrg FloodLoop(BW, x - 1, y, value); 485eaef79e5Smrg FloodLoop(BW, x, y + 1, value); 486eaef79e5Smrg FloodLoop(BW, x + 1, y, value); 487eaef79e5Smrg } 488eaef79e5Smrg} 489eaef79e5Smrg*/ 490eaef79e5Smrg 491cbc4e2beSmrgstatic void 492eaef79e5SmrgFloodLoop(BitmapWidget BW, Position x, Position y, int value) 493eaef79e5Smrg{ 494eaef79e5Smrg Position save_x, save_y, x_left, x_right; 495cbc4e2beSmrg 496cbc4e2beSmrg if (QueryFlood(BW, x, y, value)) 497eaef79e5Smrg Flood(BW, x, y, value) 498eaef79e5Smrg 499eaef79e5Smrg 500eaef79e5Smrg save_x = x; 501eaef79e5Smrg save_y = y; 502eaef79e5Smrg 503eaef79e5Smrg x++; 504eaef79e5Smrg while (QueryFlood(BW, x, y, value)) { 505eaef79e5Smrg Flood(BW, x, y, value); 506eaef79e5Smrg x++; 507eaef79e5Smrg } 508eaef79e5Smrg x_right = --x; 509eaef79e5Smrg 510eaef79e5Smrg x = save_x; 511eaef79e5Smrg x--; 512eaef79e5Smrg while (QueryFlood(BW, x, y, value)) { 513eaef79e5Smrg Flood(BW, x, y, value); 514eaef79e5Smrg x--; 515eaef79e5Smrg } 516eaef79e5Smrg x_left = ++x; 517eaef79e5Smrg 518eaef79e5Smrg 519eaef79e5Smrg x = x_left; 520eaef79e5Smrg y = save_y; 521eaef79e5Smrg y++; 522cbc4e2beSmrg 523eaef79e5Smrg while (x <= x_right) { 524eaef79e5Smrg Boolean flag = False; 525eaef79e5Smrg Position x_enter; 526cbc4e2beSmrg 527eaef79e5Smrg while (QueryFlood(BW, x, y, value) && (x <= x_right)) { 528eaef79e5Smrg flag = True; 529eaef79e5Smrg x++; 530eaef79e5Smrg } 531cbc4e2beSmrg 532eaef79e5Smrg if (flag) { 533eaef79e5Smrg if ((x == x_right) && QueryFlood(BW, x, y, value)) 534eaef79e5Smrg FloodLoop(BW, x, y, value); 535eaef79e5Smrg else 536eaef79e5Smrg FloodLoop(BW, x - 1, y, value); 537eaef79e5Smrg } 538cbc4e2beSmrg 539eaef79e5Smrg x_enter = x; 540cbc4e2beSmrg 541eaef79e5Smrg while (!QueryFlood(BW, x, y, value) && (x < x_right)) 542eaef79e5Smrg x++; 543cbc4e2beSmrg 544eaef79e5Smrg if (x == x_enter) x++; 545eaef79e5Smrg } 546eaef79e5Smrg 547eaef79e5Smrg x = x_left; 548eaef79e5Smrg y = save_y; 549eaef79e5Smrg y--; 550eaef79e5Smrg 551eaef79e5Smrg while (x <= x_right) { 552eaef79e5Smrg Boolean flag = False; 553eaef79e5Smrg Position x_enter; 554cbc4e2beSmrg 555eaef79e5Smrg while (QueryFlood(BW, x, y, value) && (x <= x_right)) { 556eaef79e5Smrg flag = True; 557eaef79e5Smrg x++; 558eaef79e5Smrg } 559cbc4e2beSmrg 560eaef79e5Smrg if (flag) { 561eaef79e5Smrg if ((x == x_right) && QueryFlood(BW, x, y, value)) 562eaef79e5Smrg FloodLoop(BW, x, y, value); 563eaef79e5Smrg else 564eaef79e5Smrg FloodLoop(BW, x - 1, y, value); 565eaef79e5Smrg } 566cbc4e2beSmrg 567eaef79e5Smrg x_enter = x; 568cbc4e2beSmrg 569eaef79e5Smrg while (!QueryFlood(BW, x, y, value) && (x < x_right)) 570eaef79e5Smrg x++; 571cbc4e2beSmrg 572eaef79e5Smrg if (x == x_enter) x++; 573eaef79e5Smrg } 574eaef79e5Smrg} 575eaef79e5Smrg 576cbc4e2beSmrgvoid 577eaef79e5SmrgBWFloodFill(Widget w, Position x, Position y, int value) 578eaef79e5Smrg{ 579eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 580eaef79e5Smrg int pixel; 581eaef79e5Smrg 582eaef79e5Smrg pixel = GetBit(BW->bitmap.image, x, y); 583eaef79e5Smrg 584eaef79e5Smrg if (value == Invert) 585eaef79e5Smrg FloodLoop(BW, x, y, (pixel ? Clear : Set)); 586eaef79e5Smrg else if (value != pixel) 587cbc4e2beSmrg FloodLoop(BW, x, y, value); 588eaef79e5Smrg} 589eaef79e5Smrg 590eaef79e5Smrg#define QueryHotInMark(BW)\ 591eaef79e5Smrg ((BW->bitmap.hot.x == max(BW->bitmap.mark.from_x,\ 592eaef79e5Smrg min(BW->bitmap.hot.x, BW->bitmap.mark.to_x)))\ 593eaef79e5Smrg &&\ 594eaef79e5Smrg (BW->bitmap.hot.y == max(BW->bitmap.mark.from_y,\ 595eaef79e5Smrg min(BW->bitmap.hot.y, BW->bitmap.mark.to_y)))) 596eaef79e5Smrg 597cbc4e2beSmrgvoid 598eaef79e5SmrgBWUp(Widget w) 599eaef79e5Smrg{ 600eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 601eaef79e5Smrg register Position x, y; 602eaef79e5Smrg bit first, up, down=0; 603eaef79e5Smrg Position from_x, from_y, to_x, to_y; 604eaef79e5Smrg 605eaef79e5Smrg if (BWQueryMarked(w)) { 606eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 607eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 608eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 609eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 610eaef79e5Smrg } 611eaef79e5Smrg else { 612eaef79e5Smrg from_x = 0; 613eaef79e5Smrg from_y = 0; 614eaef79e5Smrg to_x = BW->bitmap.width - 1; 615eaef79e5Smrg to_y = BW->bitmap.height - 1; 616eaef79e5Smrg } 617eaef79e5Smrg 618eaef79e5Smrg if ((to_y - from_y) == 0) 619eaef79e5Smrg return; 620cbc4e2beSmrg 621eaef79e5Smrg for(x = from_x; x <= to_x; x++) { 622eaef79e5Smrg first = up = GetBit(BW->bitmap.image, x, to_y); 623eaef79e5Smrg for(y = to_y - 1; y >= from_y; y--) { 624eaef79e5Smrg down = GetBit(BW->bitmap.image, x, y); 625cbc4e2beSmrg if (up != down) 626eaef79e5Smrg InvertPoint(BW, x, y); 627eaef79e5Smrg up =down; 628eaef79e5Smrg } 629eaef79e5Smrg if(first != down) 630eaef79e5Smrg InvertPoint(BW, x, to_y); 631eaef79e5Smrg } 632eaef79e5Smrg 633eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 634eaef79e5Smrg && 635eaef79e5Smrg !BWQueryMarked(w)) 636eaef79e5Smrg BWSetHotSpot(w, 637eaef79e5Smrg BW->bitmap.hot.x, 638cbc4e2beSmrg (BW->bitmap.hot.y - 1 + BW->bitmap.image->height) % 639eaef79e5Smrg BW->bitmap.image->height); 640eaef79e5Smrg 641eaef79e5Smrg} 642eaef79e5Smrg 643cbc4e2beSmrgvoid 644eaef79e5SmrgBWDown(Widget w) 645eaef79e5Smrg{ 646eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 647eaef79e5Smrg register Position x, y; 648eaef79e5Smrg bit first, down, up=0; 649eaef79e5Smrg Position from_x, from_y, to_x, to_y; 650eaef79e5Smrg 651eaef79e5Smrg if (BWQueryMarked(w)) { 652eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 653eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 654eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 655eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 656eaef79e5Smrg } 657eaef79e5Smrg else { 658eaef79e5Smrg from_x = 0; 659eaef79e5Smrg from_y = 0; 660eaef79e5Smrg to_x = BW->bitmap.width - 1; 661eaef79e5Smrg to_y = BW->bitmap.height - 1; 662eaef79e5Smrg } 663eaef79e5Smrg 664eaef79e5Smrg if ((to_y - from_y) == 0) 665eaef79e5Smrg return; 666eaef79e5Smrg 667eaef79e5Smrg for(x = from_x; x <= to_x; x++) { 668eaef79e5Smrg first = down = GetBit(BW->bitmap.image, x, from_y); 669eaef79e5Smrg for(y = from_y + 1; y <= to_y; y++) { 670eaef79e5Smrg up = GetBit(BW->bitmap.image, x, y); 671eaef79e5Smrg if (down != up) 672eaef79e5Smrg InvertPoint(BW, x, y); 673eaef79e5Smrg down = up; 674eaef79e5Smrg } 675cbc4e2beSmrg if(first != up) 676eaef79e5Smrg InvertPoint(BW, x, from_y); 677eaef79e5Smrg } 678cbc4e2beSmrg 679eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 680eaef79e5Smrg && 681eaef79e5Smrg !BWQueryMarked(w)) 682eaef79e5Smrg BWSetHotSpot(w, 683eaef79e5Smrg BW->bitmap.hot.x, 684eaef79e5Smrg (BW->bitmap.hot.y + 1) % BW->bitmap.image->height); 685eaef79e5Smrg} 686eaef79e5Smrg 687cbc4e2beSmrgvoid 688eaef79e5SmrgBWLeft(Widget w) 689eaef79e5Smrg{ 690eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 691eaef79e5Smrg register Position x, y; 692eaef79e5Smrg bit first, left, right=0; 693eaef79e5Smrg Position from_x, from_y, to_x, to_y; 694cbc4e2beSmrg 695eaef79e5Smrg if (BWQueryMarked(w)) { 696eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 697eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 698eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 699eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 700eaef79e5Smrg } 701eaef79e5Smrg else { 702eaef79e5Smrg from_x = 0; 703eaef79e5Smrg from_y = 0; 704eaef79e5Smrg to_x = BW->bitmap.width - 1; 705eaef79e5Smrg to_y = BW->bitmap.height - 1; 706eaef79e5Smrg } 707eaef79e5Smrg 708eaef79e5Smrg if ((to_x - from_x) == 0) 709eaef79e5Smrg return; 710cbc4e2beSmrg 711eaef79e5Smrg for(y = from_y; y <= to_y; y++) { 712eaef79e5Smrg first = left = GetBit(BW->bitmap.image, to_x, y); 713eaef79e5Smrg for(x = to_x - 1; x >= from_x; x--) { 714eaef79e5Smrg right = GetBit(BW->bitmap.image, x, y); 715eaef79e5Smrg if (left != right) 716eaef79e5Smrg InvertPoint(BW, x, y); 717eaef79e5Smrg left = right; 718eaef79e5Smrg } 719eaef79e5Smrg if(first != right) 720eaef79e5Smrg InvertPoint(BW, to_x, y); 721eaef79e5Smrg } 722cbc4e2beSmrg 723eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 724eaef79e5Smrg && 725eaef79e5Smrg !BWQueryMarked(w)) 726eaef79e5Smrg BWSetHotSpot(w, 727cbc4e2beSmrg (BW->bitmap.hot.x - 1 + BW->bitmap.image->width) % 728eaef79e5Smrg BW->bitmap.image->width, 729eaef79e5Smrg BW->bitmap.hot.y); 730eaef79e5Smrg} 731eaef79e5Smrg 732cbc4e2beSmrgvoid 733eaef79e5SmrgBWRight(Widget w) 734eaef79e5Smrg{ 735eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 736eaef79e5Smrg register Position x, y; 737eaef79e5Smrg bit first, right, left=0; 738eaef79e5Smrg Position from_x, from_y, to_x, to_y; 739cbc4e2beSmrg 740eaef79e5Smrg if (BWQueryMarked(w)) { 741eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 742eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 743eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 744eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 745eaef79e5Smrg } 746eaef79e5Smrg else { 747eaef79e5Smrg from_x = 0; 748eaef79e5Smrg from_y = 0; 749eaef79e5Smrg to_x = BW->bitmap.width - 1; 750eaef79e5Smrg to_y = BW->bitmap.height - 1; 751eaef79e5Smrg } 752cbc4e2beSmrg 753eaef79e5Smrg if ((to_x - from_x) == 0) 754eaef79e5Smrg return; 755cbc4e2beSmrg 756eaef79e5Smrg for(y = from_y; y <= to_y; y++) { 757eaef79e5Smrg first = right = GetBit(BW->bitmap.image, from_x, y); 758eaef79e5Smrg for(x = from_x + 1; x <= to_x; x++) { 759eaef79e5Smrg left = GetBit(BW->bitmap.image, x, y); 760eaef79e5Smrg if (right != left) 761eaef79e5Smrg InvertPoint(BW, x, y); 762eaef79e5Smrg right = left; 763eaef79e5Smrg } 764eaef79e5Smrg if(first != left) 765eaef79e5Smrg InvertPoint(BW, from_x, y); 766eaef79e5Smrg } 767eaef79e5Smrg 768eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 769eaef79e5Smrg && 770eaef79e5Smrg !BWQueryMarked(w)) 771eaef79e5Smrg BWSetHotSpot(w, 772eaef79e5Smrg (BW->bitmap.hot.x + 1) % BW->bitmap.image->width, 773eaef79e5Smrg BW->bitmap.hot.y); 774eaef79e5Smrg} 775eaef79e5Smrg 776eaef79e5Smrg/* void TransferImageData(); */ 777eaef79e5Smrg 778cbc4e2beSmrgvoid 779eaef79e5SmrgBWFold(Widget w) 780eaef79e5Smrg{ 781eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 782eaef79e5Smrg Position x, y, new_x, new_y; 783eaef79e5Smrg Dimension horiz, vert; 784eaef79e5Smrg char *storage_data; 785eaef79e5Smrg XImage *storage; 786cbc4e2beSmrg 787cbc4e2beSmrg storage_data = CreateCleanData(Length(BW->bitmap.image->width, 788eaef79e5Smrg BW->bitmap.image->height)); 789eaef79e5Smrg 790cbc4e2beSmrg storage = CreateBitmapImage(BW, storage_data, 791cbc4e2beSmrg (Dimension) BW->bitmap.image->width, 792eaef79e5Smrg (Dimension) BW->bitmap.image->height); 793eaef79e5Smrg 794eaef79e5Smrg TransferImageData(BW->bitmap.image, storage); 795eaef79e5Smrg 796eaef79e5Smrg BW->bitmap.fold ^= True; 797eaef79e5Smrg horiz = (BW->bitmap.image->width + BW->bitmap.fold) / 2; 798eaef79e5Smrg vert = (BW->bitmap.image->height + BW->bitmap.fold) / 2; 799cbc4e2beSmrg 800eaef79e5Smrg for (x = 0; x < BW->bitmap.image->width; x++) 801eaef79e5Smrg for (y = 0; y < BW->bitmap.image->height; y++) { 802eaef79e5Smrg new_x = (int)(x + horiz) % (int)BW->bitmap.image->width; 803eaef79e5Smrg new_y = (int)(y + vert) % (int)BW->bitmap.image->height; 804cbc4e2beSmrg if(GetBit(BW->bitmap.image, new_x, new_y) != 805eaef79e5Smrg GetBit(storage, x, y)) 806eaef79e5Smrg InvertPoint(BW, new_x, new_y); 807eaef79e5Smrg } 808cbc4e2beSmrg 809eaef79e5Smrg DestroyBitmapImage(&storage); 810eaef79e5Smrg 811eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) 812cbc4e2beSmrg BWSetHotSpot(w, 813cbc4e2beSmrg (Position) 814eaef79e5Smrg ((int)(BW->bitmap.hot.x+horiz) 815eaef79e5Smrg %(int)BW->bitmap.image->width), 816eaef79e5Smrg (Position) 817eaef79e5Smrg ((int)(BW->bitmap.hot.y+vert) 818eaef79e5Smrg %(int)BW->bitmap.image->height) 819eaef79e5Smrg ); 820eaef79e5Smrg} 821eaef79e5Smrg 822eaef79e5Smrg 823cbc4e2beSmrgvoid 824eaef79e5SmrgBWClear(Widget w) 825eaef79e5Smrg{ 826eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 827eaef79e5Smrg register Position x, y; 828eaef79e5Smrg int i, length; 829eaef79e5Smrg 830eaef79e5Smrg length = Length(BW->bitmap.image->width, BW->bitmap.image->height); 831eaef79e5Smrg 832eaef79e5Smrg for (x = 0; x < BW->bitmap.image->width; x++) 833eaef79e5Smrg for (y = 0; y < BW->bitmap.image->height; y++) 834eaef79e5Smrg if (GetBit(BW->bitmap.image, x, y)) 835eaef79e5Smrg DrawSquare(BW, x, y); 836cbc4e2beSmrg 837eaef79e5Smrg for (i = 0; i < length; i++) 838eaef79e5Smrg BW->bitmap.image->data[i] = 0; 839eaef79e5Smrg 840eaef79e5Smrg} 841eaef79e5Smrg 842cbc4e2beSmrgvoid 843eaef79e5SmrgBWSet(Widget w) 844eaef79e5Smrg{ 845eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 846eaef79e5Smrg register Position x, y; 847eaef79e5Smrg int i, length; 848cbc4e2beSmrg 849eaef79e5Smrg length = Length(BW->bitmap.image->width, BW->bitmap.image->height); 850cbc4e2beSmrg 851eaef79e5Smrg for (x = 0; x < BW->bitmap.image->width; x++) 852eaef79e5Smrg for (y = 0; y < BW->bitmap.image->height; y++) 853eaef79e5Smrg if (!GetBit(BW->bitmap.image, x, y)) 854eaef79e5Smrg DrawSquare(BW, x, y); 855cbc4e2beSmrg 856eaef79e5Smrg for (i = 0; i < length; i++) 857eaef79e5Smrg BW->bitmap.image->data[i] = (char)255; 858eaef79e5Smrg 859eaef79e5Smrg} 860cbc4e2beSmrg 861cbc4e2beSmrgvoid 862eaef79e5SmrgBWRedraw(Widget w) 863eaef79e5Smrg{ 864eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 865eaef79e5Smrg 866eaef79e5Smrg XClearArea(XtDisplay(BW), XtWindow(BW), 867eaef79e5Smrg 0, 0, BW->core.width, BW->core.height, 868eaef79e5Smrg True); 869eaef79e5Smrg} 870eaef79e5Smrg 871cbc4e2beSmrgvoid 872eaef79e5SmrgBWInvert(Widget w) 873eaef79e5Smrg{ 874eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 875eaef79e5Smrg int i, length; 876eaef79e5Smrg 877eaef79e5Smrg length = Length(BW->bitmap.image->width, BW->bitmap.image->height); 878eaef79e5Smrg 879eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW), 880eaef79e5Smrg BW->bitmap.drawing_gc, 881eaef79e5Smrg InWindowX(BW, 0), InWindowY(BW, 0), 882eaef79e5Smrg InWindowX(BW, BW->bitmap.image->width) - InWindowX(BW, 0), 883eaef79e5Smrg InWindowY(BW, BW->bitmap.image->height) - InWindowY(BW, 0)); 884cbc4e2beSmrg 885eaef79e5Smrg for (i = 0; i < length; i++) 886eaef79e5Smrg BW->bitmap.image->data[i] ^= 255; 887eaef79e5Smrg} 888eaef79e5Smrg 889cbc4e2beSmrgvoid 890eaef79e5SmrgBWFlipHoriz(Widget w) 891eaef79e5Smrg{ 892eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 893eaef79e5Smrg register Position x, y; 894eaef79e5Smrg Position from_x, from_y, to_x, to_y; 895eaef79e5Smrg float half; 896cbc4e2beSmrg 897eaef79e5Smrg if (BWQueryMarked(w)) { 898eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 899eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 900eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 901eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 902eaef79e5Smrg } 903eaef79e5Smrg else { 904eaef79e5Smrg from_x = 0; 905eaef79e5Smrg from_y = 0; 906eaef79e5Smrg to_x = BW->bitmap.width - 1; 907eaef79e5Smrg to_y = BW->bitmap.height - 1; 908eaef79e5Smrg } 909eaef79e5Smrg half = (float) (to_y - from_y) / 2.0 + 0.5; 910cbc4e2beSmrg 911eaef79e5Smrg if (half == 0.0) 912eaef79e5Smrg return; 913cbc4e2beSmrg 914cbc4e2beSmrg for (x = from_x; x <= to_x; x++) 915eaef79e5Smrg for (y = 0; y < half; y++) 916cbc4e2beSmrg if (GetBit(BW->bitmap.image, x, from_y + y) != 917eaef79e5Smrg GetBit(BW->bitmap.image, x, to_y - y)) { 918eaef79e5Smrg InvertPoint(BW, x, from_y + y); 919eaef79e5Smrg InvertPoint(BW, x, to_y - y); 920eaef79e5Smrg } 921cbc4e2beSmrg 922eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 923eaef79e5Smrg && 924eaef79e5Smrg !BWQueryMarked(w)) 925eaef79e5Smrg BWSetHotSpot(w, 926eaef79e5Smrg BW->bitmap.hot.x, 927eaef79e5Smrg BW->bitmap.image->height - 1 - BW->bitmap.hot.y); 928eaef79e5Smrg} 929eaef79e5Smrg 930cbc4e2beSmrgvoid 931eaef79e5SmrgBWFlipVert(Widget w) 932eaef79e5Smrg{ 933eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 934eaef79e5Smrg register Position x, y; 935eaef79e5Smrg Position from_x, from_y, to_x, to_y; 936eaef79e5Smrg float half; 937cbc4e2beSmrg 938eaef79e5Smrg if (BWQueryMarked(w)) { 939eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 940eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 941eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 942eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 943eaef79e5Smrg } 944eaef79e5Smrg else { 945eaef79e5Smrg from_x = 0; 946eaef79e5Smrg from_y = 0; 947eaef79e5Smrg to_x = BW->bitmap.width - 1; 948eaef79e5Smrg to_y = BW->bitmap.height - 1; 949eaef79e5Smrg } 950eaef79e5Smrg half = (float) (to_x - from_x) / 2.0 + 0.5; 951eaef79e5Smrg 952eaef79e5Smrg if (half == 0) 953eaef79e5Smrg return; 954eaef79e5Smrg 955eaef79e5Smrg for (y = from_y; y <= to_y; y++) 956eaef79e5Smrg for (x = 0; x < half; x++) 957cbc4e2beSmrg if (GetBit(BW->bitmap.image, from_x + x, y) != 958eaef79e5Smrg GetBit(BW->bitmap.image, to_x - x, y)) { 959eaef79e5Smrg InvertPoint(BW, from_x + x, y); 960eaef79e5Smrg InvertPoint(BW, to_x - x, y); 961eaef79e5Smrg } 962cbc4e2beSmrg 963eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 964eaef79e5Smrg && 965eaef79e5Smrg !BWQueryMarked(w)) 966eaef79e5Smrg BWSetHotSpot(w, 967eaef79e5Smrg BW->bitmap.image->width - 1 - BW->bitmap.hot.x, 968eaef79e5Smrg BW->bitmap.hot.y); 969eaef79e5Smrg} 970eaef79e5Smrg 971eaef79e5Smrg 972cbc4e2beSmrgvoid 973eaef79e5SmrgBWRotateRight(Widget w) 974eaef79e5Smrg{ 975eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 976eaef79e5Smrg Position x, y, delta, shift, tmp; 977eaef79e5Smrg Position half_width, half_height; 978eaef79e5Smrg XPoint hot; 979eaef79e5Smrg bit quad1, quad2, quad3, quad4; 980eaef79e5Smrg Position from_x, from_y, to_x, to_y; 981cbc4e2beSmrg 982eaef79e5Smrg if (BWQueryMarked(w)) { 983eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 984eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 985eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 986eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 987eaef79e5Smrg } 988eaef79e5Smrg else { 989eaef79e5Smrg from_x = 0; 990eaef79e5Smrg from_y = 0; 991eaef79e5Smrg to_x = BW->bitmap.width - 1; 992eaef79e5Smrg to_y = BW->bitmap.height - 1; 993eaef79e5Smrg } 994eaef79e5Smrg 995eaef79e5Smrg half_width = floor((to_x - from_x) / 2.0 + 0.5); 996eaef79e5Smrg half_height = floor((to_y - from_y ) / 2.0 + 0.5); 997eaef79e5Smrg shift = min((Position)(to_x - from_x), (Position)(to_y - from_y )) % 2; 998eaef79e5Smrg delta = min((Position) half_width, (Position) half_height) - shift; 999cbc4e2beSmrg 1000eaef79e5Smrg for (x = 0; x <= delta; x++) { 1001eaef79e5Smrg for (y = 1 - shift; y <= delta; y++) { 1002cbc4e2beSmrg quad1 = GetBit(BW->bitmap.image, 1003cbc4e2beSmrg from_x + (Position)half_width + x, 1004eaef79e5Smrg from_y + (Position)half_height + y); 1005cbc4e2beSmrg quad2 = GetBit(BW->bitmap.image, 1006cbc4e2beSmrg from_x + (Position)half_width + y, 1007eaef79e5Smrg from_y + (Position)half_height - shift - x); 1008cbc4e2beSmrg quad3 = GetBit(BW->bitmap.image, 1009cbc4e2beSmrg from_x + (Position)half_width - shift - x, 1010eaef79e5Smrg from_y + (Position)half_height - shift - y); 1011cbc4e2beSmrg quad4 = GetBit(BW->bitmap.image, 1012cbc4e2beSmrg from_x + (Position)half_width - shift - y, 1013eaef79e5Smrg from_y + (Position)half_height + x); 1014eaef79e5Smrg 1015eaef79e5Smrg if (quad1 != quad2) 1016cbc4e2beSmrg InvertPoint(BW, 1017cbc4e2beSmrg from_x + (Position)half_width + x, 1018eaef79e5Smrg from_y + (Position)half_height + y); 1019eaef79e5Smrg if (quad2 != quad3) 1020cbc4e2beSmrg InvertPoint(BW, 1021cbc4e2beSmrg from_x + (Position)half_width + y, 1022eaef79e5Smrg from_y + (Position)half_height - shift - x); 1023eaef79e5Smrg if (quad3 != quad4) 1024cbc4e2beSmrg InvertPoint(BW, 1025eaef79e5Smrg from_x + (Position)half_width - shift - x, 1026eaef79e5Smrg from_y + (Position)half_height - shift - y); 1027eaef79e5Smrg if (quad4 != quad1) 1028cbc4e2beSmrg InvertPoint(BW, 1029cbc4e2beSmrg from_x + (Position)half_width - shift - y, 1030eaef79e5Smrg from_y + (Position)half_height + x); 1031eaef79e5Smrg } 1032eaef79e5Smrg } 1033cbc4e2beSmrg 1034eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 1035eaef79e5Smrg && 1036eaef79e5Smrg !BWQueryMarked(w)) { 1037eaef79e5Smrg hot.x = BW->bitmap.hot.x - half_width; 1038eaef79e5Smrg hot.y = BW->bitmap.hot.y - half_height; 1039eaef79e5Smrg if (hot.x >= 0) hot.x += shift; 1040eaef79e5Smrg if (hot.y >= 0) hot.y += shift; 1041eaef79e5Smrg tmp = hot.x; 1042eaef79e5Smrg hot.x = - hot.y; 1043eaef79e5Smrg hot.y = tmp; 1044eaef79e5Smrg if (hot.x > 0) hot.x -= shift; 1045eaef79e5Smrg if (hot.y > 0) hot.y -= shift; 1046eaef79e5Smrg hot.x += half_width; 1047eaef79e5Smrg hot.y += half_height; 1048eaef79e5Smrg if (QueryInBitmap(BW, hot.x, hot.y)) 1049eaef79e5Smrg BWSetHotSpot(w, hot.x, hot.y); 1050eaef79e5Smrg } 1051cbc4e2beSmrg 1052eaef79e5Smrg} 1053eaef79e5Smrg 1054cbc4e2beSmrgvoid 1055eaef79e5SmrgBWRotateLeft(Widget w) 1056eaef79e5Smrg{ 1057eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1058eaef79e5Smrg Position x, y,delta, shift, tmp; 1059eaef79e5Smrg Position half_width, half_height; 1060eaef79e5Smrg XPoint hot; 1061eaef79e5Smrg bit quad1, quad2, quad3, quad4; 1062eaef79e5Smrg Position from_x, from_y, to_x, to_y; 1063cbc4e2beSmrg 1064eaef79e5Smrg if (BWQueryMarked(w)) { 1065eaef79e5Smrg from_x = BW->bitmap.mark.from_x; 1066eaef79e5Smrg from_y = BW->bitmap.mark.from_y; 1067eaef79e5Smrg to_x = BW->bitmap.mark.to_x; 1068eaef79e5Smrg to_y = BW->bitmap.mark.to_y; 1069eaef79e5Smrg } 1070eaef79e5Smrg else { 1071eaef79e5Smrg from_x = 0; 1072eaef79e5Smrg from_y = 0; 1073eaef79e5Smrg to_x = BW->bitmap.width - 1; 1074eaef79e5Smrg to_y = BW->bitmap.height - 1; 1075eaef79e5Smrg } 1076eaef79e5Smrg 1077eaef79e5Smrg half_width = floor((to_x - from_x) / 2.0 + 0.5); 1078eaef79e5Smrg half_height = floor((to_y - from_y ) / 2.0 + 0.5); 1079eaef79e5Smrg shift = min((Position)(to_x - from_x), (Position)(to_y - from_y )) % 2; 1080eaef79e5Smrg delta = min((Position) half_width, (Position) half_height) - shift; 1081cbc4e2beSmrg 1082eaef79e5Smrg for (x = 0; x <= delta; x++) { 1083eaef79e5Smrg for (y = 1 - shift; y <= delta; y++) { 1084cbc4e2beSmrg quad1 = GetBit(BW->bitmap.image, 1085cbc4e2beSmrg from_x + (Position)half_width + x, 1086eaef79e5Smrg from_y + (Position)half_height + y); 1087cbc4e2beSmrg quad2 = GetBit(BW->bitmap.image, 1088cbc4e2beSmrg from_x + (Position)half_width + y, 1089eaef79e5Smrg from_y + (Position)half_height - shift - x); 1090cbc4e2beSmrg quad3 = GetBit(BW->bitmap.image, 1091cbc4e2beSmrg from_x + (Position)half_width - shift - x, 1092eaef79e5Smrg from_y + (Position)half_height - shift - y); 1093cbc4e2beSmrg quad4 = GetBit(BW->bitmap.image, 1094cbc4e2beSmrg from_x + (Position)half_width - shift - y, 1095eaef79e5Smrg from_y + (Position)half_height + x); 1096eaef79e5Smrg 1097eaef79e5Smrg if (quad1 != quad4) 1098cbc4e2beSmrg InvertPoint(BW, 1099cbc4e2beSmrg from_x + (Position)half_width + x, 1100eaef79e5Smrg from_y + (Position)half_height + y); 1101eaef79e5Smrg if (quad2 != quad1) 1102cbc4e2beSmrg InvertPoint(BW, 1103cbc4e2beSmrg from_x + (Position)half_width + y, 1104eaef79e5Smrg from_y + (Position)half_height - shift - x); 1105eaef79e5Smrg if (quad3 != quad2) 1106cbc4e2beSmrg InvertPoint(BW, 1107eaef79e5Smrg from_x + (Position)half_width - shift - x, 1108eaef79e5Smrg from_y + (Position)half_height - shift - y); 1109eaef79e5Smrg if (quad4 != quad3) 1110cbc4e2beSmrg InvertPoint(BW, 1111cbc4e2beSmrg from_x + (Position)half_width - shift - y, 1112eaef79e5Smrg from_y + (Position)half_height + x); 1113eaef79e5Smrg } 1114eaef79e5Smrg } 1115cbc4e2beSmrg 1116eaef79e5Smrg if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y) 1117eaef79e5Smrg && 1118eaef79e5Smrg !BWQueryMarked(w)) { 1119eaef79e5Smrg hot.x = BW->bitmap.hot.x - half_width; 1120eaef79e5Smrg hot.y = BW->bitmap.hot.y - half_height; 1121eaef79e5Smrg if (hot.x >= 0) hot.x += shift; 1122eaef79e5Smrg if (hot.y >= 0) hot.y += shift; 1123eaef79e5Smrg tmp = hot.x; 1124eaef79e5Smrg hot.x = hot.y; 1125eaef79e5Smrg hot.y = - tmp; 1126eaef79e5Smrg if (hot.x > 0) hot.x -= shift; 1127eaef79e5Smrg if (hot.y > 0) hot.y -= shift; 1128eaef79e5Smrg hot.x += half_width; 1129eaef79e5Smrg hot.y += half_height; 1130eaef79e5Smrg if (QueryInBitmap(BW, hot.x, hot.y)) 1131eaef79e5Smrg BWSetHotSpot(w, hot.x, hot.y); 1132eaef79e5Smrg } 1133eaef79e5Smrg} 1134eaef79e5Smrg 1135eaef79e5Smrg 1136cbc4e2beSmrgvoid 1137cbc4e2beSmrgCopyImageData(XImage *source, XImage *destination, 1138cbc4e2beSmrg Position from_x, Position from_y, 1139cbc4e2beSmrg Position to_x, Position to_y, 1140eaef79e5Smrg Position at_x, Position at_y) 1141eaef79e5Smrg{ 1142eaef79e5Smrg Position x, y, delta_x, delta_y; 1143cbc4e2beSmrg 1144eaef79e5Smrg delta_x = to_x - from_x + 1; 1145eaef79e5Smrg delta_y = to_y - from_y + 1; 1146cbc4e2beSmrg 1147eaef79e5Smrg for (x = 0; x < delta_x; x++) 1148eaef79e5Smrg for (y = 0; y < delta_y; y++) 1149eaef79e5Smrg if (GetBit(source, from_x + x, from_y + y)) 1150eaef79e5Smrg SetBit(destination, at_x + x, at_y + y); 1151eaef79e5Smrg else 1152eaef79e5Smrg ClearBit(destination, at_x + x, at_y + y); 1153eaef79e5Smrg} 1154cbc4e2beSmrg 1155eaef79e5SmrgXImage * 1156eaef79e5SmrgConvertToBitmapImage(BitmapWidget BW, XImage *image) 1157eaef79e5Smrg{ 1158eaef79e5Smrg XImage *bitmap_image; 1159eaef79e5Smrg char *data; 1160eaef79e5Smrg Position x, y; 1161cbc4e2beSmrg 1162eaef79e5Smrg data = CreateCleanData(Length(image->width, image->height)); 1163cbc4e2beSmrg bitmap_image = CreateBitmapImage(BW, data, 1164cbc4e2beSmrg (Dimension) image->width, 1165eaef79e5Smrg (Dimension) image->height); 1166eaef79e5Smrg 1167eaef79e5Smrg for (x = 0; x < min(image->width, bitmap_image->width); x++) 1168eaef79e5Smrg for (y = 0; y < min(image->height, bitmap_image->height); y++) 1169eaef79e5Smrg if ((XGetPixel(image, x, y) != 0) != GetBit(bitmap_image, x, y)) 1170eaef79e5Smrg InvertBit(bitmap_image, x, y); 1171eaef79e5Smrg 1172eaef79e5Smrg return bitmap_image; 1173eaef79e5Smrg} 1174eaef79e5Smrg 1175cbc4e2beSmrgvoid 1176eaef79e5SmrgTransferImageData(XImage *source, XImage *destination) 1177eaef79e5Smrg{ 1178eaef79e5Smrg Position x, y; 1179cbc4e2beSmrg 1180eaef79e5Smrg for (x = 0; x < min(source->width, destination->width); x++) 1181eaef79e5Smrg for (y = 0; y < min(source->height, destination->height); y++) 1182eaef79e5Smrg if (GetBit(source, x, y) != GetBit(destination, x, y)) 1183eaef79e5Smrg InvertBit(destination, x, y); 1184eaef79e5Smrg} 1185eaef79e5Smrg 1186cbc4e2beSmrgvoid 1187eaef79e5SmrgBWStore(Widget w) 1188eaef79e5Smrg{ 1189eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1190eaef79e5Smrg Dimension width, height; 1191eaef79e5Smrg char *storage_data; 1192eaef79e5Smrg 1193eaef79e5Smrg if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { 1194eaef79e5Smrg 1195eaef79e5Smrg DestroyBitmapImage(&BW->bitmap.storage); 1196eaef79e5Smrg 1197eaef79e5Smrg width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; 1198eaef79e5Smrg height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; 1199cbc4e2beSmrg 1200eaef79e5Smrg storage_data = CreateCleanData(Length(width, height)); 1201eaef79e5Smrg 1202eaef79e5Smrg BW->bitmap.storage = CreateBitmapImage(BW, 1203eaef79e5Smrg storage_data, 1204eaef79e5Smrg width, height); 1205eaef79e5Smrg 1206eaef79e5Smrg CopyImageData(BW->bitmap.image, BW->bitmap.storage, 1207eaef79e5Smrg BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, 1208eaef79e5Smrg BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 1209eaef79e5Smrg 0, 0); 1210eaef79e5Smrg } 1211eaef79e5Smrg} 1212eaef79e5Smrg 1213cbc4e2beSmrgvoid 1214eaef79e5SmrgBWClearMarked(Widget w) 1215eaef79e5Smrg{ 1216eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1217cbc4e2beSmrg 1218eaef79e5Smrg if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) 1219eaef79e5Smrg BWDrawFilledRectangle(w, 1220eaef79e5Smrg BW->bitmap.mark.from_x, 1221eaef79e5Smrg BW->bitmap.mark.from_y, 1222eaef79e5Smrg BW->bitmap.mark.to_x, 1223eaef79e5Smrg BW->bitmap.mark.to_y, 1224eaef79e5Smrg Clear); 1225eaef79e5Smrg} 1226eaef79e5Smrg 1227eaef79e5Smrg 1228cbc4e2beSmrgvoid 1229eaef79e5SmrgBWDragMarked(Widget w, Position at_x, Position at_y) 1230eaef79e5Smrg{ 1231eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1232eaef79e5Smrg 1233eaef79e5Smrg if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) 1234cbc4e2beSmrg BWDrawRectangle(w, 1235cbc4e2beSmrg at_x, at_y, 1236eaef79e5Smrg at_x + BW->bitmap.mark.to_x - BW->bitmap.mark.from_x, 1237eaef79e5Smrg at_y + BW->bitmap.mark.to_y - BW->bitmap.mark.from_y, 1238eaef79e5Smrg Highlight); 1239eaef79e5Smrg} 1240eaef79e5Smrg 1241cbc4e2beSmrgvoid 1242eaef79e5SmrgBWDragStored(Widget w, Position at_x, Position at_y) 1243eaef79e5Smrg{ 1244eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1245cbc4e2beSmrg 1246eaef79e5Smrg if (BW->bitmap.storage) 1247cbc4e2beSmrg BWDrawRectangle(w, 1248eaef79e5Smrg at_x, at_y, 1249eaef79e5Smrg at_x + BW->bitmap.storage->width - 1, 1250eaef79e5Smrg at_y + BW->bitmap.storage->height - 1, 1251eaef79e5Smrg Highlight); 1252eaef79e5Smrg} 1253eaef79e5Smrg 1254cbc4e2beSmrgstatic void 1255cbc4e2beSmrgDrawImageData(BitmapWidget BW, XImage *image, 1256eaef79e5Smrg Position at_x, Position at_y, int value) 1257eaef79e5Smrg{ 1258eaef79e5Smrg Position x, y; 1259eaef79e5Smrg Boolean C, S, I, H; 1260eaef79e5Smrg bit A, B; 1261eaef79e5Smrg 1262eaef79e5Smrg C = value == Clear; 1263eaef79e5Smrg S = value == Set; 1264eaef79e5Smrg I = value == Invert; 1265eaef79e5Smrg H = value == Highlight; 1266eaef79e5Smrg 1267cbc4e2beSmrg for (x = 0; x < image->width; x++) 1268eaef79e5Smrg for (y = 0; y < image->height; y++) { 1269eaef79e5Smrg A = GetBit(image, x, y); 1270eaef79e5Smrg B = GetBit(BW->bitmap.image, at_x + x, at_y + y); 1271eaef79e5Smrg if ((A & C) | ((A | B) & S) | ((A ^ B) & I) | ((A | B) & H)) 1272eaef79e5Smrg value = (A & H) ? Highlight : Set; 1273eaef79e5Smrg else 1274eaef79e5Smrg value = Clear; 1275cbc4e2beSmrg BWDrawPoint((Widget) BW, 1276cbc4e2beSmrg at_x + x, at_y + y, 1277eaef79e5Smrg value); 1278eaef79e5Smrg } 1279eaef79e5Smrg} 1280eaef79e5Smrg 1281cbc4e2beSmrgvoid 1282eaef79e5SmrgBWRestore(Widget w, Position at_x, Position at_y, int value) 1283eaef79e5Smrg{ 1284eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1285cbc4e2beSmrg 1286eaef79e5Smrg if (BW->bitmap.storage) { 1287eaef79e5Smrg DrawImageData(BW, BW->bitmap.storage, at_x, at_y, value); 1288eaef79e5Smrg /*DestroyBitmapImage(&BW->bitmap.storage);*/ 1289eaef79e5Smrg } 1290eaef79e5Smrg} 1291eaef79e5Smrg 1292cbc4e2beSmrgvoid 1293eaef79e5SmrgBWCopy(Widget w, Position at_x, Position at_y, int value) 1294eaef79e5Smrg{ 1295eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1296eaef79e5Smrg XImage *storage; 1297eaef79e5Smrg char *storage_data; 1298eaef79e5Smrg Dimension width, height; 1299eaef79e5Smrg 1300eaef79e5Smrg if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { 1301eaef79e5Smrg 1302eaef79e5Smrg width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; 1303eaef79e5Smrg height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; 1304cbc4e2beSmrg 1305eaef79e5Smrg storage_data = CreateCleanData(Length(width, height)); 1306eaef79e5Smrg 1307eaef79e5Smrg storage = CreateBitmapImage(BW, storage_data, width, height); 1308eaef79e5Smrg 1309eaef79e5Smrg CopyImageData(BW->bitmap.image, storage, 1310eaef79e5Smrg BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, 1311eaef79e5Smrg BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 1312eaef79e5Smrg 0, 0); 1313eaef79e5Smrg 1314eaef79e5Smrg DrawImageData(BW, storage, at_x, at_y, value); 1315eaef79e5Smrg 1316eaef79e5Smrg DestroyBitmapImage(&storage); 1317eaef79e5Smrg } 1318eaef79e5Smrg} 1319eaef79e5Smrg 1320eaef79e5Smrg/* void BWMark(); */ 1321eaef79e5Smrg 1322cbc4e2beSmrgvoid 1323eaef79e5SmrgBWMove(Widget w, Position at_x, Position at_y, int value) 1324eaef79e5Smrg{ 1325eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1326eaef79e5Smrg XImage *storage; 1327eaef79e5Smrg char *storage_data; 1328eaef79e5Smrg Dimension width, height; 1329eaef79e5Smrg 1330eaef79e5Smrg if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { 1331eaef79e5Smrg 1332eaef79e5Smrg width = BW->bitmap.mark.to_x - BW->bitmap.mark.from_x + 1; 1333eaef79e5Smrg height = BW->bitmap.mark.to_y - BW->bitmap.mark.from_y + 1; 1334cbc4e2beSmrg 1335eaef79e5Smrg storage_data = CreateCleanData(Length(width, height)); 1336eaef79e5Smrg 1337eaef79e5Smrg storage = CreateBitmapImage(BW, storage_data, width, height); 1338eaef79e5Smrg 1339eaef79e5Smrg CopyImageData(BW->bitmap.image, storage, 1340eaef79e5Smrg BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, 1341eaef79e5Smrg BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 1342eaef79e5Smrg 0, 0); 1343eaef79e5Smrg 1344eaef79e5Smrg BWDrawFilledRectangle(w, 1345eaef79e5Smrg BW->bitmap.mark.from_x, BW->bitmap.mark.from_y, 1346eaef79e5Smrg BW->bitmap.mark.to_x, BW->bitmap.mark.to_y, 1347eaef79e5Smrg Clear); 1348eaef79e5Smrg 1349eaef79e5Smrg DrawImageData(BW, storage, at_x, at_y, value); 1350eaef79e5Smrg 1351eaef79e5Smrg BWMark(w, at_x, at_y, 1352eaef79e5Smrg at_x + BW->bitmap.mark.to_x - BW->bitmap.mark.from_x, 1353eaef79e5Smrg at_y + BW->bitmap.mark.to_y - BW->bitmap.mark.from_y); 1354eaef79e5Smrg 1355eaef79e5Smrg DestroyBitmapImage(&storage); 1356eaef79e5Smrg } 1357eaef79e5Smrg} 1358eaef79e5Smrg 1359cbc4e2beSmrgvoid 1360eaef79e5SmrgBWRedrawMark(Widget w) 1361eaef79e5Smrg{ 1362eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1363cbc4e2beSmrg 1364cbc4e2beSmrg if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) 1365eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, 1366cbc4e2beSmrg InWindowX(BW, BW->bitmap.mark.from_x), 1367cbc4e2beSmrg InWindowY(BW, BW->bitmap.mark.from_y), 1368cbc4e2beSmrg InWindowX(BW, BW->bitmap.mark.to_x + 1) - 1369eaef79e5Smrg InWindowX(BW, BW->bitmap.mark.from_x), 1370eaef79e5Smrg InWindowY(BW, BW->bitmap.mark.to_y + 1) - 1371eaef79e5Smrg InWindowY(BW, BW->bitmap.mark.from_y)); 1372eaef79e5Smrg} 1373eaef79e5Smrg 1374cbc4e2beSmrgvoid 1375eaef79e5SmrgBWStoreToBuffer(Widget w) 1376eaef79e5Smrg{ 1377eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1378cbc4e2beSmrg 1379cbc4e2beSmrg memmove( BW->bitmap.buffer->data, BW->bitmap.image->data, 1380eaef79e5Smrg Length(BW->bitmap.image->width, BW->bitmap.image->height)); 1381eaef79e5Smrg 1382eaef79e5Smrg BW->bitmap.buffer_hot = BW->bitmap.hot; 1383eaef79e5Smrg BW->bitmap.buffer_mark = BW->bitmap.mark; 1384eaef79e5Smrg} 1385eaef79e5Smrg 1386cbc4e2beSmrgvoid 1387eaef79e5SmrgBWUnmark(Widget w) 1388eaef79e5Smrg{ 1389eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1390eaef79e5Smrg 1391eaef79e5Smrg BW->bitmap.buffer_mark = BW->bitmap.mark; 1392eaef79e5Smrg 1393eaef79e5Smrg if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) { 1394eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, 1395cbc4e2beSmrg InWindowX(BW, BW->bitmap.mark.from_x), 1396cbc4e2beSmrg InWindowY(BW, BW->bitmap.mark.from_y), 1397cbc4e2beSmrg InWindowX(BW, BW->bitmap.mark.to_x + 1) - 1398eaef79e5Smrg InWindowX(BW, BW->bitmap.mark.from_x), 1399eaef79e5Smrg InWindowY(BW, BW->bitmap.mark.to_y + 1) - 1400eaef79e5Smrg InWindowY(BW, BW->bitmap.mark.from_y)); 1401cbc4e2beSmrg 1402eaef79e5Smrg BW->bitmap.mark.from_x = BW->bitmap.mark.from_y = NotSet; 1403eaef79e5Smrg BW->bitmap.mark.to_x = BW->bitmap.mark.to_y = NotSet; 1404eaef79e5Smrg } 1405eaef79e5Smrg} 1406eaef79e5Smrg 1407cbc4e2beSmrgvoid 1408cbc4e2beSmrgBWMark(Widget w, Position from_x, Position from_y, 1409eaef79e5Smrg Position to_x, Position to_y) 1410eaef79e5Smrg{ 1411eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1412eaef79e5Smrg 1413eaef79e5Smrg BWUnmark(w); 1414cbc4e2beSmrg 1415eaef79e5Smrg if (QuerySet(from_x, from_y)) { 1416eaef79e5Smrg if ((from_x == to_x) && (from_y == to_y)) { 1417eaef79e5Smrg /* 1418eaef79e5Smrg BW->bitmap.mark.from_x = 0; 1419eaef79e5Smrg BW->bitmap.mark.from_y = 0; 1420eaef79e5Smrg BW->bitmap.mark.to_x = BW->bitmap.image->width - 1; 1421eaef79e5Smrg BW->bitmap.mark.to_y = BW->bitmap.image->height - 1; 1422eaef79e5Smrg */ 1423eaef79e5Smrg return; 1424eaef79e5Smrg } 1425eaef79e5Smrg else { 1426eaef79e5Smrg QuerySwap(from_x, to_x); 1427eaef79e5Smrg QuerySwap(from_y, to_y); 1428eaef79e5Smrg from_x = max(0, from_x); 1429eaef79e5Smrg from_y = max(0, from_y); 1430eaef79e5Smrg to_x = min(BW->bitmap.image->width - 1, to_x); 1431eaef79e5Smrg to_y = min(BW->bitmap.image->height - 1, to_y); 1432cbc4e2beSmrg 1433eaef79e5Smrg BW->bitmap.mark.from_x = from_x; 1434eaef79e5Smrg BW->bitmap.mark.from_y = from_y; 1435eaef79e5Smrg BW->bitmap.mark.to_x = to_x; 1436eaef79e5Smrg BW->bitmap.mark.to_y = to_y; 1437eaef79e5Smrg } 1438cbc4e2beSmrg 1439eaef79e5Smrg XFillRectangle(XtDisplay(BW), XtWindow(BW), BW->bitmap.highlighting_gc, 1440eaef79e5Smrg InWindowX(BW, BW->bitmap.mark.from_x), 1441cbc4e2beSmrg InWindowY(BW, BW->bitmap.mark.from_y), 1442eaef79e5Smrg InWindowX(BW, BW->bitmap.mark.to_x + 1) - 1443eaef79e5Smrg InWindowX(BW, BW->bitmap.mark.from_x), 1444cbc4e2beSmrg InWindowY(BW, BW->bitmap.mark.to_y +1) - 1445eaef79e5Smrg InWindowY(BW, BW->bitmap.mark.from_y)); 1446eaef79e5Smrg } 1447eaef79e5Smrg} 1448eaef79e5Smrg 1449cbc4e2beSmrgvoid 1450eaef79e5SmrgBWMarkAll(Widget w) 1451eaef79e5Smrg{ 1452eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1453eaef79e5Smrg 1454eaef79e5Smrg BWMark(w, 0, 0, BW->bitmap.image->width - 1, BW->bitmap.image->height - 1); 1455eaef79e5Smrg} 1456eaef79e5Smrg 1457cbc4e2beSmrgvoid 1458eaef79e5SmrgBWUndo(Widget w) 1459eaef79e5Smrg{ 1460eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1461eaef79e5Smrg Position x, y; 1462eaef79e5Smrg char *tmp_data; 1463eaef79e5Smrg XPoint tmp_hot; 1464eaef79e5Smrg BWArea tmp_mark; 1465cbc4e2beSmrg 1466eaef79e5Smrg tmp_data = BW->bitmap.image->data; 1467eaef79e5Smrg BW->bitmap.image->data = BW->bitmap.buffer->data; 1468eaef79e5Smrg BW->bitmap.buffer->data = tmp_data; 1469eaef79e5Smrg 1470eaef79e5Smrg tmp_hot = BW->bitmap.hot; 1471eaef79e5Smrg tmp_mark = BW->bitmap.mark; 1472cbc4e2beSmrg 1473eaef79e5Smrg for (x = 0; x < BW->bitmap.image->width; x++) 1474eaef79e5Smrg for (y = 0; y < BW->bitmap.image->height; y++) 1475eaef79e5Smrg if (GetBit(BW->bitmap.image, x, y) != GetBit(BW->bitmap.buffer, x, y)) 1476eaef79e5Smrg DrawSquare(BW, x, y); 1477eaef79e5Smrg 1478eaef79e5Smrg BWSetHotSpot(w, BW->bitmap.buffer_hot.x, BW->bitmap.buffer_hot.y); 1479cbc4e2beSmrg/* 1480eaef79e5Smrg BWMark(w, BW->bitmap.buffer_mark.from_x, BW->bitmap.buffer_mark.from_y, 1481eaef79e5Smrg BW->bitmap.buffer_mark.to_x, BW->bitmap.buffer_mark.to_y); 1482eaef79e5Smrg*/ 1483eaef79e5Smrg BW->bitmap.buffer_hot = tmp_hot; 1484eaef79e5Smrg BW->bitmap.buffer_mark= tmp_mark; 1485eaef79e5Smrg 1486eaef79e5Smrg} 1487eaef79e5Smrg 1488cbc4e2beSmrgvoid 1489eaef79e5SmrgBWHighlightAxes(Widget w) 1490eaef79e5Smrg{ 1491eaef79e5Smrg BitmapWidget BW = (BitmapWidget) w; 1492eaef79e5Smrg 1493eaef79e5Smrg XDrawLine(XtDisplay(BW), XtWindow(BW), 1494eaef79e5Smrg BW->bitmap.axes_gc, 1495cbc4e2beSmrg InWindowX(BW, 0), 1496eaef79e5Smrg InWindowY(BW, 0), 1497eaef79e5Smrg InWindowX(BW, BW->bitmap.width), 1498eaef79e5Smrg InWindowY(BW, BW->bitmap.height)); 1499eaef79e5Smrg XDrawLine(XtDisplay(BW), XtWindow(BW), 1500eaef79e5Smrg BW->bitmap.axes_gc, 1501eaef79e5Smrg InWindowX(BW, BW->bitmap.width), 1502cbc4e2beSmrg InWindowY(BW, 0), 1503eaef79e5Smrg InWindowX(BW, 0), 1504eaef79e5Smrg InWindowY(BW, BW->bitmap.height)); 1505eaef79e5Smrg XDrawLine(XtDisplay(BW), XtWindow(BW), 1506eaef79e5Smrg BW->bitmap.axes_gc, 1507eaef79e5Smrg InWindowX(BW, 0), 1508eaef79e5Smrg InWindowY(BW, (float)BW->bitmap.height / 2.0), 1509eaef79e5Smrg InWindowX(BW, BW->bitmap.width), 1510eaef79e5Smrg InWindowY(BW, (float)BW->bitmap.height / 2.0)); 1511eaef79e5Smrg XDrawLine(XtDisplay(BW), XtWindow(BW), 1512eaef79e5Smrg BW->bitmap.axes_gc, 1513eaef79e5Smrg InWindowX(BW, (float)BW->bitmap.width / 2.0), 1514eaef79e5Smrg InWindowY(BW, 0), 1515eaef79e5Smrg InWindowX(BW, (float)BW->bitmap.width / 2.0), 1516eaef79e5Smrg InWindowY(BW, BW->bitmap.height)); 1517eaef79e5Smrg} 1518cbc4e2beSmrg 1519eaef79e5Smrgtypedef struct { 1520eaef79e5Smrg Position *x, *y; 1521eaef79e5Smrg Dimension *width, *height; 1522eaef79e5Smrg} Table; 1523eaef79e5Smrg 1524eaef79e5SmrgXImage * 1525cbc4e2beSmrgScaleBitmapImage(BitmapWidget BW, XImage *src, 1526eaef79e5Smrg double scale_x, double scale_y) 1527eaef79e5Smrg{ 1528eaef79e5Smrg char *data; 1529eaef79e5Smrg XImage *dst; 1530cbc4e2beSmrg Table table; 1531eaef79e5Smrg Position x, y, w, h; 1532eaef79e5Smrg Dimension width, height; 1533eaef79e5Smrg bit pixel; 1534eaef79e5Smrg 1535eaef79e5Smrg width = max(rint(scale_x * src->width), 1); 1536eaef79e5Smrg height = max(rint(scale_y * src->height), 1); 1537eaef79e5Smrg 1538eaef79e5Smrg data = CreateCleanData(Length(width, height)); 1539eaef79e5Smrg dst = CreateBitmapImage(BW, data, width, height); 1540eaef79e5Smrg 1541eaef79e5Smrg /* 1542eaef79e5Smrg * It would be nice to check if width or height < 1.0 and 1543eaef79e5Smrg * average the skipped pixels. But, it is slow as it is now. 1544eaef79e5Smrg */ 1545eaef79e5Smrg if (scale_x == 1.0 && scale_y == 1.0) 1546eaef79e5Smrg memmove( dst->data, src->data, Length(width, height)); 1547eaef79e5Smrg else { 1548eaef79e5Smrg table.x = (Position *) XtMalloc(sizeof(Position) * src->width); 1549eaef79e5Smrg table.y = (Position *) XtMalloc(sizeof(Position) * src->height); 1550eaef79e5Smrg table.width = (Dimension *) XtMalloc(sizeof(Dimension) * src->width); 1551eaef79e5Smrg table.height = (Dimension *) XtMalloc(sizeof(Dimension) * src->height); 1552cbc4e2beSmrg 1553eaef79e5Smrg for (x = 0; x < src->width; x++) { 1554eaef79e5Smrg table.x[x] = rint(scale_x * x); 1555eaef79e5Smrg table.width[x] = rint(scale_x * (x + 1)) - rint(scale_x * x); 1556eaef79e5Smrg } 1557eaef79e5Smrg for (y = 0; y < src->height; y++) { 1558eaef79e5Smrg table.y[y] = rint(scale_y * y); 1559eaef79e5Smrg table.height[y] = rint(scale_y * (y + 1)) - rint(scale_y * y); 1560eaef79e5Smrg } 1561cbc4e2beSmrg 1562eaef79e5Smrg for (x = 0; x < src->width; x++) 1563eaef79e5Smrg for (y = 0; y < src->height; y++) { 1564eaef79e5Smrg pixel = GetBit(src, x, y); 1565eaef79e5Smrg for (w = 0; (int)w < (int)table.width[x]; w++) 1566eaef79e5Smrg for (h = 0; (int)h < (int)table.height[y]; h++) 1567cbc4e2beSmrg if (pixel) SetBit(dst, 1568cbc4e2beSmrg table.x[x] + w, 1569eaef79e5Smrg table.y[y] + h); 1570eaef79e5Smrg } 1571eaef79e5Smrg 1572eaef79e5Smrg XtFree((char *)table.x); 1573eaef79e5Smrg XtFree((char *)table.y); 1574eaef79e5Smrg XtFree((char *)table.width); 1575eaef79e5Smrg XtFree((char *)table.height); 1576eaef79e5Smrg } 1577cbc4e2beSmrg 1578eaef79e5Smrg return (dst); 1579eaef79e5Smrg} 1580eaef79e5Smrg 1581eaef79e5Smrg/*****************************************************************************/ 1582