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