4 * This module implements simple window commands for the BLT toolkit.
6 * Copyright 1991-1998 Lucent Technologies, Inc.
8 * Permission to use, copy, modify, and distribute this software and
9 * its documentation for any purpose and without fee is hereby
10 * granted, provided that the above copyright notice appear in all
11 * copies and that both that the copyright notice and warranty
12 * disclaimer appear in supporting documentation, and that the names
13 * of Lucent Technologies any of their entities not be used in
14 * advertising or publicity pertaining to distribution of the software
15 * without specific, written prior permission.
17 * Lucent Technologies disclaims all warranties with regard to this
18 * software, including all implied warranties of merchantability and
19 * fitness. In no event shall Lucent Technologies be liable for any
20 * special, indirect or consequential damages or any damages
21 * whatsoever resulting from loss of use, data or profits, whether in
22 * an action of contract, negligence or other tortuous action, arising
23 * out of or in connection with the use or performance of this
32 #include <X11/Xutil.h>
34 #include <X11/Xproto.h>
37 static Tcl_CmdProc WinopCmd;
40 GetRealizedWindow(interp, string, tkwinPtr)
47 tkwin = Tk_NameToWindow(interp, string, Tk_MainWindow(interp));
51 if (Tk_WindowId(tkwin) == None) {
52 Tk_MakeWindowExist(tkwin);
59 StringToWindow(interp, string)
65 if (string[0] == '.') {
68 if (GetRealizedWindow(interp, string, &tkwin) != TCL_OK) {
71 if (Tk_IsTopLevel(tkwin)) {
72 return Blt_GetRealWindowId(tkwin);
74 return Tk_WindowId(tkwin);
76 } else if (Tcl_GetInt(interp, string, &xid) == TCL_OK) {
78 static TkWinWindow tkWinWindow;
80 tkWinWindow.handle = (HWND)xid;
81 tkWinWindow.winPtr = NULL;
82 tkWinWindow.type = TWD_WINDOW;
83 return (Window)&tkWinWindow;
102 TkWinWindow *winPtr = (TkWinWindow *)window;
104 result = GetWindowRect(winPtr->handle, ®ion);
106 *widthPtr = region.right - region.left;
107 *heightPtr = region.bottom - region.top;
116 *----------------------------------------------------------------------
118 * XGeometryErrorProc --
120 * Flags errors generated from XGetGeometry calls to the X server.
126 * Sets a flag, indicating an error occurred.
128 *----------------------------------------------------------------------
132 XGeometryErrorProc(clientData, errEventPtr)
133 ClientData clientData;
134 XErrorEvent *errEventPtr;
136 int *errorPtr = clientData;
138 *errorPtr = TCL_ERROR;
143 GetWindowSize(interp, window, widthPtr, heightPtr)
146 int *widthPtr, *heightPtr;
150 int x, y, borderWidth, depth;
152 Tk_ErrorHandler handler;
155 tkwin = Tk_MainWindow(interp);
156 handler = Tk_CreateErrorHandler(Tk_Display(tkwin), any, X_GetGeometry,
157 any, XGeometryErrorProc, &result);
158 result = XGetGeometry(Tk_Display(tkwin), window, &root, &x, &y,
159 (unsigned int *)widthPtr, (unsigned int *)heightPtr,
160 (unsigned int *)&borderWidth, (unsigned int *)&depth);
161 Tk_DeleteErrorHandler(handler);
162 XSync(Tk_Display(tkwin), False);
174 ColormapOp(clientData, interp, argc, argv)
175 ClientData clientData;
177 int argc; /* Not used. */
182 #define MAXCOLORS 256
183 register XColor *colorPtr;
184 XColor colorArr[MAXCOLORS];
185 unsigned long int pixelValues[MAXCOLORS];
186 int inUse[MAXCOLORS];
188 unsigned long int *indexPtr;
191 if (GetRealizedWindow(interp, argv[2], &tkwin) != TCL_OK) {
194 /* Initially, we assume all color cells are allocated. */
195 memset((char *)inUse, 0, sizeof(int) * MAXCOLORS);
198 * Start allocating color cells. This will tell us which color cells
199 * haven't already been allocated in the colormap. We'll release the
200 * cells as soon as we find out how many there are.
203 for (indexPtr = pixelValues, i = 0; i < MAXCOLORS; i++, indexPtr++) {
204 if (!XAllocColorCells(Tk_Display(tkwin), Tk_Colormap(tkwin),
205 False, NULL, 0, indexPtr, 1)) {
208 inUse[*indexPtr] = TRUE;/* Indicate the cell is unallocated */
211 XFreeColors(Tk_Display(tkwin), Tk_Colormap(tkwin), pixelValues, nFree, 0);
212 for (colorPtr = colorArr, i = 0; i < MAXCOLORS; i++, colorPtr++) {
215 XQueryColors(Tk_Display(tkwin), Tk_Colormap(tkwin), colorArr, MAXCOLORS);
216 for (colorPtr = colorArr, i = 0; i < MAXCOLORS; i++, colorPtr++) {
217 if (!inUse[colorPtr->pixel]) {
218 sprintf(string, "#%02x%02x%02x", (colorPtr->red >> 8),
219 (colorPtr->green >> 8), (colorPtr->blue >> 8));
220 Tcl_AppendElement(interp, string);
221 sprintf(string, "%ld", colorPtr->pixel);
222 Tcl_AppendElement(interp, string);
232 LowerOp(clientData, interp, argc, argv)
233 ClientData clientData;
235 int argc; /* Not used. */
242 display = Tk_Display(Tk_MainWindow(interp));
243 for (i = 2; i < argc; i++) {
244 window = StringToWindow(interp, argv[i]);
245 if (window == None) {
248 XLowerWindow(display, window);
255 RaiseOp(clientData, interp, argc, argv)
256 ClientData clientData;
258 int argc; /* Not used. */
265 display = Tk_Display(Tk_MainWindow(interp));
266 for (i = 2; i < argc; i++) {
267 window = StringToWindow(interp, argv[i]);
268 if (window == None) {
271 XRaiseWindow(display, window);
278 MapOp(clientData, interp, argc, argv)
279 ClientData clientData;
281 int argc; /* Not used. */
288 display = Tk_Display(Tk_MainWindow(interp));
289 for (i = 2; i < argc; i++) {
290 if (argv[i][0] == '.') {
294 if (GetRealizedWindow(interp, argv[i], &tkwin) != TCL_OK) {
297 fakePtr = (Tk_FakeWin *) tkwin;
298 fakePtr->flags |= TK_MAPPED;
299 window = Tk_WindowId(tkwin);
303 if (Tcl_GetInt(interp, argv[i], &xid) != TCL_OK) {
306 window = (Window)xid;
308 XMapWindow(display, window);
315 MoveOp(clientData, interp, argc, argv)
316 ClientData clientData;
318 int argc; /* Not Used. */
326 tkwin = Tk_MainWindow(interp);
327 display = Tk_Display(tkwin);
328 window = StringToWindow(interp, argv[2]);
329 if (window == None) {
332 if (Tk_GetPixels(interp, tkwin, argv[3], &x) != TCL_OK) {
333 Tcl_AppendResult(interp, ": bad window x-coordinate", (char *)NULL);
336 if (Tk_GetPixels(interp, tkwin, argv[4], &y) != TCL_OK) {
337 Tcl_AppendResult(interp, ": bad window y-coordinate", (char *)NULL);
340 XMoveWindow(display, window, x, y);
346 UnmapOp(clientData, interp, argc, argv)
347 ClientData clientData;
349 int argc; /* Not used. */
356 display = Tk_Display(Tk_MainWindow(interp));
357 for (i = 2; i < argc; i++) {
358 if (argv[i][0] == '.') {
362 if (GetRealizedWindow(interp, argv[i], &tkwin) != TCL_OK) {
365 fakePtr = (Tk_FakeWin *) tkwin;
366 fakePtr->flags &= ~TK_MAPPED;
367 window = Tk_WindowId(tkwin);
371 if (Tcl_GetInt(interp, argv[i], &xid) != TCL_OK) {
374 window = (Window)xid;
376 XMapWindow(display, window);
383 ChangesOp(clientData, interp, argc, argv)
384 ClientData clientData;
386 int argc; /* Not used. */
387 char **argv; /* Not used. */
391 if (GetRealizedWindow(interp, argv[2], &tkwin) != TCL_OK) {
394 if (Tk_IsTopLevel(tkwin)) {
395 XSetWindowAttributes attrs;
399 window = Blt_GetRealWindowId(tkwin);
400 attrs.backing_store = WhenMapped;
401 attrs.save_under = True;
402 mask = CWBackingStore | CWSaveUnder;
403 XChangeWindowAttributes(Tk_Display(tkwin), window, mask, &attrs);
410 ParentOp(clientData, interp, argc, argv)
411 ClientData clientData;
413 int argc; /* Not used. */
414 char **argv; /* Not used. */
420 if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) {
423 window = Blt_GetParent(Tk_Display(Tk_MainWindow(interp)), (Window)value);
425 sprintf(buf, "0x%x", (int)window);
426 Tcl_AppendResult(interp, buf, 0);
433 QueryOp(clientData, interp, argc, argv)
434 ClientData clientData;
436 int argc; /* Not used. */
437 char **argv; /* Not used. */
439 int rootX, rootY, childX, childY;
442 Tk_Window tkwin = (Tk_Window)clientData;
445 if (XQueryPointer(Tk_Display(tkwin), Tk_WindowId(tkwin), &root,
446 &child, &rootX, &rootY, &childX, &childY, &mask)) {
449 sprintf(string, "@%d,%d", rootX, rootY);
450 Tcl_SetResult(interp, string, TCL_VOLATILE);
457 WarpToOp(clientData, interp, argc, argv)
458 ClientData clientData;
460 int argc; /* Not used. */
463 Tk_Window tkwin, mainWindow;
465 mainWindow = (Tk_Window)clientData;
467 if (argv[2][0] == '@') {
471 if (Blt_GetXY(interp, mainWindow, argv[2], &x, &y) != TCL_OK) {
474 root = RootWindow(Tk_Display(mainWindow),
475 Tk_ScreenNumber(mainWindow));
476 XWarpPointer(Tk_Display(mainWindow), None, root, 0, 0, 0, 0, x, y);
478 if (GetRealizedWindow(interp, argv[2], &tkwin) != TCL_OK) {
481 if (!Tk_IsMapped(tkwin)) {
482 Tcl_AppendResult(interp, "can't warp to unmapped window \"",
483 Tk_PathName(tkwin), "\"", (char *)NULL);
486 XWarpPointer(Tk_Display(tkwin), None, Tk_WindowId(tkwin),
487 0, 0, 0, 0, Tk_Width(tkwin) / 2, Tk_Height(tkwin) / 2);
490 return QueryOp(clientData, interp, 0, (char **)NULL);
495 ReparentOp(clientData, interp, argc, argv)
496 ClientData clientData;
503 if (GetRealizedWindow(interp, argv[2], &tkwin) != TCL_OK) {
509 if (GetRealizedWindow(interp, argv[3], &newParent) != TCL_OK) {
512 Blt_RelinkWindow2(tkwin, Blt_GetRealWindowId(tkwin), newParent, 0, 0);
514 Blt_UnlinkWindow(tkwin);
522 * This is a temporary home for these image routines. They will be
523 * moved when a new image type is created for them.
527 ConvolveOp(clientData, interp, argc, argv)
528 ClientData clientData; /* Not used. */
530 int argc; /* Not used. */
533 Tk_PhotoHandle srcPhoto, destPhoto;
534 Blt_ColorImage srcImage, destImage;
542 int result = TCL_ERROR;
544 srcPhoto = Blt_FindPhoto(interp, argv[2]);
545 if (srcPhoto == NULL) {
546 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
547 " exist or is not a photo image", (char *)NULL);
550 destPhoto = Blt_FindPhoto(interp, argv[3]);
551 if (destPhoto == NULL) {
552 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
553 " exist or is not a photo image", (char *)NULL);
556 if (Tcl_SplitList(interp, argv[4], &nValues, &valueArr) != TCL_OK) {
561 Tcl_AppendResult(interp, "empty kernel", (char *)NULL);
564 dim = (int)sqrt((double)nValues);
565 if ((dim * dim) != nValues) {
566 Tcl_AppendResult(interp, "kernel must be square", (char *)NULL);
569 kernel = Blt_Malloc(sizeof(double) * nValues);
571 for (i = 0; i < nValues; i++) {
572 if (Tcl_GetDouble(interp, valueArr[i], &value) != TCL_OK) {
578 filter.kernel = kernel;
579 filter.support = dim * 0.5;
580 filter.sum = (sum == 0.0) ? 1.0 : sum;
581 filter.scale = 1.0 / nValues;
583 srcImage = Blt_PhotoToColorImage(srcPhoto);
584 destImage = Blt_ConvolveColorImage(srcImage, &filter);
585 Blt_FreeColorImage(srcImage);
586 Blt_ColorImageToPhoto(destImage, destPhoto);
587 Blt_FreeColorImage(destImage);
590 if (valueArr != NULL) {
593 if (kernel != NULL) {
601 QuantizeOp(clientData, interp, argc, argv)
602 ClientData clientData; /* Not used. */
604 int argc; /* Not used. */
607 Tk_PhotoHandle srcPhoto, destPhoto;
608 Tk_PhotoImageBlock src, dest;
609 Blt_ColorImage srcImage, destImage;
613 srcPhoto = Blt_FindPhoto(interp, argv[2]);
614 if (srcPhoto == NULL) {
615 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
616 " exist or is not a photo image", (char *)NULL);
619 Tk_PhotoGetImage(srcPhoto, &src);
620 if ((src.width <= 1) || (src.height <= 1)) {
621 Tcl_AppendResult(interp, "source image \"", argv[2], "\" is empty",
625 destPhoto = Blt_FindPhoto(interp, argv[3]);
626 if (destPhoto == NULL) {
627 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
628 " exist or is not a photo image", (char *)NULL);
631 Tk_PhotoGetImage(destPhoto, &dest);
632 if ((dest.width != src.width) || (dest.height != src.height)) {
633 Tk_PhotoSetSize(destPhoto, src.width, src.height);
636 if (Tcl_GetInt(interp, argv[4], &nColors) != TCL_OK) {
640 srcImage = Blt_PhotoToColorImage(srcPhoto);
641 destImage = Blt_PhotoToColorImage(destPhoto);
642 result = Blt_QuantizeColorImage(srcImage, destImage, nColors);
643 if (result == TCL_OK) {
644 Blt_ColorImageToPhoto(destImage, destPhoto);
646 Blt_FreeColorImage(srcImage);
647 Blt_FreeColorImage(destImage);
652 GetColorPix32(Tcl_Interp *interp, Tk_Window tkwin, char *color, Pix32 *colPtr) {
654 int red, green, blue;
657 if (*color == '#' && strlen(color) == 7 && 3 ==
658 sscanf(color+1, "%02x%02x%02x", &red, &green, &blue)) {
660 colPtr->Green = green;
664 xCol = Tk_GetColor(interp, tkwin, Tk_GetUid(color));
668 colPtr->Red = (xCol->red >> 8);
669 colPtr->Green = (xCol->green >> 8);
670 colPtr->Blue = (xCol->blue >> 8);
675 XColorToPix32(XColor *xCol, Pix32 *colPtr) {
678 colPtr->Red = (xCol->red >> 8);
679 colPtr->Green = (xCol->green >> 8);
680 colPtr->Blue = (xCol->blue >> 8);
686 AlphaOp(clientData, interp, argc, argv)
687 ClientData clientData; /* Not used. */
689 int argc; /* Not used. */
692 Tk_PhotoHandle srcPhoto, destPhoto;
693 Tk_PhotoImageBlock src, dest;
694 Blt_ColorImage srcImage, destImage;
695 int result, alpha, anycolor = 0, withAlpha, hasWith = 0;
696 Tk_Window tkwin = (Tk_Window)clientData;
699 int negate = 0, shift = 0;
702 if (!strcmp("-shift", argv[2])) {
708 srcPhoto = Blt_FindPhoto(interp, argv[2]);
709 if (srcPhoto == NULL) {
710 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
711 " exist or is not a photo image", (char *)NULL);
714 Tk_PhotoGetImage(srcPhoto, &src);
715 if ((src.width <= 1) || (src.height <= 1)) {
716 Tcl_AppendResult(interp, "source image \"", argv[2], "\" is empty",
720 destPhoto = Blt_FindPhoto(interp, argv[3]);
721 if (destPhoto == NULL) {
722 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
723 " exist or is not a photo image", (char *)NULL);
726 Tk_PhotoGetImage(destPhoto, &dest);
727 if (0 && srcPhoto == destPhoto) {
728 Tcl_AppendResult(interp, "src and dest images must be different",
733 if (string[0] == '!') {
737 if (!strcmp(string, "*")) {
740 Tcl_AppendResult(interp, "must give an alpha", 0);
745 if (GetColorPix32(interp, tkwin, string, &oldColor) != TCL_OK) {
750 if (Tcl_GetInt(interp, argv[5], &alpha) != TCL_OK) {
753 if (alpha<0 || alpha > 255) {
754 Tcl_AppendResult(interp, "alpha must be >= 0 and <= 255", argv[3],
760 if (Tcl_GetInt(interp, argv[6], &withAlpha) != TCL_OK) {
764 if (withAlpha<0 || withAlpha > 255) {
765 Tcl_AppendResult(interp, "withalpha must be >= 0 and <= 255", argv[3],
770 if ((dest.width != src.width) || (dest.height != src.height)) {
771 Tk_PhotoSetSize(destPhoto, src.width, src.height);
773 srcImage = Blt_PhotoToColorImage(srcPhoto);
774 destImage = Blt_PhotoToColorImage(destPhoto);
779 Pix32 *srcPtr, *destPtr, *endPtr, *color;
780 unsigned char origAlpha;
782 width = Blt_ColorImageWidth(srcImage);
783 height = Blt_ColorImageHeight(srcImage);
784 count = width * height;
787 srcPtr = Blt_ColorImageBits(srcImage);
788 destPtr = Blt_ColorImageBits(destImage);
790 for (endPtr = destPtr + count; destPtr < endPtr; srcPtr++, destPtr++) {
791 origAlpha = srcPtr->Alpha;
792 if (origAlpha == 0) {
793 destPtr->value = srcPtr->value;
796 destPtr->value = color->value;
797 destPtr->Alpha = srcPtr->Blue;
799 } else if (!anycolor) {
801 for (endPtr = destPtr + count; destPtr < endPtr; srcPtr++, destPtr++) {
802 origAlpha = srcPtr->Alpha;
803 destPtr->value = srcPtr->value;
804 same = (srcPtr->Red == color->Red && srcPtr->Green == color->Green &&
805 srcPtr->Blue == color->Blue);
806 if (hasWith && origAlpha != withAlpha) {
809 if ((!same) && (origAlpha != (unsigned char)-1)) {
817 destPtr->Alpha = origAlpha;
820 for (endPtr = destPtr + count; destPtr < endPtr; srcPtr++, destPtr++) {
821 origAlpha = srcPtr->Alpha;
822 destPtr->value = srcPtr->value;
823 if (hasWith && origAlpha == withAlpha) {
824 destPtr->Alpha = alpha;
825 } else if (origAlpha == (unsigned char)-1) {
826 destPtr->Alpha = alpha;
832 if (result == TCL_OK) {
833 Blt_ColorImageToPhoto(destImage, destPhoto);
835 Blt_FreeColorImage(srcImage);
836 Blt_FreeColorImage(destImage);
842 RecolorOp(clientData, interp, argc, argv)
843 ClientData clientData; /* Not used. */
845 int argc; /* Not used. */
848 Tk_PhotoHandle srcPhoto, destPhoto;
849 Tk_PhotoImageBlock src, dest;
850 Blt_ColorImage srcImage, destImage;
852 Tk_Window tkwin = (Tk_Window)clientData;
853 Pix32 oldColor, newColor;
856 srcPhoto = Blt_FindPhoto(interp, argv[2]);
857 if (srcPhoto == NULL) {
858 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
859 " exist or is not a photo image", (char *)NULL);
862 Tk_PhotoGetImage(srcPhoto, &src);
863 if ((src.width <= 1) || (src.height <= 1)) {
864 Tcl_AppendResult(interp, "source image \"", argv[2], "\" is empty",
868 destPhoto = Blt_FindPhoto(interp, argv[3]);
869 if (destPhoto == NULL) {
870 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
871 " exist or is not a photo image", (char *)NULL);
874 Tk_PhotoGetImage(destPhoto, &dest);
875 if (GetColorPix32(interp, tkwin, argv[4], &oldColor) != TCL_OK) {
878 if (GetColorPix32(interp, tkwin, argv[5], &newColor) != TCL_OK) {
882 if (Tcl_GetInt(interp, argv[6], &alpha) != TCL_OK) {
885 if (alpha<0 || alpha > 255) {
886 Tcl_AppendResult(interp, "alpha must be >= 0 and <= 255", argv[3],
891 if ((dest.width != src.width) || (dest.height != src.height)) {
892 Tk_PhotoSetSize(destPhoto, src.width, src.height);
894 srcImage = Blt_PhotoToColorImage(srcPhoto);
895 destImage = Blt_PhotoToColorImage(destPhoto);
896 result = Blt_RecolorImage(srcImage, destImage, &oldColor, &newColor, alpha);
897 if (result == TCL_OK) {
898 Blt_ColorImageToPhoto(destImage, destPhoto);
900 Blt_FreeColorImage(srcImage);
901 Blt_FreeColorImage(destImage);
907 ColorsOp(clientData, interp, argc, argv)
908 ClientData clientData; /* Not used. */
910 int argc; /* Not used. */
913 Tk_PhotoHandle srcPhoto;
914 Tk_PhotoImageBlock src;
915 Blt_ColorImage srcImage;
916 int top, x, y, isalph, iscnt, isNew, cnt;
917 int i, rng[4], from = 0;
918 register Pix32 *srcPtr;
923 Blt_HashSearch cursor;
929 if (!strcmp(argv[2], "-alpha")) {
931 } else if (!strcmp(argv[2], "-from")) {
934 Tcl_AppendResult(interp, "expected 4 args: x1 y1 x2 y2", (char *)NULL);
937 for (i=0; i<4; i++) {
938 if (Tcl_GetInt(interp, argv[i+3], rng+i)) {
944 } else if (!strcmp(argv[2], "-count")) {
947 Tcl_AppendResult(interp, "expected -from, -alpha or -count", (char *)NULL);
954 Tcl_AppendResult(interp, "too few arguments", (char *)NULL);
957 srcPhoto = Blt_FindPhoto(interp, argv[2]);
958 if (srcPhoto == NULL) {
959 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
960 " exist or is not a photo image", (char *)NULL);
963 Tk_PhotoGetImage(srcPhoto, &src);
964 if ((src.width < 1) || (src.height < 1)) {
967 srcImage = Blt_PhotoToColorImage(srcPhoto);
968 srcPtr = Blt_ColorImageBits(srcImage);
970 Blt_InitHashTable(&hTbl, BLT_STRING_KEYS);
971 for (y = 0; y < src.height; y++) {
972 if (from && (y < rng[1] || y > rng[3])) continue;
973 for (x = 0; x < src.width; x++) {
974 if (from && (x < rng[0] || x > rng[2])) continue;
976 sprintf(buf, "#%02x%02x%02x", srcPtr->Red, srcPtr->Green, srcPtr->Blue);
978 sprintf(buf, "#%02x%02x%02x:%02x", srcPtr->Red, srcPtr->Green, srcPtr->Blue, srcPtr->Alpha);
980 hPtr = Blt_CreateHashEntry(&hTbl, buf, &isNew);
982 Blt_SetHashValue(hPtr, 1);
984 cnt = (int)Blt_GetHashValue(hPtr);
986 Blt_SetHashValue(hPtr, cnt);
991 listPtr = Tcl_NewListObj(0,0);
992 for (hPtr = Blt_FirstHashEntry(&hTbl, &cursor);
993 hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
995 Tcl_Obj *objPtr = Tcl_NewStringObj(Blt_GetHashKey(&hTbl, hPtr), -1);
996 Tcl_ListObjAppendElement(interp, listPtr, objPtr);
998 cnt = (int)Blt_GetHashValue(hPtr);
999 sprintf(buf, "%d", cnt);
1000 objPtr = Tcl_NewStringObj(buf, -1);
1001 Tcl_ListObjAppendElement(interp, listPtr, objPtr);
1004 Tcl_SetObjResult(interp, listPtr);
1005 Blt_DeleteHashTable(&hTbl);
1011 TransOp(clientData, interp, argc, argv)
1012 ClientData clientData; /* Not used. */
1014 int argc; /* Not used. */
1017 Tk_PhotoHandle srcPhoto;
1018 Tk_PhotoImageBlock src;
1019 Blt_ColorImage srcImage;
1020 int x, y, alpha,isSet = 0;
1021 register Pix32 *srcPtr;
1026 if (Tcl_GetInt(interp, argv[5], &alpha) != TCL_OK) {
1029 if (alpha<0 || alpha > 255) {
1030 Tcl_AppendResult(interp, "alpha must be >= 0 and <= 255", argv[3],
1035 if (Tcl_GetInt(interp, argv[3], &x) != TCL_OK) {
1038 if (Tcl_GetInt(interp, argv[4], &y) != TCL_OK) {
1041 srcPhoto = Blt_FindPhoto(interp, argv[2]);
1042 if (srcPhoto == NULL) {
1043 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
1044 " exist or is not a photo image", (char *)NULL);
1047 Tk_PhotoGetImage(srcPhoto, &src);
1048 if ((src.width < 1) || (src.height < 1)) {
1049 Tcl_AppendResult(interp, "empty image", (char *)NULL);
1052 srcImage = Blt_PhotoToColorImage(srcPhoto);
1053 srcPtr = Blt_ColorImageBits(srcImage);
1054 if (y < 0 || y >= src.height || x < 0 || x >= src.width) {
1055 Tcl_AppendResult(interp, "out of range", (char *)NULL);
1058 srcPtr = srcPtr + y*src.width + x;
1060 srcPtr->Alpha = alpha;
1061 Blt_ColorImageToPhoto(srcImage, srcPhoto);
1063 sprintf(buf, "%d", srcPtr->Alpha);
1064 Tcl_AppendResult(interp, buf, 0);
1069 #define PD_SRC_OVER(srcColor,srcAlpha,dstColor,dstAlpha) \
1070 (srcColor*srcAlpha/255) + dstAlpha*(255-srcAlpha)/255*dstColor/255
1071 #define PD_SRC_OVER_ALPHA(srcAlpha,dstAlpha) \
1072 (srcAlpha + (255-srcAlpha)*dstAlpha/255)
1076 Pix32 *srcPtr, Pix32 *src2Ptr, Pix32 *destPtr,
1077 unsigned char alpha, unsigned char dAlpha
1080 destPtr->Red = PD_SRC_OVER(srcPtr->Red, alpha, src2Ptr->Red, dAlpha);
1081 destPtr->Green = PD_SRC_OVER(srcPtr->Green, alpha, src2Ptr->Green, dAlpha);
1082 destPtr->Blue = PD_SRC_OVER(srcPtr->Blue, alpha, src2Ptr->Blue, dAlpha);
1083 destPtr->Alpha = 255; /* PD_SRC_OVER_ALPHA(alpha, dAlpha); */
1087 void PixMerged( Pix32 *srcPtr, Pix32 *src2Ptr, Pix32 *destPtr, Pix32 *colorPtr) {
1088 unsigned char alpha;
1091 alpha = srcPtr->Blue;
1092 isdead = (srcPtr->Red == 0xde && srcPtr->Green == 0xad);
1093 if (alpha == 0 && isdead) { /* "," inner fill */
1094 destPtr->value = src2Ptr->value;
1095 } else if (alpha == 0) { /* "." none or transparent */
1097 } else if (isdead == 0) { /* solid color with alpha */
1098 destPtr->value = colorPtr->value;
1099 destPtr->Alpha = alpha;
1100 } else { /* Blend color with inner fill */
1101 PixBlend( colorPtr, src2Ptr, destPtr, alpha, src2Ptr->Alpha);
1106 /* For RGB grab alpha from blue and substitute maskcolor for RG="#DEAD"*/
1107 int Blt_ImageMergeInner(Tcl_Interp *interp, char *srcName, char *src2Name,
1108 char * destName, XColor *maskColor, int leaveMsg) {
1109 Tk_PhotoHandle srcPhoto, srcPhoto2, destPhoto;
1110 Tk_PhotoImageBlock src, src2, dest;
1111 Blt_ColorImage srcImage, srcImage2, destImage;
1120 srcPhoto = Blt_FindPhoto(interp, srcName);
1121 if (srcPhoto == NULL) {
1123 Tcl_AppendResult(interp, "source image \"", srcName, "\" doesn't",
1124 " exist or is not a photo image", (char *)NULL);
1127 Tk_PhotoGetImage(srcPhoto, &src);
1128 if ((src.width <= 1) || (src.height <= 1)) {
1130 Tcl_AppendResult(interp, "source image \"", srcName, "\" is empty",
1135 srcPhoto2 = Blt_FindPhoto(interp, src2Name);
1136 if (srcPhoto2 == NULL) {
1138 Tcl_AppendResult(interp, "source image \"", src2Name, "\" doesn't",
1139 " exist or is not a photo image", (char *)NULL);
1142 Tk_PhotoGetImage(srcPhoto2, &src2);
1143 if ((src2.width <= 1) || (src2.height <= 1)) {
1145 Tcl_AppendResult(interp, "source image \"", src2Name, "\" is empty",
1150 XColorToPix32(maskColor, &withColor);
1157 if (isdigit(argv[5][0]) == 0 && argv[5][0] != '.') {
1161 tkwin = Tk_MainWindow(interp);
1165 if (colStr[0] == '!') {
1172 if (src.width < 4 || src.height < 4) {
1173 Tcl_AppendResult(interp, "src image too small ", 0);
1176 if (src2.width < 4 || src2.height < 4) {
1177 Tcl_AppendResult(interp, "src2 image too small ", 0);
1180 if (dest.width < 4 || dest.height < 4) {
1181 Tcl_AppendResult(interp, "dest image too small ", 0);
1187 if (Tcl_GetDouble(interp, argv[5], &opacity) != TCL_OK) {
1190 if (opacity < 0.0 || opacity > 1.0) {
1191 Tcl_AppendResult(interp, "opacity must be >= 0.0 and <= 1.0: ", argv[5], (char *)NULL);
1196 if (Tcl_GetDouble(interp, argv[6], &opacity2) != TCL_OK) {
1199 if (opacity2 < 0.0 || opacity2 > 1.0) {
1200 Tcl_AppendResult(interp, "opacity must be >= 0.0 and <= 1.0: ", argv[6], (char *)NULL);
1205 if (isWc == 0 && ((src2.width != src.width) || (src2.height != src.height))) {
1207 sw = (src2.width>src.width?src2.width:src.width);
1208 sh = (src2.height>src.height?src2.height:src.height);
1209 Tk_PhotoSetSize(srcPhoto2, sw, sh);
1210 Tk_PhotoGetImage(srcPhoto2, &src2);
1211 if (sw != src.width || sh != src.height) {
1212 Tk_PhotoSetSize(srcPhoto, sw, sh);
1213 Tk_PhotoGetImage(srcPhoto, &src);
1218 destPhoto = Blt_FindPhoto(interp, destName);
1219 if (destPhoto == NULL) {
1221 Tcl_AppendResult(interp, "destination image \"", destName, "\" doesn't",
1222 " exist or is not a photo image", (char *)NULL);
1225 Tk_PhotoGetImage(destPhoto, &dest);
1227 if ((dest.width != src.width) || (dest.height != src.height)) {
1228 Tk_PhotoSetSize(destPhoto, src.width, src.height);
1230 srcImage = Blt_PhotoToColorImage(srcPhoto);
1231 srcImage2 = Blt_PhotoToColorImage(srcPhoto2);
1232 destImage = Blt_PhotoToColorImage(destPhoto);
1234 Tk_PhotoGetImage(destPhoto, &dest);
1235 if ((dest.width != src.width) || (dest.height != src.height)) {
1236 Tk_PhotoSetSize(destPhoto, src.width, src.height);
1237 destImage = Blt_PhotoToColorImage(destPhoto);
1240 result = Blt_MergeColorImage(srcImage, srcImage2, destImage, opacity, opacity2,
1241 isWc ? &withColor : NULL);
1243 int xs1, xs2, xd1, xd2, xsc, xdc;
1244 int ys1, ys2, yd1, yd2, ysc, ydc;
1245 Pix32 *srcPtr, *src2Ptr, *destPtr;
1247 srcPtr = Blt_ColorImageBits(srcImage);
1248 src2Ptr = Blt_ColorImageBits(srcImage2);
1249 destPtr = Blt_ColorImageBits(destImage);
1251 xsc = (src2.width/2);
1252 ysc = (src2.height/2);
1253 xdc = (dest.width/2);
1254 ydc = (dest.height/2);
1255 for (xs1 = xsc-1, xs2=xsc, xd1 = xdc-1, xd2=xd1+1;
1256 xd1>=0; xd1--, xs1--, xd2++, xs2++) {
1257 if (xs1<0) { xs1 = xsc-1; xs2 = xs1+1; }
1258 for (ys1 = ysc-1, ys2 = ysc, yd1 = ydc-1, yd2=yd1+1;
1259 yd1>=0; yd1--, ys1--, yd2++, ys2++) {
1260 if (ys1<0) { ys1 = ysc-1; ys2 = ys1+1; }
1262 #define DDDC_O(ind,ind2) if ( withColor.value == srcPtr[ind].value) destPtr[ind].value = src2Ptr[ind2].value
1263 #define DDDC(ind,ind2) PixMerged(srcPtr+(ind), src2Ptr+(ind2), destPtr+(ind), &withColor)
1265 DDDC(yd1*dest.width+xd1, ys1*src2.width+xs1);
1266 if (ys2>=src2.height) { ys2--; }
1267 if (xs2>=src2.width) { xs2--; }
1268 if (yd2<dest.height && xd2<dest.width) {
1269 DDDC(yd2*dest.width+xd2, ys2*src2.width+xs2);
1271 if (xd2<dest.width) {
1272 DDDC(yd1*dest.width+xd2, ys1*src2.width+xs2);
1274 if (yd2<dest.height) {
1275 DDDC(yd2*dest.width+xd1, ys2*src2.width+xs1);
1282 if (result == TCL_OK) {
1283 Blt_ColorImageToPhoto(destImage, destPhoto);
1285 Blt_FreeColorImage(srcImage);
1286 Blt_FreeColorImage(srcImage2);
1287 Blt_FreeColorImage(destImage);
1294 MergeOp(clientData, interp, argc, argv)
1295 ClientData clientData; /* Not used. */
1297 int argc; /* Not used. */
1300 Tk_PhotoHandle srcPhoto, srcPhoto2, destPhoto;
1301 Tk_PhotoImageBlock src, src2, dest;
1302 Blt_ColorImage srcImage, srcImage2, destImage;
1311 srcPhoto = Blt_FindPhoto(interp, argv[2]);
1312 if (srcPhoto == NULL) {
1313 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
1314 " exist or is not a photo image", (char *)NULL);
1317 Tk_PhotoGetImage(srcPhoto, &src);
1318 if ((src.width <= 1) || (src.height <= 1)) {
1319 Tcl_AppendResult(interp, "source image \"", argv[2], "\" is empty",
1324 srcPhoto2 = Blt_FindPhoto(interp, argv[3]);
1325 if (srcPhoto2 == NULL) {
1326 Tcl_AppendResult(interp, "source image \"", argv[3], "\" doesn't",
1327 " exist or is not a photo image", (char *)NULL);
1330 Tk_PhotoGetImage(srcPhoto2, &src2);
1331 if ((src2.width <= 1) || (src2.height <= 1)) {
1332 Tcl_AppendResult(interp, "source image \"", argv[3], "\" is empty",
1338 if (isdigit(argv[5][0]) == 0 && argv[5][0] != '.') {
1342 tkwin = Tk_MainWindow(interp);
1346 if (colStr[0] == '!') {
1351 if (GetColorPix32(interp, tkwin, colStr, &withColor) != TCL_OK) {
1354 if (src.width < 4 || src.height < 4) {
1355 Tcl_AppendResult(interp, "src image too small ", 0);
1358 if (src2.width < 4 || src2.height < 4) {
1359 Tcl_AppendResult(interp, "src2 image too small ", 0);
1365 if (Tcl_GetDouble(interp, argv[5], &opacity) != TCL_OK) {
1368 if (opacity < 0.0 || opacity > 1.0) {
1369 Tcl_AppendResult(interp, "opacity must be >= 0.0 and <= 1.0: ", argv[5], (char *)NULL);
1374 if (Tcl_GetDouble(interp, argv[6], &opacity2) != TCL_OK) {
1377 if (opacity2 < 0.0 || opacity2 > 1.0) {
1378 Tcl_AppendResult(interp, "opacity must be >= 0.0 and <= 1.0: ", argv[6], (char *)NULL);
1383 if (isWc == 0 && ((src2.width != src.width) || (src2.height != src.height))) {
1385 sw = (src2.width>src.width?src2.width:src.width);
1386 sh = (src2.height>src.height?src2.height:src.height);
1387 Tk_PhotoSetSize(srcPhoto2, sw, sh);
1388 Tk_PhotoGetImage(srcPhoto2, &src2);
1389 if (sw != src.width || sh != src.height) {
1390 Tk_PhotoSetSize(srcPhoto, sw, sh);
1391 Tk_PhotoGetImage(srcPhoto, &src);
1396 destPhoto = Blt_FindPhoto(interp, argv[4]);
1397 if (destPhoto == NULL) {
1398 Tcl_AppendResult(interp, "destination image \"", argv[4], "\" doesn't",
1399 " exist or is not a photo image", (char *)NULL);
1402 Tk_PhotoGetImage(destPhoto, &dest);
1404 srcImage = Blt_PhotoToColorImage(srcPhoto);
1405 srcImage2 = Blt_PhotoToColorImage(srcPhoto2);
1406 destImage = Blt_PhotoToColorImage(destPhoto);
1408 Tk_PhotoGetImage(destPhoto, &dest);
1409 if ((dest.width != src.width) || (dest.height != src.height)) {
1410 Tk_PhotoSetSize(destPhoto, src.width, src.height);
1411 destImage = Blt_PhotoToColorImage(destPhoto);
1414 result = Blt_MergeColorImage(srcImage, srcImage2, destImage, opacity, opacity2,
1415 isWc ? &withColor : NULL);
1417 int xs1, xs2, xd1, xd2, xsc, xdc;
1418 int ys1, ys2, yd1, yd2, ysc, ydc;
1419 Pix32 *srcPtr, *src2Ptr, *destPtr;
1421 srcPtr = Blt_ColorImageBits(srcImage);
1422 src2Ptr = Blt_ColorImageBits(srcImage2);
1423 destPtr = Blt_ColorImageBits(destImage);
1425 xsc = (src2.width/2);
1426 ysc = (src2.height/2);
1427 xdc = (dest.width/2);
1428 ydc = (dest.height/2);
1429 for (xs1 = xsc-1, xs2=xs1+1, xd1 = xdc-1, xd2=xdc;
1430 xd1>=0; xd1--, xs1--, xd2++, xs2++) {
1431 if (xs1<0) { xs1 = xsc-1; xs2 = xs1+1; }
1432 for (ys1 = ysc-1, ys2 = ys1+1, yd1 = ydc-1, yd2=yd1+1;
1433 yd1>=0; yd1--, ys1--, yd2++, ys2++) {
1434 if (ys1<0) { ys1 = ysc-1; ys2 = ys1+1; }
1436 #define DDC(ind,ind2) destPtr[ind].value = ( withColor.value == srcPtr[ind].value ? src2Ptr[ind2].value : srcPtr[ind].value)
1438 DDC(yd1*dest.width+xd1, ys1*src2.width+xs1);
1439 //destPtr[yd1*dest.width+xd1].value = srcPtr[ys1*src2.width+xs1].value;
1440 if (ys2>=src2.height) { ys2--; }
1441 if (xs2>=src2.width) { xs2--; }
1442 if (yd2<dest.height && xd2<dest.width)
1443 DDC(yd2*dest.width+xd2, ys2*src2.width+xs2);
1444 // destPtr[yd2*dest.width+xd2].value = srcPtr[ys2*src2.width+xs2].value;
1446 DDC(yd1*dest.width+xd2, ys1*src2.width+xs2);
1447 //destPtr[yd1*dest.width+xd2].value = srcPtr[ys1*src2.width+xs2].value;
1448 if (yd2<dest.height)
1449 DDC(yd2*dest.width+xd1, ys2*src2.width+xs1);
1450 //destPtr[yd2*dest.width+xd1].value = srcPtr[ys2*src2.width+xs1].value;
1451 //if (ya<src.height && ya2<dest.height && xa<src.width && xa2<dest.width) {}
1457 if (result == TCL_OK) {
1458 Blt_ColorImageToPhoto(destImage, destPhoto);
1460 Blt_FreeColorImage(srcImage);
1461 Blt_FreeColorImage(srcImage2);
1462 Blt_FreeColorImage(destImage);
1469 ReadJPEGOp(clientData, interp, argc, argv)
1470 ClientData clientData; /* Not used. */
1472 int argc; /* Not used. */
1477 Tcl_DString dString;
1479 Tk_PhotoHandle photo; /* The photo image to write into. */
1481 photo = Blt_FindPhoto(interp, argv[3]);
1482 if (photo == NULL) {
1483 Tcl_AppendResult(interp, "image \"", argv[3], "\" doesn't",
1484 " exist or is not a photo image", (char *)NULL);
1487 Tcl_DStringInit(&dString);
1488 fileName = Tcl_TranslateFileName(interp, argv[2], &dString);
1490 result = Blt_JPEGToPhoto(interp, fileName, photo);
1491 Tcl_DStringInit(&dString);
1494 Tcl_AppendResult(interp, "JPEG support not compiled", (char *)NULL);
1499 static double Drand( double val) {
1503 return (double)random()/RAND_MAX;
1507 #define SLANTX(x,y) (doslant==0 || slant == 0.0?x:(((int)(x + (y * slant)))%src.width))
1508 #define ARCX(x,y) (doarc==0 || sineVal == 0.0?x:(((int)(x + (src.width*sqrt(0.5*0.5-((double)y/src.height-0.5)*((double)y/src.height-0.5)) * sineVal)))%src.width))
1509 #define SINEX(x,y) (dosine==0 || sineVal == 0.0?x:(((int)(x + (src.width*(*tfunc)(M_PI *y/src.height) * sineVal)))%src.width))
1511 #define RANDX(c) (dorand==0 || randVal == 0.0?c:(c+(Drand(0) * randVal - (randVal/2.0))))
1515 #define SKEWX(c) ((doskew==0 || skew == 1.0)?c:(ox>=skew?1.0:c/skew))
1516 #define CLAMP(c) ((((c) < 0.0) ? 0.0 : ((c) > 1.0) ? 1.0 : (c)))
1519 GradientsOp(clientData, interp, argc, argv)
1520 ClientData clientData; /* Not used. */
1522 int argc; /* Not used. */
1530 XColor *leftPtr, *rightPtr;
1533 tkwin = Tk_MainWindow(interp);
1535 leftPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(argv[2]));
1536 if (leftPtr == NULL) {
1539 rightPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(argv[3]));
1540 if (rightPtr == NULL) {
1543 if (Tcl_GetInt(interp, argv[4], &width) != TCL_OK) {
1547 Tcl_AppendResult(interp, "width must be > 2", 0);
1550 left[0] = (double)(leftPtr->red >> 8);
1551 left[1] = (double)(leftPtr->green >> 8);
1552 left[2] = (double)(leftPtr->blue >> 8);
1553 range[0] = (double)((rightPtr->red - leftPtr->red) / 257.0);
1554 range[1] = (double)((rightPtr->green - leftPtr->green) / 257.0);
1555 range[2] = (double)((rightPtr->blue - leftPtr->blue) / 257.0);
1558 for (x = 0; x < width; x++) {
1560 t = ((double)( sin(M_PI_2 * (double)x / (double)width)));
1562 C.red = (unsigned short)(left[0] + t * range[0]);
1563 C.green = (unsigned short)(left[1] + t * range[1]);
1564 C.blue = (unsigned short)(left[2] + t * range[2]);
1565 sprintf(cbuf, "#%02x%02x%02x", C.red, C.green, C.blue);
1566 if (x) { Tcl_AppendResult(interp, " ", 0); }
1567 Tcl_AppendResult(interp, cbuf, 0);
1573 Blt_GetGradient(Tcl_Interp *interp, Tk_Window tkwin, Gradient *gradPtr) {
1574 XColor *leftPtr, *rightPtr;
1579 XColor **destPtr, C;
1581 leftPtr = gradPtr->color;
1582 rightPtr = gradPtr->color2;
1583 left[0] = (double)(leftPtr->red >> 8);
1584 left[1] = (double)(leftPtr->green >> 8);
1585 left[2] = (double)(leftPtr->blue >> 8);
1586 range[0] = (double)((rightPtr->red - leftPtr->red) / 257.0);
1587 range[1] = (double)((rightPtr->green - leftPtr->green) / 257.0);
1588 range[2] = (double)((rightPtr->blue - leftPtr->blue) / 257.0);
1591 width = gradPtr->width;
1592 if (gradPtr->grads) {
1593 Blt_FreeGradient(gradPtr);
1595 destPtr = gradPtr->grads = (XColor**)Blt_Calloc(width+1, sizeof(XColor*));
1596 for (x = 0; x < width; x++) {
1598 t = ((double)( sin(M_PI_2 * (double)x / (double)width)));
1600 C.red = (unsigned short)(left[0] + t * range[0]);
1601 C.green = (unsigned short)(left[1] + t * range[1]);
1602 C.blue = (unsigned short)(left[2] + t * range[2]);
1603 /**destPtr = Tk_GetColorByValue(tkwin, &C); */
1604 sprintf(cbuf, "#%02x%02x%02x", C.red, C.green, C.blue);
1605 *destPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(cbuf));
1606 if (*destPtr == NULL) break;
1609 gradPtr->origColor = gradPtr->color;
1610 gradPtr->origColor2 = gradPtr->color2;
1611 gradPtr->origWidth = gradPtr->width;
1616 Blt_FreeGradient(Gradient *gradPtr) {
1618 if (gradPtr->grads) {
1619 destPtr = gradPtr->grads;
1621 Tk_FreeColor(*destPtr);
1624 Blt_Free( gradPtr->grads);
1626 gradPtr->grads = NULL;
1633 GradientOp(clientData, interp, argc, argv)
1634 ClientData clientData; /* Not used. */
1636 int argc; /* Not used. */
1639 Tk_PhotoHandle photo;
1640 Tk_PhotoImageBlock src;
1641 XColor *leftPtr, *rightPtr;
1646 Blt_ColorImage destImage;
1647 double skew, randVal, slant, sineVal;
1648 int dorand, doslant, doskew, doarc, dosine, gtype, result, ox;
1649 int nWidth = 0, nHeight = 0;
1651 static char *types[] = { "linear", "radial", "sine", "halfsine", "rectangular", "split", "blank", 0 };
1653 ILinearIdx, IRadialIdx, ISineIdx, IHalfSineIdx, IRectIdx, ISplitIdx,
1656 double (*tfunc)(double);
1669 tkwin = Tk_MainWindow(interp);
1670 photo = Blt_FindPhoto(interp, argv[2]);
1671 if (photo == NULL) {
1672 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
1673 " exist or is not a photo image", (char *)NULL);
1676 Tk_PhotoGetImage(photo, &src);
1677 leftPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(argv[3]));
1678 if (leftPtr == NULL) {
1681 rightPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(argv[4]));
1682 if (rightPtr == NULL) {
1687 Tcl_AppendResult(interp, "expected argument", argv[5], (char *)NULL);
1690 if (!strcmp("-alpha", argv[5])) {
1691 if (Tcl_GetInt(interp, argv[6], &alpha) != TCL_OK) {
1694 if (alpha<=0 || alpha > 255) {
1695 Tcl_AppendResult(interp, "alpha must be > 0 and <= 255", argv[6],
1699 aVal = (unsigned char) alpha;
1701 } else if (!strcmp("-type", argv[5])) {
1702 objPtr = Tcl_NewStringObj(argv[6],-1);
1703 Tcl_IncrRefCount(objPtr);
1704 result = Tcl_GetIndexFromObj(interp, objPtr, types, "type", 0,
1706 Tcl_DecrRefCount(objPtr);
1707 if (result != TCL_OK) {
1711 } else if (!strcmp("-skew", argv[5])) {
1713 if (Tcl_GetDouble(interp, argv[6], &skew) != TCL_OK) {
1716 if (skew<0.0 || skew>1.0) {
1717 Tcl_AppendResult(interp, "skew must be >=0 && <=1.0: ", argv[6],
1721 } else if (!strcmp("-width", argv[5])) {
1722 if (Tk_GetPixels(interp, tkwin, argv[6], &nWidth) != TCL_OK) {
1725 if (nWidth<1 || nWidth>5000) {
1726 Tcl_AppendResult(interp, "width must be >=1 && <=5000: ", argv[6],
1730 } else if (!strcmp("-height", argv[5])) {
1731 if (Tk_GetPixels(interp, tkwin, argv[6], &nHeight) != TCL_OK) {
1734 if (nHeight<1 || nHeight>5000) {
1735 Tcl_AppendResult(interp, "width must be >=1 && <=5000: ", argv[6],
1739 } else if (!strcmp("-rand", argv[5])) {
1741 if (Tcl_GetDouble(interp, argv[6], &randVal) != TCL_OK) {
1744 if (randVal<0.0 || randVal>0.1) {
1745 Tcl_AppendResult(interp, "randVal must be >= 0.0 && <= 0.1: ", argv[6],
1749 } else if (!strcmp("-slant", argv[5])) {
1751 if (Tcl_GetDouble(interp, argv[6], &slant) != TCL_OK) {
1754 if (slant<-1000.0 || slant>1000.0) {
1755 Tcl_AppendResult(interp, "slant must be >= -1000.0 && <= 1000.0: ", argv[6],
1759 } else if (!strcmp("-mathval", argv[5])) {
1761 if (Tcl_GetDouble(interp, argv[6], &sineVal) != TCL_OK) {
1764 if (sineVal<-1000.0 || sineVal>1000.0) {
1765 Tcl_AppendResult(interp, "mathval must be >= -1000.0 && <= 1000.0: ", argv[6],
1769 } else if (!strcmp("-mathfunc", argv[5])) {
1770 if (!strcmp("circle", argv[6])) {
1773 } else if (!strcmp("sin", argv[6])) {
1775 } else if (!strcmp("cos", argv[6])) {
1777 } else if (!strcmp("atan", argv[6])) {
1779 } else if (!strcmp("acos", argv[6])) {
1781 } else if (!strcmp("asin", argv[6])) {
1783 } else if (!strcmp("rand", argv[6])) {
1785 } else if (!strcmp("cosh", argv[6])) {
1787 } else if (!strcmp("sinh", argv[6])) {
1789 } else if (!strcmp("tan", argv[6])) {
1791 } else if (!strcmp("tanh", argv[6])) {
1793 } else if (!strcmp("log", argv[6])) {
1795 } else if (!strcmp("log10", argv[6])) {
1797 } else if (!strcmp("exp", argv[6])) {
1799 } else if (!strcmp("sqrt", argv[6])) {
1802 Tcl_AppendResult(interp, "mathfunc ", argv[6], " not one of: ",
1803 "sin cos tan sinh cosh tanh asin acos atan log log10 exp sqrt rand circle", (char *)NULL);
1807 Tcl_AppendResult(interp, "argument \"", argv[5], "\" not one of: -type -skew -rand -slant -curve -circle",
1814 if ((nWidth>0 || nHeight>0) && ((nWidth != src.width) || (nHeight != src.height))) {
1815 if (nWidth<=0) { nWidth = src.width; }
1816 if (nHeight<=0) { nHeight = src.height; }
1817 Tk_PhotoSetSize(photo, nWidth, nHeight);
1818 Tk_PhotoGetImage(photo, &src);
1820 left[0] = (double)(leftPtr->red >> 8);
1821 left[1] = (double)(leftPtr->green >> 8);
1822 left[2] = (double)(leftPtr->blue >> 8);
1823 range[0] = (double)((rightPtr->red - leftPtr->red) / 257.0);
1824 range[1] = (double)((rightPtr->green - leftPtr->green) / 257.0);
1825 range[2] = (double)((rightPtr->blue - leftPtr->blue) / 257.0);
1827 destImage = Blt_CreateColorImage(src.width, src.height);
1828 destPtr = Blt_ColorImageBits(destImage);
1830 if (gtype == ILinearIdx) {
1831 register int x, y, sx;
1834 for (y = 0; y < src.height; y++) {
1835 for (x = 0; x < src.width; x++) {
1836 ox = (double)x / src.width;
1840 t = (double)sx / src.width;
1844 destPtr->Red = (unsigned char)(left[0] + t * range[0]);
1845 destPtr->Green = (unsigned char)(left[1] + t * range[1]);
1846 destPtr->Blue = (unsigned char)(left[2] + t * range[2]);
1847 destPtr->Alpha = aVal;
1851 } else if (gtype == ISineIdx) {
1852 register int x, y, sx;
1855 for (y = 0; y < src.height; y++) {
1856 for (x = 0; x < src.width; x++) {
1857 ox = (double)x / src.width;
1861 t = ((double)(sin(2*M_PI_2 * (double)sx / (double)src.width)));
1865 destPtr->Red = (unsigned char)(left[0] + t * range[0]);
1866 destPtr->Green = (unsigned char)(left[1] + t * range[1]);
1867 destPtr->Blue = (unsigned char)(left[2] + t * range[2]);
1868 destPtr->Alpha = aVal;
1872 } else if (gtype == IHalfSineIdx) {
1873 register int x, y, sx;
1876 for (y = 0; y < src.height; y++) {
1877 for (x = 0; x < src.width; x++) {
1878 ox = (double)x / src.width;
1882 t = ((double)( sin(M_PI_2 * (double)sx / (double)src.width)));
1886 destPtr->Red = (unsigned char)(left[0] + t * range[0]);
1887 destPtr->Green = (unsigned char)(left[1] + t * range[1]);
1888 destPtr->Blue = (unsigned char)(left[2] + t * range[2]);
1889 destPtr->Alpha = aVal;
1893 } else if (gtype == IRadialIdx) {
1894 register int x, y, sx;
1895 register double dx, dy;
1901 for (y = 0; y < src.height; y++) {
1902 dy = (y / (double)src.height) - midY;
1904 for (x = 0; x < src.width; x++) {
1905 ox = (double)x / src.width;
1909 dx = (sx / (double)src.width) - midX;
1910 t = 1.0 - (double)sqrt(dx * dx + dy2);
1914 destPtr->Red = (unsigned char)(left[0] + t * range[0]);
1915 destPtr->Green = (unsigned char)(left[1] + t * range[1]);
1916 destPtr->Blue = (unsigned char)(left[2] + t * range[2]);
1917 destPtr->Alpha = aVal;
1922 } else if (gtype == IRectIdx) {
1923 register int x, y, sx;
1924 register double dx, dy;
1927 double cosTheta, sinTheta;
1930 angle = M_PI_2 * -0.3;
1931 cosTheta = cos(angle);
1932 sinTheta = sin(angle);
1934 midX = 0.5, midY = 0.5;
1935 for (y = 0; y < src.height; y++) {
1936 dy = (y / (double)src.height) - midY;
1937 for (x = 0; x < src.width; x++) {
1938 ox = (double)x / src.width;
1942 dx = (sx / (double)src.width) - midX;
1943 px = dx * cosTheta - dy * sinTheta;
1944 py = dx * sinTheta + dy * cosTheta;
1945 t = FABS(px) + FABS(py);
1949 destPtr->Red = (unsigned char)(left[0] + t * range[0]);
1950 destPtr->Green = (unsigned char)(left[1] + t * range[1]);
1951 destPtr->Blue = (unsigned char)(left[2] + t * range[2]);
1952 destPtr->Alpha = aVal;
1956 } else if (gtype == ISplitIdx) {
1957 register int x, y, sx, midx;
1961 for (y = 0; y < src.height; y++) {
1962 for (x = 0; x < src.width; x++) {
1963 ox = (double)x / src.width;
1968 sx += (0.1 * src.width);
1970 sx -= (0.1 * src.width);
1972 t = (double)sx / src.width;
1976 destPtr->Red = (unsigned char)(left[0] + t * range[0]);
1977 destPtr->Green = (unsigned char)(left[1] + t * range[1]);
1978 destPtr->Blue = (unsigned char)(left[2] + t * range[2]);
1979 destPtr->Alpha = aVal;
1983 } else if (gtype == IBlankIdx) {
1986 for (y = 0; y < src.height; y++) {
1987 for (x = 0; x < src.width; x++) {
1988 destPtr->Red = (unsigned char)0xFF;
1989 destPtr->Green = (unsigned char)0xFF;
1990 destPtr->Blue = (unsigned char)0xFF;
1991 destPtr->Alpha = aVal;
1996 Blt_ColorImageToPhoto(destImage, photo);
1997 Blt_FreeColorImage(destImage);
2003 ResampleOp(clientData, interp, argc, argv)
2004 ClientData clientData; /* Not used. */
2006 int argc; /* Not used. */
2009 Tk_PhotoHandle srcPhoto, destPhoto;
2010 Tk_PhotoImageBlock src, dest;
2011 ResampleFilter *filterPtr, *vertFilterPtr, *horzFilterPtr;
2014 srcPhoto = Blt_FindPhoto(interp, argv[2]);
2015 if (srcPhoto == NULL) {
2016 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
2017 " exist or is not a photo image", (char *)NULL);
2020 destPhoto = Blt_FindPhoto(interp, argv[3]);
2021 if (destPhoto == NULL) {
2022 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
2023 " exist or is not a photo image", (char *)NULL);
2026 filterName = (argc > 4) ? argv[4] : "none";
2027 if (Blt_GetResampleFilter(interp, filterName, &filterPtr) != TCL_OK) {
2030 vertFilterPtr = horzFilterPtr = filterPtr;
2031 if ((filterPtr != NULL) && (argc > 5)) {
2032 if (Blt_GetResampleFilter(interp, argv[5], &filterPtr) != TCL_OK) {
2035 vertFilterPtr = filterPtr;
2037 Tk_PhotoGetImage(srcPhoto, &src);
2038 if ((src.width <= 1) || (src.height <= 1)) {
2039 Tcl_AppendResult(interp, "source image \"", argv[2], "\" is empty",
2043 Tk_PhotoGetImage(destPhoto, &dest);
2044 if ((dest.width <= 1) || (dest.height <= 1)) {
2045 Tk_PhotoSetSize(destPhoto, src.width, src.height);
2048 if ((src.width == dest.width) && (src.height == dest.height)) {
2050 /* Source and destination image sizes are the same. Don't
2051 * resample. Simply make copy of image */
2052 dest.width = src.width;
2053 dest.height = src.height;
2054 dest.pixelPtr = src.pixelPtr;
2055 dest.pixelSize = src.pixelSize;
2056 dest.pitch = src.pitch;
2057 dest.offset[0] = src.offset[0];
2058 dest.offset[1] = src.offset[1];
2059 dest.offset[2] = src.offset[2];
2060 Tk_PhotoPutBlock(destPhoto, &dest, 0, 0, dest.width, dest.height);
2063 if (filterPtr == NULL) {
2064 Blt_ResizePhoto(srcPhoto, 0, 0, src.width, src.height, destPhoto);
2066 Blt_ResamplePhoto(srcPhoto, 0, 0, src.width, src.height, destPhoto,
2067 horzFilterPtr, vertFilterPtr);
2074 BlurOp(clientData, interp, argc, argv)
2075 ClientData clientData; /* Not used. */
2077 int argc; /* Not used. */
2080 Tk_PhotoHandle srcPhoto, destPhoto;
2081 Tk_PhotoImageBlock src, dest;
2085 srcPhoto = Blt_FindPhoto(interp, argv[2]);
2086 if (srcPhoto == NULL) {
2087 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
2088 " exist or is not a photo image", (char *)NULL);
2091 destPhoto = Blt_FindPhoto(interp, argv[3]);
2092 if (destPhoto == NULL) {
2093 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
2094 " exist or is not a photo image", (char *)NULL);
2098 if (Tcl_GetDouble(interp, argv[4], &radius) != TCL_OK) {
2102 Tk_PhotoGetImage(srcPhoto, &src);
2103 if ((src.width <= 1) || (src.height <= 1)) {
2104 Tcl_AppendResult(interp, "source image \"", argv[2], "\" is empty",
2108 Tk_PhotoGetImage(destPhoto, &dest);
2109 Tk_PhotoSetSize(destPhoto, src.width, src.height);
2110 return Blt_BlurColorImage(srcPhoto, destPhoto, (int)(radius + 0.5) );
2115 RotateOp(clientData, interp, argc, argv)
2116 ClientData clientData; /* Not used. */
2118 int argc; /* Not used. */
2121 Tk_PhotoHandle srcPhoto, destPhoto;
2122 Blt_ColorImage srcImage, destImage;
2125 srcPhoto = Blt_FindPhoto(interp, argv[2]);
2126 if (srcPhoto == NULL) {
2127 Tcl_AppendResult(interp, "image \"", argv[2], "\" doesn't",
2128 " exist or is not a photo image", (char *)NULL);
2131 destPhoto = Blt_FindPhoto(interp, argv[3]);
2132 if (destPhoto == NULL) {
2133 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
2134 " exist or is not a photo image", (char *)NULL);
2137 if (Tcl_ExprDouble(interp, argv[4], &theta) != TCL_OK) {
2140 srcImage = Blt_PhotoToColorImage(srcPhoto);
2141 destImage = Blt_RotateColorImage(srcImage, theta);
2143 Blt_ColorImageToPhoto(destImage, destPhoto);
2144 Blt_FreeColorImage(srcImage);
2145 Blt_FreeColorImage(destImage);
2151 Blt_ImageMirror(Tcl_Interp *interp, char *srcImg, char *dstImg, int flip, int flags) {
2152 Tk_PhotoHandle srcPhoto, destPhoto;
2153 Blt_ColorImage srcImage, destImage;
2154 int x, y, x1, x2, y2;
2155 Tk_PhotoImageBlock src, dest;
2156 Pix32 *destPtr, *srcPtr;
2158 srcPhoto = Blt_FindPhoto(interp, srcImg);
2159 if (srcPhoto == NULL) {
2160 Tcl_AppendResult(interp, "image \"", srcImg, "\" doesn't",
2161 " exist or is not a photo image", (char *)NULL);
2164 Tk_PhotoGetImage(srcPhoto, &src);
2165 destPhoto = Blt_FindPhoto(interp, dstImg);
2166 if (destPhoto == NULL) {
2167 Tcl_AppendResult(interp, "destination image \"", dstImg, "\" doesn't",
2168 " exist or is not a photo image", (char *)NULL);
2173 if ((flip == MIRROR_TILE || flip == MIRROR_INNER || flip == MIRROR_OUTER ) && srcPhoto == destPhoto) {
2174 Tcl_AppendResult(interp, "image must be different", (char *)NULL);
2177 Tk_PhotoGetImage(destPhoto, &dest);
2178 if (src.width <= 0 || src.height <= 0) {
2179 Tcl_AppendResult(interp, "src image empty ", 0);
2183 if (flip == MIRROR_TILE) {
2184 if ((dest.width != (src.width *2)) || (dest.height <= (src.height*2))) {
2185 Tk_PhotoSetSize(destPhoto, 2*src.width, 2*src.height);
2186 Tk_PhotoGetImage(destPhoto, &dest);
2188 } else if (flip != MIRROR_OUTER && flip != MIRROR_INNER) {
2189 if ((dest.width != src.width) || (dest.height <= src.height)) {
2190 Tk_PhotoSetSize(destPhoto, src.width, src.height);
2191 Tk_PhotoGetImage(destPhoto, &dest);
2195 srcImage = Blt_PhotoToColorImage(srcPhoto);
2196 destImage = Blt_PhotoToColorImage(destPhoto);
2197 destPtr = Blt_ColorImageBits(destImage);
2198 srcPtr = Blt_ColorImageBits(srcImage);
2200 if (flip == MIRROR_INNER) {
2202 int xs1, xs2, xd1, xd2, xsc, xdc;
2203 int ys1, ys2, yd1, yd2, ysc, ydc;
2205 if (src.width < 4 || src.height < 4) {
2206 Tcl_AppendResult(interp, "src image too small ", 0);
2209 if (dest.width < 4 || dest.height < 4) {
2210 Tcl_AppendResult(interp, "dest image too small ", 0);
2213 xsc = (src.width/2);
2214 ysc = (src.height/2);
2215 xdc = (dest.width/2);
2216 ydc = (dest.height/2);
2217 for (xs1 = xsc-1, xs2=xs1+1, xd1 = xdc-1, xd2=xd1+1;
2218 xd1>=0; xd1--, xs1--, xd2++, xs2++) {
2219 if (xs1<0) { xs1 = xsc-1; xs2 = xs1+1; }
2220 for (ys1 = ysc-1, ys2 = ys1+1, yd1 = ydc-1, yd2=yd1+1;
2221 yd1>=0; yd1--, ys1--, yd2++, ys2++) {
2222 if (ys1<0) { ys1 = ysc-1; ys2 = ys1+1; }
2223 destPtr[yd1*dest.width+xd1].value = srcPtr[ys1*src.width+xs1].value;
2224 if (ys2>=src.height) { ys2--; }
2225 if (xs2>=src.width) { xs2--; }
2226 if (yd2<dest.height && xd2<dest.width)
2227 destPtr[yd2*dest.width+xd2].value = srcPtr[ys2*src.width+xs2].value;
2229 destPtr[yd1*dest.width+xd2].value = srcPtr[ys1*src.width+xs2].value;
2230 if (yd2<dest.height)
2231 destPtr[yd2*dest.width+xd1].value = srcPtr[ys2*src.width+xs1].value;
2232 //if (ya<src.height && ya2<dest.height && xa<src.width && xa2<dest.width) {}
2236 if (flip == MIRROR_X) {
2238 for (y = 0; y < src.height; y++) {
2239 for (x = 0, x1 = src.width*y, x2 = src.width*(y+1)-1;
2242 destPtr[x2].value = srcPtr[x1].value;
2246 if (flip == MIRROR_Y) {
2248 for (x = 0; x < src.width; x++) {
2249 for (y = 0, y2 = src.height-1; y < src.height; y++, y2--) {
2250 destPtr[y2*dest.width+x].value = srcPtr[y*src.width+x].value;
2254 if (flip == MIRROR_XY) {
2256 for (x = 0, x2 = src.width-1; x < src.width; x++, x2--) {
2257 for (y = 0, y2 = src.height-1; y < src.height; y++, y2--) {
2258 destPtr[y2*dest.width+x2].value = srcPtr[y*src.width+x].value;
2263 if (flip == MIRROR_TILE) {
2264 for (y = 0; y < src.height; y++) {
2265 for (x = 0; x < src.width; x++) {
2266 destPtr[y*dest.width+x].value = srcPtr[y*src.width+x].value;
2270 for (y = 0; y < src.height; y++) {
2271 for (x = 0, x1 = src.width*y, x2 = 2*src.width*(y+1)-1;
2274 destPtr[x2].value = srcPtr[x1].value;
2278 for (x = 0; x < src.width; x++) {
2279 for (y = 0, y2 = 2*src.height-1; y < src.height; y++, y2--) {
2280 destPtr[y2*dest.width+x].value = srcPtr[y*src.width+x].value;
2284 for (x = 0, x2 = 2*src.width-1; x < src.width; x++, x2--) {
2285 for (y = 0, y2 = 2*src.height-1; y < src.height; y++, y2--) {
2286 destPtr[y2*dest.width+x2].value = srcPtr[y*src.width+x].value;
2291 if (flip == MIRROR_OUTER) {
2292 int split = (flags&1);
2293 int sx1, sx2, sy1, sy2,
2294 smx = (src.width/2), smy=(src.height/2),
2295 dmx = (dest.width/2), dmy=(dest.height/2);
2297 /* Initialize whole background to center pixel. */
2298 int sind = (src.height/2)*src.width+src.width/2;
2299 for (x = 0; x < dest.width; x++) {
2300 for (y = 0; y < dest.height; y++) {
2301 destPtr[y*dest.width+x].value =
2306 /* Copy top & bottom pixels. */
2307 for (y = 0, y2 = dest.height-1, sy1 = 0, sy2 = src.height-1;
2309 y++, y2--, sy1++, sy2--) {
2310 if (sy1 >= smy) { if (split) { sy1--; sy2++; } else { sy1 = sy2 = smy; }}
2311 for (x = 0, x2 = dest.width-1, sx1 = 0, sx2 = src.width-1;
2312 x < dmx; x++, x2--, sx1++, sx2--) {
2313 if (sx1 >= smx) { if (split) { sx1--; sx2++; } else { sx1 = sx2 = smx; }}
2314 /* Top - left & right */
2315 destPtr[y*dest.width+x].value = srcPtr[sy1*src.width+sx1].value;
2316 destPtr[y*dest.width+x2].value = srcPtr[sy1*src.width+sx2].value;
2317 /* Bottom - left & right */
2318 destPtr[y2*dest.width+x].value = srcPtr[sy2*src.width+sx1].value;
2319 destPtr[y2*dest.width+x2].value = srcPtr[sy2*src.width+sx2].value;
2322 /* Copy left & right pixels. */
2323 for (x = 0, x2 = dest.width-1, sx1 = 0, sx2 = src.width-1;
2325 x++, x2--, sx1++, sx2--) {
2326 if (sx1 >= smx) { if (split) { sx1--; sx2++; } else { sx1 = sx2 = smx; }}
2327 for (y = 0, y2 = dest.height-1, sy1 = 0, sy2 = src.height-1;
2328 y < dmy; y++, y2--, sy1++, sy2--) {
2329 if (sy1 >= smy) { if (split) { sy1--; sy2++; } else { sy1 = sy2 = smy; }}
2330 /* Left - top & bottom */
2331 destPtr[y*dest.width+x].value = srcPtr[sy1*src.width+sx1].value;
2332 destPtr[y*dest.width+x2].value = srcPtr[sy1*src.width+sx2].value;
2333 /* Right - top & bottom */
2334 destPtr[y2*dest.width+x].value = srcPtr[sy2*src.width+sx1].value;
2335 destPtr[y2*dest.width+x2].value = srcPtr[sy2*src.width+sx2].value;
2340 Blt_ColorImageToPhoto(destImage, destPhoto);
2341 Blt_FreeColorImage(srcImage);
2342 Blt_FreeColorImage(destImage);
2349 MirrorOp(clientData, interp, argc, argv)
2350 ClientData clientData; /* Not used. */
2352 int argc; /* Not used. */
2355 Tk_PhotoHandle srcPhoto, destPhoto;
2360 srcPhoto = Blt_FindPhoto(interp, argv[2]);
2361 if (srcPhoto == NULL) {
2362 Tcl_AppendResult(interp, "image \"", argv[2], "\" doesn't",
2363 " exist or is not a photo image", (char *)NULL);
2366 destPhoto = Blt_FindPhoto(interp, argv[3]);
2367 if (destPhoto == NULL) {
2368 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
2369 " exist or is not a photo image", (char *)NULL);
2373 if (!strcmp(argv[4],"x")) {
2374 flip = MIRROR_X; /* 1 */
2375 } else if (!strcmp(argv[4],"y")) {
2376 flip = MIRROR_Y; /* 2 */
2377 } else if (!strcmp(argv[4],"xy")) {
2378 flip = MIRROR_XY; /* 3 */
2379 } else if (!strcmp(argv[4],"tile")) {
2380 flip = MIRROR_TILE; /* 4 */
2381 } else if (!strcmp(argv[4],"outer")) {
2382 flip = MIRROR_OUTER; /* 5 */
2383 } else if (!strcmp(argv[4],"inner")) {
2384 flip = MIRROR_INNER; /* 6 */
2386 Tcl_AppendResult(interp, "direction ", argv[4],
2387 " must be \"x\", \"y\", \"xy\",\"tile\", \"inner\", or \"outer\"", (char *)NULL);
2392 if (flip != MIRROR_OUTER) {
2393 Tcl_AppendResult(interp, "halo is for outer only", 0);
2396 if (Tcl_GetInt(interp, argv[5], &halo) != TCL_OK) {
2400 return Blt_ImageMirror(interp, argv[2], argv[3], flip, halo);
2405 * --------------------------------------------------------------------------
2409 * Snaps a picture of a window and stores it in a designated
2410 * photo image. The window must be completely visible or
2411 * the snap will fail.
2414 * Returns a standard Tcl result. interp->result contains
2415 * the list of the graph coordinates. If an error occurred
2416 * while parsing the window positions, TCL_ERROR is returned,
2417 * then interp->result will contain an error message.
2419 * -------------------------------------------------------------------------
2423 SnapOp(clientData, interp, argc, argv)
2424 ClientData clientData;
2426 int argc; /* Not used. */
2430 int width, height, destWidth, destHeight;
2433 tkwin = Tk_MainWindow(interp);
2434 window = StringToWindow(interp, argv[2]);
2435 if (window == None) {
2438 if (GetWindowSize(interp, window, &width, &height) != TCL_OK) {
2439 Tcl_AppendResult(interp, "can't get window geometry of \"", argv[2],
2440 "\"", (char *)NULL);
2443 destWidth = width, destHeight = height;
2444 if ((argc > 4) && (Blt_GetPixels(interp, tkwin, argv[4], PIXELS_POSITIVE,
2445 &destWidth) != TCL_OK)) {
2448 if ((argc > 5) && (Blt_GetPixels(interp, tkwin, argv[5], PIXELS_POSITIVE,
2449 &destHeight) != TCL_OK)) {
2452 return Blt_SnapPhoto(interp, tkwin, window, 0, 0, width, height, destWidth,
2453 destHeight, argv[3], GAMMA);
2458 SubsampleOp(clientData, interp, argc, argv)
2459 ClientData clientData; /* Main window of the interpreter. */
2461 int argc; /* Not used. */
2465 Tk_PhotoHandle srcPhoto, destPhoto;
2466 Tk_PhotoImageBlock src, dest;
2467 ResampleFilter *filterPtr, *vertFilterPtr, *horzFilterPtr;
2473 srcPhoto = Blt_FindPhoto(interp, argv[2]);
2474 if (srcPhoto == NULL) {
2475 Tcl_AppendResult(interp, "source image \"", argv[2], "\" doesn't",
2476 " exist or is not a photo image", (char *)NULL);
2479 destPhoto = Blt_FindPhoto(interp, argv[3]);
2480 if (destPhoto == NULL) {
2481 Tcl_AppendResult(interp, "destination image \"", argv[3], "\" doesn't",
2482 " exist or is not a photo image", (char *)NULL);
2485 tkwin = (Tk_Window)clientData;
2486 flag = PIXELS_NONNEGATIVE;
2487 if (Blt_GetPixels(interp, tkwin, argv[4], flag, &x) != TCL_OK) {
2490 if (Blt_GetPixels(interp, tkwin, argv[5], flag, &y) != TCL_OK) {
2493 flag = PIXELS_POSITIVE;
2494 if (Blt_GetPixels(interp, tkwin, argv[6], flag, &width) != TCL_OK) {
2497 if (Blt_GetPixels(interp, tkwin, argv[7], flag, &height) != TCL_OK) {
2500 filterName = (argc > 8) ? argv[8] : "none";
2501 if (Blt_GetResampleFilter(interp, filterName, &filterPtr) != TCL_OK) {
2504 vertFilterPtr = horzFilterPtr = filterPtr;
2505 if ((filterPtr != NULL) && (argc > 9)) {
2506 if (Blt_GetResampleFilter(interp, argv[9], &filterPtr) != TCL_OK) {
2509 vertFilterPtr = filterPtr;
2511 Tk_PhotoGetImage(srcPhoto, &src);
2512 Tk_PhotoGetImage(destPhoto, &dest);
2513 if ((src.width <= 1) || (src.height <= 1)) {
2514 Tcl_AppendResult(interp, "source image \"", argv[2], "\" is empty",
2518 if (((x + width) > src.width) || ((y + height) > src.height)) {
2519 Tcl_AppendResult(interp, "nonsensical dimensions for subregion: x=",
2520 argv[4], " y=", argv[5], " width=", argv[6], " height=",
2521 argv[7], (char *)NULL);
2524 if ((dest.width <= 1) || (dest.height <= 1)) {
2525 Tk_PhotoSetSize(destPhoto, width, height);
2527 if (filterPtr == NULL) {
2528 Blt_ResizePhoto(srcPhoto, x, y, width, height, destPhoto);
2530 Blt_ResamplePhoto(srcPhoto, x, y, width, height, destPhoto,
2531 horzFilterPtr, vertFilterPtr);
2536 static Blt_OpSpec imageOps[] =
2538 {"alpha", 2, (Blt_Op)AlphaOp, 6, 10, "?-shift? srcPhoto destPhoto Color ?alpha? ?withalpha?",},
2539 {"blur", 2, (Blt_Op)BlurOp, 5, 6, "srcPhoto destPhoto ?radius?",},
2540 {"colors", 3, (Blt_Op)ColorsOp, 4, 0, "?-alpha? ?-count? ?-from x1 y1 x2 y2? srcPhoto",},
2541 {"convolve", 3, (Blt_Op)ConvolveOp, 6, 6, "srcPhoto destPhoto filter",},
2542 {"gradient", 1, (Blt_Op)GradientOp, 6, 0, "photo left right ?-type lines|normal|radial|rectangular|linear|sine|halfsine? ?-skew val? ?-slant val? ?-rand val? ?-mathval val? ?-mathfunc circle|sin|cos|tan|asin|acos|atan|sinh|cosh|tanh|exp|sqrt|log|log10|rand?",},
2543 {"merge", 2, (Blt_Op)MergeOp, 6, 7, "srcPhoto1 srcPhoto2 destPhoto ?opacity? ?opacity2?",},
2544 {"mirror", 3, (Blt_Op)MirrorOp, 5, 7, "srcPhoto destPhoto ?x|y|xy|tile|outer|innert? ?halo?",},
2545 {"quantize", 2, (Blt_Op)QuantizeOp, 4, 5, "srcPhoto destPhoto ?nColors?",},
2546 {"readjpeg", 3, (Blt_Op)ReadJPEGOp, 5, 5, "fileName photoName",},
2547 {"recolor", 3, (Blt_Op)RecolorOp, 7, 8, "srcPhoto destPhoto oldColor newColor ?alpha?",},
2548 {"resample", 3, (Blt_Op)ResampleOp, 5, 7,
2549 "srcPhoto destPhoto ?horzFilter vertFilter?",},
2550 {"rotate", 2, (Blt_Op)RotateOp, 6, 6, "srcPhoto destPhoto angle",},
2551 {"subsample", 2, (Blt_Op)SubsampleOp, 9, 11,
2552 "srcPhoto destPhoto x y width height ?horzFilter? ?vertFilter?",},
2553 {"trans", 2, (Blt_Op)TransOp, 6, 7, "image x y ?alpha?",},
2556 static int nImageOps = sizeof(imageOps) / sizeof(Blt_OpSpec);
2560 ImageOp(clientData, interp, argc, argv)
2561 ClientData clientData; /* Main window of interpreter. */
2562 Tcl_Interp *interp; /* Current interpreter. */
2563 int argc; /* Number of arguments. */
2564 char **argv; /* Argument strings. */
2569 proc = Blt_GetOp(interp, nImageOps, imageOps, BLT_OP_ARG2, argc, argv, 0);
2573 clientData = (ClientData)Tk_MainWindow(interp);
2574 result = (*proc) (clientData, interp, argc - 1, argv + 1);
2578 static Blt_OpSpec winOps[] =
2580 {"changes", 3, (Blt_Op)ChangesOp, 3, 3, "window",},
2582 {"colormap", 3, (Blt_Op)ColormapOp, 3, 3, "window",},
2584 {"gradients", 1, (Blt_Op)GradientsOp, 5, 5, "color1 color2 width",},
2585 {"image", 1, (Blt_Op)ImageOp, 2, 0, "args",},
2586 {"lower", 1, (Blt_Op)LowerOp, 2, 0, "window ?window?...",},
2587 {"map", 2, (Blt_Op)MapOp, 2, 0, "window ?window?...",},
2588 {"move", 2, (Blt_Op)MoveOp, 5, 5, "window x y",},
2589 {"parent", 3, (Blt_Op)ParentOp, 3, 3, "window",},
2590 {"query", 3, (Blt_Op)QueryOp, 2, 2, "",},
2591 {"raise", 2, (Blt_Op)RaiseOp, 2, 0, "window ?window?...",},
2593 {"reparent", 3, (Blt_Op)ReparentOp, 3, 4, "window ?parent?",},
2595 {"snap", 2, (Blt_Op)SnapOp, 4, 8, "window photoName ?width height?",},
2596 {"unmap", 1, (Blt_Op)UnmapOp, 2, 0, "window ?window?...",},
2597 {"warpto", 1, (Blt_Op)WarpToOp, 2, 5, "?window?",},
2600 static int nWinOps = sizeof(winOps) / sizeof(Blt_OpSpec);
2604 WinopCmd(clientData, interp, argc, argv)
2605 ClientData clientData; /* Main window of interpreter. */
2606 Tcl_Interp *interp; /* Current interpreter. */
2607 int argc; /* Number of arguments. */
2608 char **argv; /* Argument strings. */
2613 proc = Blt_GetOp(interp, nWinOps, winOps, BLT_OP_ARG1, argc, argv, 0);
2617 clientData = (ClientData)Tk_MainWindow(interp);
2618 result = (*proc) (clientData, interp, argc, argv);
2623 Blt_WinopInit(interp)
2626 static Blt_CmdSpec cmdSpec = {"winop", WinopCmd,};
2628 if (Blt_InitCmd(interp, "blt", &cmdSpec) == NULL) {
2634 #endif /* NO_WINOP */