diff --git a/MagickCore/display.c b/MagickCore/display.c index 0d47b14287..6dfb5a7782 100644 --- a/MagickCore/display.c +++ b/MagickCore/display.c @@ -10,7 +10,7 @@ % DDDD IIIII SSSSS P LLLLL A A Y % % % % % -% MagickCore Methods to Interactively Display and Edit an Image % +% Methods to Interactively Display and Edit an Image % % % % Software Design % % Cristy % @@ -33,1596 +33,256 @@ % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % +% Use the display program to display an image or image sequence on any X +% server. % */ /* Include declarations. */ -#include "MagickCore/studio.h" -#include "MagickCore/artifact.h" -#include "MagickCore/attribute.h" -#include "MagickCore/blob.h" -#include "MagickCore/cache.h" -#include "MagickCore/cache-private.h" -#include "MagickCore/channel.h" -#include "MagickCore/client.h" -#include "MagickCore/color.h" -#include "MagickCore/colorspace.h" -#include "MagickCore/composite.h" -#include "MagickCore/constitute.h" -#include "MagickCore/decorate.h" -#include "MagickCore/delegate.h" -#include "MagickCore/display.h" +#include "MagickWand/studio.h" +#include "MagickWand/MagickWand.h" +#include "MagickWand/mogrify-private.h" #include "MagickCore/display-private.h" -#include "MagickCore/distort.h" -#include "MagickCore/draw.h" -#include "MagickCore/effect.h" -#include "MagickCore/enhance.h" -#include "MagickCore/exception.h" -#include "MagickCore/exception-private.h" -#include "MagickCore/fx.h" -#include "MagickCore/geometry.h" -#include "MagickCore/image.h" -#include "MagickCore/image-private.h" -#include "MagickCore/list.h" -#include "MagickCore/locale-private.h" -#include "MagickCore/log.h" -#include "MagickCore/magick.h" -#include "MagickCore/memory_.h" -#include "MagickCore/monitor.h" -#include "MagickCore/monitor-private.h" -#include "MagickCore/montage.h" -#include "MagickCore/nt-base-private.h" -#include "MagickCore/option.h" -#include "MagickCore/paint.h" -#include "MagickCore/pixel.h" -#include "MagickCore/pixel-accessor.h" -#include "MagickCore/property.h" -#include "MagickCore/quantum.h" -#include "MagickCore/quantum-private.h" -#include "MagickCore/resize.h" -#include "MagickCore/resource_.h" -#include "MagickCore/shear.h" -#include "MagickCore/segment.h" -#include "MagickCore/statistic.h" -#include "MagickCore/string_.h" #include "MagickCore/string-private.h" -#include "MagickCore/timer-private.h" -#include "MagickCore/transform.h" -#include "MagickCore/transform-private.h" -#include "MagickCore/threshold.h" -#include "MagickCore/utility.h" -#include "MagickCore/utility-private.h" -#include "MagickCore/version.h" -#include "MagickCore/visual-effects.h" -#include "MagickCore/widget.h" -#include "MagickCore/widget-private.h" -#include "MagickCore/xwindow.h" -#include "MagickCore/xwindow-private.h" - -#if defined(MAGICKCORE_X11_DELEGATE) -/* - Define declarations. -*/ -#define MaxColors MagickMin((ssize_t) windows->visual_info->colormap_size,256L) - -/* - Constant declarations. -*/ -static const unsigned char - HighlightBitmap[8] = - { - 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 - }, - OpaqueBitmap[8] = - { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }, - ShadowBitmap[8] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - -/* - Help widget declarations. -*/ -static const char - ImageAnnotateHelp[] = - { - "In annotate mode, the Command widget has these options:\n" - "\n" - " Font Name\n" - " fixed\n" - " variable\n" - " 5x8\n" - " 6x10\n" - " 7x13bold\n" - " 8x13bold\n" - " 9x15bold\n" - " 10x20\n" - " 12x24\n" - " Browser...\n" - " Font Color\n" - " black\n" - " blue\n" - " cyan\n" - " green\n" - " gray\n" - " red\n" - " magenta\n" - " yellow\n" - " white\n" - " transparent\n" - " Browser...\n" - " Font Color\n" - " black\n" - " blue\n" - " cyan\n" - " green\n" - " gray\n" - " red\n" - " magenta\n" - " yellow\n" - " white\n" - " transparent\n" - " Browser...\n" - " Rotate Text\n" - " -90\n" - " -45\n" - " -30\n" - " 0\n" - " 30\n" - " 45\n" - " 90\n" - " 180\n" - " Dialog...\n" - " Help\n" - " Dismiss\n" - "\n" - "Choose a font name from the Font Name sub-menu. Additional\n" - "font names can be specified with the font browser. You can\n" - "change the menu names by setting the X resources font1\n" - "through font9.\n" - "\n" - "Choose a font color from the Font Color sub-menu.\n" - "Additional font colors can be specified with the color\n" - "browser. You can change the menu colors by setting the X\n" - "resources pen1 through pen9.\n" - "\n" - "If you select the color browser and press Grab, you can\n" - "choose the font color by moving the pointer to the desired\n" - "color on the screen and press any button.\n" - "\n" - "If you choose to rotate the text, choose Rotate Text from the\n" - "menu and select an angle. Typically you will only want to\n" - "rotate one line of text at a time. Depending on the angle you\n" - "choose, subsequent lines may end up overwriting each other.\n" - "\n" - "Choosing a font and its color is optional. The default font\n" - "is fixed and the default color is black. However, you must\n" - "choose a location to begin entering text and press button 1.\n" - "An underscore character will appear at the location of the\n" - "pointer. The cursor changes to a pencil to indicate you are\n" - "in text mode. To exit immediately, press Dismiss.\n" - "\n" - "In text mode, any key presses will display the character at\n" - "the location of the underscore and advance the underscore\n" - "cursor. Enter your text and once completed press Apply to\n" - "finish your image annotation. To correct errors press BACK\n" - "SPACE. To delete an entire line of text, press DELETE. Any\n" - "text that exceeds the boundaries of the image window is\n" - "automagically continued onto the next line.\n" - "\n" - "The actual color you request for the font is saved in the\n" - "image. However, the color that appears in your image window\n" - "may be different. For example, on a monochrome screen the\n" - "text will appear black or white even if you choose the color\n" - "red as the font color. However, the image saved to a file\n" - "with -write is written with red lettering. To assure the\n" - "correct color text in the final image, any PseudoClass image\n" - "is promoted to DirectClass (see miff(5)). To force a\n" - "PseudoClass image to remain PseudoClass, use -colors.\n" - }, - ImageChopHelp[] = - { - "In chop mode, the Command widget has these options:\n" - "\n" - " Direction\n" - " horizontal\n" - " vertical\n" - " Help\n" - " Dismiss\n" - "\n" - "If the you choose the horizontal direction (this the\n" - "default), the area of the image between the two horizontal\n" - "endpoints of the chop line is removed. Otherwise, the area\n" - "of the image between the two vertical endpoints of the chop\n" - "line is removed.\n" - "\n" - "Select a location within the image window to begin your chop,\n" - "press and hold any button. Next, move the pointer to\n" - "another location in the image. As you move a line will\n" - "connect the initial location and the pointer. When you\n" - "release the button, the area within the image to chop is\n" - "determined by which direction you choose from the Command\n" - "widget.\n" - "\n" - "To cancel the image chopping, move the pointer back to the\n" - "starting point of the line and release the button.\n" - }, - ImageColorEditHelp[] = - { - "In color edit mode, the Command widget has these options:\n" - "\n" - " Method\n" - " point\n" - " replace\n" - " floodfill\n" - " filltoborder\n" - " reset\n" - " Pixel Color\n" - " black\n" - " blue\n" - " cyan\n" - " green\n" - " gray\n" - " red\n" - " magenta\n" - " yellow\n" - " white\n" - " Browser...\n" - " Border Color\n" - " black\n" - " blue\n" - " cyan\n" - " green\n" - " gray\n" - " red\n" - " magenta\n" - " yellow\n" - " white\n" - " Browser...\n" - " Fuzz\n" - " 0%\n" - " 2%\n" - " 5%\n" - " 10%\n" - " 15%\n" - " Dialog...\n" - " Undo\n" - " Help\n" - " Dismiss\n" - "\n" - "Choose a color editing method from the Method sub-menu\n" - "of the Command widget. The point method recolors any pixel\n" - "selected with the pointer until the button is released. The\n" - "replace method recolors any pixel that matches the color of\n" - "the pixel you select with a button press. Floodfill recolors\n" - "any pixel that matches the color of the pixel you select with\n" - "a button press and is a neighbor. Whereas filltoborder recolors\n" - "any neighbor pixel that is not the border color. Finally reset\n" - "changes the entire image to the designated color.\n" - "\n" - "Next, choose a pixel color from the Pixel Color sub-menu.\n" - "Additional pixel colors can be specified with the color\n" - "browser. You can change the menu colors by setting the X\n" - "resources pen1 through pen9.\n" - "\n" - "Now press button 1 to select a pixel within the image window\n" - "to change its color. Additional pixels may be recolored as\n" - "prescribed by the method you choose.\n" - "\n" - "If the Magnify widget is mapped, it can be helpful in positioning\n" - "your pointer within the image (refer to button 2).\n" - "\n" - "The actual color you request for the pixels is saved in the\n" - "image. However, the color that appears in your image window\n" - "may be different. For example, on a monochrome screen the\n" - "pixel will appear black or white even if you choose the\n" - "color red as the pixel color. However, the image saved to a\n" - "file with -write is written with red pixels. To assure the\n" - "correct color text in the final image, any PseudoClass image\n" - "is promoted to DirectClass (see miff(5)). To force a\n" - "PseudoClass image to remain PseudoClass, use -colors.\n" - }, - ImageCompositeHelp[] = - { - "First a widget window is displayed requesting you to enter an\n" - "image name. Press Composite, Grab or type a file name.\n" - "Press Cancel if you choose not to create a composite image.\n" - "When you choose Grab, move the pointer to the desired window\n" - "and press any button.\n" - "\n" - "If the Composite image does not have any matte information,\n" - "you are informed and the file browser is displayed again.\n" - "Enter the name of a mask image. The image is typically\n" - "grayscale and the same size as the composite image. If the\n" - "image is not grayscale, it is converted to grayscale and the\n" - "resulting intensities are used as matte information.\n" - "\n" - "A small window appears showing the location of the cursor in\n" - "the image window. You are now in composite mode. To exit\n" - "immediately, press Dismiss. In composite mode, the Command\n" - "widget has these options:\n" - "\n" - " Operators\n" - " Over\n" - " In\n" - " Out\n" - " Atop\n" - " Xor\n" - " Plus\n" - " Minus\n" - " Add\n" - " Subtract\n" - " Difference\n" - " Multiply\n" - " Bumpmap\n" - " Copy\n" - " CopyRed\n" - " CopyGreen\n" - " CopyBlue\n" - " CopyOpacity\n" - " Clear\n" - " Dissolve\n" - " Displace\n" - " Help\n" - " Dismiss\n" - "\n" - "Choose a composite operation from the Operators sub-menu of\n" - "the Command widget. How each operator behaves is described\n" - "below. Image window is the image currently displayed on\n" - "your X server and image is the image obtained with the File\n" - "Browser widget.\n" - "\n" - "Over The result is the union of the two image shapes,\n" - " with image obscuring image window in the region of\n" - " overlap.\n" - "\n" - "In The result is simply image cut by the shape of\n" - " image window. None of the image data of image\n" - " window is in the result.\n" - "\n" - "Out The resulting image is image with the shape of\n" - " image window cut out.\n" - "\n" - "Atop The result is the same shape as the image window,\n" - " with image obscuring image window where the image\n" - " shapes overlap. Note this differs from over\n" - " because the portion of image outside image window's\n" - " shape does not appear in the result.\n" - "\n" - "Xor The result is the image data from both image and\n" - " image window that is outside the overlap region.\n" - " The overlap region is blank.\n" - "\n" - "Plus The result is just the sum of the image data.\n" - " Output values are cropped to QuantumRange (no overflow).\n" - "\n" - "Minus The result of image - image window, with underflow\n" - " cropped to zero.\n" - "\n" - "Add The result of image + image window, with overflow\n" - " wrapping around (mod 256).\n" - "\n" - "Subtract The result of image - image window, with underflow\n" - " wrapping around (mod 256). The add and subtract\n" - " operators can be used to perform reversible\n" - " transformations.\n" - "\n" - "Difference\n" - " The result of abs(image - image window). This\n" - " useful for comparing two very similar images.\n" - "\n" - "Multiply\n" - " The result of image * image window. This\n" - " useful for the creation of drop-shadows.\n" - "\n" - "Bumpmap The result of surface normals from image * image\n" - " window.\n" - "\n" - "Copy The resulting image is image window replaced with\n" - " image. Here the matte information is ignored.\n" - "\n" - "CopyRed The red layer of the image window is replace with\n" - " the red layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "CopyGreen\n" - " The green layer of the image window is replace with\n" - " the green layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "CopyBlue The blue layer of the image window is replace with\n" - " the blue layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "CopyOpacity\n" - " The matte layer of the image window is replace with\n" - " the matte layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "The image compositor requires a matte, or alpha channel in\n" - "the image for some operations. This extra channel usually\n" - "defines a mask which represents a sort of a cookie-cutter\n" - "for the image. This the case when matte is opaque (full\n" - "coverage) for pixels inside the shape, zero outside, and\n" - "between 0 and QuantumRange on the boundary. If image does not\n" - "have a matte channel, it is initialized with 0 for any pixel\n" - "matching in color to pixel location (0,0), otherwise QuantumRange.\n" - "\n" - "If you choose Dissolve, the composite operator becomes Over. The\n" - "image matte channel percent transparency is initialized to factor.\n" - "The image window is initialized to (100-factor). Where factor is the\n" - "value you specify in the Dialog widget.\n" - "\n" - "Displace shifts the image pixels as defined by a displacement\n" - "map. With this option, image is used as a displacement map.\n" - "Black, within the displacement map, is a maximum positive\n" - "displacement. White is a maximum negative displacement and\n" - "middle gray is neutral. The displacement is scaled to determine\n" - "the pixel shift. By default, the displacement applies in both the\n" - "horizontal and vertical directions. However, if you specify a mask,\n" - "image is the horizontal X displacement and mask the vertical Y\n" - "displacement.\n" - "\n" - "Note that matte information for image window is not retained\n" - "for colormapped X server visuals (e.g. StaticColor,\n" - "StaticColor, GrayScale, PseudoColor). Correct compositing\n" - "behavior may require a TrueColor or DirectColor visual or a\n" - "Standard Colormap.\n" - "\n" - "Choosing a composite operator is optional. The default\n" - "operator is replace. However, you must choose a location to\n" - "composite your image and press button 1. Press and hold the\n" - "button before releasing and an outline of the image will\n" - "appear to help you identify your location.\n" - "\n" - "The actual colors of the composite image is saved. However,\n" - "the color that appears in image window may be different.\n" - "For example, on a monochrome screen image window will appear\n" - "black or white even though your composited image may have\n" - "many colors. If the image is saved to a file it is written\n" - "with the correct colors. To assure the correct colors are\n" - "saved in the final image, any PseudoClass image is promoted\n" - "to DirectClass (see miff(5)). To force a PseudoClass image\n" - "to remain PseudoClass, use -colors.\n" - }, - ImageCutHelp[] = - { - "In cut mode, the Command widget has these options:\n" - "\n" - " Help\n" - " Dismiss\n" - "\n" - "To define a cut region, press button 1 and drag. The\n" - "cut region is defined by a highlighted rectangle that\n" - "expands or contracts as it follows the pointer. Once you\n" - "are satisfied with the cut region, release the button.\n" - "You are now in rectify mode. In rectify mode, the Command\n" - "widget has these options:\n" - "\n" - " Cut\n" - " Help\n" - " Dismiss\n" - "\n" - "You can make adjustments by moving the pointer to one of the\n" - "cut rectangle corners, pressing a button, and dragging.\n" - "Finally, press Cut to commit your copy region. To\n" - "exit without cutting the image, press Dismiss.\n" - }, - ImageCopyHelp[] = - { - "In copy mode, the Command widget has these options:\n" - "\n" - " Help\n" - " Dismiss\n" - "\n" - "To define a copy region, press button 1 and drag. The\n" - "copy region is defined by a highlighted rectangle that\n" - "expands or contracts as it follows the pointer. Once you\n" - "are satisfied with the copy region, release the button.\n" - "You are now in rectify mode. In rectify mode, the Command\n" - "widget has these options:\n" - "\n" - " Copy\n" - " Help\n" - " Dismiss\n" - "\n" - "You can make adjustments by moving the pointer to one of the\n" - "copy rectangle corners, pressing a button, and dragging.\n" - "Finally, press Copy to commit your copy region. To\n" - "exit without copying the image, press Dismiss.\n" - }, - ImageCropHelp[] = - { - "In crop mode, the Command widget has these options:\n" - "\n" - " Help\n" - " Dismiss\n" - "\n" - "To define a cropping region, press button 1 and drag. The\n" - "cropping region is defined by a highlighted rectangle that\n" - "expands or contracts as it follows the pointer. Once you\n" - "are satisfied with the cropping region, release the button.\n" - "You are now in rectify mode. In rectify mode, the Command\n" - "widget has these options:\n" - "\n" - " Crop\n" - " Help\n" - " Dismiss\n" - "\n" - "You can make adjustments by moving the pointer to one of the\n" - "cropping rectangle corners, pressing a button, and dragging.\n" - "Finally, press Crop to commit your cropping region. To\n" - "exit without cropping the image, press Dismiss.\n" - }, - ImageDrawHelp[] = - { - "The cursor changes to a crosshair to indicate you are in\n" - "draw mode. To exit immediately, press Dismiss. In draw mode,\n" - "the Command widget has these options:\n" - "\n" - " Element\n" - " point\n" - " line\n" - " rectangle\n" - " fill rectangle\n" - " circle\n" - " fill circle\n" - " ellipse\n" - " fill ellipse\n" - " polygon\n" - " fill polygon\n" - " Color\n" - " black\n" - " blue\n" - " cyan\n" - " green\n" - " gray\n" - " red\n" - " magenta\n" - " yellow\n" - " white\n" - " transparent\n" - " Browser...\n" - " Stipple\n" - " Brick\n" - " Diagonal\n" - " Scales\n" - " Vertical\n" - " Wavy\n" - " Translucent\n" - " Opaque\n" - " Open...\n" - " Width\n" - " 1\n" - " 2\n" - " 4\n" - " 8\n" - " 16\n" - " Dialog...\n" - " Undo\n" - " Help\n" - " Dismiss\n" - "\n" - "Choose a drawing primitive from the Element sub-menu.\n" - "\n" - "Choose a color from the Color sub-menu. Additional\n" - "colors can be specified with the color browser.\n" - "\n" - "If you choose the color browser and press Grab, you can\n" - "select the color by moving the pointer to the desired\n" - "color on the screen and press any button. The transparent\n" - "color updates the image matte channel and is useful for\n" - "image compositing.\n" - "\n" - "Choose a stipple, if appropriate, from the Stipple sub-menu.\n" - "Additional stipples can be specified with the file browser.\n" - "Stipples obtained from the file browser must be on disk in the\n" - "X11 bitmap format.\n" - "\n" - "Choose a width, if appropriate, from the Width sub-menu. To\n" - "choose a specific width select the Dialog widget.\n" - "\n" - "Choose a point in the Image window and press button 1 and\n" - "hold. Next, move the pointer to another location in the\n" - "image. As you move, a line connects the initial location and\n" - "the pointer. When you release the button, the image is\n" - "updated with the primitive you just drew. For polygons, the\n" - "image is updated when you press and release the button without\n" - "moving the pointer.\n" - "\n" - "To cancel image drawing, move the pointer back to the\n" - "starting point of the line and release the button.\n" - }, - DisplayHelp[] = - { - "BUTTONS\n" - " The effects of each button press is described below. Three\n" - " buttons are required. If you have a two button mouse,\n" - " button 1 and 3 are returned. Press ALT and button 3 to\n" - " simulate button 2.\n" - "\n" - " 1 Press this button to map or unmap the Command widget.\n" - "\n" - " 2 Press and drag to define a region of the image to\n" - " magnify.\n" - "\n" - " 3 Press and drag to choose from a select set of commands.\n" - " This button behaves differently if the image being\n" - " displayed is a visual image directory. Here, choose a\n" - " particular tile of the directory and press this button and\n" - " drag to select a command from a pop-up menu. Choose from\n" - " these menu items:\n" - "\n" - " Open\n" - " Next\n" - " Former\n" - " Delete\n" - " Update\n" - "\n" - " If you choose Open, the image represented by the tile is\n" - " displayed. To return to the visual image directory, choose\n" - " Next from the Command widget. Next and Former moves to the\n" - " next or former image respectively. Choose Delete to delete\n" - " a particular image tile. Finally, choose Update to\n" - " synchronize all the image tiles with their respective\n" - " images.\n" - "\n" - "COMMAND WIDGET\n" - " The Command widget lists a number of sub-menus and commands.\n" - " They are\n" - "\n" - " File\n" - " Open...\n" - " Next\n" - " Former\n" - " Select...\n" - " Save...\n" - " Print...\n" - " Delete...\n" - " New...\n" - " Visual Directory...\n" - " Quit\n" - " Edit\n" - " Undo\n" - " Redo\n" - " Cut\n" - " Copy\n" - " Paste\n" - " View\n" - " Half Size\n" - " Original Size\n" - " Double Size\n" - " Resize...\n" - " Apply\n" - " Refresh\n" - " Restore\n" - " Transform\n" - " Crop\n" - " Chop\n" - " Flop\n" - " Flip\n" - " Rotate Right\n" - " Rotate Left\n" - " Rotate...\n" - " Shear...\n" - " Roll...\n" - " Trim Edges\n" - " Enhance\n" - " Brightness...\n" - " Saturation...\n" - " Hue...\n" - " Gamma...\n" - " Sharpen...\n" - " Dull\n" - " Contrast Stretch...\n" - " Sigmoidal Contrast...\n" - " Normalize\n" - " Equalize\n" - " Negate\n" - " Grayscale\n" - " Map...\n" - " Quantize...\n" - " Effects\n" - " Despeckle\n" - " Emboss\n" - " Reduce Noise\n" - " Add Noise\n" - " Sharpen...\n" - " Blur...\n" - " Threshold...\n" - " Edge Detect...\n" - " Spread...\n" - " Shade...\n" - " Painting...\n" - " Segment...\n" - " F/X\n" - " Solarize...\n" - " Sepia Tone...\n" - " Swirl...\n" - " Implode...\n" - " Vignette...\n" - " Wave...\n" - " Oil Painting...\n" - " Charcoal Drawing...\n" - " Image Edit\n" - " Annotate...\n" - " Draw...\n" - " Color...\n" - " Matte...\n" - " Composite...\n" - " Add Border...\n" - " Add Frame...\n" - " Comment...\n" - " Launch...\n" - " Region of Interest...\n" - " Miscellany\n" - " Image Info\n" - " Zoom Image\n" - " Show Preview...\n" - " Show Histogram\n" - " Show Matte\n" - " Background...\n" - " Slide Show\n" - " Preferences...\n" - " Help\n" - " Overview\n" - " Browse Documentation\n" - " About Display\n" - "\n" - " Menu items with a indented triangle have a sub-menu. They\n" - " are represented above as the indented items. To access a\n" - " sub-menu item, move the pointer to the appropriate menu and\n" - " press a button and drag. When you find the desired sub-menu\n" - " item, release the button and the command is executed. Move\n" - " the pointer away from the sub-menu if you decide not to\n" - " execute a particular command.\n" - "\n" - "KEYBOARD ACCELERATORS\n" - " Accelerators are one or two key presses that effect a\n" - " particular command. The keyboard accelerators that\n" - " display(1) understands is:\n" - "\n" - " Ctl+O Press to open an image from a file.\n" - "\n" - " space Press to display the next image.\n" - "\n" - " If the image is a multi-paged document such as a Postscript\n" - " document, you can skip ahead several pages by preceding\n" - " this command with a number. For example to display the\n" - " third page beyond the current page, press 3.\n" - "\n" - " backspace Press to display the former image.\n" - "\n" - " If the image is a multi-paged document such as a Postscript\n" - " document, you can skip behind several pages by preceding\n" - " this command with a number. For example to display the\n" - " third page preceding the current page, press 3.\n" - "\n" - " Ctl+S Press to write the image to a file.\n" - "\n" - " Ctl+P Press to print the image to a Postscript printer.\n" - "\n" - " Ctl+D Press to delete an image file.\n" - "\n" - " Ctl+N Press to create a blank canvas.\n" - "\n" - " Ctl+Q Press to discard all images and exit program.\n" - "\n" - " Ctl+Z Press to undo last image transformation.\n" - "\n" - " Ctl+R Press to redo last image transformation.\n" - "\n" - " Ctl+X Press to cut a region of the image.\n" - "\n" - " Ctl+C Press to copy a region of the image.\n" - "\n" - " Ctl+V Press to paste a region to the image.\n" - "\n" - " < Press to half the image size.\n" - "\n" - " - Press to return to the original image size.\n" - "\n" - " > Press to double the image size.\n" - "\n" - " % Press to resize the image to a width and height you\n" - " specify.\n" - "\n" - "Cmd-A Press to make any image transformations permanent." - "\n" - " By default, any image size transformations are applied\n" - " to the original image to create the image displayed on\n" - " the X server. However, the transformations are not\n" - " permanent (i.e. the original image does not change\n" - " size only the X image does). For example, if you\n" - " press > the X image will appear to double in size,\n" - " but the original image will in fact remain the same size.\n" - " To force the original image to double in size, press >\n" - " followed by Cmd-A.\n" - "\n" - " @ Press to refresh the image window.\n" - "\n" - " C Press to cut out a rectangular region of the image.\n" - "\n" - " [ Press to chop the image.\n" - "\n" - " H Press to flop image in the horizontal direction.\n" - "\n" - " V Press to flip image in the vertical direction.\n" - "\n" - " / Press to rotate the image 90 degrees clockwise.\n" - "\n" - " \\ Press to rotate the image 90 degrees counter-clockwise.\n" - "\n" - " * Press to rotate the image the number of degrees you\n" - " specify.\n" - "\n" - " S Press to shear the image the number of degrees you\n" - " specify.\n" - "\n" - " R Press to roll the image.\n" - "\n" - " T Press to trim the image edges.\n" - "\n" - " Shft-H Press to vary the image hue.\n" - "\n" - " Shft-S Press to vary the color saturation.\n" - "\n" - " Shft-L Press to vary the color brightness.\n" - "\n" - " Shft-G Press to gamma correct the image.\n" - "\n" - " Shft-C Press to sharpen the image contrast.\n" - "\n" - " Shft-Z Press to dull the image contrast.\n" - "\n" - " = Press to perform histogram equalization on the image.\n" - "\n" - " Shft-N Press to perform histogram normalization on the image.\n" - "\n" - " Shft-~ Press to negate the colors of the image.\n" - "\n" - " . Press to convert the image colors to gray.\n" - "\n" - " Shft-# Press to set the maximum number of unique colors in the\n" - " image.\n" - "\n" - " F2 Press to reduce the speckles in an image.\n" - "\n" - " F3 Press to eliminate peak noise from an image.\n" - "\n" - " F4 Press to add noise to an image.\n" - "\n" - " F5 Press to sharpen an image.\n" - "\n" - " F6 Press to delete an image file.\n" - "\n" - " F7 Press to threshold the image.\n" - "\n" - " F8 Press to detect edges within an image.\n" - "\n" - " F9 Press to emboss an image.\n" - "\n" - " F10 Press to displace pixels by a random amount.\n" - "\n" - " F11 Press to negate all pixels above the threshold level.\n" - "\n" - " F12 Press to shade the image using a distant light source.\n" - "\n" - " F13 Press to lighten or darken image edges to create a 3-D effect.\n" - "\n" - " F14 Press to segment the image by color.\n" - "\n" - " Meta-S Press to swirl image pixels about the center.\n" - "\n" - " Meta-I Press to implode image pixels about the center.\n" - "\n" - " Meta-W Press to alter an image along a sine wave.\n" - "\n" - " Meta-P Press to simulate an oil painting.\n" - "\n" - " Meta-C Press to simulate a charcoal drawing.\n" - "\n" - " Alt-A Press to annotate the image with text.\n" - "\n" - " Alt-D Press to draw on an image.\n" - "\n" - " Alt-P Press to edit an image pixel color.\n" - "\n" - " Alt-M Press to edit the image matte information.\n" - "\n" - " Alt-V Press to composite the image with another.\n" - "\n" - " Alt-B Press to add a border to the image.\n" - "\n" - " Alt-F Press to add an ornamental border to the image.\n" - "\n" - " Alt-Shft-!\n" - " Press to add an image comment.\n" - "\n" - " Ctl-A Press to apply image processing techniques to a region\n" - " of interest.\n" - "\n" - " Shft-? Press to display information about the image.\n" - "\n" - " Shft-+ Press to map the zoom image window.\n" - "\n" - " Shft-P Press to preview an image enhancement, effect, or f/x.\n" - "\n" - " F1 Press to display helpful information about display(1).\n" - "\n" - " Find Press to browse documentation about ImageMagick.\n" - "\n" - " 1-9 Press to change the level of magnification.\n" - "\n" - " Use the arrow keys to move the image one pixel up, down,\n" - " left, or right within the magnify window. Be sure to first\n" - " map the magnify window by pressing button 2.\n" - "\n" - " Press ALT and one of the arrow keys to trim off one pixel\n" - " from any side of the image.\n" - }, - ImageMatteEditHelp[] = - { - "Matte information within an image is useful for some\n" - "operations such as image compositing (See IMAGE\n" - "COMPOSITING). This extra channel usually defines a mask\n" - "which represents a sort of a cookie-cutter for the image.\n" - "This the case when matte is opaque (full coverage) for\n" - "pixels inside the shape, zero outside, and between 0 and\n" - "QuantumRange on the boundary.\n" - "\n" - "A small window appears showing the location of the cursor in\n" - "the image window. You are now in matte edit mode. To exit\n" - "immediately, press Dismiss. In matte edit mode, the Command\n" - "widget has these options:\n" - "\n" - " Method\n" - " point\n" - " replace\n" - " floodfill\n" - " filltoborder\n" - " reset\n" - " Border Color\n" - " black\n" - " blue\n" - " cyan\n" - " green\n" - " gray\n" - " red\n" - " magenta\n" - " yellow\n" - " white\n" - " Browser...\n" - " Fuzz\n" - " 0%\n" - " 2%\n" - " 5%\n" - " 10%\n" - " 15%\n" - " Dialog...\n" - " Matte\n" - " Opaque\n" - " Transparent\n" - " Dialog...\n" - " Undo\n" - " Help\n" - " Dismiss\n" - "\n" - "Choose a matte editing method from the Method sub-menu of\n" - "the Command widget. The point method changes the matte value\n" - "of any pixel selected with the pointer until the button is\n" - "is released. The replace method changes the matte value of\n" - "any pixel that matches the color of the pixel you select with\n" - "a button press. Floodfill changes the matte value of any pixel\n" - "that matches the color of the pixel you select with a button\n" - "press and is a neighbor. Whereas filltoborder changes the matte\n" - "value any neighbor pixel that is not the border color. Finally\n" - "reset changes the entire image to the designated matte value.\n" - "\n" - "Choose Matte Value and pick Opaque or Transparent. For other values\n" - "select the Dialog entry. Here a dialog appears requesting a matte\n" - "value. The value you select is assigned as the opacity value of the\n" - "selected pixel or pixels.\n" - "\n" - "Now, press any button to select a pixel within the image\n" - "window to change its matte value.\n" - "\n" - "If the Magnify widget is mapped, it can be helpful in positioning\n" - "your pointer within the image (refer to button 2).\n" - "\n" - "Matte information is only valid in a DirectClass image.\n" - "Therefore, any PseudoClass image is promoted to DirectClass\n" - "(see miff(5)). Note that matte information for PseudoClass\n" - "is not retained for colormapped X server visuals (e.g.\n" - "StaticColor, StaticColor, GrayScale, PseudoColor) unless you\n" - "immediately save your image to a file (refer to Write).\n" - "Correct matte editing behavior may require a TrueColor or\n" - "DirectColor visual or a Standard Colormap.\n" - }, - ImagePanHelp[] = - { - "When an image exceeds the width or height of the X server\n" - "screen, display maps a small panning icon. The rectangle\n" - "within the panning icon shows the area that is currently\n" - "displayed in the image window. To pan about the image,\n" - "press any button and drag the pointer within the panning\n" - "icon. The pan rectangle moves with the pointer and the\n" - "image window is updated to reflect the location of the\n" - "rectangle within the panning icon. When you have selected\n" - "the area of the image you wish to view, release the button.\n" - "\n" - "Use the arrow keys to pan the image one pixel up, down,\n" - "left, or right within the image window.\n" - "\n" - "The panning icon is withdrawn if the image becomes smaller\n" - "than the dimensions of the X server screen.\n" - }, - ImagePasteHelp[] = - { - "A small window appears showing the location of the cursor in\n" - "the image window. You are now in paste mode. To exit\n" - "immediately, press Dismiss. In paste mode, the Command\n" - "widget has these options:\n" - "\n" - " Operators\n" - " over\n" - " in\n" - " out\n" - " atop\n" - " xor\n" - " plus\n" - " minus\n" - " add\n" - " subtract\n" - " difference\n" - " replace\n" - " Help\n" - " Dismiss\n" - "\n" - "Choose a composite operation from the Operators sub-menu of\n" - "the Command widget. How each operator behaves is described\n" - "below. Image window is the image currently displayed on\n" - "your X server and image is the image obtained with the File\n" - "Browser widget.\n" - "\n" - "Over The result is the union of the two image shapes,\n" - " with image obscuring image window in the region of\n" - " overlap.\n" - "\n" - "In The result is simply image cut by the shape of\n" - " image window. None of the image data of image\n" - " window is in the result.\n" - "\n" - "Out The resulting image is image with the shape of\n" - " image window cut out.\n" - "\n" - "Atop The result is the same shape as the image window,\n" - " with image obscuring image window where the image\n" - " shapes overlap. Note this differs from over\n" - " because the portion of image outside image window's\n" - " shape does not appear in the result.\n" - "\n" - "Xor The result is the image data from both image and\n" - " image window that is outside the overlap region.\n" - " The overlap region is blank.\n" - "\n" - "Plus The result is just the sum of the image data.\n" - " Output values are cropped to QuantumRange (no overflow).\n" - " This operation is independent of the matte\n" - " channels.\n" - "\n" - "Minus The result of image - image window, with underflow\n" - " cropped to zero.\n" - "\n" - "Add The result of image + image window, with overflow\n" - " wrapping around (mod 256).\n" - "\n" - "Subtract The result of image - image window, with underflow\n" - " wrapping around (mod 256). The add and subtract\n" - " operators can be used to perform reversible\n" - " transformations.\n" - "\n" - "Difference\n" - " The result of abs(image - image window). This\n" - " useful for comparing two very similar images.\n" - "\n" - "Copy The resulting image is image window replaced with\n" - " image. Here the matte information is ignored.\n" - "\n" - "CopyRed The red layer of the image window is replace with\n" - " the red layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "CopyGreen\n" - " The green layer of the image window is replace with\n" - " the green layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "CopyBlue The blue layer of the image window is replace with\n" - " the blue layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "CopyOpacity\n" - " The matte layer of the image window is replace with\n" - " the matte layer of the image. The other layers are\n" - " untouched.\n" - "\n" - "The image compositor requires a matte, or alpha channel in\n" - "the image for some operations. This extra channel usually\n" - "defines a mask which represents a sort of a cookie-cutter\n" - "for the image. This the case when matte is opaque (full\n" - "coverage) for pixels inside the shape, zero outside, and\n" - "between 0 and QuantumRange on the boundary. If image does not\n" - "have a matte channel, it is initialized with 0 for any pixel\n" - "matching in color to pixel location (0,0), otherwise QuantumRange.\n" - "\n" - "Note that matte information for image window is not retained\n" - "for colormapped X server visuals (e.g. StaticColor,\n" - "StaticColor, GrayScale, PseudoColor). Correct compositing\n" - "behavior may require a TrueColor or DirectColor visual or a\n" - "Standard Colormap.\n" - "\n" - "Choosing a composite operator is optional. The default\n" - "operator is replace. However, you must choose a location to\n" - "paste your image and press button 1. Press and hold the\n" - "button before releasing and an outline of the image will\n" - "appear to help you identify your location.\n" - "\n" - "The actual colors of the pasted image is saved. However,\n" - "the color that appears in image window may be different.\n" - "For example, on a monochrome screen image window will appear\n" - "black or white even though your pasted image may have\n" - "many colors. If the image is saved to a file it is written\n" - "with the correct colors. To assure the correct colors are\n" - "saved in the final image, any PseudoClass image is promoted\n" - "to DirectClass (see miff(5)). To force a PseudoClass image\n" - "to remain PseudoClass, use -colors.\n" - }, - ImageROIHelp[] = - { - "In region of interest mode, the Command widget has these\n" - "options:\n" - "\n" - " Help\n" - " Dismiss\n" - "\n" - "To define a region of interest, press button 1 and drag.\n" - "The region of interest is defined by a highlighted rectangle\n" - "that expands or contracts as it follows the pointer. Once\n" - "you are satisfied with the region of interest, release the\n" - "button. You are now in apply mode. In apply mode the\n" - "Command widget has these options:\n" - "\n" - " File\n" - " Save...\n" - " Print...\n" - " Edit\n" - " Undo\n" - " Redo\n" - " Transform\n" - " Flop\n" - " Flip\n" - " Rotate Right\n" - " Rotate Left\n" - " Enhance\n" - " Hue...\n" - " Saturation...\n" - " Brightness...\n" - " Gamma...\n" - " Spiff\n" - " Dull\n" - " Contrast Stretch\n" - " Sigmoidal Contrast...\n" - " Normalize\n" - " Equalize\n" - " Negate\n" - " Grayscale\n" - " Map...\n" - " Quantize...\n" - " Effects\n" - " Despeckle\n" - " Emboss\n" - " Reduce Noise\n" - " Sharpen...\n" - " Blur...\n" - " Threshold...\n" - " Edge Detect...\n" - " Spread...\n" - " Shade...\n" - " Raise...\n" - " Segment...\n" - " F/X\n" - " Solarize...\n" - " Sepia Tone...\n" - " Swirl...\n" - " Implode...\n" - " Vignette...\n" - " Wave...\n" - " Oil Painting...\n" - " Charcoal Drawing...\n" - " Miscellany\n" - " Image Info\n" - " Zoom Image\n" - " Show Preview...\n" - " Show Histogram\n" - " Show Matte\n" - " Help\n" - " Dismiss\n" - "\n" - "You can make adjustments to the region of interest by moving\n" - "the pointer to one of the rectangle corners, pressing a\n" - "button, and dragging. Finally, choose an image processing\n" - "technique from the Command widget. You can choose more than\n" - "one image processing technique to apply to an area.\n" - "Alternatively, you can move the region of interest before\n" - "applying another image processing technique. To exit, press\n" - "Dismiss.\n" - }, - ImageRotateHelp[] = - { - "In rotate mode, the Command widget has these options:\n" - "\n" - " Pixel Color\n" - " black\n" - " blue\n" - " cyan\n" - " green\n" - " gray\n" - " red\n" - " magenta\n" - " yellow\n" - " white\n" - " Browser...\n" - " Direction\n" - " horizontal\n" - " vertical\n" - " Help\n" - " Dismiss\n" - "\n" - "Choose a background color from the Pixel Color sub-menu.\n" - "Additional background colors can be specified with the color\n" - "browser. You can change the menu colors by setting the X\n" - "resources pen1 through pen9.\n" - "\n" - "If you choose the color browser and press Grab, you can\n" - "select the background color by moving the pointer to the\n" - "desired color on the screen and press any button.\n" - "\n" - "Choose a point in the image window and press this button and\n" - "hold. Next, move the pointer to another location in the\n" - "image. As you move a line connects the initial location and\n" - "the pointer. When you release the button, the degree of\n" - "image rotation is determined by the slope of the line you\n" - "just drew. The slope is relative to the direction you\n" - "choose from the Direction sub-menu of the Command widget.\n" - "\n" - "To cancel the image rotation, move the pointer back to the\n" - "starting point of the line and release the button.\n" - }; - -/* - Enumeration declarations. -*/ -typedef enum -{ - CopyMode, - CropMode, - CutMode -} ClipboardMode; - -typedef enum -{ - OpenCommand, - NextCommand, - FormerCommand, - SelectCommand, - SaveCommand, - PrintCommand, - DeleteCommand, - NewCommand, - VisualDirectoryCommand, - QuitCommand, - UndoCommand, - RedoCommand, - CutCommand, - CopyCommand, - PasteCommand, - HalfSizeCommand, - OriginalSizeCommand, - DoubleSizeCommand, - ResizeCommand, - ApplyCommand, - RefreshCommand, - RestoreCommand, - CropCommand, - ChopCommand, - FlopCommand, - FlipCommand, - RotateRightCommand, - RotateLeftCommand, - RotateCommand, - ShearCommand, - RollCommand, - TrimCommand, - HueCommand, - SaturationCommand, - BrightnessCommand, - GammaCommand, - SpiffCommand, - DullCommand, - ContrastStretchCommand, - SigmoidalContrastCommand, - NormalizeCommand, - EqualizeCommand, - NegateCommand, - GrayscaleCommand, - MapCommand, - QuantizeCommand, - DespeckleCommand, - EmbossCommand, - ReduceNoiseCommand, - AddNoiseCommand, - SharpenCommand, - BlurCommand, - ThresholdCommand, - EdgeDetectCommand, - SpreadCommand, - ShadeCommand, - RaiseCommand, - SegmentCommand, - SolarizeCommand, - SepiaToneCommand, - SwirlCommand, - ImplodeCommand, - VignetteCommand, - WaveCommand, - OilPaintCommand, - CharcoalDrawCommand, - AnnotateCommand, - DrawCommand, - ColorCommand, - MatteCommand, - CompositeCommand, - AddBorderCommand, - AddFrameCommand, - CommentCommand, - LaunchCommand, - RegionOfInterestCommand, - ROIHelpCommand, - ROIDismissCommand, - InfoCommand, - ZoomCommand, - ShowPreviewCommand, - ShowHistogramCommand, - ShowMatteCommand, - BackgroundCommand, - SlideShowCommand, - PreferencesCommand, - HelpCommand, - BrowseDocumentationCommand, - VersionCommand, - SaveToUndoBufferCommand, - FreeBuffersCommand, - NullCommand -} CommandType; - -typedef enum -{ - AnnotateNameCommand, - AnnotateFontColorCommand, - AnnotateBackgroundColorCommand, - AnnotateRotateCommand, - AnnotateHelpCommand, - AnnotateDismissCommand, - TextHelpCommand, - TextApplyCommand, - ChopDirectionCommand, - ChopHelpCommand, - ChopDismissCommand, - HorizontalChopCommand, - VerticalChopCommand, - ColorEditMethodCommand, - ColorEditColorCommand, - ColorEditBorderCommand, - ColorEditFuzzCommand, - ColorEditUndoCommand, - ColorEditHelpCommand, - ColorEditDismissCommand, - CompositeOperatorsCommand, - CompositeDissolveCommand, - CompositeDisplaceCommand, - CompositeHelpCommand, - CompositeDismissCommand, - CropHelpCommand, - CropDismissCommand, - RectifyCopyCommand, - RectifyHelpCommand, - RectifyDismissCommand, - DrawElementCommand, - DrawColorCommand, - DrawStippleCommand, - DrawWidthCommand, - DrawUndoCommand, - DrawHelpCommand, - DrawDismissCommand, - MatteEditMethod, - MatteEditBorderCommand, - MatteEditFuzzCommand, - MatteEditValueCommand, - MatteEditUndoCommand, - MatteEditHelpCommand, - MatteEditDismissCommand, - PasteOperatorsCommand, - PasteHelpCommand, - PasteDismissCommand, - RotateColorCommand, - RotateDirectionCommand, - RotateCropCommand, - RotateSharpenCommand, - RotateHelpCommand, - RotateDismissCommand, - HorizontalRotateCommand, - VerticalRotateCommand, - TileLoadCommand, - TileNextCommand, - TileFormerCommand, - TileDeleteCommand, - TileUpdateCommand -} ModeType; - -/* - Stipples. -*/ -#define BricksWidth 20 -#define BricksHeight 20 -#define DiagonalWidth 16 -#define DiagonalHeight 16 -#define HighlightWidth 8 -#define HighlightHeight 8 -#define OpaqueWidth 8 -#define OpaqueHeight 8 -#define ScalesWidth 16 -#define ScalesHeight 16 -#define ShadowWidth 8 -#define ShadowHeight 8 -#define VerticalWidth 16 -#define VerticalHeight 16 -#define WavyWidth 16 -#define WavyHeight 16 - -/* - Constant declaration. -*/ -static const int - RoiDelta = 8; - -static const unsigned char - BricksBitmap[] = - { - 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, - 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, - 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0xff, 0xff, 0x0f, 0x03, 0x0c, 0x00, - 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0x03, 0x0c, 0x00, 0xff, 0xff, 0x0f, - 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01, 0x60, 0x80, 0x01 - }, - DiagonalBitmap[] = - { - 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88, - 0x11, 0x11, 0x22, 0x22, 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22, - 0x44, 0x44, 0x88, 0x88, 0x11, 0x11, 0x22, 0x22 - }, - ScalesBitmap[] = - { - 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3, 0x80, 0x80, 0x80, 0x80, - 0x41, 0x41, 0x3e, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0xe3, 0xe3, - 0x80, 0x80, 0x80, 0x80, 0x41, 0x41, 0x3e, 0x3e - }, - VerticalBitmap[] = - { - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 - }, - WavyBitmap[] = - { - 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfb, 0xff, - 0xe7, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xbf, - 0xff, 0xbf, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f - }; - -/* - Function prototypes. -*/ -static CommandType - XImageWindowCommand(Display *,XResourceInfo *,XWindows *, - const MagickStatusType,KeySym,Image **,ExceptionInfo *); - -static Image - *XMagickCommand(Display *,XResourceInfo *,XWindows *,const CommandType, - Image **,ExceptionInfo *), - *XOpenImage(Display *,XResourceInfo *,XWindows *,const MagickBooleanType), - *XTileImage(Display *,XResourceInfo *,XWindows *,Image *,XEvent *, - ExceptionInfo *), - *XVisualDirectoryImage(Display *,XResourceInfo *,XWindows *, - ExceptionInfo *); - -static MagickBooleanType - XAnnotateEditImage(Display *,XResourceInfo *,XWindows *,Image *, - ExceptionInfo *), - XBackgroundImage(Display *,XResourceInfo *,XWindows *,Image **, - ExceptionInfo *), - XChopImage(Display *,XResourceInfo *,XWindows *,Image **, - ExceptionInfo *), - XCropImage(Display *,XResourceInfo *,XWindows *,Image *,const ClipboardMode, - ExceptionInfo *), - XColorEditImage(Display *,XResourceInfo *,XWindows *,Image **, - ExceptionInfo *), - XCompositeImage(Display *,XResourceInfo *,XWindows *,Image *, - ExceptionInfo *), - XConfigureImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *), - XDrawEditImage(Display *,XResourceInfo *,XWindows *,Image **, - ExceptionInfo *), - XMatteEditImage(Display *,XResourceInfo *,XWindows *,Image **, - ExceptionInfo *), - XPasteImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *), - XPrintImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *), - XRotateImage(Display *,XResourceInfo *,XWindows *,double,Image **, - ExceptionInfo *), - XROIImage(Display *,XResourceInfo *,XWindows *,Image **,ExceptionInfo *), - XSaveImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *), - XTrimImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *); - -static void - XDrawPanRectangle(Display *,XWindows *), - XImageCache(Display *,XResourceInfo *,XWindows *,const CommandType,Image **, - ExceptionInfo *), - XMagnifyImage(Display *,XWindows *,XEvent *,ExceptionInfo *), - XMakePanImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *), - XPanImage(Display *,XWindows *,XEvent *,ExceptionInfo *), - XMagnifyWindowCommand(Display *,XWindows *,const MagickStatusType, - const KeySym,ExceptionInfo *), - XSetCropGeometry(Display *,XWindows *,RectangleInfo *,Image *), - XScreenEvent(Display *,XWindows *,XEvent *,ExceptionInfo *), - XTranslateImage(Display *,XWindows *,Image *,const KeySym); /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % -% D i s p l a y I m a g e s % ++ D i s p l a y I m a g e C o m m a n d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% DisplayImages() displays an image sequence to any X window screen. It -% returns a value other than 0 if successful. Check the exception member -% of image to determine the reason for any failure. +% DisplayImageCommand() displays a sequence of images on any workstation +% display running an X server. Display first determines the hardware +% capabilities of the workstation. If the number of unique colors in an image +% is less than or equal to the number the workstation can support, the image +% is displayed in an X window. Otherwise the number of colors in the image is +% first reduced to match the color resolution of the workstation before it is +% displayed. % -% The format of the DisplayImages method is: +% This means that a continuous-tone 24 bits/pixel image can display on a 8 +% bit pseudo-color device or monochrome device. In most instances the reduced +% color image closely resembles the original. Alternatively, a monochrome or +% pseudo-color image sequence can display on a continuous-tone 24 bits/pixels +% device. % -% MagickBooleanType DisplayImages(const ImageInfo *image_info, -% Image *images,ExceptionInfo *exception) +% The format of the DisplayImageCommand method is: +% +% MagickBooleanType DisplayImageCommand(ImageInfo *image_info,int argc, +% char **argv,char **metadata,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % -% o image: the image. +% o argc: the number of elements in the argument vector. +% +% o argv: A text array containing the command line arguments. +% +% o metadata: any metadata is returned here. % % o exception: return any errors or warnings in this structure. % */ -MagickExport MagickBooleanType DisplayImages(const ImageInfo *image_info, - Image *images,ExceptionInfo *exception) + +static MagickBooleanType DisplayUsage(void) { + static const char + buttons[] = + " 1 press to map or unmap the Command widget\n" + " 2 press and drag to magnify a region of an image\n" + " 3 press to load an image from a visual image directory", + miscellaneous[] = + " -debug events display copious debugging information\n" + " -help print program options\n" + " -list type print a list of supported option arguments\n" + " -log format format of debugging information\n" + " -version print version information", + operators[] = + " -auto-level automagically adjust color levels of image\n" + " -auto-orient automagically orient image\n" + " -border geometry surround image with a border of color\n" + " -clip clip along the first path from the 8BIM profile\n" + " -clip-path id clip along a named path from the 8BIM profile\n" + " -colors value preferred number of colors in the image\n" + " -contrast enhance or reduce the image contrast\n" + " -crop geometry preferred size and location of the cropped image\n" + " -decipher filename convert cipher pixels to plain pixels\n" + " -deskew threshold straighten an image\n" + " -despeckle reduce the speckles within an image\n" + " -edge factor apply a filter to detect edges in the image\n" + " -enhance apply a digital filter to enhance a noisy image\n" + " -equalize perform histogram equalization to an image\n" + " -extent geometry set the image size\n" + " -extract geometry extract area from image\n" + " -flip flip image in the vertical direction\n" + " -flop flop image in the horizontal direction\n" + " -frame geometry surround image with an ornamental border\n" + " -fuzz distance colors within this distance are considered equal\n" + " -gamma value level of gamma correction\n" + " -monochrome transform image to black and white\n" + " -negate replace every pixel with its complementary color\n" + " -normalize transform image to span the full range of colors\n" + " -raise value lighten/darken image edges to create a 3-D effect\n" + " -resample geometry change the resolution of an image\n" + " -resize geometry resize the image\n" + " -roll geometry roll an image vertically or horizontally\n" + " -rotate degrees apply Paeth rotation to the image\n" + " -sample geometry scale image with pixel sampling\n" + " -segment value segment an image\n" + " -sharpen geometry sharpen the image\n" + " -strip strip image of all profiles and comments\n" + " -threshold value threshold the image\n" + " -thumbnail geometry create a thumbnail of the image\n" + " -trim trim image edges", + settings[] = + " -alpha option on, activate, off, deactivate, set, opaque, copy\n" + " transparent, extract, background, or shape\n" + " -antialias remove pixel-aliasing\n" + " -authenticate password\n" + " decipher image with this password\n" + " -backdrop display image centered on a backdrop\n" + " -channel type apply option to select image channels\n" + " -colormap type Shared or Private\n" + " -colorspace type alternate image colorspace\n" + " -comment string annotate image with comment\n" + " -compress type type of pixel compression when writing the image\n" + " -define format:option\n" + " define one or more image format options\n" + " -delay value display the next image after pausing\n" + " -density geometry horizontal and vertical density of the image\n" + " -depth value image depth\n" + " -display server display image to this X server\n" + " -dispose method layer disposal method\n" + " -dither method apply error diffusion to image\n" + " -endian type endianness (MSB or LSB) of the image\n" + " -filter type use this filter when resizing an image\n" + " -format string output formatted image characteristics\n" + " -geometry geometry preferred size and location of the Image window\n" + " -gravity type horizontal and vertical backdrop placement\n" + " -identify identify the format and characteristics of the image\n" + " -immutable displayed image cannot be modified\n" + " -interlace type type of image interlacing scheme\n" + " -interpolate method pixel color interpolation method\n" + " -label string assign a label to an image\n" + " -limit type value pixel cache resource limit\n" + " -loop iterations loop images then exit\n" + " -map type display image using this Standard Colormap\n" + " -matte store matte channel if the image has one\n" + " -monitor monitor progress\n" + " -nostdin do not try to open stdin\n" + " -page geometry size and location of an image canvas\n" + " -profile filename add, delete, or apply an image profile\n" + " -quality value JPEG/MIFF/PNG compression level\n" + " -quantize colorspace reduce colors in this colorspace\n" + " -quiet suppress all warning messages\n" + " -regard-warnings pay attention to warning messages\n" + " -remote command execute a command in an remote display process\n" + " -repage geometry size and location of an image canvas (operator)\n" + " -respect-parentheses settings remain in effect until parenthesis boundary\n" + " -sampling-factor geometry\n" + " horizontal and vertical sampling factor\n" + " -scenes range image scene range\n" + " -seed value seed a new sequence of pseudo-random numbers\n" + " -set property value set an image property\n" + " -size geometry width and height of image\n" + " -support factor resize support: > 1.0 is blurry, < 1.0 is sharp\n" + " -texture filename name of texture to tile onto the image background\n" + " -transparent-color color\n" + " transparent color\n" + " -treedepth value color tree depth\n" + " -update seconds detect when image file is modified and redisplay\n" + " -verbose print detailed information about the image\n" + " -visual type display image using this visual type\n" + " -virtual-pixel method\n" + " virtual pixel access method\n" + " -window id display image to background of this window\n" + " -window-group id exit program when this window id is destroyed\n" + " -write filename write image to a file", + sequence_operators[] = + " -coalesce merge a sequence of images\n" + " -flatten flatten a sequence of images"; + + ListMagickVersion(stdout); + (void) printf("Usage: %s [options ...] file [ [options ...] file ...]\n", + GetClientName()); + (void) printf("\nImage Settings:\n"); + (void) puts(settings); + (void) printf("\nImage Operators:\n"); + (void) puts(operators); + (void) printf("\nImage Sequence Operators:\n"); + (void) puts(sequence_operators); + (void) printf("\nMiscellaneous Options:\n"); + (void) puts(miscellaneous); + (void) printf( + "\nIn addition to those listed above, you can specify these standard X\n"); + (void) printf( + "resources as command line options: -background, -bordercolor,\n"); + (void) printf( + " -mattecolor, -borderwidth, -font, -foreground, -iconGeometry,\n"); + (void) printf("-iconic, -name, -shared-memory, -usePixmap, or -title.\n"); + (void) printf( + "\nBy default, the image format of 'file' is determined by its magic\n"); + (void) printf( + "number. To specify a particular image format, precede the filename\n"); + (void) printf( + "with an image format name and a colon (i.e. ps:image) or specify the\n"); + (void) printf( + "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n"); + (void) printf("'-' for standard input or output.\n"); + (void) printf("\nButtons: \n"); + (void) puts(buttons); + return(MagickTrue); +} + +WandExport MagickBooleanType DisplayImageCommand(ImageInfo *image_info, + int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception) +{ +#if defined(MAGICKCORE_X11_DELEGATE) +#define DestroyDisplay() \ +{ \ + if ((state & ExitState) == 0) \ + DestroyXResources(); \ + if (display != (Display *) NULL) \ + { \ + XCloseDisplay(display); \ + display=(Display *) NULL; \ + } \ + XDestroyResourceInfo(&resource_info); \ + DestroyImageStack(); \ + if (image_marker != (size_t *) NULL) \ + image_marker=(size_t *) RelinquishMagickMemory(image_marker); \ + for (i=0; i < (ssize_t) argc; i++) \ + argv[i]=DestroyString(argv[i]); \ + argv=(char **) RelinquishMagickMemory(argv); \ +} +#define ThrowDisplayException(asperity,tag,option) \ +{ \ + (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \ + option); \ + DestroyDisplay(); \ + return(MagickFalse); \ +} +#define ThrowDisplayInvalidArgumentException(option,argument) \ +{ \ + (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \ + "InvalidArgument","'%s': %s",option,argument); \ + DestroyDisplay(); \ + return(MagickFalse); \ +} + char - *argv[1]; + *resource_value, + *server_name; + + const char + *option; Display *display; @@ -1630,14637 +290,1616 @@ MagickExport MagickBooleanType DisplayImages(const ImageInfo *image_info, Image *image; + ImageStack + image_stack[MaxImageStackDepth+1]; + + MagickBooleanType + fire, + nostdin, + pend, + respect_parenthesis; + + MagickStatusType + status; + + QuantizeInfo + *quantize_info; + ssize_t i; size_t + *image_marker, + iterations, + last_image, state; - XrmDatabase - resource_database; + ssize_t + image_number, + iteration, + j, + k, + l; XResourceInfo resource_info; - assert(image_info != (const ImageInfo *) NULL); + XrmDatabase + resource_database; + + /* + Set defaults. + */ + assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); - assert(images != (Image *) NULL); - assert(images->signature == MagickCoreSignature); + assert(exception != (ExceptionInfo *) NULL); if (IsEventLogging() != MagickFalse) - (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); - display=XOpenDisplay(image_info->server_name); - if (display == (Display *) NULL) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); + if (argc == 2) { - (void) ThrowMagickException(exception,GetMagickModule(),XServerError, - "UnableToOpenXServer","`%s'",XDisplayName(image_info->server_name)); - return(MagickFalse); + option=argv[1]; + if ((LocaleCompare("version",option+1) == 0) || + (LocaleCompare("-version",option+1) == 0)) + { + ListMagickVersion(stdout); + return(MagickTrue); + } } - if (exception->severity != UndefinedException) - CatchException(exception); + SetNotifyHandlers; + display=(Display *) NULL; + j=1; + k=0; + image_marker=(size_t *) NULL; + image_number=0; + last_image=0; + NewImageStack(); + option=(char *) NULL; + pend=MagickFalse; + respect_parenthesis=MagickFalse; + nostdin=MagickFalse; + resource_database=(XrmDatabase) NULL; + (void) memset(&resource_info,0,sizeof(resource_info)); + server_name=(char *) NULL; + state=0; + status=MagickTrue; + ReadCommandlLine(argc,&argv); + status=ExpandFilenames(&argc,&argv); + if (status == MagickFalse) + ThrowDisplayException(ResourceLimitError,"MemoryAllocationFailed", + GetExceptionMessage(errno)); + image_marker=(size_t *) AcquireQuantumMemory((size_t) argc+1UL, + sizeof(*image_marker)); + if (image_marker == (size_t *) NULL) + ThrowDisplayException(ResourceLimitError,"MemoryAllocationFailed", + GetExceptionMessage(errno)); + for (i=0; i <= (ssize_t) argc; i++) + image_marker[i]=(size_t) argc; + /* + Check for server name specified on the command line. + */ + for (i=1; i < (ssize_t) argc; i++) + { + /* + Check command line for server name. + */ + option=argv[i]; + if (IsCommandOption(option) == MagickFalse) + continue; + if (LocaleCompare("display",option+1) == 0) + { + /* + User specified server name. + */ + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + server_name=argv[i]; + } + if (LocaleCompare("nostdin",option+1) == 0) + nostdin=MagickTrue; + if ((LocaleCompare("help",option+1) == 0) || + (LocaleCompare("-help",option+1) == 0)) + { + DestroyDisplay(); + return(DisplayUsage()); + } + } + /* + Get user defaults from X resource database. + */ + display=XOpenDisplay(server_name); + if (display == (Display *) NULL) + ThrowDisplayException(XServerError,"UnableToOpenXServer", + XDisplayName(server_name)); (void) XSetErrorHandler(XError); resource_database=XGetResourceDatabase(display,GetClientName()); - (void) memset(&resource_info,0,sizeof(resource_info)); - XGetResourceInfo(image_info,resource_database,GetClientName(),&resource_info); - if (image_info->page != (char *) NULL) - resource_info.image_geometry=AcquireString(image_info->page); - resource_info.immutable=MagickTrue; - argv[0]=AcquireString(GetClientName()); - state=DefaultState; - for (i=0; (state & ExitState) == 0; i++) + XGetResourceInfo(image_info,resource_database,GetClientName(), + &resource_info); + quantize_info=resource_info.quantize_info; + image_info->density=XGetResourceInstance(resource_database,GetClientName(), + "density",(char *) NULL); + if (image_info->density == (char *) NULL) + image_info->density=XGetScreenDensity(display); + resource_value=XGetResourceInstance(resource_database,GetClientName(), + "interlace","none"); + image_info->interlace=(InterlaceType) + ParseCommandOption(MagickInterlaceOptions,MagickFalse,resource_value); + image_info->page=XGetResourceInstance(resource_database,GetClientName(), + "pageGeometry",(char *) NULL); + resource_value=XGetResourceInstance(resource_database,GetClientName(), + "quality","75"); + image_info->quality=StringToUnsignedLong(resource_value); + resource_value=XGetResourceInstance(resource_database,GetClientName(), + "verbose","False"); + image_info->verbose=IsStringTrue(resource_value); + resource_value=XGetResourceInstance(resource_database,GetClientName(), + "dither","True"); + quantize_info->dither_method=IsStringTrue(resource_value) != MagickFalse ? + RiemersmaDitherMethod : NoDitherMethod; + /* + Parse command line. + */ + iteration=0; + for (i=1; ((i <= (ssize_t) argc) && ((state & ExitState) == 0)); i++) { - if ((images->iterations != 0) && (i >= (ssize_t) images->iterations)) - break; - image=GetImageFromList(images,i % GetImageListLength(images)); - (void) XDisplayImage(display,&resource_info,argv,1,&image,&state,exception); - } - (void) SetErrorHandler((ErrorHandler) NULL); - (void) SetWarningHandler((WarningHandler) NULL); - argv[0]=DestroyString(argv[0]); - (void) XCloseDisplay(display); - XDestroyResourceInfo(&resource_info); - if (exception->severity != UndefinedException) - return(MagickFalse); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -% R e m o t e D i s p l a y C o m m a n d % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% RemoteDisplayCommand() encourages a remote display program to display the -% specified image filename. -% -% The format of the RemoteDisplayCommand method is: -% -% MagickBooleanType RemoteDisplayCommand(const ImageInfo *image_info, -% const char *window,const char *filename,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o image_info: the image info. -% -% o window: Specifies the name or id of an X window. -% -% o filename: the name of the image filename to display. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType RemoteDisplayCommand(const ImageInfo *image_info, - const char *window,const char *filename,ExceptionInfo *exception) -{ - Display - *display; - - MagickStatusType - status; - - assert(image_info != (const ImageInfo *) NULL); - assert(image_info->signature == MagickCoreSignature); - assert(filename != (char *) NULL); - if (IsEventLogging() != MagickFalse) - (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); - display=XOpenDisplay(image_info->server_name); - if (display == (Display *) NULL) - { - (void) ThrowMagickException(exception,GetMagickModule(),XServerError, - "UnableToOpenXServer","`%s'",XDisplayName(image_info->server_name)); - return(MagickFalse); - } - (void) XSetErrorHandler(XError); - status=XRemoteCommand(display,window,filename); - (void) XCloseDisplay(display); - return(status != 0 ? MagickTrue : MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X A n n o t a t e E d i t I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XAnnotateEditImage() annotates the image with text. -% -% The format of the XAnnotateEditImage method is: -% -% MagickBooleanType XAnnotateEditImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -*/ - -static MagickBooleanType XAnnotateEditImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - ExceptionInfo *exception) -{ - const char - *const AnnotateMenu[] = - { - "Font Name", - "Font Color", - "Box Color", - "Rotate Text", - "Help", - "Dismiss", - (char *) NULL - }, - *const TextMenu[] = - { - "Help", - "Apply", - (char *) NULL - }; - - static const ModeType - AnnotateCommands[] = - { - AnnotateNameCommand, - AnnotateFontColorCommand, - AnnotateBackgroundColorCommand, - AnnotateRotateCommand, - AnnotateHelpCommand, - AnnotateDismissCommand - }, - TextCommands[] = - { - TextHelpCommand, - TextApplyCommand - }; - - static MagickBooleanType - transparent_box = MagickTrue, - transparent_pen = MagickFalse; - - static double - degrees = 0.0; - - static unsigned int - box_id = MaxNumberPens-2, - font_id = 0, - pen_id = 0; - - char - command[MagickPathExtent], - text[MagickPathExtent]; - - const char - *ColorMenu[MaxNumberPens+1]; - - Cursor - cursor; - - GC - annotate_context; - - int - id, - pen_number, - status, - x, - y; - - KeySym - key_symbol; - - char - *p; - - ssize_t - i; - - unsigned int - height, - width; - - size_t - state; - - XAnnotateInfo - *annotate_info, - *previous_info; - - XColor - color; - - XFontStruct - *font_info; - - XEvent - event, - text_event; - - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Annotate"); - windows->command.data=4; - (void) XCommandWidget(display,windows,AnnotateMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Track pointer until button 1 is pressed. - */ - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - cursor=XCreateFontCursor(display,XC_left_side); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ", - x+windows->image.x,y+windows->image.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,AnnotateMenu,&event); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - if (id < 0) - continue; - switch (AnnotateCommands[id]) - { - case AnnotateNameCommand: - { - const char - *FontMenu[MaxNumberFonts]; - - int - font_number; - - /* - Initialize menu selections. - */ - for (i=0; i < MaxNumberFonts; i++) - FontMenu[i]=resource_info->font_name[i]; - FontMenu[MaxNumberFonts-2]="Browser..."; - FontMenu[MaxNumberFonts-1]=(const char *) NULL; - /* - Select a font name from the pop-up menu. - */ - font_number=XMenuWidget(display,windows,AnnotateMenu[id], - (const char **) FontMenu,command); - if (font_number < 0) - break; - if (font_number == (MaxNumberFonts-2)) - { - static char - font_name[MagickPathExtent] = "fixed"; - - /* - Select a font name from a browser. - */ - resource_info->font_name[font_number]=font_name; - XFontBrowserWidget(display,windows,"Select",font_name); - if (*font_name == '\0') - break; - } - /* - Initialize font info. - */ - font_info=XLoadQueryFont(display,resource_info->font_name[ - font_number]); - if (font_info == (XFontStruct *) NULL) - { - XNoticeWidget(display,windows,"Unable to load font:", - resource_info->font_name[font_number]); - break; - } - font_id=(unsigned int) font_number; - (void) XFreeFont(display,font_info); - break; - } - case AnnotateFontColorCommand: - { - /* - Initialize menu selections. - */ - for (i=0; i < (int) (MaxNumberPens-2); i++) - ColorMenu[i]=resource_info->pen_colors[i]; - ColorMenu[MaxNumberPens-2]="transparent"; - ColorMenu[MaxNumberPens-1]="Browser..."; - ColorMenu[MaxNumberPens]=(const char *) NULL; - /* - Select a pen color from the pop-up menu. - */ - pen_number=XMenuWidget(display,windows,AnnotateMenu[id], - (const char **) ColorMenu,command); - if (pen_number < 0) - break; - transparent_pen=pen_number == (MaxNumberPens-2) ? MagickTrue : - MagickFalse; - if (transparent_pen != MagickFalse) - break; - if (pen_number == (MaxNumberPens-1)) - { - static char - color_name[MagickPathExtent] = "gray"; - - /* - Select a pen color from a dialog. - */ - resource_info->pen_colors[pen_number]=color_name; - XColorBrowserWidget(display,windows,"Select",color_name); - if (*color_name == '\0') - break; - } - /* - Set pen color. - */ - (void) XParseColor(display,windows->map_info->colormap, - resource_info->pen_colors[pen_number],&color); - XBestPixel(display,windows->map_info->colormap,(XColor *) NULL, - (unsigned int) MaxColors,&color); - windows->pixel_info->pen_colors[pen_number]=color; - pen_id=(unsigned int) pen_number; - break; - } - case AnnotateBackgroundColorCommand: - { - /* - Initialize menu selections. - */ - for (i=0; i < (int) (MaxNumberPens-2); i++) - ColorMenu[i]=resource_info->pen_colors[i]; - ColorMenu[MaxNumberPens-2]="transparent"; - ColorMenu[MaxNumberPens-1]="Browser..."; - ColorMenu[MaxNumberPens]=(const char *) NULL; - /* - Select a pen color from the pop-up menu. - */ - pen_number=XMenuWidget(display,windows,AnnotateMenu[id], - (const char **) ColorMenu,command); - if (pen_number < 0) - break; - transparent_box=pen_number == (MaxNumberPens-2) ? MagickTrue : - MagickFalse; - if (transparent_box != MagickFalse) - break; - if (pen_number == (MaxNumberPens-1)) - { - static char - color_name[MagickPathExtent] = "gray"; - - /* - Select a pen color from a dialog. - */ - resource_info->pen_colors[pen_number]=color_name; - XColorBrowserWidget(display,windows,"Select",color_name); - if (*color_name == '\0') - break; - } - /* - Set pen color. - */ - (void) XParseColor(display,windows->map_info->colormap, - resource_info->pen_colors[pen_number],&color); - XBestPixel(display,windows->map_info->colormap,(XColor *) NULL, - (unsigned int) MaxColors,&color); - windows->pixel_info->pen_colors[pen_number]=color; - box_id=(unsigned int) pen_number; - break; - } - case AnnotateRotateCommand: - { - int - entry; - - const char - *const RotateMenu[] = - { - "-90", - "-45", - "-30", - "0", - "30", - "45", - "90", - "180", - "Dialog...", - (char *) NULL, - }; - - static char - angle[MagickPathExtent] = "30.0"; - - /* - Select a command from the pop-up menu. - */ - entry=XMenuWidget(display,windows,AnnotateMenu[id],RotateMenu, - command); - if (entry < 0) - break; - if (entry != 8) - { - degrees=StringToDouble(RotateMenu[entry],(char **) NULL); - break; - } - (void) XDialogWidget(display,windows,"OK","Enter rotation angle:", - angle); - if (*angle == '\0') - break; - degrees=StringToDouble(angle,(char **) NULL); - break; - } - case AnnotateHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Annotation",ImageAnnotateHelp); - break; - } - case AnnotateDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - Change to text entering mode. - */ - x=event.xbutton.x; - y=event.xbutton.y; - state|=ExitState; - break; - } - case ButtonRelease: - break; - case Expose: - break; - case KeyPress: - { - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Annotation",ImageAnnotateHelp); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - break; - } - default: - break; - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if ((state & EscapeState) != 0) - return(MagickTrue); - /* - Set font info and check boundary conditions. - */ - font_info=XLoadQueryFont(display,resource_info->font_name[font_id]); - if (font_info == (XFontStruct *) NULL) - { - XNoticeWidget(display,windows,"Unable to load font:", - resource_info->font_name[font_id]); - font_info=windows->font_info; - } - if ((x+font_info->max_bounds.width) >= (int) windows->image.width) - x=(int) windows->image.width-font_info->max_bounds.width; - if (y < (int) (font_info->ascent+font_info->descent)) - y=(int) font_info->ascent+font_info->descent; - if (((int) font_info->max_bounds.width > (int) windows->image.width) || - ((font_info->ascent+font_info->descent) >= (int) windows->image.height)) - return(MagickFalse); - /* - Initialize annotate structure. - */ - annotate_info=(XAnnotateInfo *) AcquireMagickMemory(sizeof(*annotate_info)); - if (annotate_info == (XAnnotateInfo *) NULL) - return(MagickFalse); - XGetAnnotateInfo(annotate_info); - annotate_info->x=x; - annotate_info->y=y; - if ((transparent_box == MagickFalse) && (transparent_pen == MagickFalse)) - annotate_info->stencil=OpaqueStencil; - else - if (transparent_box == MagickFalse) - annotate_info->stencil=BackgroundStencil; + if (i < (ssize_t) argc) + option=argv[i]; else - annotate_info->stencil=ForegroundStencil; - annotate_info->height=(unsigned int) font_info->ascent+font_info->descent; - annotate_info->degrees=degrees; - annotate_info->font_info=font_info; - annotate_info->text=(char *) AcquireQuantumMemory((size_t) - windows->image.width/MagickMax((ssize_t) font_info->min_bounds.width,1)+2UL, - sizeof(*annotate_info->text)); - if (annotate_info->text == (char *) NULL) - return(MagickFalse); - /* - Create cursor and set graphic context. - */ - cursor=XCreateFontCursor(display,XC_pencil); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - annotate_context=windows->image.annotate_context; - (void) XSetFont(display,annotate_context,font_info->fid); - (void) XSetBackground(display,annotate_context, - windows->pixel_info->pen_colors[box_id].pixel); - (void) XSetForeground(display,annotate_context, - windows->pixel_info->pen_colors[pen_id].pixel); - /* - Begin annotating the image with text. - */ - (void) CloneString(&windows->command.name,"Text"); - windows->command.data=0; - (void) XCommandWidget(display,windows,TextMenu,(XEvent *) NULL); - state=DefaultState; - (void) XDrawString(display,windows->image.id,annotate_context,x,y,"_",1); - text_event.xexpose.width=(int) font_info->max_bounds.width; - text_event.xexpose.height=font_info->max_bounds.ascent+ - font_info->max_bounds.descent; - p=annotate_info->text; - do - { - /* - Display text cursor. - */ - *p='\0'; - (void) XDrawString(display,windows->image.id,annotate_context,x,y,"_",1); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - (void) XSetBackground(display,annotate_context, - windows->pixel_info->background_color.pixel); - (void) XSetForeground(display,annotate_context, - windows->pixel_info->foreground_color.pixel); - id=XCommandWidget(display,windows,AnnotateMenu,&event); - (void) XSetBackground(display,annotate_context, - windows->pixel_info->pen_colors[box_id].pixel); - (void) XSetForeground(display,annotate_context, - windows->pixel_info->pen_colors[pen_id].pixel); - if (id < 0) - continue; - switch (TextCommands[id]) - { - case TextHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Annotation",ImageAnnotateHelp); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - break; - } - case TextApplyCommand: - { - /* - Finished annotating. - */ - annotate_info->width=(unsigned int) XTextWidth(font_info, - annotate_info->text,(int) strlen(annotate_info->text)); - XRefreshWindow(display,&windows->image,&text_event); - state|=ExitState; - break; - } - default: - break; - } - continue; - } - /* - Erase text cursor. - */ - text_event.xexpose.x=x; - text_event.xexpose.y=y-font_info->max_bounds.ascent; - (void) XClearArea(display,windows->image.id,x,text_event.xexpose.y, - (unsigned int) text_event.xexpose.width,(unsigned int) - text_event.xexpose.height,MagickFalse); - XRefreshWindow(display,&windows->image,&text_event); - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.window != windows->image.id) - break; - if (event.xbutton.button == Button2) - { - /* - Request primary selection. - */ - (void) XConvertSelection(display,XA_PRIMARY,XA_STRING,XA_STRING, - windows->image.id,CurrentTime); - break; - } + if (image != (Image *) NULL) break; - } - case Expose: - { - if (event.xexpose.count == 0) - { - XAnnotateInfo - *text_info; - - /* - Refresh Image window. - */ - XRefreshWindow(display,&windows->image,(XEvent *) NULL); - text_info=annotate_info; - while (text_info != (XAnnotateInfo *) NULL) - { - if (annotate_info->stencil == ForegroundStencil) - (void) XDrawString(display,windows->image.id,annotate_context, - text_info->x,text_info->y,text_info->text, - (int) strlen(text_info->text)); - else - (void) XDrawImageString(display,windows->image.id, - annotate_context,text_info->x,text_info->y,text_info->text, - (int) strlen(text_info->text)); - text_info=text_info->previous; - } - (void) XDrawString(display,windows->image.id,annotate_context, - x,y,"_",1); - } - break; - } - case KeyPress: - { - int - length; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - length=XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - *(command+length)='\0'; - if (((event.xkey.state & ControlMask) != 0) || - ((event.xkey.state & Mod1Mask) != 0)) - state|=ModifierState; - if ((state & ModifierState) != 0) - switch ((int) key_symbol) - { - case XK_u: - case XK_U: - { - key_symbol=DeleteCommand; - break; - } - default: - break; - } - switch ((int) key_symbol) - { - case XK_BackSpace: - { - /* - Erase one character. - */ - if (p == annotate_info->text) - { - if (annotate_info->previous == (XAnnotateInfo *) NULL) - break; - else - { - /* - Go to end of the previous line of text. - */ - annotate_info=annotate_info->previous; - p=annotate_info->text; - x=annotate_info->x+annotate_info->width; - y=annotate_info->y; - if (annotate_info->width != 0) - p+=strlen(annotate_info->text); - break; - } - } - p--; - x-=XTextWidth(font_info,p,1); - text_event.xexpose.x=x; - text_event.xexpose.y=y-font_info->max_bounds.ascent; - XRefreshWindow(display,&windows->image,&text_event); - break; - } - case XK_bracketleft: - { - key_symbol=XK_Escape; - break; - } - case DeleteCommand: - { - /* - Erase the entire line of text. - */ - while (p != annotate_info->text) - { - p--; - x-=XTextWidth(font_info,p,1); - text_event.xexpose.x=x; - XRefreshWindow(display,&windows->image,&text_event); - } - break; - } - case XK_Escape: - case XK_F20: - { - /* - Finished annotating. - */ - annotate_info->width=(unsigned int) XTextWidth(font_info, - annotate_info->text,(int) strlen(annotate_info->text)); - XRefreshWindow(display,&windows->image,&text_event); - state|=ExitState; - break; - } - default: - { - /* - Draw a single character on the Image window. - */ - if ((state & ModifierState) != 0) - break; - if (*command == '\0') - break; - *p=(*command); - if (annotate_info->stencil == ForegroundStencil) - (void) XDrawString(display,windows->image.id,annotate_context, - x,y,p,1); - else - (void) XDrawImageString(display,windows->image.id, - annotate_context,x,y,p,1); - x+=XTextWidth(font_info,p,1); - p++; - if ((x+font_info->max_bounds.width) < (int) windows->image.width) - break; - } - case XK_Return: - case XK_KP_Enter: - { - /* - Advance to the next line of text. - */ - *p='\0'; - annotate_info->width=(unsigned int) XTextWidth(font_info, - annotate_info->text,(int) strlen(annotate_info->text)); - if (annotate_info->next != (XAnnotateInfo *) NULL) - { - /* - Line of text already exists. - */ - annotate_info=annotate_info->next; - x=annotate_info->x; - y=annotate_info->y; - p=annotate_info->text; - break; - } - annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1, - sizeof(*annotate_info->next)); - if (annotate_info->next == (XAnnotateInfo *) NULL) - return(MagickFalse); - *annotate_info->next=(*annotate_info); - annotate_info->next->previous=annotate_info; - annotate_info=annotate_info->next; - annotate_info->text=(char *) AcquireQuantumMemory((size_t) - windows->image.width/MagickMax((ssize_t) - font_info->min_bounds.width,1)+2UL,sizeof(*annotate_info->text)); - if (annotate_info->text == (char *) NULL) - return(MagickFalse); - annotate_info->y+=annotate_info->height; - if (annotate_info->y > (int) windows->image.height) - annotate_info->y=(int) annotate_info->height; - annotate_info->next=(XAnnotateInfo *) NULL; - x=annotate_info->x; - y=annotate_info->y; - p=annotate_info->text; - break; - } - } - break; - } - case KeyRelease: - { - /* - Respond to a user key release. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - state&=(~ModifierState); - break; - } - case SelectionNotify: - { - Atom - type; - - int - format; - - unsigned char - *data; - - unsigned long - after, - length; - - /* - Obtain response from primary selection. - */ - if (event.xselection.property == (Atom) None) - break; - status=XGetWindowProperty(display,event.xselection.requestor, - event.xselection.property,0L,(long) MagickPathExtent,True,XA_STRING, - &type,&format,&length,&after,&data); - if ((status != Success) || (type != XA_STRING) || (format == 32) || - (length == 0)) - break; - /* - Annotate Image window with primary selection. - */ - for (i=0; i < (ssize_t) length; i++) - { - if ((char) data[i] != '\n') - { - /* - Draw a single character on the Image window. - */ - *p=(char) data[i]; - (void) XDrawString(display,windows->image.id,annotate_context, - x,y,p,1); - x+=XTextWidth(font_info,p,1); - p++; - if ((x+font_info->max_bounds.width) < (int) windows->image.width) - continue; - } - /* - Advance to the next line of text. - */ - *p='\0'; - annotate_info->width=(unsigned int) XTextWidth(font_info, - annotate_info->text,(int) strlen(annotate_info->text)); - if (annotate_info->next != (XAnnotateInfo *) NULL) - { - /* - Line of text already exists. - */ - annotate_info=annotate_info->next; - x=annotate_info->x; - y=annotate_info->y; - p=annotate_info->text; - continue; - } - annotate_info->next=(XAnnotateInfo *) AcquireQuantumMemory(1, - sizeof(*annotate_info->next)); - if (annotate_info->next == (XAnnotateInfo *) NULL) - return(MagickFalse); - *annotate_info->next=(*annotate_info); - annotate_info->next->previous=annotate_info; - annotate_info=annotate_info->next; - annotate_info->text=(char *) AcquireQuantumMemory((size_t) - windows->image.width/MagickMax((ssize_t) - font_info->min_bounds.width,1)+2UL,sizeof(*annotate_info->text)); - if (annotate_info->text == (char *) NULL) - return(MagickFalse); - annotate_info->y+=annotate_info->height; - if (annotate_info->y > (int) windows->image.height) - annotate_info->y=(int) annotate_info->height; - annotate_info->next=(XAnnotateInfo *) NULL; - x=annotate_info->x; - y=annotate_info->y; - p=annotate_info->text; - } - (void) XFree((void *) data); - break; - } - default: - break; - } - } while ((state & ExitState) == 0); - (void) XFreeCursor(display,cursor); - /* - Annotation is relative to image configuration. - */ - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - /* - Initialize annotated image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - while (annotate_info != (XAnnotateInfo *) NULL) - { - if (annotate_info->width == 0) - { - /* - No text on this line-- go to the next line of text. - */ - previous_info=annotate_info->previous; - annotate_info->text=(char *) - RelinquishMagickMemory(annotate_info->text); - annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info); - annotate_info=previous_info; - continue; - } - /* - Determine pixel index for box and pen color. - */ - windows->pixel_info->box_color=windows->pixel_info->pen_colors[box_id]; - if (windows->pixel_info->colors != 0) - for (i=0; i < (ssize_t) windows->pixel_info->colors; i++) - if (windows->pixel_info->pixels[i] == - windows->pixel_info->pen_colors[box_id].pixel) - { - windows->pixel_info->box_index=(unsigned short) i; - break; - } - windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id]; - if (windows->pixel_info->colors != 0) - for (i=0; i < (ssize_t) windows->pixel_info->colors; i++) - if (windows->pixel_info->pixels[i] == - windows->pixel_info->pen_colors[pen_id].pixel) - { - windows->pixel_info->pen_index=(unsigned short) i; - break; - } - /* - Define the annotate geometry string. - */ - annotate_info->x=(int) - width*(annotate_info->x+windows->image.x)/windows->image.ximage->width; - annotate_info->y=(int) height*(annotate_info->y-font_info->ascent+ - windows->image.y)/windows->image.ximage->height; - (void) FormatLocaleString(annotate_info->geometry,MagickPathExtent, - "%ux%u%+d%+d",width*annotate_info->width/windows->image.ximage->width, - height*annotate_info->height/windows->image.ximage->height, - annotate_info->x+x,annotate_info->y+y); - /* - Annotate image with text. - */ - status=XAnnotateImage(display,windows->pixel_info,annotate_info,image, - exception); - if (status == 0) - return(MagickFalse); - /* - Free up memory. - */ - previous_info=annotate_info->previous; - annotate_info->text=DestroyString(annotate_info->text); - annotate_info=(XAnnotateInfo *) RelinquishMagickMemory(annotate_info); - annotate_info=previous_info; - } - (void) XSetForeground(display,annotate_context, - windows->pixel_info->foreground_color.pixel); - (void) XSetBackground(display,annotate_context, - windows->pixel_info->background_color.pixel); - (void) XSetFont(display,annotate_context,windows->font_info->fid); - XSetCursorState(display,windows,MagickFalse); - (void) XFreeFont(display,font_info); - /* - Update image configuration. - */ - XConfigureImageColormap(display,resource_info,windows,image,exception); - (void) XConfigureImage(display,resource_info,windows,image,exception); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X B a c k g r o u n d I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XBackgroundImage() displays the image in the background of a window. -% -% The format of the XBackgroundImage method is: -% -% MagickBooleanType XBackgroundImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XBackgroundImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image **image, - ExceptionInfo *exception) -{ -#define BackgroundImageTag "Background/Image" - - int - status; - - static char - window_id[MagickPathExtent] = "root"; - - XResourceInfo - background_resources; - - /* - Put image in background. - */ - status=XDialogWidget(display,windows,"Background", - "Enter window id (id 0x00 selects window with pointer):",window_id); - if (*window_id == '\0') - return(MagickFalse); - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XInfoWidget(display,windows,BackgroundImageTag); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - background_resources=(*resource_info); - background_resources.window_id=window_id; - background_resources.backdrop=status != 0 ? MagickTrue : MagickFalse; - status=XDisplayBackgroundImage(display,&background_resources,*image, - exception); - if (status != MagickFalse) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_retain_colors,CurrentTime); - XSetCursorState(display,windows,MagickFalse); - (void) XMagickCommand(display,resource_info,windows,UndoCommand,image, - exception); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X C h o p I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XChopImage() chops the X image. -% -% The format of the XChopImage method is: -% -% MagickBooleanType XChopImage(Display *display,XResourceInfo *resource_info, -% XWindows *windows,Image **image,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XChopImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image **image, - ExceptionInfo *exception) -{ - const char - *const ChopMenu[] = - { - "Direction", - "Help", - "Dismiss", - (char *) NULL - }; - - static ModeType - direction = HorizontalChopCommand; - - static const ModeType - ChopCommands[] = - { - ChopDirectionCommand, - ChopHelpCommand, - ChopDismissCommand - }, - DirectionCommands[] = - { - HorizontalChopCommand, - VerticalChopCommand - }; - - char - text[MagickPathExtent]; - - Image - *chop_image; - - int - id, - x, - y; - - double - scale_factor; - - RectangleInfo - chop_info; - - unsigned int - distance, - height, - width; - - size_t - state; - - XEvent - event; - - XSegment - segment_info; - - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Chop"); - windows->command.data=1; - (void) XCommandWidget(display,windows,ChopMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Track pointer until button 1 is pressed. - */ - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - state=DefaultState; - (void) memset(&segment_info,0,sizeof(segment_info)); - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ", - x+windows->image.x,y+windows->image.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,ChopMenu,&event); - if (id < 0) - continue; - switch (ChopCommands[id]) - { - case ChopDirectionCommand: - { - char - command[MagickPathExtent]; - - const char - *const Directions[] = - { - "horizontal", - "vertical", - (char *) NULL, - }; - - /* - Select a command from the pop-up menu. - */ - id=XMenuWidget(display,windows,ChopMenu[id],Directions,command); - if (id >= 0) - direction=DirectionCommands[id]; - break; - } - case ChopHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Chop",ImageChopHelp); - break; - } - case ChopDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - User has committed to start point of chopping line. - */ - segment_info.x1=(short int) event.xbutton.x; - segment_info.x2=(short int) event.xbutton.x; - segment_info.y1=(short int) event.xbutton.y; - segment_info.y2=(short int) event.xbutton.y; - state|=ExitState; - break; - } - case ButtonRelease: - break; - case Expose: - break; - case KeyPress: - { - char - command[MagickPathExtent]; - - KeySym - key_symbol; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Chop",ImageChopHelp); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - } - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if ((state & EscapeState) != 0) - return(MagickTrue); - /* - Draw line as pointer moves until the mouse button is released. - */ - chop_info.width=0; - chop_info.height=0; - chop_info.x=0; - chop_info.y=0; - distance=0; - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - state=DefaultState; - do - { - if (distance > 9) - { - /* - Display info and draw chopping line. - */ - if (windows->info.mapped == MagickFalse) - (void) XMapWindow(display,windows->info.id); - (void) FormatLocaleString(text,MagickPathExtent, - " %.20gx%.20g%+.20g%+.20g",(double) chop_info.width,(double) - chop_info.height,(double) chop_info.x,(double) chop_info.y); - XInfoWidget(display,windows,text); - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&segment_info); - } - else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (distance > 9) - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&segment_info); - switch (event.type) - { - case ButtonPress: - { - segment_info.x2=(short int) event.xmotion.x; - segment_info.y2=(short int) event.xmotion.y; - break; - } - case ButtonRelease: - { - /* - User has committed to chopping line. - */ - segment_info.x2=(short int) event.xbutton.x; - segment_info.y2=(short int) event.xbutton.y; - state|=ExitState; - break; - } - case Expose: - break; - case MotionNotify: - { - segment_info.x2=(short int) event.xmotion.x; - segment_info.y2=(short int) event.xmotion.y; - } - default: - break; - } - /* - Check boundary conditions. - */ - if (segment_info.x2 < 0) - segment_info.x2=0; - else - if (segment_info.x2 > windows->image.ximage->width) - segment_info.x2=windows->image.ximage->width; - if (segment_info.y2 < 0) - segment_info.y2=0; - else - if (segment_info.y2 > windows->image.ximage->height) - segment_info.y2=windows->image.ximage->height; - distance=(unsigned int) - (((segment_info.x2-segment_info.x1)*(segment_info.x2-segment_info.x1))+ - ((segment_info.y2-segment_info.y1)*(segment_info.y2-segment_info.y1))); - /* - Compute chopping geometry. - */ - if (direction == HorizontalChopCommand) - { - chop_info.width=(size_t) (segment_info.x2-segment_info.x1+1); - chop_info.x=(ssize_t) windows->image.x+segment_info.x1; - chop_info.height=0; - chop_info.y=0; - if (segment_info.x1 > (int) segment_info.x2) - { - chop_info.width=(size_t) (segment_info.x1-segment_info.x2+1); - chop_info.x=(ssize_t) windows->image.x+segment_info.x2; - } - } - else - { - chop_info.width=0; - chop_info.height=(size_t) (segment_info.y2-segment_info.y1+1); - chop_info.x=0; - chop_info.y=(ssize_t) windows->image.y+segment_info.y1; - if (segment_info.y1 > segment_info.y2) - { - chop_info.height=(size_t) (segment_info.y1-segment_info.y2+1); - chop_info.y=(ssize_t) windows->image.y+segment_info.y2; - } - } - } while ((state & ExitState) == 0); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if (distance <= 9) - return(MagickTrue); - /* - Image chopping is relative to image configuration. - */ - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - windows->image.window_changes.width=windows->image.ximage->width- - (unsigned int) chop_info.width; - windows->image.window_changes.height=windows->image.ximage->height- - (unsigned int) chop_info.height; - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - scale_factor=(double) width/windows->image.ximage->width; - chop_info.x+=x; - chop_info.x=(ssize_t) (scale_factor*chop_info.x+0.5); - chop_info.width=(unsigned int) (scale_factor*chop_info.width+0.5); - scale_factor=(double) height/windows->image.ximage->height; - chop_info.y+=y; - chop_info.y=(ssize_t) (scale_factor*chop_info.y+0.5); - chop_info.height=(unsigned int) (scale_factor*chop_info.height+0.5); - /* - Chop image. - */ - chop_image=ChopImage(*image,&chop_info,exception); - XSetCursorState(display,windows,MagickFalse); - if (chop_image == (Image *) NULL) - return(MagickFalse); - *image=DestroyImage(*image); - *image=chop_image; - /* - Update image configuration. - */ - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X C o l o r E d i t I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XColorEditImage() allows the user to interactively change the color of one -% pixel for a DirectColor image or one colormap entry for a PseudoClass image. -% -% The format of the XColorEditImage method is: -% -% MagickBooleanType XColorEditImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XColorEditImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image **image, - ExceptionInfo *exception) -{ - const char - *const ColorEditMenu[] = - { - "Method", - "Pixel Color", - "Border Color", - "Fuzz", - "Undo", - "Help", - "Dismiss", - (char *) NULL - }; - - static const ModeType - ColorEditCommands[] = - { - ColorEditMethodCommand, - ColorEditColorCommand, - ColorEditBorderCommand, - ColorEditFuzzCommand, - ColorEditUndoCommand, - ColorEditHelpCommand, - ColorEditDismissCommand - }; - - static PaintMethod - method = PointMethod; - - static unsigned int - pen_id = 0; - - static XColor - border_color = { 0, 0, 0, 0, 0, 0 }; - - char - command[MagickPathExtent], - text[MagickPathExtent]; - - Cursor - cursor; - - int - entry, - id, - x, - x_offset, - y, - y_offset; - - Quantum - *q; - - ssize_t - i; - - unsigned int - height, - width; - - size_t - state; - - XColor - color; - - XEvent - event; - - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Color Edit"); - windows->command.data=4; - (void) XCommandWidget(display,windows,ColorEditMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Make cursor. - */ - cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap, - resource_info->background_color,resource_info->foreground_color); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - /* - Track pointer until button 1 is pressed. - */ - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ", - x+windows->image.x,y+windows->image.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,ColorEditMenu,&event); - if (id < 0) - { - (void) XCheckDefineCursor(display,windows->image.id,cursor); - continue; - } - switch (ColorEditCommands[id]) - { - case ColorEditMethodCommand: - { - char - **methods; - - /* - Select a method from the pop-up menu. - */ - methods=(char **) GetCommandOptions(MagickMethodOptions); - if (methods == (char **) NULL) - break; - entry=XMenuWidget(display,windows,ColorEditMenu[id], - (const char **) methods,command); - if (entry >= 0) - method=(PaintMethod) ParseCommandOption(MagickMethodOptions, - MagickFalse,methods[entry]); - methods=DestroyStringList(methods); - break; - } - case ColorEditColorCommand: - { - const char - *ColorMenu[MaxNumberPens]; - - int - pen_number; - - /* - Initialize menu selections. - */ - for (i=0; i < (int) (MaxNumberPens-2); i++) - ColorMenu[i]=resource_info->pen_colors[i]; - ColorMenu[MaxNumberPens-2]="Browser..."; - ColorMenu[MaxNumberPens-1]=(const char *) NULL; - /* - Select a pen color from the pop-up menu. - */ - pen_number=XMenuWidget(display,windows,ColorEditMenu[id], - (const char **) ColorMenu,command); - if (pen_number < 0) - break; - if (pen_number == (MaxNumberPens-2)) - { - static char - color_name[MagickPathExtent] = "gray"; - - /* - Select a pen color from a dialog. - */ - resource_info->pen_colors[pen_number]=color_name; - XColorBrowserWidget(display,windows,"Select",color_name); - if (*color_name == '\0') - break; - } - /* - Set pen color. - */ - (void) XParseColor(display,windows->map_info->colormap, - resource_info->pen_colors[pen_number],&color); - XBestPixel(display,windows->map_info->colormap,(XColor *) NULL, - (unsigned int) MaxColors,&color); - windows->pixel_info->pen_colors[pen_number]=color; - pen_id=(unsigned int) pen_number; - break; - } - case ColorEditBorderCommand: - { - const char - *ColorMenu[MaxNumberPens]; - - int - pen_number; - - /* - Initialize menu selections. - */ - for (i=0; i < (int) (MaxNumberPens-2); i++) - ColorMenu[i]=resource_info->pen_colors[i]; - ColorMenu[MaxNumberPens-2]="Browser..."; - ColorMenu[MaxNumberPens-1]=(const char *) NULL; - /* - Select a pen color from the pop-up menu. - */ - pen_number=XMenuWidget(display,windows,ColorEditMenu[id], - (const char **) ColorMenu,command); - if (pen_number < 0) - break; - if (pen_number == (MaxNumberPens-2)) - { - static char - color_name[MagickPathExtent] = "gray"; - - /* - Select a pen color from a dialog. - */ - resource_info->pen_colors[pen_number]=color_name; - XColorBrowserWidget(display,windows,"Select",color_name); - if (*color_name == '\0') - break; - } - /* - Set border color. - */ - (void) XParseColor(display,windows->map_info->colormap, - resource_info->pen_colors[pen_number],&border_color); - break; - } - case ColorEditFuzzCommand: - { - const char - *const FuzzMenu[] = - { - "0%", - "2%", - "5%", - "10%", - "15%", - "Dialog...", - (char *) NULL, - }; - - static char - fuzz[MagickPathExtent]; - - /* - Select a command from the pop-up menu. - */ - entry=XMenuWidget(display,windows,ColorEditMenu[id],FuzzMenu, - command); - if (entry < 0) - break; - if (entry != 5) - { - (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(double) - QuantumRange+1.0); - break; - } - (void) (void) CopyMagickString(fuzz,"20%",MagickPathExtent); - (void) XDialogWidget(display,windows,"Ok", - "Enter fuzz factor (0.0 - 99.9%):",fuzz); - if (*fuzz == '\0') - break; - (void) ConcatenateMagickString(fuzz,"%",MagickPathExtent); - (*image)->fuzz=StringToDoubleInterval(fuzz,(double) QuantumRange+ - 1.0); - break; - } - case ColorEditUndoCommand: - { - (void) XMagickCommand(display,resource_info,windows,UndoCommand, - image,exception); - break; - } - case ColorEditHelpCommand: - default: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Annotation",ImageColorEditHelp); - break; - } - case ColorEditDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - } - (void) XCheckDefineCursor(display,windows->image.id,cursor); - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if ((event.xbutton.window != windows->image.id) && - (event.xbutton.window != windows->magnify.id)) - break; - /* - exit loop. - */ - x=event.xbutton.x; - y=event.xbutton.y; - (void) XMagickCommand(display,resource_info,windows, - SaveToUndoBufferCommand,image,exception); - state|=UpdateConfigurationState; - break; - } - case ButtonRelease: - { - if (event.xbutton.button != Button1) - break; - if ((event.xbutton.window != windows->image.id) && - (event.xbutton.window != windows->magnify.id)) - break; - /* - Update colormap information. - */ - x=event.xbutton.x; - y=event.xbutton.y; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - XInfoWidget(display,windows,text); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - state&=(~UpdateConfigurationState); - break; - } - case Expose: - break; - case KeyPress: - { - KeySym - key_symbol; - - if (event.xkey.window == windows->magnify.id) - { - Window - window; - - window=windows->magnify.id; - while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ; - } - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Annotation",ImageColorEditHelp); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - break; - } - default: - break; - } - if (event.xany.window == windows->magnify.id) - { - x=windows->magnify.x-windows->image.x; - y=windows->magnify.y-windows->image.y; - } - x_offset=x; - y_offset=y; - if ((state & UpdateConfigurationState) != 0) - { - CacheView - *image_view; - - int - x, - y; - - /* - Pixel edit is relative to image configuration. - */ - (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1, - MagickTrue); - color=windows->pixel_info->pen_colors[pen_id]; - XPutPixel(windows->image.ximage,x_offset,y_offset,color.pixel); - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y, - &width,&height); - x_offset=(int) - (width*(windows->image.x+x_offset)/windows->image.ximage->width+x); - y_offset=(int) - (height*(windows->image.y+y_offset)/windows->image.ximage->height+y); - if ((x_offset < 0) || (y_offset < 0)) - continue; - if ((x_offset >= (int) (*image)->columns) || - (y_offset >= (int) (*image)->rows)) - continue; - image_view=AcquireAuthenticCacheView(*image,exception); - switch (method) - { - case PointMethod: - default: - { - /* - Update color information using point algorithm. - */ - if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse) - return(MagickFalse); - q=GetCacheViewAuthenticPixels(image_view,(ssize_t)x_offset, - (ssize_t) y_offset,1,1,exception); - if (q == (Quantum *) NULL) - break; - SetPixelRed(*image,ScaleShortToQuantum(color.red),q); - SetPixelGreen(*image,ScaleShortToQuantum(color.green),q); - SetPixelBlue(*image,ScaleShortToQuantum(color.blue),q); - (void) SyncCacheViewAuthenticPixels(image_view,exception); - break; - } - case ReplaceMethod: - { - PixelInfo - pixel, - target; - - /* - Update color information using replace algorithm. - */ - (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t) - x_offset,(ssize_t) y_offset,&target,exception); - if ((*image)->storage_class == DirectClass) - { - for (y=0; y < (int) (*image)->rows; y++) - { - q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y, - (*image)->columns,1,exception); - if (q == (Quantum *) NULL) - break; - for (x=0; x < (int) (*image)->columns; x++) - { - GetPixelInfoPixel(*image,q,&pixel); - if (IsFuzzyEquivalencePixelInfo(&pixel,&target)) - { - SetPixelRed(*image,ScaleShortToQuantum( - color.red),q); - SetPixelGreen(*image,ScaleShortToQuantum( - color.green),q); - SetPixelBlue(*image,ScaleShortToQuantum( - color.blue),q); - } - q+=GetPixelChannels(*image); - } - if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) - break; - } - } - else - { - for (i=0; i < (ssize_t) (*image)->colors; i++) - if (IsFuzzyEquivalencePixelInfo((*image)->colormap+i,&target)) - { - (*image)->colormap[i].red=(double) ScaleShortToQuantum( - color.red); - (*image)->colormap[i].green=(double) ScaleShortToQuantum( - color.green); - (*image)->colormap[i].blue=(double) ScaleShortToQuantum( - color.blue); - } - (void) SyncImage(*image,exception); - } - break; - } - case FloodfillMethod: - case FillToBorderMethod: - { - DrawInfo - *draw_info; - - PixelInfo - target; - - /* - Update color information using floodfill algorithm. - */ - (void) GetOneVirtualPixelInfo(*image, - GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t) - y_offset,&target,exception); - if (method == FillToBorderMethod) - { - target.red=(double) - ScaleShortToQuantum(border_color.red); - target.green=(double) - ScaleShortToQuantum(border_color.green); - target.blue=(double) - ScaleShortToQuantum(border_color.blue); - } - draw_info=CloneDrawInfo(resource_info->image_info, - (DrawInfo *) NULL); - (void) QueryColorCompliance(resource_info->pen_colors[pen_id], - AllCompliance,&draw_info->fill,exception); - (void) FloodfillPaintImage(*image,draw_info,&target, - (ssize_t)x_offset,(ssize_t)y_offset, - method != FloodfillMethod ? MagickTrue : MagickFalse,exception); - draw_info=DestroyDrawInfo(draw_info); - break; - } - case ResetMethod: - { - /* - Update color information using reset algorithm. - */ - if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse) - return(MagickFalse); - for (y=0; y < (int) (*image)->rows; y++) - { - q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y, - (*image)->columns,1,exception); - if (q == (Quantum *) NULL) - break; - for (x=0; x < (int) (*image)->columns; x++) - { - SetPixelRed(*image,ScaleShortToQuantum(color.red),q); - SetPixelGreen(*image,ScaleShortToQuantum(color.green),q); - SetPixelBlue(*image,ScaleShortToQuantum(color.blue),q); - q+=GetPixelChannels(*image); - } - if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) - break; - } - break; - } - } - image_view=DestroyCacheView(image_view); - state&=(~UpdateConfigurationState); - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - XSetCursorState(display,windows,MagickFalse); - (void) XFreeCursor(display,cursor); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X C o m p o s i t e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XCompositeImage() requests an image name from the user, reads the image and -% composites it with the X window image at a location the user chooses with -% the pointer. -% -% The format of the XCompositeImage method is: -% -% MagickBooleanType XCompositeImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XCompositeImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - ExceptionInfo *exception) -{ - const char - *const CompositeMenu[] = - { - "Operators", - "Dissolve", - "Displace", - "Help", - "Dismiss", - (char *) NULL - }; - - static char - displacement_geometry[MagickPathExtent] = "30x30", - filename[MagickPathExtent] = "\0"; - - static CompositeOperator - compose = CopyCompositeOp; - - static const ModeType - CompositeCommands[] = - { - CompositeOperatorsCommand, - CompositeDissolveCommand, - CompositeDisplaceCommand, - CompositeHelpCommand, - CompositeDismissCommand - }; - - char - text[MagickPathExtent]; - - Cursor - cursor; - - Image - *composite_image; - - int - entry, - id, - x, - y; - - double - blend, - scale_factor; - - RectangleInfo - highlight_info, - composite_info; - - unsigned int - height, - width; - - size_t - state; - - XEvent - event; - - /* - Request image file name from user. - */ - XFileBrowserWidget(display,windows,"Composite",filename); - if (*filename == '\0') - return(MagickTrue); - /* - Read image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) CopyMagickString(resource_info->image_info->filename,filename, - MagickPathExtent); - composite_image=ReadImage(resource_info->image_info,exception); - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (composite_image == (Image *) NULL) - return(MagickFalse); - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Composite"); - windows->command.data=1; - (void) XCommandWidget(display,windows,CompositeMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Track pointer until button 1 is pressed. - */ - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - composite_info.x=(ssize_t) windows->image.x+x; - composite_info.y=(ssize_t) windows->image.y+y; - composite_info.width=0; - composite_info.height=0; - cursor=XCreateFontCursor(display,XC_ul_angle); - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - blend=0.0; - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ", - (long) composite_info.x,(long) composite_info.y); - XInfoWidget(display,windows,text); - } - highlight_info=composite_info; - highlight_info.x=composite_info.x-windows->image.x; - highlight_info.y=composite_info.y-windows->image.y; - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,CompositeMenu,&event); - if (id < 0) - continue; - switch (CompositeCommands[id]) - { - case CompositeOperatorsCommand: - { - char - command[MagickPathExtent], - **operators; - - /* - Select a command from the pop-up menu. - */ - operators=GetCommandOptions(MagickComposeOptions); - if (operators == (char **) NULL) - break; - entry=XMenuWidget(display,windows,CompositeMenu[id], - (const char **) operators,command); - if (entry >= 0) - compose=(CompositeOperator) ParseCommandOption( - MagickComposeOptions,MagickFalse,operators[entry]); - operators=DestroyStringList(operators); - break; - } - case CompositeDissolveCommand: - { - static char - factor[MagickPathExtent] = "20.0"; - - /* - Dissolve the two images a given percent. - */ - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - (void) XDialogWidget(display,windows,"Dissolve", - "Enter the blend factor (0.0 - 99.9%):",factor); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - if (*factor == '\0') - break; - blend=StringToDouble(factor,(char **) NULL); - compose=DissolveCompositeOp; - break; - } - case CompositeDisplaceCommand: - { - /* - Get horizontal and vertical scale displacement geometry. - */ - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - (void) XDialogWidget(display,windows,"Displace", - "Enter the horizontal and vertical scale:",displacement_geometry); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - if (*displacement_geometry == '\0') - break; - compose=DisplaceCompositeOp; - break; - } - case CompositeHelpCommand: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Composite",ImageCompositeHelp); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - case CompositeDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Button Press: 0x%lx %u +%d+%d",event.xbutton.window, - event.xbutton.button,event.xbutton.x,event.xbutton.y); - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - Change cursor. - */ - composite_info.width=composite_image->columns; - composite_info.height=composite_image->rows; - (void) XCheckDefineCursor(display,windows->image.id,cursor); - composite_info.x=(ssize_t) windows->image.x+event.xbutton.x; - composite_info.y=(ssize_t) windows->image.y+event.xbutton.y; - break; - } - case ButtonRelease: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Button Release: 0x%lx %u +%d+%d",event.xbutton.window, - event.xbutton.button,event.xbutton.x,event.xbutton.y); - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - if ((composite_info.width != 0) && (composite_info.height != 0)) - { - /* - User has selected the location of the composite image. - */ - composite_info.x=(ssize_t) windows->image.x+event.xbutton.x; - composite_info.y=(ssize_t) windows->image.y+event.xbutton.y; - state|=ExitState; - } - break; - } - case Expose: - break; - case KeyPress: - { - char - command[MagickPathExtent]; - - KeySym - key_symbol; - - int - length; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - length=XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - *(command+length)='\0'; - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Key press: 0x%lx (%s)",(unsigned long) key_symbol,command); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - composite_image=DestroyImage(composite_image); - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Composite",ImageCompositeHelp); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - composite_info.x=(ssize_t) windows->image.x+x; - composite_info.y=(ssize_t) windows->image.y+y; - break; - } - default: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d", - event.type); - break; - } - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - XSetCursorState(display,windows,MagickFalse); - (void) XFreeCursor(display,cursor); - if ((state & EscapeState) != 0) - return(MagickTrue); - /* - Image compositing is relative to image configuration. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - scale_factor=(double) width/windows->image.ximage->width; - composite_info.x+=x; - composite_info.x=(ssize_t) (scale_factor*composite_info.x+0.5); - composite_info.width=(unsigned int) (scale_factor*composite_info.width+0.5); - scale_factor=(double) height/windows->image.ximage->height; - composite_info.y+=y; - composite_info.y=(ssize_t) (scale_factor*composite_info.y+0.5); - composite_info.height=(unsigned int) (scale_factor*composite_info.height+0.5); - if ((composite_info.width != composite_image->columns) || - (composite_info.height != composite_image->rows)) - { - Image - *resize_image; - - /* - Scale composite image. - */ - resize_image=ResizeImage(composite_image,composite_info.width, - composite_info.height,composite_image->filter,exception); - composite_image=DestroyImage(composite_image); - if (resize_image == (Image *) NULL) - { - XSetCursorState(display,windows,MagickFalse); - return(MagickFalse); - } - composite_image=resize_image; - } - if (compose == DisplaceCompositeOp) - (void) SetImageArtifact(composite_image,"compose:args", - displacement_geometry); - if (blend != 0.0) - { - CacheView - *image_view; - - int - y; - - Quantum - opacity; - - int - x; - - Quantum - *q; - - /* - Create mattes for blending. - */ - (void) SetImageAlphaChannel(composite_image,OpaqueAlphaChannel,exception); - opacity=(Quantum) (ScaleQuantumToChar(QuantumRange)- - ((ssize_t) ScaleQuantumToChar(QuantumRange)*blend)/100); - if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) - return(MagickFalse); - image->alpha_trait=BlendPixelTrait; - image_view=AcquireAuthenticCacheView(image,exception); - for (y=0; y < (int) image->rows; y++) - { - q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y,image->columns,1, - exception); - if (q == (Quantum *) NULL) - break; - for (x=0; x < (int) image->columns; x++) - { - SetPixelAlpha(image,opacity,q); - q+=GetPixelChannels(image); - } - if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) - break; - } - image_view=DestroyCacheView(image_view); - } - /* - Composite image with X Image window. - */ - (void) CompositeImage(image,composite_image,compose,MagickTrue, - composite_info.x,composite_info.y,exception); - composite_image=DestroyImage(composite_image); - XSetCursorState(display,windows,MagickFalse); - /* - Update image configuration. - */ - XConfigureImageColormap(display,resource_info,windows,image,exception); - (void) XConfigureImage(display,resource_info,windows,image,exception); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X C o n f i g u r e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XConfigureImage() creates a new X image. It also notifies the window -% manager of the new image size and configures the transient widows. -% -% The format of the XConfigureImage method is: -% -% MagickBooleanType XConfigureImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XConfigureImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - ExceptionInfo *exception) -{ - char - geometry[MagickPathExtent]; - - MagickStatusType - status; - - size_t - mask, - height, - width; - - ssize_t - x, - y; - - XSizeHints - *size_hints; - - XWindowChanges - window_changes; - - /* - Dismiss if window dimensions are zero. - */ - width=(unsigned int) windows->image.window_changes.width; - height=(unsigned int) windows->image.window_changes.height; - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Configure Image: %dx%d=>%.20gx%.20g",windows->image.ximage->width, - windows->image.ximage->height,(double) width,(double) height); - if ((width*height) == 0) - return(MagickTrue); - x=0; - y=0; - /* - Resize image to fit Image window dimensions. - */ - XSetCursorState(display,windows,MagickTrue); - (void) XFlush(display); - if (((int) width != windows->image.ximage->width) || - ((int) height != windows->image.ximage->height)) - image->taint=MagickTrue; - windows->magnify.x=(int) - width*windows->magnify.x/windows->image.ximage->width; - windows->magnify.y=(int) - height*windows->magnify.y/windows->image.ximage->height; - windows->image.x=(int) (width*windows->image.x/windows->image.ximage->width); - windows->image.y=(int) - (height*windows->image.y/windows->image.ximage->height); - status=XMakeImage(display,resource_info,&windows->image,image, - (unsigned int) width,(unsigned int) height,exception); - if (status == MagickFalse) - XNoticeWidget(display,windows,"Unable to configure X image:", - windows->image.name); - /* - Notify window manager of the new configuration. - */ - if (resource_info->image_geometry != (char *) NULL) - (void) FormatLocaleString(geometry,MagickPathExtent,"%s>!", - resource_info->image_geometry); - else - (void) FormatLocaleString(geometry,MagickPathExtent,"%ux%u+0+0>!", - XDisplayWidth(display,windows->image.screen), - XDisplayHeight(display,windows->image.screen)); - (void) ParseMetaGeometry(geometry,&x,&y,&width,&height); - window_changes.width=(int) width; - if (window_changes.width > XDisplayWidth(display,windows->image.screen)) - window_changes.width=XDisplayWidth(display,windows->image.screen); - window_changes.height=(int) height; - if (window_changes.height > XDisplayHeight(display,windows->image.screen)) - window_changes.height=XDisplayHeight(display,windows->image.screen); - mask=(size_t) (CWWidth | CWHeight); - if (resource_info->backdrop) - { - mask|=CWX | CWY; - window_changes.x=(int) - ((XDisplayWidth(display,windows->image.screen)/2)-(width/2)); - window_changes.y=(int) - ((XDisplayHeight(display,windows->image.screen)/2)-(height/2)); - } - (void) XReconfigureWMWindow(display,windows->image.id,windows->image.screen, - (unsigned int) mask,&window_changes); - (void) XClearWindow(display,windows->image.id); - XRefreshWindow(display,&windows->image,(XEvent *) NULL); - /* - Update Magnify window configuration. - */ - if (windows->magnify.mapped != MagickFalse) - XMakeMagnifyImage(display,windows,exception); - windows->pan.crop_geometry=windows->image.crop_geometry; - XBestIconSize(display,&windows->pan,image); - while (((windows->pan.width << 1) < MaxIconSize) && - ((windows->pan.height << 1) < MaxIconSize)) - { - windows->pan.width<<=1; - windows->pan.height<<=1; - } - if (windows->pan.geometry != (char *) NULL) - (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y, - &windows->pan.width,&windows->pan.height); - window_changes.width=(int) windows->pan.width; - window_changes.height=(int) windows->pan.height; - size_hints=XAllocSizeHints(); - if (size_hints != (XSizeHints *) NULL) - { - /* - Set new size hints. - */ - size_hints->flags=PSize | PMinSize | PMaxSize; - size_hints->width=window_changes.width; - size_hints->height=window_changes.height; - size_hints->min_width=size_hints->width; - size_hints->min_height=size_hints->height; - size_hints->max_width=size_hints->width; - size_hints->max_height=size_hints->height; - (void) XSetNormalHints(display,windows->pan.id,size_hints); - (void) XFree((void *) size_hints); - } - (void) XReconfigureWMWindow(display,windows->pan.id,windows->pan.screen, - (unsigned int) (CWWidth | CWHeight),&window_changes); - /* - Update icon window configuration. - */ - windows->icon.crop_geometry=windows->image.crop_geometry; - XBestIconSize(display,&windows->icon,image); - window_changes.width=(int) windows->icon.width; - window_changes.height=(int) windows->icon.height; - (void) XReconfigureWMWindow(display,windows->icon.id,windows->icon.screen, - (unsigned int) (CWWidth | CWHeight),&window_changes); - XSetCursorState(display,windows,MagickFalse); - return(status != 0 ? MagickTrue : MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X C r o p I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XCropImage() allows the user to select a region of the image and crop, copy, -% or cut it. For copy or cut, the image can subsequently be composited onto -% the image with XPasteImage. -% -% The format of the XCropImage method is: -% -% MagickBooleanType XCropImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% const ClipboardMode mode,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -% o mode: This unsigned value specified whether the image should be -% cropped, copied, or cut. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XCropImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - const ClipboardMode mode,ExceptionInfo *exception) -{ - const char - *const CropModeMenu[] = - { - "Help", - "Dismiss", - (char *) NULL - }, - *RectifyModeMenu[] = - { - "Crop", - "Help", - "Dismiss", - (char *) NULL - }; - - static const ModeType - CropCommands[] = - { - CropHelpCommand, - CropDismissCommand - }, - RectifyCommands[] = - { - RectifyCopyCommand, - RectifyHelpCommand, - RectifyDismissCommand - }; - - CacheView - *image_view; - - char - command[MagickPathExtent], - text[MagickPathExtent]; - - Cursor - cursor; - - int - id, - x, - y; - - KeySym - key_symbol; - - Image - *crop_image; - - double - scale_factor; - - RectangleInfo - crop_info, - highlight_info; - - Quantum - *q; - - unsigned int - height, - width; - - size_t - state; - - XEvent - event; - - /* - Map Command widget. - */ - switch (mode) - { - case CopyMode: - { - (void) CloneString(&windows->command.name,"Copy"); - break; - } - case CropMode: - { - (void) CloneString(&windows->command.name,"Crop"); - break; - } - case CutMode: - { - (void) CloneString(&windows->command.name,"Cut"); - break; - } - } - RectifyModeMenu[0]=windows->command.name; - windows->command.data=0; - (void) XCommandWidget(display,windows,CropModeMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Track pointer until button 1 is pressed. - */ - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - crop_info.x=(ssize_t) windows->image.x+x; - crop_info.y=(ssize_t) windows->image.y+y; - crop_info.width=0; - crop_info.height=0; - cursor=XCreateFontCursor(display,XC_fleur); - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ", - (long) crop_info.x,(long) crop_info.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,CropModeMenu,&event); - if (id < 0) - continue; - switch (CropCommands[id]) - { - case CropHelpCommand: - { - switch (mode) - { - case CopyMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Copy",ImageCopyHelp); - break; - } - case CropMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Crop",ImageCropHelp); - break; - } - case CutMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Cut",ImageCutHelp); - break; - } - } - break; - } - case CropDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - Note first corner of cropping rectangle-- exit loop. - */ - (void) XCheckDefineCursor(display,windows->image.id,cursor); - crop_info.x=(ssize_t) windows->image.x+event.xbutton.x; - crop_info.y=(ssize_t) windows->image.y+event.xbutton.y; - state|=ExitState; - break; - } - case ButtonRelease: - break; - case Expose: - break; - case KeyPress: - { - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - switch (mode) - { - case CopyMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Copy",ImageCopyHelp); - break; - } - case CropMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Crop",ImageCropHelp); - break; - } - case CutMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Cut",ImageCutHelp); - break; - } - } - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - if (event.xmotion.window != windows->image.id) - break; - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - crop_info.x=(ssize_t) windows->image.x+x; - crop_info.y=(ssize_t) windows->image.y+y; - break; - } - default: - break; - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - if ((state & EscapeState) != 0) - { - /* - User want to exit without cropping. - */ - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - (void) XFreeCursor(display,cursor); - return(MagickTrue); - } - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - do - { - /* - Size rectangle as pointer moves until the mouse button is released. - */ - x=(int) crop_info.x; - y=(int) crop_info.y; - crop_info.width=0; - crop_info.height=0; - state=DefaultState; - do - { - highlight_info=crop_info; - highlight_info.x=crop_info.x-windows->image.x; - highlight_info.y=crop_info.y-windows->image.y; - if ((highlight_info.width > 3) && (highlight_info.height > 3)) - { - /* - Display info and draw cropping rectangle. - */ - if (windows->info.mapped == MagickFalse) - (void) XMapWindow(display,windows->info.id); - (void) FormatLocaleString(text,MagickPathExtent, - " %.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double) - crop_info.height,(double) crop_info.x,(double) crop_info.y); - XInfoWidget(display,windows,text); - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - } else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if ((highlight_info.width > 3) && (highlight_info.height > 3)) - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - switch (event.type) + if (isatty(STDIN_FILENO) != MagickFalse || (nostdin != MagickFalse)) + option="logo:"; + else + option="-"; + if (LocaleCompare(option,"(") == 0) { - case ButtonPress: - { - crop_info.x=(ssize_t) windows->image.x+event.xbutton.x; - crop_info.y=(ssize_t) windows->image.y+event.xbutton.y; - break; - } - case ButtonRelease: - { - /* - User has committed to cropping rectangle. - */ - crop_info.x=(ssize_t) windows->image.x+event.xbutton.x; - crop_info.y=(ssize_t) windows->image.y+event.xbutton.y; - XSetCursorState(display,windows,MagickFalse); - state|=ExitState; - windows->command.data=0; - (void) XCommandWidget(display,windows,RectifyModeMenu, - (XEvent *) NULL); - break; - } - case Expose: - break; - case MotionNotify: - { - crop_info.x=(ssize_t) windows->image.x+event.xmotion.x; - crop_info.y=(ssize_t) windows->image.y+event.xmotion.y; - } - default: - break; + FireImageStack(MagickFalse,MagickTrue,pend); + if (k == MaxImageStackDepth) + ThrowDisplayException(OptionError,"ParenthesisNestedTooDeeply", + option); + PushImageStack(); + continue; } - if ((((int) crop_info.x != x) && ((int) crop_info.y != y)) || - ((state & ExitState) != 0)) - { - /* - Check boundary conditions. - */ - if (crop_info.x < 0) - crop_info.x=0; - else - if (crop_info.x > (ssize_t) windows->image.ximage->width) - crop_info.x=(ssize_t) windows->image.ximage->width; - if ((int) crop_info.x < x) - crop_info.width=(unsigned int) (x-crop_info.x); - else - { - crop_info.width=(unsigned int) (crop_info.x-x); - crop_info.x=(ssize_t) x; - } - if (crop_info.y < 0) - crop_info.y=0; - else - if (crop_info.y > (ssize_t) windows->image.ximage->height) - crop_info.y=(ssize_t) windows->image.ximage->height; - if ((int) crop_info.y < y) - crop_info.height=(unsigned int) (y-crop_info.y); - else - { - crop_info.height=(unsigned int) (crop_info.y-y); - crop_info.y=(ssize_t) y; - } - } - } while ((state & ExitState) == 0); - /* - Wait for user to grab a corner of the rectangle or press return. - */ - state=DefaultState; - (void) XMapWindow(display,windows->info.id); - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent, - " %.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double) - crop_info.height,(double) crop_info.x,(double) crop_info.y); - XInfoWidget(display,windows,text); - } - highlight_info=crop_info; - highlight_info.x=crop_info.x-windows->image.x; - highlight_info.y=crop_info.y-windows->image.y; - if ((highlight_info.width <= 3) || (highlight_info.height <= 3)) - { - state|=EscapeState; - state|=ExitState; - break; - } - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - id=XCommandWidget(display,windows,RectifyModeMenu,&event); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - if (id >= 0) - switch (RectifyCommands[id]) - { - case RectifyCopyCommand: - { - state|=ExitState; - break; - } - case RectifyHelpCommand: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - switch (mode) - { - case CopyMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Copy",ImageCopyHelp); - break; - } - case CropMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Crop",ImageCropHelp); - break; - } - case CutMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Cut",ImageCutHelp); - break; - } - } - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - case RectifyDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - continue; - } - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - switch (event.type) + if (LocaleCompare(option,")") == 0) { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - x=windows->image.x+event.xbutton.x; - y=windows->image.y+event.xbutton.y; - if ((x < (int) (crop_info.x+RoiDelta)) && - (x > (int) (crop_info.x-RoiDelta)) && - (y < (int) (crop_info.y+RoiDelta)) && - (y > (int) (crop_info.y-RoiDelta))) - { - crop_info.x=(ssize_t) (crop_info.x+crop_info.width); - crop_info.y=(ssize_t) (crop_info.y+crop_info.height); - state|=UpdateConfigurationState; - break; - } - if ((x < (int) (crop_info.x+RoiDelta)) && - (x > (int) (crop_info.x-RoiDelta)) && - (y < (int) (crop_info.y+crop_info.height+RoiDelta)) && - (y > (int) (crop_info.y+crop_info.height-RoiDelta))) - { - crop_info.x=(ssize_t) (crop_info.x+crop_info.width); - state|=UpdateConfigurationState; - break; - } - if ((x < (int) (crop_info.x+crop_info.width+RoiDelta)) && - (x > (int) (crop_info.x+crop_info.width-RoiDelta)) && - (y < (int) (crop_info.y+RoiDelta)) && - (y > (int) (crop_info.y-RoiDelta))) - { - crop_info.y=(ssize_t) (crop_info.y+crop_info.height); - state|=UpdateConfigurationState; - break; - } - if ((x < (int) (crop_info.x+crop_info.width+RoiDelta)) && - (x > (int) (crop_info.x+crop_info.width-RoiDelta)) && - (y < (int) (crop_info.y+crop_info.height+RoiDelta)) && - (y > (int) (crop_info.y+crop_info.height-RoiDelta))) - { - state|=UpdateConfigurationState; - break; - } - } - case ButtonRelease: - { - if (event.xbutton.window == windows->pan.id) - if ((highlight_info.x != crop_info.x-windows->image.x) || - (highlight_info.y != crop_info.y-windows->image.y)) - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id, - event.xbutton.time); - break; - } - case Expose: - { - if (event.xexpose.window == windows->image.id) - if (event.xexpose.count == 0) - { - event.xexpose.x=(int) highlight_info.x; - event.xexpose.y=(int) highlight_info.y; - event.xexpose.width=(int) highlight_info.width; - event.xexpose.height=(int) highlight_info.height; - XRefreshWindow(display,&windows->image,&event); - } - if (event.xexpose.window == windows->info.id) - if (event.xexpose.count == 0) - XInfoWidget(display,windows,text); - break; - } - case KeyPress: - { - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - state|=EscapeState; - case XK_Return: - { - state|=ExitState; - break; - } - case XK_Home: - case XK_KP_Home: - { - crop_info.x=(ssize_t) (windows->image.width/2L-crop_info.width/ - 2L); - crop_info.y=(ssize_t) (windows->image.height/2L-crop_info.height/ - 2L); - break; - } - case XK_Left: - case XK_KP_Left: - { - crop_info.x--; - break; - } - case XK_Up: - case XK_KP_Up: - case XK_Next: - { - crop_info.y--; - break; - } - case XK_Right: - case XK_KP_Right: - { - crop_info.x++; - break; - } - case XK_Prior: - case XK_Down: - case XK_KP_Down: - { - crop_info.y++; - break; - } - case XK_F1: - case XK_Help: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - switch (mode) - { - case CopyMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Copy",ImageCopyHelp); - break; - } - case CropMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Cropg",ImageCropHelp); - break; - } - case CutMode: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Cutg",ImageCutHelp); - break; - } - } - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id, - event.xkey.time); - break; - } - case KeyRelease: - break; - case MotionNotify: - { - if (event.xmotion.window != windows->image.id) - break; - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - crop_info.x=(ssize_t) windows->image.x+event.xmotion.x; - crop_info.y=(ssize_t) windows->image.y+event.xmotion.y; - break; - } - case SelectionRequest: - { - XSelectionEvent - notify; - - XSelectionRequestEvent - *request; - - /* - Set primary selection. - */ - (void) FormatLocaleString(text,MagickPathExtent, - "%.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double) - crop_info.height,(double) crop_info.x,(double) crop_info.y); - request=(&(event.xselectionrequest)); - (void) XChangeProperty(request->display,request->requestor, - request->property,request->target,8,PropModeReplace, - (unsigned char *) text,(int) strlen(text)); - notify.type=SelectionNotify; - notify.display=request->display; - notify.requestor=request->requestor; - notify.selection=request->selection; - notify.target=request->target; - notify.time=request->time; - if (request->property == None) - notify.property=request->target; - else - notify.property=request->property; - (void) XSendEvent(request->display,request->requestor,False,0, - (XEvent *) ¬ify); - } - default: - break; + FireImageStack(MagickFalse,MagickTrue,MagickTrue); + if (k == 0) + ThrowDisplayException(OptionError,"UnableToParseExpression",option); + PopImageStack(); + continue; } - if ((state & UpdateConfigurationState) != 0) - { - (void) XPutBackEvent(display,&event); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - break; - } - } while ((state & ExitState) == 0); - } while ((state & ExitState) == 0); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - XSetCursorState(display,windows,MagickFalse); - if ((state & EscapeState) != 0) - return(MagickTrue); - if (mode == CropMode) - if (((int) crop_info.width != windows->image.ximage->width) || - ((int) crop_info.height != windows->image.ximage->height)) + if (IsCommandOption(option) == MagickFalse) { + const char + *filename; + + Image + *display_image, + *image_list, + *images; + /* - Reconfigure Image window as defined by cropping rectangle. + Option is a file name. */ - XSetCropGeometry(display,windows,&crop_info,image); - windows->image.window_changes.width=(int) crop_info.width; - windows->image.window_changes.height=(int) crop_info.height; - (void) XConfigureImage(display,resource_info,windows,image,exception); - return(MagickTrue); - } - /* - Copy image before applying image transforms. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - scale_factor=(double) width/windows->image.ximage->width; - crop_info.x+=x; - crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5); - crop_info.width=(unsigned int) (scale_factor*crop_info.width+0.5); - scale_factor=(double) height/windows->image.ximage->height; - crop_info.y+=y; - crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5); - crop_info.height=(unsigned int) (scale_factor*crop_info.height+0.5); - crop_info.x+=image->page.x; - crop_info.y+=image->page.y; - crop_image=CropImage(image,&crop_info,exception); - XSetCursorState(display,windows,MagickFalse); - if (crop_image == (Image *) NULL) - return(MagickFalse); - if (resource_info->copy_image != (Image *) NULL) - resource_info->copy_image=DestroyImage(resource_info->copy_image); - resource_info->copy_image=crop_image; - if (mode == CopyMode) - { - (void) XConfigureImage(display,resource_info,windows,image,exception); - return(MagickTrue); - } - /* - Cut image. - */ - if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) - return(MagickFalse); - image->alpha_trait=BlendPixelTrait; - image_view=AcquireAuthenticCacheView(image,exception); - for (y=0; y < (int) crop_info.height; y++) - { - q=GetCacheViewAuthenticPixels(image_view,crop_info.x,y+crop_info.y, - crop_info.width,1,exception); - if (q == (Quantum *) NULL) - break; - for (x=0; x < (int) crop_info.width; x++) - { - SetPixelAlpha(image,TransparentAlpha,q); - q+=GetPixelChannels(image); - } - if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) - break; - } - image_view=DestroyCacheView(image_view); - /* - Update image configuration. - */ - XConfigureImageColormap(display,resource_info,windows,image,exception); - (void) XConfigureImage(display,resource_info,windows,image,exception); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X D r a w I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XDrawEditImage() draws a graphic element (point, line, rectangle, etc.) on -% the image. -% -% The format of the XDrawEditImage method is: -% -% MagickBooleanType XDrawEditImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XDrawEditImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image **image, - ExceptionInfo *exception) -{ - const char - *const DrawMenu[] = - { - "Element", - "Color", - "Stipple", - "Width", - "Undo", - "Help", - "Dismiss", - (char *) NULL - }; - - static ElementType - element = PointElement; - - static const ModeType - DrawCommands[] = - { - DrawElementCommand, - DrawColorCommand, - DrawStippleCommand, - DrawWidthCommand, - DrawUndoCommand, - DrawHelpCommand, - DrawDismissCommand - }; - - static Pixmap - stipple = (Pixmap) NULL; - - static unsigned int - pen_id = 0, - line_width = 1; - - char - command[MagickPathExtent], - text[MagickPathExtent]; - - Cursor - cursor; - - int - entry, - id, - number_coordinates, - x, - y; - - double - degrees; - - MagickStatusType - status; - - RectangleInfo - rectangle_info; - - int - i; - - unsigned int - distance, - height, - max_coordinates, - width; - - size_t - state; - - Window - root_window; - - XDrawInfo - draw_info; - - XEvent - event; - - XPoint - *coordinate_info; - - XSegment - line_info; - - /* - Allocate polygon info. - */ - max_coordinates=2048; - coordinate_info=(XPoint *) AcquireQuantumMemory((size_t) max_coordinates, - sizeof(*coordinate_info)); - if (coordinate_info == (XPoint *) NULL) - { - (void) ThrowMagickException(exception,GetMagickModule(), - ResourceLimitError,"MemoryAllocationFailed","`%s'","..."); - return(MagickFalse); - } - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Draw"); - windows->command.data=4; - (void) XCommandWidget(display,windows,DrawMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Wait for first button press. - */ - root_window=XRootWindow(display,XDefaultScreen(display)); - draw_info.stencil=OpaqueStencil; - status=MagickTrue; - cursor=XCreateFontCursor(display,XC_tcross); - for ( ; ; ) - { - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ", - x+windows->image.x,y+windows->image.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,DrawMenu,&event); - if (id < 0) - continue; - switch (DrawCommands[id]) + FireImageStack(MagickFalse,MagickFalse,pend); + filename=option; + if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1))) { - case DrawElementCommand: + option=argv[++i]; + filename=option; + } + (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); + images=ReadImage(image_info,exception); + CatchException(exception); + status&=(images != (Image *) NULL) && + (exception->severity < ErrorException); + if (images == (Image *) NULL) + continue; + AppendImageStack(images); + FinalizeImageSettings(image_info,image,MagickFalse); + iterations=image->iterations; + image_list=CloneImageList(image,exception); + if (image_list == (Image *) NULL) + ThrowDisplayException(ResourceLimitError,"MemoryAllocationFailed", + GetExceptionMessage(errno)); + display_image=image_list; + do + { + /* + Transmogrify image as defined by the image processing options. + */ + resource_info.quantum=1; + if (resource_info.window_id != (char *) NULL) { - const char - *const Elements[] = + /* + Display image to a specified X window. + */ + status=XDisplayBackgroundImage(display,&resource_info, + display_image,exception); + if (status != MagickFalse) { - "point", - "line", - "rectangle", - "fill rectangle", - "circle", - "fill circle", - "ellipse", - "fill ellipse", - "polygon", - "fill polygon", - (char *) NULL, - }; - - /* - Select a command from the pop-up menu. - */ - element=(ElementType) (XMenuWidget(display,windows, - DrawMenu[id],Elements,command)+1); - break; - } - case DrawColorCommand: - { - const char - *ColorMenu[MaxNumberPens+1]; - - int - pen_number; - - MagickBooleanType - transparent; - - XColor - color; - - /* - Initialize menu selections. - */ - for (i=0; i < (int) (MaxNumberPens-2); i++) - ColorMenu[i]=resource_info->pen_colors[i]; - ColorMenu[MaxNumberPens-2]="transparent"; - ColorMenu[MaxNumberPens-1]="Browser..."; - ColorMenu[MaxNumberPens]=(char *) NULL; - /* - Select a pen color from the pop-up menu. - */ - pen_number=XMenuWidget(display,windows,DrawMenu[id], - (const char **) ColorMenu,command); - if (pen_number < 0) - break; - transparent=pen_number == (MaxNumberPens-2) ? MagickTrue : - MagickFalse; - if (transparent != MagickFalse) - { - draw_info.stencil=TransparentStencil; - break; + state|=RetainColorsState; + status=MagickFalse; } - if (pen_number == (MaxNumberPens-1)) - { - static char - color_name[MagickPathExtent] = "gray"; - - /* - Select a pen color from a dialog. - */ - resource_info->pen_colors[pen_number]=color_name; - XColorBrowserWidget(display,windows,"Select",color_name); - if (*color_name == '\0') - break; - } - /* - Set pen color. - */ - (void) XParseColor(display,windows->map_info->colormap, - resource_info->pen_colors[pen_number],&color); - XBestPixel(display,windows->map_info->colormap,(XColor *) NULL, - (unsigned int) MaxColors,&color); - windows->pixel_info->pen_colors[pen_number]=color; - pen_id=(unsigned int) pen_number; - draw_info.stencil=OpaqueStencil; - break; + if (GetNextImageInList(display_image) == (Image *) NULL) + state|=ExitState; } - case DrawStippleCommand: + else + do { - const char - *StipplesMenu[] = - { - "Brick", - "Diagonal", - "Scales", - "Vertical", - "Wavy", - "Translucent", - "Opaque", - (char *) NULL, - (char *) NULL, - }; - Image - *stipple_image; - - ImageInfo - *image_info; - - int - status; - - static char - filename[MagickPathExtent] = "\0"; + *nexus; /* - Select a command from the pop-up menu. + Display image to X server. */ - StipplesMenu[7]="Open..."; - entry=XMenuWidget(display,windows,DrawMenu[id],StipplesMenu, - command); - if (entry < 0) + if (resource_info.delay != 1) + display_image->delay=resource_info.delay; + nexus=XDisplayImage(display,&resource_info,argv,argc, + &display_image,&state,exception); + if (nexus == (Image *) NULL) break; - if (stipple != (Pixmap) NULL) - (void) XFreePixmap(display,stipple); - stipple=(Pixmap) NULL; - if (entry != 7) - { - switch (entry) - { - case 0: - { - stipple=XCreateBitmapFromData(display,root_window, - (char *) BricksBitmap,BricksWidth,BricksHeight); - break; - } - case 1: - { - stipple=XCreateBitmapFromData(display,root_window, - (char *) DiagonalBitmap,DiagonalWidth,DiagonalHeight); - break; - } - case 2: - { - stipple=XCreateBitmapFromData(display,root_window, - (char *) ScalesBitmap,ScalesWidth,ScalesHeight); - break; - } - case 3: - { - stipple=XCreateBitmapFromData(display,root_window, - (char *) VerticalBitmap,VerticalWidth,VerticalHeight); - break; - } - case 4: - { - stipple=XCreateBitmapFromData(display,root_window, - (char *) WavyBitmap,WavyWidth,WavyHeight); - break; - } - case 5: - { - stipple=XCreateBitmapFromData(display,root_window, - (char *) HighlightBitmap,HighlightWidth, - HighlightHeight); - break; - } - case 6: - default: - { - stipple=XCreateBitmapFromData(display,root_window, - (char *) OpaqueBitmap,OpaqueWidth,OpaqueHeight); - break; - } - } - break; - } - XFileBrowserWidget(display,windows,"Stipple",filename); - if (*filename == '\0') - break; - /* - Read image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - image_info=AcquireImageInfo(); - (void) CopyMagickString(image_info->filename,filename, - MagickPathExtent); - stipple_image=ReadImage(image_info,exception); - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (stipple_image == (Image *) NULL) - break; - (void) AcquireUniqueFileResource(filename); - (void) FormatLocaleString(stipple_image->filename, - MagickPathExtent,"xbm:%s",filename); - (void) WriteImage(image_info,stipple_image,exception); - stipple_image=DestroyImage(stipple_image); - image_info=DestroyImageInfo(image_info); - status=XReadBitmapFile(display,root_window,filename,&width, - &height,&stipple,&x,&y); - (void) RelinquishUniqueFileResource(filename); - if ((status != BitmapSuccess) != 0) - XNoticeWidget(display,windows,"Unable to read X bitmap image:", - filename); - break; - } - case DrawWidthCommand: - { - const char - *const WidthsMenu[] = - { - "1", - "2", - "4", - "8", - "16", - "Dialog...", - (char *) NULL, - }; - - static char - width[MagickPathExtent] = "0"; - - /* - Select a command from the pop-up menu. - */ - entry=XMenuWidget(display,windows,DrawMenu[id],WidthsMenu, - command); - if (entry < 0) - break; - if (entry != 5) - { - line_width=(unsigned int) StringToUnsignedLong( - WidthsMenu[entry]); - break; - } - (void) XDialogWidget(display,windows,"Ok","Enter line width:", - width); - if (*width == '\0') - break; - line_width=(unsigned int) StringToUnsignedLong(width); - break; - } - case DrawUndoCommand: - { - (void) XMagickCommand(display,resource_info,windows,UndoCommand, - image,exception); - break; - } - case DrawHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Rotation",ImageDrawHelp); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - break; - } - case DrawDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - (void) XCheckDefineCursor(display,windows->image.id,cursor); - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - exit loop. - */ - x=event.xbutton.x; - y=event.xbutton.y; - state|=ExitState; - break; - } - case ButtonRelease: - break; - case Expose: - break; - case KeyPress: - { - KeySym - key_symbol; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Rotation",ImageDrawHelp); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - break; - } - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if ((state & EscapeState) != 0) - break; - /* - Draw element as pointer moves until the button is released. - */ - distance=0; - degrees=0.0; - line_info.x1=x; - line_info.y1=y; - line_info.x2=x; - line_info.y2=y; - rectangle_info.x=(ssize_t) x; - rectangle_info.y=(ssize_t) y; - rectangle_info.width=0; - rectangle_info.height=0; - number_coordinates=1; - coordinate_info->x=x; - coordinate_info->y=y; - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - state=DefaultState; - do - { - switch (element) - { - case PointElement: - default: - { - if (number_coordinates > 1) - { - (void) XDrawLines(display,windows->image.id, - windows->image.highlight_context,coordinate_info, - number_coordinates,CoordModeOrigin); - (void) FormatLocaleString(text,MagickPathExtent," %+d%+d", - coordinate_info[number_coordinates-1].x, - coordinate_info[number_coordinates-1].y); - XInfoWidget(display,windows,text); - } - break; - } - case LineElement: - { - if (distance > 9) - { - /* - Display angle of the line. - */ - degrees=RadiansToDegrees(-atan2((double) (line_info.y2- - line_info.y1),(double) (line_info.x2-line_info.x1))); - (void) FormatLocaleString(text,MagickPathExtent," %g", - (double) degrees); - XInfoWidget(display,windows,text); - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&line_info); - } - else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - break; - } - case RectangleElement: - case FillRectangleElement: - { - if ((rectangle_info.width > 3) && (rectangle_info.height > 3)) - { - /* - Display info and draw drawing rectangle. - */ - (void) FormatLocaleString(text,MagickPathExtent, - " %.20gx%.20g%+.20g%+.20g",(double) rectangle_info.width, - (double) rectangle_info.height,(double) rectangle_info.x, - (double) rectangle_info.y); - XInfoWidget(display,windows,text); - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&rectangle_info); - } - else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - break; - } - case CircleElement: - case FillCircleElement: - case EllipseElement: - case FillEllipseElement: - { - if ((rectangle_info.width > 3) && (rectangle_info.height > 3)) - { - /* - Display info and draw drawing rectangle. - */ - (void) FormatLocaleString(text,MagickPathExtent, - " %.20gx%.20g%+.20g%+.20g",(double) rectangle_info.width, - (double) rectangle_info.height,(double) rectangle_info.x, - (double) rectangle_info.y); - XInfoWidget(display,windows,text); - XHighlightEllipse(display,windows->image.id, - windows->image.highlight_context,&rectangle_info); - } - else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - break; - } - case PolygonElement: - case FillPolygonElement: - { - if (number_coordinates > 1) - (void) XDrawLines(display,windows->image.id, - windows->image.highlight_context,coordinate_info, - number_coordinates,CoordModeOrigin); - if (distance > 9) - { - /* - Display angle of the line. - */ - degrees=RadiansToDegrees(-atan2((double) (line_info.y2- - line_info.y1),(double) (line_info.x2-line_info.x1))); - (void) FormatLocaleString(text,MagickPathExtent," %g", - (double) degrees); - XInfoWidget(display,windows,text); - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&line_info); - } - else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - break; - } - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - switch (element) - { - case PointElement: - default: - { - if (number_coordinates > 1) - (void) XDrawLines(display,windows->image.id, - windows->image.highlight_context,coordinate_info, - number_coordinates,CoordModeOrigin); - break; - } - case LineElement: - { - if (distance > 9) - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&line_info); - break; - } - case RectangleElement: - case FillRectangleElement: - { - if ((rectangle_info.width > 3) && (rectangle_info.height > 3)) - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&rectangle_info); - break; - } - case CircleElement: - case FillCircleElement: - case EllipseElement: - case FillEllipseElement: - { - if ((rectangle_info.width > 3) && (rectangle_info.height > 3)) - XHighlightEllipse(display,windows->image.id, - windows->image.highlight_context,&rectangle_info); - break; - } - case PolygonElement: - case FillPolygonElement: - { - if (number_coordinates > 1) - (void) XDrawLines(display,windows->image.id, - windows->image.highlight_context,coordinate_info, - number_coordinates,CoordModeOrigin); - if (distance > 9) - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&line_info); - break; - } - } - switch (event.type) - { - case ButtonPress: - break; - case ButtonRelease: - { - /* - User has committed to element. - */ - line_info.x2=event.xbutton.x; - line_info.y2=event.xbutton.y; - rectangle_info.x=(ssize_t) event.xbutton.x; - rectangle_info.y=(ssize_t) event.xbutton.y; - coordinate_info[number_coordinates].x=event.xbutton.x; - coordinate_info[number_coordinates].y=event.xbutton.y; - if (((element != PolygonElement) && - (element != FillPolygonElement)) || (distance <= 9)) - { - state|=ExitState; - break; - } - number_coordinates++; - if (number_coordinates < (int) max_coordinates) - { - line_info.x1=event.xbutton.x; - line_info.y1=event.xbutton.y; - break; - } - max_coordinates<<=1; - coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info, - max_coordinates,sizeof(*coordinate_info)); - if (coordinate_info == (XPoint *) NULL) - (void) ThrowMagickException(exception,GetMagickModule(), - ResourceLimitError,"MemoryAllocationFailed","`%s'","..."); - break; - } - case Expose: - break; - case MotionNotify: - { - if (event.xmotion.window != windows->image.id) - break; - if (element != PointElement) - { - line_info.x2=event.xmotion.x; - line_info.y2=event.xmotion.y; - rectangle_info.x=(ssize_t) event.xmotion.x; - rectangle_info.y=(ssize_t) event.xmotion.y; - break; - } - coordinate_info[number_coordinates].x=event.xbutton.x; - coordinate_info[number_coordinates].y=event.xbutton.y; - number_coordinates++; - if (number_coordinates < (int) max_coordinates) - break; - max_coordinates<<=1; - coordinate_info=(XPoint *) ResizeQuantumMemory(coordinate_info, - max_coordinates,sizeof(*coordinate_info)); - if (coordinate_info == (XPoint *) NULL) - (void) ThrowMagickException(exception,GetMagickModule(), - ResourceLimitError,"MemoryAllocationFailed","`%s'","..."); - break; - } - default: - break; - } - /* - Check boundary conditions. - */ - if (line_info.x2 < 0) - line_info.x2=0; - else - if (line_info.x2 > (int) windows->image.width) - line_info.x2=(short) windows->image.width; - if (line_info.y2 < 0) - line_info.y2=0; - else - if (line_info.y2 > (int) windows->image.height) - line_info.y2=(short) windows->image.height; - distance=(unsigned int) - (((line_info.x2-line_info.x1+1)*(line_info.x2-line_info.x1+1))+ - ((line_info.y2-line_info.y1+1)*(line_info.y2-line_info.y1+1))); - if ((((int) rectangle_info.x != x) && ((int) rectangle_info.y != y)) || - ((state & ExitState) != 0)) - { - if (rectangle_info.x < 0) - rectangle_info.x=0; - else - if (rectangle_info.x > (ssize_t) windows->image.width) - rectangle_info.x=(ssize_t) windows->image.width; - if ((int) rectangle_info.x < x) - rectangle_info.width=(unsigned int) (x-rectangle_info.x); - else - { - rectangle_info.width=(unsigned int) (rectangle_info.x-x); - rectangle_info.x=(ssize_t) x; - } - if (rectangle_info.y < 0) - rectangle_info.y=0; - else - if (rectangle_info.y > (ssize_t) windows->image.height) - rectangle_info.y=(ssize_t) windows->image.height; - if ((int) rectangle_info.y < y) - rectangle_info.height=(unsigned int) (y-rectangle_info.y); - else - { - rectangle_info.height=(unsigned int) (rectangle_info.y-y); - rectangle_info.y=(ssize_t) y; - } - } - } while ((state & ExitState) == 0); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - if ((element == PointElement) || (element == PolygonElement) || - (element == FillPolygonElement)) - { - /* - Determine polygon bounding box. - */ - rectangle_info.x=(ssize_t) coordinate_info->x; - rectangle_info.y=(ssize_t) coordinate_info->y; - x=coordinate_info->x; - y=coordinate_info->y; - for (i=1; i < number_coordinates; i++) - { - if (coordinate_info[i].x > x) - x=coordinate_info[i].x; - if (coordinate_info[i].y > y) - y=coordinate_info[i].y; - if ((ssize_t) coordinate_info[i].x < rectangle_info.x) - rectangle_info.x=MagickMax((ssize_t) coordinate_info[i].x,0); - if ((ssize_t) coordinate_info[i].y < rectangle_info.y) - rectangle_info.y=MagickMax((ssize_t) coordinate_info[i].y,0); - } - rectangle_info.width=(size_t) (x-rectangle_info.x); - rectangle_info.height=(size_t) (y-rectangle_info.y); - for (i=0; i < number_coordinates; i++) - { - coordinate_info[i].x-=rectangle_info.x; - coordinate_info[i].y-=rectangle_info.y; - } - } - else - if (distance <= 9) - continue; - else - if ((element == RectangleElement) || - (element == CircleElement) || (element == EllipseElement)) - { - rectangle_info.width--; - rectangle_info.height--; - } - /* - Drawing is relative to image configuration. - */ - draw_info.x=(int) rectangle_info.x; - draw_info.y=(int) rectangle_info.y; - (void) XMagickCommand(display,resource_info,windows,SaveToUndoBufferCommand, - image,exception); - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - draw_info.x+=windows->image.x-(line_width/2); - if (draw_info.x < 0) - draw_info.x=0; - draw_info.x=(int) (width*draw_info.x/windows->image.ximage->width); - draw_info.y+=windows->image.y-(line_width/2); - if (draw_info.y < 0) - draw_info.y=0; - draw_info.y=(int) height*draw_info.y/windows->image.ximage->height; - draw_info.width=(unsigned int) rectangle_info.width+(line_width << 1); - if (draw_info.width > (unsigned int) (*image)->columns) - draw_info.width=(unsigned int) (*image)->columns; - draw_info.height=(unsigned int) rectangle_info.height+(line_width << 1); - if (draw_info.height > (unsigned int) (*image)->rows) - draw_info.height=(unsigned int) (*image)->rows; - (void) FormatLocaleString(draw_info.geometry,MagickPathExtent,"%ux%u%+d%+d", - width*draw_info.width/windows->image.ximage->width, - height*draw_info.height/windows->image.ximage->height, - draw_info.x+x,draw_info.y+y); - /* - Initialize drawing attributes. - */ - draw_info.degrees=0.0; - draw_info.element=element; - draw_info.stipple=stipple; - draw_info.line_width=line_width; - draw_info.line_info=line_info; - if (line_info.x1 > (int) (line_width/2)) - draw_info.line_info.x1=(short) line_width/2; - if (line_info.y1 > (int) (line_width/2)) - draw_info.line_info.y1=(short) line_width/2; - draw_info.line_info.x2=(short) (line_info.x2-line_info.x1+(line_width/2)); - draw_info.line_info.y2=(short) (line_info.y2-line_info.y1+(line_width/2)); - if ((draw_info.line_info.x2 < 0) && (draw_info.line_info.y2 < 0)) - { - draw_info.line_info.x2=(-draw_info.line_info.x2); - draw_info.line_info.y2=(-draw_info.line_info.y2); - } - if (draw_info.line_info.x2 < 0) - { - draw_info.line_info.x2=(-draw_info.line_info.x2); - Swap(draw_info.line_info.x1,draw_info.line_info.x2); - } - if (draw_info.line_info.y2 < 0) - { - draw_info.line_info.y2=(-draw_info.line_info.y2); - Swap(draw_info.line_info.y1,draw_info.line_info.y2); - } - draw_info.rectangle_info=rectangle_info; - if (draw_info.rectangle_info.x > (ssize_t) (line_width/2)) - draw_info.rectangle_info.x=(ssize_t) line_width/2; - if (draw_info.rectangle_info.y > (ssize_t) (line_width/2)) - draw_info.rectangle_info.y=(ssize_t) line_width/2; - draw_info.number_coordinates=(unsigned int) number_coordinates; - draw_info.coordinate_info=coordinate_info; - windows->pixel_info->pen_color=windows->pixel_info->pen_colors[pen_id]; - /* - Draw element on image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - status=XDrawImage(display,windows->pixel_info,&draw_info,*image,exception); - XSetCursorState(display,windows,MagickFalse); - /* - Update image colormap and return to image drawing. - */ - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - } - XSetCursorState(display,windows,MagickFalse); - coordinate_info=(XPoint *) RelinquishMagickMemory(coordinate_info); - return(status != 0 ? MagickTrue : MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X D r a w P a n R e c t a n g l e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XDrawPanRectangle() draws a rectangle in the pan window. The pan window -% displays a zoom image and the rectangle shows which portion of the image is -% displayed in the Image window. -% -% The format of the XDrawPanRectangle method is: -% -% XDrawPanRectangle(Display *display,XWindows *windows) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o windows: Specifies a pointer to a XWindows structure. -% -*/ -static void XDrawPanRectangle(Display *display,XWindows *windows) -{ - double - scale_factor; - - RectangleInfo - highlight_info; - - /* - Determine dimensions of the panning rectangle. - */ - scale_factor=(double) windows->pan.width/windows->image.ximage->width; - highlight_info.x=(ssize_t) (scale_factor*windows->image.x+0.5); - highlight_info.width=(unsigned int) (scale_factor*windows->image.width+0.5); - scale_factor=(double) - windows->pan.height/windows->image.ximage->height; - highlight_info.y=(ssize_t) (scale_factor*windows->image.y+0.5); - highlight_info.height=(unsigned int) (scale_factor*windows->image.height+0.5); - /* - Display the panning rectangle. - */ - (void) XClearWindow(display,windows->pan.id); - XHighlightRectangle(display,windows->pan.id,windows->pan.annotate_context, - &highlight_info); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X I m a g e C a c h e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XImageCache() handles the creation, manipulation, and destruction of the -% image cache (undo and redo buffers). -% -% The format of the XImageCache method is: -% -% void XImageCache(Display *display,XResourceInfo *resource_info, -% XWindows *windows,const CommandType command,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o command: Specifies a command to perform. -% -% o image: the image; XImageCache may transform the image and return a new -% image pointer. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static void XImageCache(Display *display,XResourceInfo *resource_info, - XWindows *windows,const CommandType command,Image **image, - ExceptionInfo *exception) -{ - Image - *cache_image; - - static Image - *redo_image = (Image *) NULL, - *undo_image = (Image *) NULL; - - switch (command) - { - case FreeBuffersCommand: - { - /* - Free memory from the undo and redo cache. - */ - while (undo_image != (Image *) NULL) - { - cache_image=undo_image; - undo_image=GetPreviousImageInList(undo_image); - cache_image->list=DestroyImage(cache_image->list); - cache_image=DestroyImage(cache_image); - } - undo_image=NewImageList(); - if (redo_image != (Image *) NULL) - redo_image=DestroyImage(redo_image); - redo_image=NewImageList(); - return; - } - case UndoCommand: - { - char - image_geometry[MagickPathExtent]; - - /* - Undo the last image transformation. - */ - if (undo_image == (Image *) NULL) - { - (void) XBell(display,0); - return; - } - cache_image=undo_image; - undo_image=GetPreviousImageInList(undo_image); - windows->image.window_changes.width=(int) cache_image->columns; - windows->image.window_changes.height=(int) cache_image->rows; - (void) FormatLocaleString(image_geometry,MagickPathExtent,"%dx%d!", - windows->image.ximage->width,windows->image.ximage->height); - (void) TransformImage(image,windows->image.crop_geometry,image_geometry, - exception); - if (windows->image.crop_geometry != (char *) NULL) - windows->image.crop_geometry=(char *) RelinquishMagickMemory( - windows->image.crop_geometry); - windows->image.crop_geometry=cache_image->geometry; - if (redo_image != (Image *) NULL) - redo_image=DestroyImage(redo_image); - redo_image=(*image); - *image=cache_image->list; - cache_image=DestroyImage(cache_image); - if (windows->image.orphan != MagickFalse) - return; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - return; - } - case CutCommand: - case PasteCommand: - case ApplyCommand: - case HalfSizeCommand: - case OriginalSizeCommand: - case DoubleSizeCommand: - case ResizeCommand: - case TrimCommand: - case CropCommand: - case ChopCommand: - case FlipCommand: - case FlopCommand: - case RotateRightCommand: - case RotateLeftCommand: - case RotateCommand: - case ShearCommand: - case RollCommand: - case NegateCommand: - case ContrastStretchCommand: - case SigmoidalContrastCommand: - case NormalizeCommand: - case EqualizeCommand: - case HueCommand: - case SaturationCommand: - case BrightnessCommand: - case GammaCommand: - case SpiffCommand: - case DullCommand: - case GrayscaleCommand: - case MapCommand: - case QuantizeCommand: - case DespeckleCommand: - case EmbossCommand: - case ReduceNoiseCommand: - case AddNoiseCommand: - case SharpenCommand: - case BlurCommand: - case ThresholdCommand: - case EdgeDetectCommand: - case SpreadCommand: - case ShadeCommand: - case RaiseCommand: - case SegmentCommand: - case SolarizeCommand: - case SepiaToneCommand: - case SwirlCommand: - case ImplodeCommand: - case VignetteCommand: - case WaveCommand: - case OilPaintCommand: - case CharcoalDrawCommand: - case AnnotateCommand: - case AddBorderCommand: - case AddFrameCommand: - case CompositeCommand: - case CommentCommand: - case LaunchCommand: - case RegionOfInterestCommand: - case SaveToUndoBufferCommand: - case RedoCommand: - { - Image - *previous_image; - - ssize_t - bytes; - - bytes=(ssize_t) ((*image)->columns*(*image)->rows*sizeof(PixelInfo)); - if (undo_image != (Image *) NULL) - { - /* - Ensure the undo cache has enough memory available. - */ - previous_image=undo_image; - while (previous_image != (Image *) NULL) - { - bytes+=previous_image->list->columns*previous_image->list->rows* - sizeof(PixelInfo); - if (bytes <= (ssize_t) (resource_info->undo_cache << 20)) + while ((nexus != (Image *) NULL) && ((state & ExitState) == 0)) { - previous_image=GetPreviousImageInList(previous_image); - continue; - } - bytes-=previous_image->list->columns*previous_image->list->rows* - sizeof(PixelInfo); - if (previous_image == undo_image) - undo_image=NewImageList(); - else - previous_image->next->previous=NewImageList(); - break; - } - while (previous_image != (Image *) NULL) - { - /* - Delete any excess memory from undo cache. - */ - cache_image=previous_image; - previous_image=GetPreviousImageInList(previous_image); - cache_image->list=DestroyImage(cache_image->list); - cache_image=DestroyImage(cache_image); - } - } - if (bytes > (ssize_t) (resource_info->undo_cache << 20)) - break; - /* - Save image before transformations are applied. - */ - cache_image=AcquireImage((ImageInfo *) NULL,exception); - if (cache_image == (Image *) NULL) - break; - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - cache_image->list=CloneImage(*image,0,0,MagickTrue,exception); - XSetCursorState(display,windows,MagickFalse); - if (cache_image->list == (Image *) NULL) - { - cache_image=DestroyImage(cache_image); - break; - } - cache_image->columns=(size_t) windows->image.ximage->width; - cache_image->rows=(size_t) windows->image.ximage->height; - cache_image->geometry=windows->image.crop_geometry; - if (windows->image.crop_geometry != (char *) NULL) - { - cache_image->geometry=AcquireString((char *) NULL); - (void) CopyMagickString(cache_image->geometry, - windows->image.crop_geometry,MagickPathExtent); - } - if (undo_image == (Image *) NULL) - { - undo_image=cache_image; - break; - } - undo_image->next=cache_image; - undo_image->next->previous=undo_image; - undo_image=undo_image->next; - break; - } - default: - break; - } - if (command == RedoCommand) - { - /* - Redo the last image transformation. - */ - if (redo_image == (Image *) NULL) - { - (void) XBell(display,0); - return; - } - windows->image.window_changes.width=(int) redo_image->columns; - windows->image.window_changes.height=(int) redo_image->rows; - if (windows->image.crop_geometry != (char *) NULL) - windows->image.crop_geometry=(char *) - RelinquishMagickMemory(windows->image.crop_geometry); - windows->image.crop_geometry=redo_image->geometry; - *image=DestroyImage(*image); - *image=redo_image; - redo_image=NewImageList(); - if (windows->image.orphan != MagickFalse) - return; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - return; - } - if (command != InfoCommand) - return; - /* - Display image info. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - XDisplayImageInfo(display,resource_info,windows,undo_image,*image,exception); - XSetCursorState(display,windows,MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X I m a g e W i n d o w C o m m a n d % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XImageWindowCommand() makes a transform to the image or Image window as -% specified by a user menu button or keyboard command. -% -% The format of the XImageWindowCommand method is: -% -% CommandType XImageWindowCommand(Display *display, -% XResourceInfo *resource_info,XWindows *windows, -% const MagickStatusType state,KeySym key_symbol,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o nexus: Method XImageWindowCommand returns an image when the -% user chooses 'Open Image' from the command menu. Otherwise a null -% image is returned. -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o state: key mask. -% -% o key_symbol: Specifies a command to perform. -% -% o image: the image; XImageWIndowCommand may transform the image and -% return a new image pointer. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static CommandType XImageWindowCommand(Display *display, - XResourceInfo *resource_info,XWindows *windows,const MagickStatusType state, - KeySym key_symbol,Image **image,ExceptionInfo *exception) -{ - static char - delta[MagickPathExtent] = ""; + Image + *next; - static const char - Digits[] = "01234567890"; - - static KeySym - last_symbol = XK_0; - - if ((key_symbol >= XK_0) && (key_symbol <= XK_9)) - { - if (((last_symbol < XK_0) || (last_symbol > XK_9))) - { - *delta='\0'; - resource_info->quantum=1; - } - last_symbol=key_symbol; - delta[strlen(delta)+1]='\0'; - delta[strlen(delta)]=Digits[key_symbol-XK_0]; - resource_info->quantum=StringToLong(delta); - return(NullCommand); - } - last_symbol=key_symbol; - if (resource_info->immutable) - { - /* - Virtual image window has a restricted command set. - */ - switch (key_symbol) - { - case XK_question: - return(InfoCommand); - case XK_p: - case XK_Print: - return(PrintCommand); - case XK_space: - return(NextCommand); - case XK_q: - case XK_Escape: - return(QuitCommand); - default: - break; - } - return(NullCommand); - } - switch ((int) key_symbol) - { - case XK_o: - { - if ((state & ControlMask) == 0) - break; - return(OpenCommand); - } - case XK_space: - return(NextCommand); - case XK_BackSpace: - return(FormerCommand); - case XK_s: - { - if ((state & Mod1Mask) != 0) - return(SwirlCommand); - if ((state & ControlMask) == 0) - return(ShearCommand); - return(SaveCommand); - } - case XK_p: - case XK_Print: - { - if ((state & Mod1Mask) != 0) - return(OilPaintCommand); - if ((state & Mod4Mask) != 0) - return(ColorCommand); - if ((state & ControlMask) == 0) - return(NullCommand); - return(PrintCommand); - } - case XK_d: - { - if ((state & Mod4Mask) != 0) - return(DrawCommand); - if ((state & ControlMask) == 0) - return(NullCommand); - return(DeleteCommand); - } - case XK_Select: - { - if ((state & ControlMask) == 0) - return(NullCommand); - return(SelectCommand); - } - case XK_n: - { - if ((state & ControlMask) == 0) - return(NullCommand); - return(NewCommand); - } - case XK_q: - case XK_Escape: - return(QuitCommand); - case XK_z: - case XK_Undo: - { - if ((state & ControlMask) == 0) - return(NullCommand); - return(UndoCommand); - } - case XK_r: - case XK_Redo: - { - if ((state & ControlMask) == 0) - return(RollCommand); - return(RedoCommand); - } - case XK_x: - { - if ((state & ControlMask) == 0) - return(NullCommand); - return(CutCommand); - } - case XK_c: - { - if ((state & Mod1Mask) != 0) - return(CharcoalDrawCommand); - if ((state & ControlMask) == 0) - return(CropCommand); - return(CopyCommand); - } - case XK_v: - case XK_Insert: - { - if ((state & Mod4Mask) != 0) - return(CompositeCommand); - if ((state & ControlMask) == 0) - return(FlipCommand); - return(PasteCommand); - } - case XK_less: - return(HalfSizeCommand); - case XK_minus: - return(OriginalSizeCommand); - case XK_greater: - return(DoubleSizeCommand); - case XK_percent: - return(ResizeCommand); - case XK_at: - return(RefreshCommand); - case XK_bracketleft: - return(ChopCommand); - case XK_h: - return(FlopCommand); - case XK_slash: - return(RotateRightCommand); - case XK_backslash: - return(RotateLeftCommand); - case XK_asterisk: - return(RotateCommand); - case XK_t: - return(TrimCommand); - case XK_H: - return(HueCommand); - case XK_S: - return(SaturationCommand); - case XK_L: - return(BrightnessCommand); - case XK_G: - return(GammaCommand); - case XK_C: - return(SpiffCommand); - case XK_Z: - return(DullCommand); - case XK_N: - return(NormalizeCommand); - case XK_equal: - return(EqualizeCommand); - case XK_asciitilde: - return(NegateCommand); - case XK_period: - return(GrayscaleCommand); - case XK_numbersign: - return(QuantizeCommand); - case XK_F2: - return(DespeckleCommand); - case XK_F3: - return(EmbossCommand); - case XK_F4: - return(ReduceNoiseCommand); - case XK_F5: - return(AddNoiseCommand); - case XK_F6: - return(SharpenCommand); - case XK_F7: - return(BlurCommand); - case XK_F8: - return(ThresholdCommand); - case XK_F9: - return(EdgeDetectCommand); - case XK_F10: - return(SpreadCommand); - case XK_F11: - return(ShadeCommand); - case XK_F12: - return(RaiseCommand); - case XK_F13: - return(SegmentCommand); - case XK_i: - { - if ((state & Mod1Mask) == 0) - return(NullCommand); - return(ImplodeCommand); - } - case XK_w: - { - if ((state & Mod1Mask) == 0) - return(NullCommand); - return(WaveCommand); - } - case XK_m: - { - if ((state & Mod4Mask) == 0) - return(NullCommand); - return(MatteCommand); - } - case XK_b: - { - if ((state & Mod4Mask) == 0) - return(NullCommand); - return(AddBorderCommand); - } - case XK_f: - { - if ((state & Mod4Mask) == 0) - return(NullCommand); - return(AddFrameCommand); - } - case XK_exclam: - { - if ((state & Mod4Mask) == 0) - return(NullCommand); - return(CommentCommand); - } - case XK_a: - { - if ((state & Mod1Mask) != 0) - return(ApplyCommand); - if ((state & Mod4Mask) != 0) - return(AnnotateCommand); - if ((state & ControlMask) == 0) - return(NullCommand); - return(RegionOfInterestCommand); - } - case XK_question: - return(InfoCommand); - case XK_plus: - return(ZoomCommand); - case XK_P: - { - if ((state & ShiftMask) == 0) - return(NullCommand); - return(ShowPreviewCommand); - } - case XK_Execute: - return(LaunchCommand); - case XK_F1: - return(HelpCommand); - case XK_Find: - return(BrowseDocumentationCommand); - case XK_Menu: - { - (void) XMapRaised(display,windows->command.id); - return(NullCommand); - } - case XK_Next: - case XK_Prior: - case XK_Home: - case XK_KP_Home: - { - XTranslateImage(display,windows,*image,key_symbol); - return(NullCommand); - } - case XK_Up: - case XK_KP_Up: - case XK_Down: - case XK_KP_Down: - case XK_Left: - case XK_KP_Left: - case XK_Right: - case XK_KP_Right: - { - if ((state & Mod1Mask) != 0) - { - RectangleInfo - crop_info; - - /* - Trim one pixel from edge of image. - */ - crop_info.x=0; - crop_info.y=0; - crop_info.width=(size_t) windows->image.ximage->width; - crop_info.height=(size_t) windows->image.ximage->height; - if ((key_symbol == XK_Up) || (key_symbol == XK_KP_Up)) - { - if (resource_info->quantum >= (int) crop_info.height) - resource_info->quantum=(int) crop_info.height-1; - crop_info.height-=resource_info->quantum; - } - if ((key_symbol == XK_Down) || (key_symbol == XK_KP_Down)) - { - if (resource_info->quantum >= (int) (crop_info.height-crop_info.y)) - resource_info->quantum=(int) (crop_info.height-crop_info.y-1); - crop_info.y+=resource_info->quantum; - crop_info.height-=resource_info->quantum; - } - if ((key_symbol == XK_Left) || (key_symbol == XK_KP_Left)) - { - if (resource_info->quantum >= (int) crop_info.width) - resource_info->quantum=(int) crop_info.width-1; - crop_info.width-=resource_info->quantum; - } - if ((key_symbol == XK_Right) || (key_symbol == XK_KP_Right)) - { - if (resource_info->quantum >= (int) (crop_info.width-crop_info.x)) - resource_info->quantum=(int) (crop_info.width-crop_info.x-1); - crop_info.x+=resource_info->quantum; - crop_info.width-=resource_info->quantum; - } - if ((int) (windows->image.x+windows->image.width) > - (int) crop_info.width) - windows->image.x=(int) (crop_info.width-windows->image.width); - if ((int) (windows->image.y+windows->image.height) > - (int) crop_info.height) - windows->image.y=(int) (crop_info.height-windows->image.height); - XSetCropGeometry(display,windows,&crop_info,*image); - windows->image.window_changes.width=(int) crop_info.width; - windows->image.window_changes.height=(int) crop_info.height; - (void) XSetWindowBackgroundPixmap(display,windows->image.id,None); - (void) XConfigureImage(display,resource_info,windows,*image, - exception); - return(NullCommand); - } - XTranslateImage(display,windows,*image,key_symbol); - return(NullCommand); - } - default: - return(NullCommand); - } - return(NullCommand); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X M a g i c k C o m m a n d % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XMagickCommand() makes a transform to the image or Image window as -% specified by a user menu button or keyboard command. -% -% The format of the XMagickCommand method is: -% -% Image *XMagickCommand(Display *display,XResourceInfo *resource_info, -% XWindows *windows,const CommandType command,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o command: Specifies a command to perform. -% -% o image: the image; XMagickCommand may transform the image and return a -% new image pointer. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static Image *XMagickCommand(Display *display,XResourceInfo *resource_info, - XWindows *windows,const CommandType command,Image **image, - ExceptionInfo *exception) -{ - char - filename[MagickPathExtent], - geometry[MagickPathExtent], - modulate_factors[MagickPathExtent]; - - GeometryInfo - geometry_info; - - Image - *nexus; - - ImageInfo - *image_info; - - int - x, - y; - - MagickStatusType - flags, - status; - - QuantizeInfo - quantize_info; - - RectangleInfo - page_geometry; - - int - i; - - static char - color[MagickPathExtent] = "gray"; - - unsigned int - height, - width; - - /* - Process user command. - */ - XCheckRefreshWindows(display,windows); - XImageCache(display,resource_info,windows,command,image,exception); - nexus=NewImageList(); - windows->image.window_changes.width=windows->image.ximage->width; - windows->image.window_changes.height=windows->image.ximage->height; - image_info=CloneImageInfo(resource_info->image_info); - SetGeometryInfo(&geometry_info); - GetQuantizeInfo(&quantize_info); - switch (command) - { - case OpenCommand: - { - /* - Load image. - */ - nexus=XOpenImage(display,resource_info,windows,MagickFalse); - break; - } - case NextCommand: - { - /* - Display next image. - */ - for (i=0; i < resource_info->quantum; i++) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - break; - } - case FormerCommand: - { - /* - Display former image. - */ - for (i=0; i < resource_info->quantum; i++) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_former_image,CurrentTime); - break; - } - case SelectCommand: - { - int - status; - - /* - Select image. - */ - if (*resource_info->home_directory == '\0') - (void) CopyMagickString(resource_info->home_directory,".", - MagickPathExtent); - status=chdir(resource_info->home_directory); - if (status == -1) - (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError, - "UnableToOpenFile","%s",resource_info->home_directory); - nexus=XOpenImage(display,resource_info,windows,MagickTrue); - break; - } - case SaveCommand: - { - /* - Save image. - */ - status=XSaveImage(display,resource_info,windows,*image,exception); - if (status == MagickFalse) - { - char - message[MagickPathExtent]; - - (void) FormatLocaleString(message,MagickPathExtent,"%s:%s", - exception->reason != (char *) NULL ? exception->reason : "", - exception->description != (char *) NULL ? exception->description : - ""); - XNoticeWidget(display,windows,"Unable to save file:",message); - break; - } - break; - } - case PrintCommand: - { - /* - Print image. - */ - status=XPrintImage(display,resource_info,windows,*image,exception); - if (status == MagickFalse) - { - char - message[MagickPathExtent]; - - (void) FormatLocaleString(message,MagickPathExtent,"%s:%s", - exception->reason != (char *) NULL ? exception->reason : "", - exception->description != (char *) NULL ? exception->description : - ""); - XNoticeWidget(display,windows,"Unable to print file:",message); - break; - } - break; - } - case DeleteCommand: - { - static char - filename[MagickPathExtent] = "\0"; - - /* - Delete image file. - */ - XFileBrowserWidget(display,windows,"Delete",filename); - if (*filename == '\0') - break; - status=ShredFile(filename); - status|=remove_utf8(filename); - if (status != MagickFalse) - XNoticeWidget(display,windows,"Unable to delete image file:",filename); - break; - } - case NewCommand: - { - int - status; - - static char - color[MagickPathExtent] = "gray", - geometry[MagickPathExtent] = "640x480"; - - static const char - *format = "gradient"; - - /* - Query user for canvas geometry. - */ - status=XDialogWidget(display,windows,"New","Enter image geometry:", - geometry); - if (*geometry == '\0') - break; - if (status == 0) - format="xc"; - XColorBrowserWidget(display,windows,"Select",color); - if (*color == '\0') - break; - /* - Create canvas. - */ - (void) FormatLocaleString(image_info->filename,MagickPathExtent, - "%s:%s",format,color); - (void) CloneString(&image_info->size,geometry); - nexus=ReadImage(image_info,exception); - CatchException(exception); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - break; - } - case VisualDirectoryCommand: - { - /* - Visual Image directory. - */ - nexus=XVisualDirectoryImage(display,resource_info,windows,exception); - break; - } - case QuitCommand: - { - /* - exit program. - */ - if (resource_info->confirm_exit == MagickFalse) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_exit,CurrentTime); - else - { - int - status; - - /* - Confirm program exit. - */ - status=XConfirmWidget(display,windows,"Do you really want to exit", - resource_info->client_name); - if (status > 0) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_exit,CurrentTime); - } - break; - } - case CutCommand: - { - /* - Cut image. - */ - (void) XCropImage(display,resource_info,windows,*image,CutMode,exception); - break; - } - case CopyCommand: - { - /* - Copy image. - */ - (void) XCropImage(display,resource_info,windows,*image,CopyMode, - exception); - break; - } - case PasteCommand: - { - /* - Paste image. - */ - status=XPasteImage(display,resource_info,windows,*image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to paste X image", - (*image)->filename); - break; - } - break; - } - case HalfSizeCommand: - { - /* - Half image size. - */ - windows->image.window_changes.width=windows->image.ximage->width/2; - windows->image.window_changes.height=windows->image.ximage->height/2; - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case OriginalSizeCommand: - { - /* - Original image size. - */ - windows->image.window_changes.width=(int) (*image)->columns; - windows->image.window_changes.height=(int) (*image)->rows; - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case DoubleSizeCommand: - { - /* - Double the image size. - */ - windows->image.window_changes.width=windows->image.ximage->width << 1; - windows->image.window_changes.height=windows->image.ximage->height << 1; - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case ResizeCommand: - { - int - status; - - size_t - height, - width; - - ssize_t - x, - y; - - /* - Resize image. - */ - width=(size_t) windows->image.ximage->width; - height=(size_t) windows->image.ximage->height; - x=0; - y=0; - (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g+0+0", - (double) width,(double) height); - status=XDialogWidget(display,windows,"Resize", - "Enter resize geometry (e.g. 640x480, 200%):",geometry); - if (*geometry == '\0') - break; - if (status == 0) - (void) ConcatenateMagickString(geometry,"!",MagickPathExtent); - (void) ParseMetaGeometry(geometry,&x,&y,&width,&height); - windows->image.window_changes.width=(int) width; - windows->image.window_changes.height=(int) height; - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case ApplyCommand: - { - char - image_geometry[MagickPathExtent]; - - if ((windows->image.crop_geometry == (char *) NULL) && - ((int) (*image)->columns == windows->image.ximage->width) && - ((int) (*image)->rows == windows->image.ximage->height)) - break; - /* - Apply size transforms to image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - /* - Crop and/or scale displayed image. - */ - (void) FormatLocaleString(image_geometry,MagickPathExtent,"%dx%d!", - windows->image.ximage->width,windows->image.ximage->height); - (void) TransformImage(image,windows->image.crop_geometry,image_geometry, - exception); - if (windows->image.crop_geometry != (char *) NULL) - windows->image.crop_geometry=(char *) RelinquishMagickMemory( - windows->image.crop_geometry); - windows->image.x=0; - windows->image.y=0; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case RefreshCommand: - { - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case RestoreCommand: - { - /* - Restore Image window to its original size. - */ - if ((windows->image.width == (unsigned int) (*image)->columns) && - (windows->image.height == (unsigned int) (*image)->rows) && - (windows->image.crop_geometry == (char *) NULL)) - { - (void) XBell(display,0); - break; - } - windows->image.window_changes.width=(int) (*image)->columns; - windows->image.window_changes.height=(int) (*image)->rows; - if (windows->image.crop_geometry != (char *) NULL) - { - windows->image.crop_geometry=(char *) - RelinquishMagickMemory(windows->image.crop_geometry); - windows->image.crop_geometry=(char *) NULL; - windows->image.x=0; - windows->image.y=0; - } - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case CropCommand: - { - /* - Crop image. - */ - (void) XCropImage(display,resource_info,windows,*image,CropMode, - exception); - break; - } - case ChopCommand: - { - /* - Chop image. - */ - status=XChopImage(display,resource_info,windows,image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to cut X image", - (*image)->filename); - break; - } - break; - } - case FlopCommand: - { - Image - *flop_image; - - /* - Flop image scanlines. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flop_image=FlopImage(*image,exception); - if (flop_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=flop_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.crop_geometry != (char *) NULL) - { - /* - Flop crop geometry. - */ - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - (void) XParseGeometry(windows->image.crop_geometry,&x,&y, - &width,&height); - (void) FormatLocaleString(windows->image.crop_geometry, - MagickPathExtent,"%ux%u%+d%+d",width,height,(int) (*image)->columns- - (int) width-x,y); - } - if (windows->image.orphan != MagickFalse) - break; - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case FlipCommand: - { - Image - *flip_image; - - /* - Flip image scanlines. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flip_image=FlipImage(*image,exception); - if (flip_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=flip_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.crop_geometry != (char *) NULL) - { - /* - Flip crop geometry. - */ - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - (void) XParseGeometry(windows->image.crop_geometry,&x,&y, - &width,&height); - (void) FormatLocaleString(windows->image.crop_geometry, - MagickPathExtent,"%ux%u%+d%+d",width,height,x,(int) (*image)->rows- - (int) height-y); - } - if (windows->image.orphan != MagickFalse) - break; - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case RotateRightCommand: - { - /* - Rotate image 90 degrees clockwise. - */ - status=XRotateImage(display,resource_info,windows,90.0,image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to rotate X image", - (*image)->filename); - break; - } - break; - } - case RotateLeftCommand: - { - /* - Rotate image 90 degrees counter-clockwise. - */ - status=XRotateImage(display,resource_info,windows,-90.0,image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to rotate X image", - (*image)->filename); - break; - } - break; - } - case RotateCommand: - { - /* - Rotate image. - */ - status=XRotateImage(display,resource_info,windows,0.0,image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to rotate X image", - (*image)->filename); - break; - } - break; - } - case ShearCommand: - { - Image - *shear_image; - - static char - geometry[MagickPathExtent] = "45.0x45.0"; - - /* - Query user for shear color and geometry. - */ - XColorBrowserWidget(display,windows,"Select",color); - if (*color == '\0') - break; - (void) XDialogWidget(display,windows,"Shear","Enter shear geometry:", - geometry); - if (*geometry == '\0') - break; - /* - Shear image. - */ - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) QueryColorCompliance(color,AllCompliance, - &(*image)->background_color,exception); - flags=ParseGeometry(geometry,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=geometry_info.rho; - shear_image=ShearImage(*image,geometry_info.rho,geometry_info.sigma, - exception); - if (shear_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=shear_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - windows->image.window_changes.width=(int) (*image)->columns; - windows->image.window_changes.height=(int) (*image)->rows; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case RollCommand: - { - Image - *roll_image; - - static char - geometry[MagickPathExtent] = "+2+2"; - - /* - Query user for the roll geometry. - */ - (void) XDialogWidget(display,windows,"Roll","Enter roll geometry:", - geometry); - if (*geometry == '\0') - break; - /* - Roll image. - */ - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) ParsePageGeometry(*image,geometry,&page_geometry, - exception); - roll_image=RollImage(*image,page_geometry.x,page_geometry.y, - exception); - if (roll_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=roll_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - windows->image.window_changes.width=(int) (*image)->columns; - windows->image.window_changes.height=(int) (*image)->rows; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case TrimCommand: - { - static char - fuzz[MagickPathExtent]; - - /* - Query user for the fuzz factor. - */ - (void) FormatLocaleString(fuzz,MagickPathExtent,"%g%%",100.0* - (*image)->fuzz/(QuantumRange+1.0)); - (void) XDialogWidget(display,windows,"Trim","Enter fuzz factor:",fuzz); - if (*fuzz == '\0') - break; - (*image)->fuzz=StringToDoubleInterval(fuzz,(double) QuantumRange+1.0); - /* - Trim image. - */ - status=XTrimImage(display,resource_info,windows,*image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to trim X image", - (*image)->filename); - break; - } - break; - } - case HueCommand: - { - static char - hue_percent[MagickPathExtent] = "110"; - - /* - Query user for percent hue change. - */ - (void) XDialogWidget(display,windows,"Apply", - "Enter percent change in image hue (0-200):",hue_percent); - if (*hue_percent == '\0') - break; - /* - Vary the image hue. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) CopyMagickString(modulate_factors,"100.0/100.0/",MagickPathExtent); - (void) ConcatenateMagickString(modulate_factors,hue_percent, - MagickPathExtent); - (void) ModulateImage(*image,modulate_factors,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SaturationCommand: - { - static char - saturation_percent[MagickPathExtent] = "110"; - - /* - Query user for percent saturation change. - */ - (void) XDialogWidget(display,windows,"Apply", - "Enter percent change in color saturation (0-200):",saturation_percent); - if (*saturation_percent == '\0') - break; - /* - Vary color saturation. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) CopyMagickString(modulate_factors,"100.0/",MagickPathExtent); - (void) ConcatenateMagickString(modulate_factors,saturation_percent, - MagickPathExtent); - (void) ModulateImage(*image,modulate_factors,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case BrightnessCommand: - { - static char - brightness_percent[MagickPathExtent] = "110"; - - /* - Query user for percent brightness change. - */ - (void) XDialogWidget(display,windows,"Apply", - "Enter percent change in color brightness (0-200):",brightness_percent); - if (*brightness_percent == '\0') - break; - /* - Vary the color brightness. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) CopyMagickString(modulate_factors,brightness_percent, - MagickPathExtent); - (void) ModulateImage(*image,modulate_factors,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case GammaCommand: - { - static char - factor[MagickPathExtent] = "1.6"; - - /* - Query user for gamma value. - */ - (void) XDialogWidget(display,windows,"Gamma", - "Enter gamma value (e.g. 1.2):",factor); - if (*factor == '\0') - break; - /* - Gamma correct image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) GammaImage(*image,strtod(factor,(char **) NULL),exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SpiffCommand: - { - /* - Sharpen the image contrast. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) ContrastImage(*image,MagickTrue,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case DullCommand: - { - /* - Dull the image contrast. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) ContrastImage(*image,MagickFalse,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case ContrastStretchCommand: - { - double - black_point, - white_point; - - static char - levels[MagickPathExtent] = "1%"; - - /* - Query user for gamma value. - */ - (void) XDialogWidget(display,windows,"Contrast Stretch", - "Enter black and white points:",levels); - if (*levels == '\0') - break; - /* - Contrast stretch image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(levels,&geometry_info); - black_point=geometry_info.rho; - white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : black_point; - if ((flags & PercentValue) != 0) - { - black_point*=(double) (*image)->columns*(*image)->rows/100.0; - white_point*=(double) (*image)->columns*(*image)->rows/100.0; - } - white_point=(double) (*image)->columns*(*image)->rows-white_point; - (void) ContrastStretchImage(*image,black_point,white_point, - exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SigmoidalContrastCommand: - { - GeometryInfo - geometry_info; - - MagickStatusType - flags; - - static char - levels[MagickPathExtent] = "3x50%"; - - /* - Query user for gamma value. - */ - (void) XDialogWidget(display,windows,"Sigmoidal Contrast", - "Enter contrast and midpoint:",levels); - if (*levels == '\0') - break; - /* - Contrast stretch image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(levels,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=1.0*QuantumRange/2.0; - if ((flags & PercentValue) != 0) - geometry_info.sigma=1.0*QuantumRange*geometry_info.sigma/100.0; - (void) SigmoidalContrastImage(*image,MagickTrue,geometry_info.rho, - geometry_info.sigma,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case NormalizeCommand: - { - /* - Perform histogram normalization on the image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) NormalizeImage(*image,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case EqualizeCommand: - { - /* - Perform histogram equalization on the image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) EqualizeImage(*image,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case NegateCommand: - { - /* - Negate colors in image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) NegateImage(*image,MagickFalse,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case GrayscaleCommand: - { - /* - Convert image to grayscale. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) SetImageType(*image,(*image)->alpha_trait == UndefinedPixelTrait ? - GrayscaleType : GrayscaleAlphaType,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case MapCommand: - { - Image - *affinity_image; - - static char - filename[MagickPathExtent] = "\0"; - - /* - Request image file name from user. - */ - XFileBrowserWidget(display,windows,"Map",filename); - if (*filename == '\0') - break; - /* - Map image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); - affinity_image=ReadImage(image_info,exception); - if (affinity_image != (Image *) NULL) - { - (void) RemapImage(&quantize_info,*image,affinity_image,exception); - affinity_image=DestroyImage(affinity_image); - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case QuantizeCommand: - { - int - status; - - static char - colors[MagickPathExtent] = "256"; - - /* - Query user for maximum number of colors. - */ - status=XDialogWidget(display,windows,"Quantize", - "Maximum number of colors:",colors); - if (*colors == '\0') - break; - /* - Color reduce the image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - quantize_info.number_colors=StringToUnsignedLong(colors); - quantize_info.dither_method=status != 0 ? RiemersmaDitherMethod : - NoDitherMethod; - (void) QuantizeImage(&quantize_info,*image,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case DespeckleCommand: - { - Image - *despeckle_image; - - /* - Despeckle image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - despeckle_image=DespeckleImage(*image,exception); - if (despeckle_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=despeckle_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case EmbossCommand: - { - Image - *emboss_image; - - static char - radius[MagickPathExtent] = "0.0x1.0"; - - /* - Query user for emboss radius. - */ - (void) XDialogWidget(display,windows,"Emboss", - "Enter the emboss radius and standard deviation:",radius); - if (*radius == '\0') - break; - /* - Reduce noise in the image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(radius,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=1.0; - emboss_image=EmbossImage(*image,geometry_info.rho,geometry_info.sigma, - exception); - if (emboss_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=emboss_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case ReduceNoiseCommand: - { - Image - *noise_image; - - static char - radius[MagickPathExtent] = "0"; - - /* - Query user for noise radius. - */ - (void) XDialogWidget(display,windows,"Reduce Noise", - "Enter the noise radius:",radius); - if (*radius == '\0') - break; - /* - Reduce noise in the image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(radius,&geometry_info); - noise_image=StatisticImage(*image,NonpeakStatistic,(size_t) - geometry_info.rho,(size_t) geometry_info.rho,exception); - if (noise_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=noise_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case AddNoiseCommand: - { - char - **noises; - - Image - *noise_image; - - static char - noise_type[MagickPathExtent] = "Gaussian"; - - /* - Add noise to the image. - */ - noises=GetCommandOptions(MagickNoiseOptions); - if (noises == (char **) NULL) - break; - XListBrowserWidget(display,windows,&windows->widget, - (const char **) noises,"Add Noise", - "Select a type of noise to add to your image:",noise_type); - noises=DestroyStringList(noises); - if (*noise_type == '\0') - break; - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - noise_image=AddNoiseImage(*image,(NoiseType) ParseCommandOption( - MagickNoiseOptions,MagickFalse,noise_type),1.0,exception); - if (noise_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=noise_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SharpenCommand: - { - Image - *sharp_image; - - static char - radius[MagickPathExtent] = "0.0x1.0"; - - /* - Query user for sharpen radius. - */ - (void) XDialogWidget(display,windows,"Sharpen", - "Enter the sharpen radius and standard deviation:",radius); - if (*radius == '\0') - break; - /* - Sharpen image scanlines. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(radius,&geometry_info); - sharp_image=SharpenImage(*image,geometry_info.rho,geometry_info.sigma, - exception); - if (sharp_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=sharp_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case BlurCommand: - { - Image - *blur_image; - - static char - radius[MagickPathExtent] = "0.0x1.0"; - - /* - Query user for blur radius. - */ - (void) XDialogWidget(display,windows,"Blur", - "Enter the blur radius and standard deviation:",radius); - if (*radius == '\0') - break; - /* - Blur an image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(radius,&geometry_info); - blur_image=BlurImage(*image,geometry_info.rho,geometry_info.sigma, - exception); - if (blur_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=blur_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case ThresholdCommand: - { - double - threshold; - - static char - factor[MagickPathExtent] = "128"; - - /* - Query user for threshold value. - */ - (void) XDialogWidget(display,windows,"Threshold", - "Enter threshold value:",factor); - if (*factor == '\0') - break; - /* - Gamma correct image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - threshold=StringToDoubleInterval(factor,(double) QuantumRange+1.0); - (void) BilevelImage(*image,threshold,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case EdgeDetectCommand: - { - Image - *edge_image; - - static char - radius[MagickPathExtent] = "0"; - - /* - Query user for edge factor. - */ - (void) XDialogWidget(display,windows,"Detect Edges", - "Enter the edge detect radius:",radius); - if (*radius == '\0') - break; - /* - Detect edge in image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(radius,&geometry_info); - edge_image=EdgeImage(*image,geometry_info.rho,exception); - if (edge_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=edge_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SpreadCommand: - { - Image - *spread_image; - - static char - amount[MagickPathExtent] = "2"; - - /* - Query user for spread amount. - */ - (void) XDialogWidget(display,windows,"Spread", - "Enter the displacement amount:",amount); - if (*amount == '\0') - break; - /* - Displace image pixels by a random amount. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(amount,&geometry_info); - spread_image=EdgeImage(*image,geometry_info.rho,exception); - if (spread_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=spread_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case ShadeCommand: - { - Image - *shade_image; - - int - status; - - static char - geometry[MagickPathExtent] = "30x30"; - - /* - Query user for the shade geometry. - */ - status=XDialogWidget(display,windows,"Shade", - "Enter the azimuth and elevation of the light source:",geometry); - if (*geometry == '\0') - break; - /* - Shade image pixels. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(geometry,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=1.0; - shade_image=ShadeImage(*image,status != 0 ? MagickTrue : MagickFalse, - geometry_info.rho,geometry_info.sigma,exception); - if (shade_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=shade_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case RaiseCommand: - { - static char - bevel_width[MagickPathExtent] = "10"; - - /* - Query user for bevel width. - */ - (void) XDialogWidget(display,windows,"Raise","Bevel width:",bevel_width); - if (*bevel_width == '\0') - break; - /* - Raise an image. - */ - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) ParsePageGeometry(*image,bevel_width,&page_geometry, - exception); - (void) RaiseImage(*image,&page_geometry,MagickTrue,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SegmentCommand: - { - static char - threshold[MagickPathExtent] = "1.0x1.5"; - - /* - Query user for smoothing threshold. - */ - (void) XDialogWidget(display,windows,"Segment","Smooth threshold:", - threshold); - if (*threshold == '\0') - break; - /* - Segment an image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(threshold,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=1.0; - (void) SegmentImage(*image,sRGBColorspace,MagickFalse,geometry_info.rho, - geometry_info.sigma,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SepiaToneCommand: - { - double - threshold; - - Image - *sepia_image; - - static char - factor[MagickPathExtent] = "80%"; - - /* - Query user for sepia-tone factor. - */ - (void) XDialogWidget(display,windows,"Sepia Tone", - "Enter the sepia tone factor (0 - 99.9%):",factor); - if (*factor == '\0') - break; - /* - Sepia tone image pixels. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - threshold=StringToDoubleInterval(factor,(double) QuantumRange+1.0); - sepia_image=SepiaToneImage(*image,threshold,exception); - if (sepia_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=sepia_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SolarizeCommand: - { - double - threshold; - - static char - factor[MagickPathExtent] = "60%"; - - /* - Query user for solarize factor. - */ - (void) XDialogWidget(display,windows,"Solarize", - "Enter the solarize factor (0 - 99.9%):",factor); - if (*factor == '\0') - break; - /* - Solarize image pixels. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - threshold=StringToDoubleInterval(factor,(double) QuantumRange+1.0); - (void) SolarizeImage(*image,threshold,exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case SwirlCommand: - { - Image - *swirl_image; - - static char - degrees[MagickPathExtent] = "60"; - - /* - Query user for swirl angle. - */ - (void) XDialogWidget(display,windows,"Swirl","Enter the swirl angle:", - degrees); - if (*degrees == '\0') - break; - /* - Swirl image pixels about the center. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(degrees,&geometry_info); - swirl_image=SwirlImage(*image,geometry_info.rho,(*image)->interpolate, - exception); - if (swirl_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=swirl_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case ImplodeCommand: - { - Image - *implode_image; - - static char - factor[MagickPathExtent] = "0.3"; - - /* - Query user for implode factor. - */ - (void) XDialogWidget(display,windows,"Implode", - "Enter the implosion/explosion factor (-1.0 - 1.0):",factor); - if (*factor == '\0') - break; - /* - Implode image pixels about the center. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(factor,&geometry_info); - implode_image=ImplodeImage(*image,geometry_info.rho,(*image)->interpolate, - exception); - if (implode_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=implode_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case VignetteCommand: - { - Image - *vignette_image; - - static char - geometry[MagickPathExtent] = "0x20"; - - /* - Query user for the vignette geometry. - */ - (void) XDialogWidget(display,windows,"Vignette", - "Enter the radius, sigma, and x and y offsets:",geometry); - if (*geometry == '\0') - break; - /* - Soften the edges of the image in vignette style - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(geometry,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=1.0; - if ((flags & XiValue) == 0) - geometry_info.xi=0.1*(*image)->columns; - if ((flags & PsiValue) == 0) - geometry_info.psi=0.1*(*image)->rows; - vignette_image=VignetteImage(*image,geometry_info.rho,0.0,(ssize_t) - ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5), - exception); - if (vignette_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=vignette_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case WaveCommand: - { - Image - *wave_image; - - static char - geometry[MagickPathExtent] = "25x150"; - - /* - Query user for the wave geometry. - */ - (void) XDialogWidget(display,windows,"Wave", - "Enter the amplitude and length of the wave:",geometry); - if (*geometry == '\0') - break; - /* - Alter an image along a sine wave. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(geometry,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=1.0; - wave_image=WaveImage(*image,geometry_info.rho,geometry_info.sigma, - (*image)->interpolate,exception); - if (wave_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=wave_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case OilPaintCommand: - { - Image - *paint_image; - - static char - radius[MagickPathExtent] = "0"; - - /* - Query user for circular neighborhood radius. - */ - (void) XDialogWidget(display,windows,"Oil Paint", - "Enter the mask radius:",radius); - if (*radius == '\0') - break; - /* - OilPaint image scanlines. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(radius,&geometry_info); - paint_image=OilPaintImage(*image,geometry_info.rho,geometry_info.sigma, - exception); - if (paint_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=paint_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case CharcoalDrawCommand: - { - Image - *charcoal_image; - - static char - radius[MagickPathExtent] = "0x1"; - - /* - Query user for charcoal radius. - */ - (void) XDialogWidget(display,windows,"Charcoal Draw", - "Enter the charcoal radius and sigma:",radius); - if (*radius == '\0') - break; - /* - Charcoal the image. - */ - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - flags=ParseGeometry(radius,&geometry_info); - if ((flags & SigmaValue) == 0) - geometry_info.sigma=geometry_info.rho; - charcoal_image=CharcoalImage(*image,geometry_info.rho,geometry_info.sigma, - exception); - if (charcoal_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=charcoal_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case AnnotateCommand: - { - /* - Annotate the image with text. - */ - status=XAnnotateEditImage(display,resource_info,windows,*image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to annotate X image", - (*image)->filename); - break; - } - break; - } - case DrawCommand: - { - /* - Draw image. - */ - status=XDrawEditImage(display,resource_info,windows,image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to draw on the X image", - (*image)->filename); - break; - } - break; - } - case ColorCommand: - { - /* - Color edit. - */ - status=XColorEditImage(display,resource_info,windows,image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to pixel edit X image", - (*image)->filename); - break; - } - break; - } - case MatteCommand: - { - /* - Matte edit. - */ - status=XMatteEditImage(display,resource_info,windows,image,exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to matte edit X image", - (*image)->filename); - break; - } - break; - } - case CompositeCommand: - { - /* - Composite image. - */ - status=XCompositeImage(display,resource_info,windows,*image, - exception); - if (status == MagickFalse) - { - XNoticeWidget(display,windows,"Unable to composite X image", - (*image)->filename); - break; - } - break; - } - case AddBorderCommand: - { - Image - *border_image; - - static char - geometry[MagickPathExtent] = "6x6"; - - /* - Query user for border color and geometry. - */ - XColorBrowserWidget(display,windows,"Select",color); - if (*color == '\0') - break; - (void) XDialogWidget(display,windows,"Add Border", - "Enter border geometry:",geometry); - if (*geometry == '\0') - break; - /* - Add a border to the image. - */ - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) QueryColorCompliance(color,AllCompliance,&(*image)->border_color, - exception); - (void) ParsePageGeometry(*image,geometry,&page_geometry, - exception); - border_image=BorderImage(*image,&page_geometry,(*image)->compose, - exception); - if (border_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=border_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - windows->image.window_changes.width=(int) (*image)->columns; - windows->image.window_changes.height=(int) (*image)->rows; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case AddFrameCommand: - { - FrameInfo - frame_info; - - Image - *frame_image; - - static char - geometry[MagickPathExtent] = "6x6"; - - /* - Query user for frame color and geometry. - */ - XColorBrowserWidget(display,windows,"Select",color); - if (*color == '\0') - break; - (void) XDialogWidget(display,windows,"Add Frame","Enter frame geometry:", - geometry); - if (*geometry == '\0') - break; - /* - Surround image with an ornamental border. - */ - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) QueryColorCompliance(color,AllCompliance,&(*image)->matte_color, - exception); - (void) ParsePageGeometry(*image,geometry,&page_geometry, - exception); - frame_info.width=page_geometry.width; - frame_info.height=page_geometry.height; - frame_info.outer_bevel=page_geometry.x; - frame_info.inner_bevel=page_geometry.y; - frame_info.x=(ssize_t) frame_info.width; - frame_info.y=(ssize_t) frame_info.height; - frame_info.width=(*image)->columns+2*frame_info.width; - frame_info.height=(*image)->rows+2*frame_info.height; - frame_image=FrameImage(*image,&frame_info,(*image)->compose,exception); - if (frame_image != (Image *) NULL) - { - *image=DestroyImage(*image); - *image=frame_image; - } - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (windows->image.orphan != MagickFalse) - break; - windows->image.window_changes.width=(int) (*image)->columns; - windows->image.window_changes.height=(int) (*image)->rows; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - break; - } - case CommentCommand: - { - const char - *value; - - FILE - *file; - - int - unique_file; - - /* - Edit image comment. - */ - unique_file=AcquireUniqueFileResource(image_info->filename); - if (unique_file == -1) - { - XNoticeWidget(display,windows,"Unable to edit image comment", - image_info->filename); - break; - } - value=GetImageProperty(*image,"comment",exception); - if (value == (char *) NULL) - unique_file=close(unique_file)-1; - else - { - const char - *p; - - file=fdopen(unique_file,"w"); - if (file == (FILE *) NULL) - { - XNoticeWidget(display,windows,"Unable to edit image comment", - image_info->filename); - break; - } - for (p=value; *p != '\0'; p++) - (void) fputc((int) *p,file); - (void) fputc('\n',file); - (void) fclose(file); - } - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - status=InvokeDelegate(image_info,*image,"edit",(char *) NULL, - exception); - if (status == MagickFalse) - XNoticeWidget(display,windows,"Unable to edit image comment", - (char *) NULL); - else - { - char - *comment; - - comment=FileToString(image_info->filename,~0UL,exception); - if (comment != (char *) NULL) - { - (void) SetImageProperty(*image,"comment",comment,exception); - (*image)->taint=MagickTrue; - } - } - (void) RelinquishUniqueFileResource(image_info->filename); - XSetCursorState(display,windows,MagickFalse); - break; - } - case LaunchCommand: - { - /* - Launch program. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) AcquireUniqueFilename(filename); - (void) FormatLocaleString((*image)->filename,MagickPathExtent,"launch:%s", - filename); - status=WriteImage(image_info,*image,exception); - if (status == MagickFalse) - XNoticeWidget(display,windows,"Unable to launch image editor", - (char *) NULL); - else - { - nexus=ReadImage(resource_info->image_info,exception); - CatchException(exception); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - } - (void) RelinquishUniqueFileResource(filename); - XSetCursorState(display,windows,MagickFalse); - break; - } - case RegionOfInterestCommand: - { - /* - Apply an image processing technique to a region of interest. - */ - (void) XROIImage(display,resource_info,windows,image,exception); - break; - } - case InfoCommand: - break; - case ZoomCommand: - { - /* - Zoom image. - */ - if (windows->magnify.mapped != MagickFalse) - (void) XRaiseWindow(display,windows->magnify.id); - else - { - /* - Make magnify image. - */ - XSetCursorState(display,windows,MagickTrue); - (void) XMapRaised(display,windows->magnify.id); - XSetCursorState(display,windows,MagickFalse); - } - break; - } - case ShowPreviewCommand: - { - char - **previews; - - Image - *preview_image; - - PreviewType - preview; - - static char - preview_type[MagickPathExtent] = "Gamma"; - - /* - Select preview type from menu. - */ - previews=GetCommandOptions(MagickPreviewOptions); - if (previews == (char **) NULL) - break; - XListBrowserWidget(display,windows,&windows->widget, - (const char **) previews,"Preview", - "Select an enhancement, effect, or F/X:",preview_type); - previews=DestroyStringList(previews); - if (*preview_type == '\0') - break; - /* - Show image preview. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - preview=(PreviewType) ParseCommandOption(MagickPreviewOptions, - MagickFalse,preview_type); - (void) FormatImageProperty(*image,"group","%.20g",(double) - windows->image.id); - (void) DeleteImageProperty(*image,"label"); - (void) SetImageProperty(*image,"label","Preview",exception); - preview_image=PreviewImage(*image,preview,exception); - if (preview_image == (Image *) NULL) - break; - (void) AcquireUniqueFilename(filename); - (void) FormatLocaleString(preview_image->filename,MagickPathExtent, - "show:%s",filename); - status=WriteImage(image_info,preview_image,exception); - (void) RelinquishUniqueFileResource(filename); - preview_image=DestroyImage(preview_image); - if (status == MagickFalse) - XNoticeWidget(display,windows,"Unable to show image preview", - (*image)->filename); - XDelay(display,1500); - XSetCursorState(display,windows,MagickFalse); - break; - } - case ShowHistogramCommand: - { - Image - *histogram_image; - - /* - Show image histogram. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) DeleteImageProperty(*image,"label"); - (void) FormatImageProperty(*image,"group","%.20g",(double) - windows->image.id); - (void) SetImageProperty(*image,"label","Histogram",exception); - (void) AcquireUniqueFilename(filename); - (void) FormatLocaleString((*image)->filename,MagickPathExtent, - "histogram:%s",filename); - status=WriteImage(image_info,*image,exception); - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); - histogram_image=ReadImage(image_info,exception); - (void) RelinquishUniqueFileResource(filename); - if (histogram_image == (Image *) NULL) - break; - (void) FormatLocaleString(histogram_image->filename,MagickPathExtent, - "show:%s",filename); - status=WriteImage(image_info,histogram_image,exception); - histogram_image=DestroyImage(histogram_image); - if (status == MagickFalse) - XNoticeWidget(display,windows,"Unable to show histogram", - (*image)->filename); - XDelay(display,1500); - XSetCursorState(display,windows,MagickFalse); - break; - } - case ShowMatteCommand: - { - Image - *matte_image; - - if ((*image)->alpha_trait == UndefinedPixelTrait) - { - XNoticeWidget(display,windows, - "Image does not have any matte information",(*image)->filename); - break; - } - /* - Show image matte. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) FormatImageProperty(*image,"group","%.20g",(double) - windows->image.id); - (void) DeleteImageProperty(*image,"label"); - (void) SetImageProperty(*image,"label","Matte",exception); - (void) AcquireUniqueFilename(filename); - (void) FormatLocaleString((*image)->filename,MagickPathExtent,"matte:%s", - filename); - status=WriteImage(image_info,*image,exception); - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); - matte_image=ReadImage(image_info,exception); - (void) RelinquishUniqueFileResource(filename); - if (matte_image == (Image *) NULL) - break; - (void) FormatLocaleString(matte_image->filename,MagickPathExtent, - "show:%s",filename); - status=WriteImage(image_info,matte_image,exception); - matte_image=DestroyImage(matte_image); - if (status == MagickFalse) - XNoticeWidget(display,windows,"Unable to show matte", - (*image)->filename); - XDelay(display,1500); - XSetCursorState(display,windows,MagickFalse); - break; - } - case BackgroundCommand: - { - /* - Background image. - */ - status=XBackgroundImage(display,resource_info,windows,image,exception); - if (status == MagickFalse) - break; - nexus=CloneImage(*image,0,0,MagickTrue,exception); - if (nexus != (Image *) NULL) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - break; - } - case SlideShowCommand: - { - static char - delay[MagickPathExtent] = "5"; - - /* - Display next image after pausing. - */ - (void) XDialogWidget(display,windows,"Slide Show", - "Pause how many 1/100ths of a second between images:",delay); - if (*delay == '\0') - break; - resource_info->delay=StringToUnsignedLong(delay); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - break; - } - case PreferencesCommand: - { - /* - Set user preferences. - */ - status=XPreferencesWidget(display,resource_info,windows); - if (status == MagickFalse) - break; - nexus=CloneImage(*image,0,0,MagickTrue,exception); - if (nexus != (Image *) NULL) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - break; - } - case HelpCommand: - { - /* - User requested help. - */ - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Display",DisplayHelp); - break; - } - case BrowseDocumentationCommand: - { - Atom - mozilla_atom; - - Window - mozilla_window, - root_window; - - /* - Browse the ImageMagick documentation. - */ - root_window=XRootWindow(display,XDefaultScreen(display)); - mozilla_atom=XInternAtom(display,"_MOZILLA_VERSION",MagickFalse); - mozilla_window=XWindowByProperty(display,root_window,mozilla_atom); - if (mozilla_window != (Window) NULL) - { - char - command[MagickPathExtent]; - - /* - Display documentation using Netscape remote control. - */ - (void) FormatLocaleString(command,MagickPathExtent, - "openurl(%s,new-tab)",MagickAuthoritativeURL); - mozilla_atom=XInternAtom(display,"_MOZILLA_COMMAND",MagickFalse); - (void) XChangeProperty(display,mozilla_window,mozilla_atom,XA_STRING, - 8,PropModeReplace,(unsigned char *) command,(int) strlen(command)); - XSetCursorState(display,windows,MagickFalse); - break; - } - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - status=InvokeDelegate(image_info,*image,"browse",(char *) NULL, - exception); - if (status == MagickFalse) - XNoticeWidget(display,windows,"Unable to browse documentation", - (char *) NULL); - XDelay(display,1500); - XSetCursorState(display,windows,MagickFalse); - break; - } - case VersionCommand: - { - XNoticeWidget(display,windows,GetMagickVersion((size_t *) NULL), - GetMagickCopyright()); - break; - } - case SaveToUndoBufferCommand: - break; - default: - { - (void) XBell(display,0); - break; - } - } - image_info=DestroyImageInfo(image_info); - return(nexus); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X M a g n i f y I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XMagnifyImage() magnifies portions of the image as indicated by the pointer. -% The magnified portion is displayed in a separate window. -% -% The format of the XMagnifyImage method is: -% -% void XMagnifyImage(Display *display,XWindows *windows,XEvent *event, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o event: Specifies a pointer to a XEvent structure. If it is NULL, -% the entire image is refreshed. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static void XMagnifyImage(Display *display,XWindows *windows,XEvent *event, - ExceptionInfo *exception) -{ - char - text[MagickPathExtent]; - - int - x, - y; - - size_t - state; - - /* - Update magnified image until the mouse button is released. - */ - (void) XCheckDefineCursor(display,windows->image.id,windows->magnify.cursor); - state=DefaultState; - x=event->xbutton.x; - y=event->xbutton.y; - windows->magnify.x=(int) windows->image.x+x; - windows->magnify.y=(int) windows->image.y+y; - do - { - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ", - windows->magnify.x,windows->magnify.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,event,exception); - switch (event->type) - { - case ButtonPress: - break; - case ButtonRelease: - { - /* - User has finished magnifying image. - */ - x=event->xbutton.x; - y=event->xbutton.y; - state|=ExitState; - break; - } - case Expose: - break; - case MotionNotify: - { - x=event->xmotion.x; - y=event->xmotion.y; - break; - } - default: - break; - } - /* - Check boundary conditions. - */ - if (x < 0) - x=0; - else - if (x >= (int) windows->image.width) - x=(int) windows->image.width-1; - if (y < 0) - y=0; - else - if (y >= (int) windows->image.height) - y=(int) windows->image.height-1; - } while ((state & ExitState) == 0); - /* - Display magnified image. - */ - XSetCursorState(display,windows,MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X M a g n i f y W i n d o w C o m m a n d % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XMagnifyWindowCommand() moves the image within an Magnify window by one -% pixel as specified by the key symbol. -% -% The format of the XMagnifyWindowCommand method is: -% -% void XMagnifyWindowCommand(Display *display,XWindows *windows, -% const MagickStatusType state,const KeySym key_symbol, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o state: key mask. -% -% o key_symbol: Specifies a KeySym which indicates which side of the image -% to trim. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static void XMagnifyWindowCommand(Display *display,XWindows *windows, - const MagickStatusType state,const KeySym key_symbol,ExceptionInfo *exception) -{ - unsigned int - quantum; - - /* - User specified a magnify factor or position. - */ - quantum=1; - if ((state & Mod1Mask) != 0) - quantum=10; - switch ((int) key_symbol) - { - case QuitCommand: - { - (void) XWithdrawWindow(display,windows->magnify.id, - windows->magnify.screen); - break; - } - case XK_Home: - case XK_KP_Home: - { - windows->magnify.x=(int) windows->image.width/2; - windows->magnify.y=(int) windows->image.height/2; - break; - } - case XK_Left: - case XK_KP_Left: - { - if (windows->magnify.x > 0) - windows->magnify.x-=quantum; - break; - } - case XK_Up: - case XK_KP_Up: - { - if (windows->magnify.y > 0) - windows->magnify.y-=quantum; - break; - } - case XK_Right: - case XK_KP_Right: - { - if (windows->magnify.x < (int) (windows->image.ximage->width-1)) - windows->magnify.x+=quantum; - break; - } - case XK_Down: - case XK_KP_Down: - { - if (windows->magnify.y < (int) (windows->image.ximage->height-1)) - windows->magnify.y+=quantum; - break; - } - case XK_0: - case XK_1: - case XK_2: - case XK_3: - case XK_4: - case XK_5: - case XK_6: - case XK_7: - case XK_8: - case XK_9: - { - windows->magnify.data=(key_symbol-XK_0); - break; - } - case XK_KP_0: - case XK_KP_1: - case XK_KP_2: - case XK_KP_3: - case XK_KP_4: - case XK_KP_5: - case XK_KP_6: - case XK_KP_7: - case XK_KP_8: - case XK_KP_9: - { - windows->magnify.data=(key_symbol-XK_KP_0); - break; - } - default: - break; - } - XMakeMagnifyImage(display,windows,exception); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X M a k e P a n I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XMakePanImage() creates a thumbnail of the image and displays it in the Pan -% icon window. -% -% The format of the XMakePanImage method is: -% -% void XMakePanImage(Display *display,XResourceInfo *resource_info, -% XWindows *windows,Image *image,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static void XMakePanImage(Display *display,XResourceInfo *resource_info, - XWindows *windows,Image *image,ExceptionInfo *exception) -{ - MagickStatusType - status; - - /* - Create and display image for panning icon. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - windows->pan.x=(int) windows->image.x; - windows->pan.y=(int) windows->image.y; - status=XMakeImage(display,resource_info,&windows->pan,image, - windows->pan.width,windows->pan.height,exception); - if (status == MagickFalse) - ThrowXWindowException(ResourceLimitError, - "MemoryAllocationFailed",image->filename); - (void) XSetWindowBackgroundPixmap(display,windows->pan.id, - windows->pan.pixmap); - (void) XClearWindow(display,windows->pan.id); - XDrawPanRectangle(display,windows); - XSetCursorState(display,windows,MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X M a t t a E d i t I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XMatteEditImage() allows the user to interactively change the Matte channel -% of an image. If the image is PseudoClass it is promoted to DirectClass -% before the matte information is stored. -% -% The format of the XMatteEditImage method is: -% -% MagickBooleanType XMatteEditImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XMatteEditImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image **image, - ExceptionInfo *exception) -{ - const char - *const MatteEditMenu[] = - { - "Method", - "Border Color", - "Fuzz", - "Matte Value", - "Undo", - "Help", - "Dismiss", - (char *) NULL - }; - - static char - matte[MagickPathExtent] = "0"; - - static const ModeType - MatteEditCommands[] = - { - MatteEditMethod, - MatteEditBorderCommand, - MatteEditFuzzCommand, - MatteEditValueCommand, - MatteEditUndoCommand, - MatteEditHelpCommand, - MatteEditDismissCommand - }; - - static PaintMethod - method = PointMethod; - - static XColor - border_color = { 0, 0, 0, 0, 0, 0 }; - - char - command[MagickPathExtent], - text[MagickPathExtent]; - - Cursor - cursor; - - int - entry, - id, - x, - x_offset, - y, - y_offset; - - int - i; - - Quantum - *q; - - unsigned int - height, - width; - - size_t - state; - - XEvent - event; - - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Matte Edit"); - windows->command.data=4; - (void) XCommandWidget(display,windows,MatteEditMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Make cursor. - */ - cursor=XMakeCursor(display,windows->image.id,windows->map_info->colormap, - resource_info->background_color,resource_info->foreground_color); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - /* - Track pointer until button 1 is pressed. - */ - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+d%+d ", - x+windows->image.x,y+windows->image.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,MatteEditMenu,&event); - if (id < 0) - { - (void) XCheckDefineCursor(display,windows->image.id,cursor); - continue; - } - switch (MatteEditCommands[id]) - { - case MatteEditMethod: - { - char - **methods; - - /* - Select a method from the pop-up menu. - */ - methods=GetCommandOptions(MagickMethodOptions); - if (methods == (char **) NULL) - break; - entry=XMenuWidget(display,windows,MatteEditMenu[id], - (const char **) methods,command); - if (entry >= 0) - method=(PaintMethod) ParseCommandOption(MagickMethodOptions, - MagickFalse,methods[entry]); - methods=DestroyStringList(methods); - break; - } - case MatteEditBorderCommand: - { - const char - *ColorMenu[MaxNumberPens]; - - int - pen_number; - - /* - Initialize menu selections. - */ - for (i=0; i < (int) (MaxNumberPens-2); i++) - ColorMenu[i]=resource_info->pen_colors[i]; - ColorMenu[MaxNumberPens-2]="Browser..."; - ColorMenu[MaxNumberPens-1]=(const char *) NULL; - /* - Select a pen color from the pop-up menu. - */ - pen_number=XMenuWidget(display,windows,MatteEditMenu[id], - (const char **) ColorMenu,command); - if (pen_number < 0) - break; - if (pen_number == (MaxNumberPens-2)) - { - static char - color_name[MagickPathExtent] = "gray"; - - /* - Select a pen color from a dialog. - */ - resource_info->pen_colors[pen_number]=color_name; - XColorBrowserWidget(display,windows,"Select",color_name); - if (*color_name == '\0') - break; - } - /* - Set border color. - */ - (void) XParseColor(display,windows->map_info->colormap, - resource_info->pen_colors[pen_number],&border_color); - break; - } - case MatteEditFuzzCommand: - { - const char - *const FuzzMenu[] = - { - "0%", - "2%", - "5%", - "10%", - "15%", - "Dialog...", - (char *) NULL, - }; - - static char - fuzz[MagickPathExtent]; - - /* - Select a command from the pop-up menu. - */ - entry=XMenuWidget(display,windows,MatteEditMenu[id],FuzzMenu, - command); - if (entry < 0) - break; - if (entry != 5) - { - (*image)->fuzz=StringToDoubleInterval(FuzzMenu[entry],(double) - QuantumRange+1.0); - break; - } - (void) CopyMagickString(fuzz,"20%",MagickPathExtent); - (void) XDialogWidget(display,windows,"Ok", - "Enter fuzz factor (0.0 - 99.9%):",fuzz); - if (*fuzz == '\0') - break; - (void) ConcatenateMagickString(fuzz,"%",MagickPathExtent); - (*image)->fuzz=StringToDoubleInterval(fuzz,(double) QuantumRange+ - 1.0); - break; - } - case MatteEditValueCommand: - { - const char - *const MatteMenu[] = - { - "Opaque", - "Transparent", - "Dialog...", - (char *) NULL, - }; - - static char - message[MagickPathExtent]; - - /* - Select a command from the pop-up menu. - */ - entry=XMenuWidget(display,windows,MatteEditMenu[id],MatteMenu, - command); - if (entry < 0) - break; - if (entry != 2) - { - (void) FormatLocaleString(matte,MagickPathExtent,QuantumFormat, - OpaqueAlpha); - if (LocaleCompare(MatteMenu[entry],"Transparent") == 0) - (void) FormatLocaleString(matte,MagickPathExtent, - QuantumFormat,(Quantum) TransparentAlpha); - break; - } - (void) FormatLocaleString(message,MagickPathExtent, - "Enter matte value (0 - " QuantumFormat "):",(Quantum) - QuantumRange); - (void) XDialogWidget(display,windows,"Matte",message,matte); - if (*matte == '\0') - break; - break; - } - case MatteEditUndoCommand: - { - (void) XMagickCommand(display,resource_info,windows,UndoCommand, - image,exception); - break; - } - case MatteEditHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Matte Edit",ImageMatteEditHelp); - break; - } - case MatteEditDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - (void) XCheckDefineCursor(display,windows->image.id,cursor); - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if ((event.xbutton.window != windows->image.id) && - (event.xbutton.window != windows->magnify.id)) - break; - /* - Update matte data. - */ - x=event.xbutton.x; - y=event.xbutton.y; - (void) XMagickCommand(display,resource_info,windows, - SaveToUndoBufferCommand,image,exception); - state|=UpdateConfigurationState; - break; - } - case ButtonRelease: - { - if (event.xbutton.button != Button1) - break; - if ((event.xbutton.window != windows->image.id) && - (event.xbutton.window != windows->magnify.id)) - break; - /* - Update colormap information. - */ - x=event.xbutton.x; - y=event.xbutton.y; - XConfigureImageColormap(display,resource_info,windows,*image,exception); - (void) XConfigureImage(display,resource_info,windows,*image,exception); - XInfoWidget(display,windows,text); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - state&=(~UpdateConfigurationState); - break; - } - case Expose: - break; - case KeyPress: - { - char - command[MagickPathExtent]; - - KeySym - key_symbol; - - if (event.xkey.window == windows->magnify.id) - { - Window - window; - - window=windows->magnify.id; - while (XCheckWindowEvent(display,window,KeyPressMask,&event)) ; - } - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Matte Edit",ImageMatteEditHelp); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - break; - } - default: - break; - } - if (event.xany.window == windows->magnify.id) - { - x=windows->magnify.x-windows->image.x; - y=windows->magnify.y-windows->image.y; - } - x_offset=x; - y_offset=y; - if ((state & UpdateConfigurationState) != 0) - { - CacheView - *image_view; - - int - x, - y; - - /* - Matte edit is relative to image configuration. - */ - (void) XClearArea(display,windows->image.id,x_offset,y_offset,1,1, - MagickTrue); - XPutPixel(windows->image.ximage,x_offset,y_offset, - windows->pixel_info->background_color.pixel); - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width, - &height); - x_offset=(int) (width*(windows->image.x+x_offset)/ - windows->image.ximage->width+x); - y_offset=(int) (height*(windows->image.y+y_offset)/ - windows->image.ximage->height+y); - if ((x_offset < 0) || (y_offset < 0)) - continue; - if ((x_offset >= (int) (*image)->columns) || - (y_offset >= (int) (*image)->rows)) - continue; - if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse) - return(MagickFalse); - if ((*image)->alpha_trait == UndefinedPixelTrait) - (void) SetImageAlphaChannel(*image,OpaqueAlphaChannel,exception); - image_view=AcquireAuthenticCacheView(*image,exception); - switch (method) - { - case PointMethod: - default: - { - /* - Update matte information using point algorithm. - */ - q=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset, - (ssize_t) y_offset,1,1,exception); - if (q == (Quantum *) NULL) - break; - SetPixelAlpha(*image,(Quantum) StringToLong(matte),q); - (void) SyncCacheViewAuthenticPixels(image_view,exception); - break; - } - case ReplaceMethod: - { - PixelInfo - pixel, - target; - - /* - Update matte information using replace algorithm. - */ - (void) GetOneCacheViewVirtualPixelInfo(image_view,(ssize_t) - x_offset,(ssize_t) y_offset,&target,exception); - for (y=0; y < (int) (*image)->rows; y++) - { - q=GetCacheViewAuthenticPixels(image_view,0,(ssize_t) y, - (*image)->columns,1,exception); - if (q == (Quantum *) NULL) - break; - for (x=0; x < (int) (*image)->columns; x++) - { - GetPixelInfoPixel(*image,q,&pixel); - if (IsFuzzyEquivalencePixelInfo(&pixel,&target)) - SetPixelAlpha(*image,(Quantum) StringToLong(matte),q); - q+=GetPixelChannels(*image); - } - if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) - break; - } - break; - } - case FloodfillMethod: - case FillToBorderMethod: - { - ChannelType - channel_mask; - - DrawInfo - *draw_info; - - PixelInfo - target; - - /* - Update matte information using floodfill algorithm. - */ - (void) GetOneVirtualPixelInfo(*image, - GetPixelCacheVirtualMethod(*image),(ssize_t) x_offset,(ssize_t) - y_offset,&target,exception); - if (method == FillToBorderMethod) - { - target.red=(double) ScaleShortToQuantum( - border_color.red); - target.green=(double) ScaleShortToQuantum( - border_color.green); - target.blue=(double) ScaleShortToQuantum( - border_color.blue); - } - draw_info=CloneDrawInfo(resource_info->image_info, - (DrawInfo *) NULL); - draw_info->fill.alpha=(double) ClampToQuantum( - StringToDouble(matte,(char **) NULL)); - channel_mask=SetImageChannelMask(*image,AlphaChannel); - (void) FloodfillPaintImage(*image,draw_info,&target,(ssize_t) - x_offset,(ssize_t) y_offset, - method != FloodfillMethod ? MagickTrue : MagickFalse,exception); - (void) SetPixelChannelMask(*image,channel_mask); - draw_info=DestroyDrawInfo(draw_info); - break; - } - case ResetMethod: - { - /* - Update matte information using reset algorithm. - */ - if (SetImageStorageClass(*image,DirectClass,exception) == MagickFalse) - return(MagickFalse); - for (y=0; y < (int) (*image)->rows; y++) - { - q=QueueCacheViewAuthenticPixels(image_view,0,(ssize_t) y, - (*image)->columns,1,exception); - if (q == (Quantum *) NULL) - break; - for (x=0; x < (int) (*image)->columns; x++) - { - SetPixelAlpha(*image,(Quantum) StringToLong(matte),q); - q+=GetPixelChannels(*image); - } - if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) - break; - } - if (StringToLong(matte) == (long) OpaqueAlpha) - (*image)->alpha_trait=UndefinedPixelTrait; - break; - } - } - image_view=DestroyCacheView(image_view); - state&=(~UpdateConfigurationState); - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - XSetCursorState(display,windows,MagickFalse); - (void) XFreeCursor(display,cursor); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X O p e n I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XOpenImage() loads an image from a file. -% -% The format of the XOpenImage method is: -% -% Image *XOpenImage(Display *display,XResourceInfo *resource_info, -% XWindows *windows,const unsigned int command) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o command: A value other than zero indicates that the file is selected -% from the command line argument list. -% -*/ -static Image *XOpenImage(Display *display,XResourceInfo *resource_info, - XWindows *windows,const MagickBooleanType command) -{ - const MagickInfo - *magick_info; - - ExceptionInfo - *exception; - - Image - *nexus; - - ImageInfo - *image_info; - - static char - filename[MagickPathExtent] = "\0"; - - /* - Request file name from user. - */ - if (command == MagickFalse) - XFileBrowserWidget(display,windows,"Open",filename); - else - { - char - **filelist, - **files; - - int - count, - status; - - int - i, - j; - - /* - Select next image from the command line. - */ - status=XGetCommand(display,windows->image.id,&files,&count); - if (status == 0) - { - ThrowXWindowException(XServerError,"UnableToGetProperty","..."); - return((Image *) NULL); - } - filelist=(char **) AcquireQuantumMemory((size_t) count,sizeof(*filelist)); - if (filelist == (char **) NULL) - { - ThrowXWindowException(ResourceLimitError, - "MemoryAllocationFailed","..."); - (void) XFreeStringList(files); - return((Image *) NULL); - } - j=0; - for (i=1; i < count; i++) - if (*files[i] != '-') - filelist[j++]=files[i]; - filelist[j]=(char *) NULL; - XListBrowserWidget(display,windows,&windows->widget, - (const char **) filelist,"Load","Select Image to Load:",filename); - filelist=(char **) RelinquishMagickMemory(filelist); - (void) XFreeStringList(files); - } - if (*filename == '\0') - return((Image *) NULL); - image_info=CloneImageInfo(resource_info->image_info); - (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL, - (void *) NULL); - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); - exception=AcquireExceptionInfo(); - (void) SetImageInfo(image_info,0,exception); - if (LocaleCompare(image_info->magick,"X") == 0) - { - char - seconds[MagickPathExtent]; - - /* - User may want to delay the X server screen grab. - */ - (void) CopyMagickString(seconds,"0",MagickPathExtent); - (void) XDialogWidget(display,windows,"Grab","Enter any delay in seconds:", - seconds); - if (*seconds == '\0') - return((Image *) NULL); - XDelay(display,(size_t) (1000*StringToLong(seconds))); - } - magick_info=GetMagickInfo(image_info->magick,exception); - if ((magick_info != (const MagickInfo *) NULL) && - GetMagickRawSupport(magick_info) == MagickTrue) - { - char - geometry[MagickPathExtent]; - - /* - Request image size from the user. - */ - (void) CopyMagickString(geometry,"512x512",MagickPathExtent); - if (image_info->size != (char *) NULL) - (void) CopyMagickString(geometry,image_info->size,MagickPathExtent); - (void) XDialogWidget(display,windows,"Load","Enter the image geometry:", - geometry); - (void) CloneString(&image_info->size,geometry); - } - /* - Load the image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); - nexus=ReadImage(image_info,exception); - CatchException(exception); - XSetCursorState(display,windows,MagickFalse); - if (nexus != (Image *) NULL) - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - else - { - char - *text, - **textlist; - - /* - Unknown image format. - */ - text=FileToString(filename,~0UL,exception); - if (text == (char *) NULL) - return((Image *) NULL); - textlist=StringToList(text); - if (textlist != (char **) NULL) - { - char - title[MagickPathExtent]; - - int - i; - - (void) FormatLocaleString(title,MagickPathExtent, - "Unknown format: %s",filename); - XTextViewWidget(display,resource_info,windows,MagickTrue,title, - (const char **) textlist); - for (i=0; textlist[i] != (char *) NULL; i++) - textlist[i]=DestroyString(textlist[i]); - textlist=(char **) RelinquishMagickMemory(textlist); - } - text=DestroyString(text); - } - exception=DestroyExceptionInfo(exception); - image_info=DestroyImageInfo(image_info); - return(nexus); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X P a n I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XPanImage() pans the image until the mouse button is released. -% -% The format of the XPanImage method is: -% -% void XPanImage(Display *display,XWindows *windows,XEvent *event, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o event: Specifies a pointer to a XEvent structure. If it is NULL, -% the entire image is refreshed. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static void XPanImage(Display *display,XWindows *windows,XEvent *event, - ExceptionInfo *exception) -{ - char - text[MagickPathExtent]; - - Cursor - cursor; - - double - x_factor, - y_factor; - - RectangleInfo - pan_info; - - size_t - state; - - /* - Define cursor. - */ - if ((windows->image.ximage->width > (int) windows->image.width) && - (windows->image.ximage->height > (int) windows->image.height)) - cursor=XCreateFontCursor(display,XC_fleur); - else - if (windows->image.ximage->width > (int) windows->image.width) - cursor=XCreateFontCursor(display,XC_sb_h_double_arrow); - else - if (windows->image.ximage->height > (int) windows->image.height) - cursor=XCreateFontCursor(display,XC_sb_v_double_arrow); - else - cursor=XCreateFontCursor(display,XC_arrow); - (void) XCheckDefineCursor(display,windows->pan.id,cursor); - /* - Pan image as pointer moves until the mouse button is released. - */ - x_factor=(double) windows->image.ximage->width/windows->pan.width; - y_factor=(double) windows->image.ximage->height/windows->pan.height; - pan_info.width=windows->pan.width*windows->image.width/ - windows->image.ximage->width; - pan_info.height=windows->pan.height*windows->image.height/ - windows->image.ximage->height; - pan_info.x=0; - pan_info.y=0; - state=UpdateConfigurationState; - do - { - switch (event->type) - { - case ButtonPress: - { - /* - User choose an initial pan location. - */ - pan_info.x=(ssize_t) event->xbutton.x; - pan_info.y=(ssize_t) event->xbutton.y; - state|=UpdateConfigurationState; - break; - } - case ButtonRelease: - { - /* - User has finished panning the image. - */ - pan_info.x=(ssize_t) event->xbutton.x; - pan_info.y=(ssize_t) event->xbutton.y; - state|=UpdateConfigurationState | ExitState; - break; - } - case MotionNotify: - { - pan_info.x=(ssize_t) event->xmotion.x; - pan_info.y=(ssize_t) event->xmotion.y; - state|=UpdateConfigurationState; - } - default: - break; - } - if ((state & UpdateConfigurationState) != 0) - { - /* - Check boundary conditions. - */ - if (pan_info.x < (ssize_t) (pan_info.width/2)) - pan_info.x=0; - else - pan_info.x=(ssize_t) (x_factor*(pan_info.x-(pan_info.width/2))); - if (pan_info.x < 0) - pan_info.x=0; - else - if ((int) (pan_info.x+windows->image.width) > - windows->image.ximage->width) - pan_info.x=(ssize_t) - (windows->image.ximage->width-windows->image.width); - if (pan_info.y < (ssize_t) (pan_info.height/2)) - pan_info.y=0; - else - pan_info.y=(ssize_t) (y_factor*(pan_info.y-(pan_info.height/2))); - if (pan_info.y < 0) - pan_info.y=0; - else - if ((int) (pan_info.y+windows->image.height) > - windows->image.ximage->height) - pan_info.y=(ssize_t) - (windows->image.ximage->height-windows->image.height); - if ((windows->image.x != (int) pan_info.x) || - (windows->image.y != (int) pan_info.y)) - { - /* - Display image pan offset. - */ - windows->image.x=(int) pan_info.x; - windows->image.y=(int) pan_info.y; - (void) FormatLocaleString(text,MagickPathExtent," %ux%u%+d%+d ", - windows->image.width,windows->image.height,windows->image.x, - windows->image.y); - XInfoWidget(display,windows,text); - /* - Refresh Image window. - */ - XDrawPanRectangle(display,windows); - XRefreshWindow(display,&windows->image,(XEvent *) NULL); - } - state&=(~UpdateConfigurationState); - } - /* - Wait for next event. - */ - if ((state & ExitState) == 0) - XScreenEvent(display,windows,event,exception); - } while ((state & ExitState) == 0); - /* - Restore cursor. - */ - (void) XCheckDefineCursor(display,windows->pan.id,windows->pan.cursor); - (void) XFreeCursor(display,cursor); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X P a s t e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XPasteImage() pastes an image previously saved with XCropImage in the X -% window image at a location the user chooses with the pointer. -% -% The format of the XPasteImage method is: -% -% MagickBooleanType XPasteImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XPasteImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - ExceptionInfo *exception) -{ - const char - *const PasteMenu[] = - { - "Operator", - "Help", - "Dismiss", - (char *) NULL - }; - - static const ModeType - PasteCommands[] = - { - PasteOperatorsCommand, - PasteHelpCommand, - PasteDismissCommand - }; - - static CompositeOperator - compose = CopyCompositeOp; - - char - text[MagickPathExtent]; - - Cursor - cursor; - - Image - *paste_image; - - int - entry, - id, - x, - y; - - double - scale_factor; - - RectangleInfo - highlight_info, - paste_info; - - unsigned int - height, - width; - - size_t - state; - - XEvent - event; - - /* - Copy image. - */ - if (resource_info->copy_image == (Image *) NULL) - return(MagickFalse); - paste_image=CloneImage(resource_info->copy_image,0,0,MagickTrue,exception); - if (paste_image == (Image *) NULL) - return(MagickFalse); - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Paste"); - windows->command.data=1; - (void) XCommandWidget(display,windows,PasteMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Track pointer until button 1 is pressed. - */ - XSetCursorState(display,windows,MagickFalse); - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - paste_info.x=(ssize_t) windows->image.x+x; - paste_info.y=(ssize_t) windows->image.y+y; - paste_info.width=0; - paste_info.height=0; - cursor=XCreateFontCursor(display,XC_ul_angle); - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ", - (long) paste_info.x,(long) paste_info.y); - XInfoWidget(display,windows,text); - } - highlight_info=paste_info; - highlight_info.x=paste_info.x-windows->image.x; - highlight_info.y=paste_info.y-windows->image.y; - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,PasteMenu,&event); - if (id < 0) - continue; - switch (PasteCommands[id]) - { - case PasteOperatorsCommand: - { - char - command[MagickPathExtent], - **operators; - - /* - Select a command from the pop-up menu. - */ - operators=GetCommandOptions(MagickComposeOptions); - if (operators == (char **) NULL) - break; - entry=XMenuWidget(display,windows,PasteMenu[id], - (const char **) operators,command); - if (entry >= 0) - compose=(CompositeOperator) ParseCommandOption( - MagickComposeOptions,MagickFalse,operators[entry]); - operators=DestroyStringList(operators); - break; - } - case PasteHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Composite",ImagePasteHelp); - break; - } - case PasteDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Button Press: 0x%lx %u +%d+%d",event.xbutton.window, - event.xbutton.button,event.xbutton.x,event.xbutton.y); - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - Paste rectangle is relative to image configuration. - */ - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y, - &width,&height); - scale_factor=(double) windows->image.ximage->width/width; - paste_info.width=(unsigned int) (scale_factor*paste_image->columns+0.5); - scale_factor=(double) windows->image.ximage->height/height; - paste_info.height=(unsigned int) (scale_factor*paste_image->rows+0.5); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - paste_info.x=(ssize_t) windows->image.x+event.xbutton.x; - paste_info.y=(ssize_t) windows->image.y+event.xbutton.y; - break; - } - case ButtonRelease: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Button Release: 0x%lx %u +%d+%d",event.xbutton.window, - event.xbutton.button,event.xbutton.x,event.xbutton.y); - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - if ((paste_info.width != 0) && (paste_info.height != 0)) - { - /* - User has selected the location of the paste image. - */ - paste_info.x=(ssize_t) windows->image.x+event.xbutton.x; - paste_info.y=(ssize_t) windows->image.y+event.xbutton.y; - state|=ExitState; - } - break; - } - case Expose: - break; - case KeyPress: - { - char - command[MagickPathExtent]; - - KeySym - key_symbol; - - int - length; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - length=XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - *(command+length)='\0'; - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Key press: 0x%lx (%s)",(long) key_symbol,command); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - paste_image=DestroyImage(paste_image); - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Composite",ImagePasteHelp); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - paste_info.x=(ssize_t) windows->image.x+x; - paste_info.y=(ssize_t) windows->image.y+y; - break; - } - default: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d", - event.type); - break; - } - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - XSetCursorState(display,windows,MagickFalse); - (void) XFreeCursor(display,cursor); - if ((state & EscapeState) != 0) - return(MagickTrue); - /* - Image pasting is relative to image configuration. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - scale_factor=(double) width/windows->image.ximage->width; - paste_info.x+=x; - paste_info.x=(ssize_t) (scale_factor*paste_info.x+0.5); - paste_info.width=(unsigned int) (scale_factor*paste_info.width+0.5); - scale_factor=(double) height/windows->image.ximage->height; - paste_info.y+=y; - paste_info.y=(ssize_t) (scale_factor*paste_info.y*scale_factor+0.5); - paste_info.height=(unsigned int) (scale_factor*paste_info.height+0.5); - /* - Paste image with X Image window. - */ - (void) CompositeImage(image,paste_image,compose,MagickTrue,paste_info.x, - paste_info.y,exception); - paste_image=DestroyImage(paste_image); - XSetCursorState(display,windows,MagickFalse); - /* - Update image colormap. - */ - XConfigureImageColormap(display,resource_info,windows,image,exception); - (void) XConfigureImage(display,resource_info,windows,image,exception); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X P r i n t I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XPrintImage() prints an image to a Postscript printer. -% -% The format of the XPrintImage method is: -% -% MagickBooleanType XPrintImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XPrintImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - ExceptionInfo *exception) -{ - char - filename[MagickPathExtent], - geometry[MagickPathExtent]; - - const char - *const PageSizes[] = - { - "Letter", - "Tabloid", - "Ledger", - "Legal", - "Statement", - "Executive", - "A3", - "A4", - "A5", - "B4", - "B5", - "Folio", - "Quarto", - "10x14", - (char *) NULL - }; - - Image - *print_image; - - ImageInfo - *image_info; - - MagickStatusType - status; - - /* - Request Postscript page geometry from user. - */ - image_info=CloneImageInfo(resource_info->image_info); - (void) FormatLocaleString(geometry,MagickPathExtent,"Letter"); - if (image_info->page != (char *) NULL) - (void) CopyMagickString(geometry,image_info->page,MagickPathExtent); - XListBrowserWidget(display,windows,&windows->widget,PageSizes,"Select", - "Select Postscript Page Geometry:",geometry); - if (*geometry == '\0') - return(MagickTrue); - image_info->page=GetPageGeometry(geometry); - /* - Apply image transforms. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - print_image=CloneImage(image,0,0,MagickTrue,exception); - if (print_image == (Image *) NULL) - return(MagickFalse); - (void) FormatLocaleString(geometry,MagickPathExtent,"%dx%d!", - windows->image.ximage->width,windows->image.ximage->height); - (void) TransformImage(&print_image,windows->image.crop_geometry,geometry, - exception); - /* - Print image. - */ - (void) AcquireUniqueFilename(filename); - (void) FormatLocaleString(print_image->filename,MagickPathExtent,"print:%s", - filename); - status=WriteImage(image_info,print_image,exception); - (void) RelinquishUniqueFileResource(filename); - print_image=DestroyImage(print_image); - image_info=DestroyImageInfo(image_info); - XSetCursorState(display,windows,MagickFalse); - return(status != 0 ? MagickTrue : MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X R O I I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XROIImage() applies an image processing technique to a region of interest. -% -% The format of the XROIImage method is: -% -% MagickBooleanType XROIImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image **image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XROIImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image **image, - ExceptionInfo *exception) -{ -#define ApplyMenus 7 - - const char - *const ROIMenu[] = - { - "Help", - "Dismiss", - (char *) NULL - }, - *const ApplyMenu[] = - { - "File", - "Edit", - "Transform", - "Enhance", - "Effects", - "F/X", - "Miscellany", - "Help", - "Dismiss", - (char *) NULL - }, - *const FileMenu[] = - { - "Save...", - "Print...", - (char *) NULL - }, - *const EditMenu[] = - { - "Undo", - "Redo", - (char *) NULL - }, - *const TransformMenu[] = - { - "Flop", - "Flip", - "Rotate Right", - "Rotate Left", - (char *) NULL - }, - *const EnhanceMenu[] = - { - "Hue...", - "Saturation...", - "Brightness...", - "Gamma...", - "Spiff", - "Dull", - "Contrast Stretch...", - "Sigmoidal Contrast...", - "Normalize", - "Equalize", - "Negate", - "Grayscale", - "Map...", - "Quantize...", - (char *) NULL - }, - *const EffectsMenu[] = - { - "Despeckle", - "Emboss", - "Reduce Noise", - "Add Noise", - "Sharpen...", - "Blur...", - "Threshold...", - "Edge Detect...", - "Spread...", - "Shade...", - "Raise...", - "Segment...", - (char *) NULL - }, - *const FXMenu[] = - { - "Solarize...", - "Sepia Tone...", - "Swirl...", - "Implode...", - "Vignette...", - "Wave...", - "Oil Paint...", - "Charcoal Draw...", - (char *) NULL - }, - *const MiscellanyMenu[] = - { - "Image Info", - "Zoom Image", - "Show Preview...", - "Show Histogram", - "Show Matte", - (char *) NULL - }; - - const char - *const *Menus[ApplyMenus] = - { - FileMenu, - EditMenu, - TransformMenu, - EnhanceMenu, - EffectsMenu, - FXMenu, - MiscellanyMenu - }; - - static const CommandType - ApplyCommands[] = - { - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - HelpCommand, - QuitCommand - }, - FileCommands[] = - { - SaveCommand, - PrintCommand - }, - EditCommands[] = - { - UndoCommand, - RedoCommand - }, - TransformCommands[] = - { - FlopCommand, - FlipCommand, - RotateRightCommand, - RotateLeftCommand - }, - EnhanceCommands[] = - { - HueCommand, - SaturationCommand, - BrightnessCommand, - GammaCommand, - SpiffCommand, - DullCommand, - ContrastStretchCommand, - SigmoidalContrastCommand, - NormalizeCommand, - EqualizeCommand, - NegateCommand, - GrayscaleCommand, - MapCommand, - QuantizeCommand - }, - EffectsCommands[] = - { - DespeckleCommand, - EmbossCommand, - ReduceNoiseCommand, - AddNoiseCommand, - SharpenCommand, - BlurCommand, - EdgeDetectCommand, - SpreadCommand, - ShadeCommand, - RaiseCommand, - SegmentCommand - }, - FXCommands[] = - { - SolarizeCommand, - SepiaToneCommand, - SwirlCommand, - ImplodeCommand, - VignetteCommand, - WaveCommand, - OilPaintCommand, - CharcoalDrawCommand - }, - MiscellanyCommands[] = - { - InfoCommand, - ZoomCommand, - ShowPreviewCommand, - ShowHistogramCommand, - ShowMatteCommand - }, - ROICommands[] = - { - ROIHelpCommand, - ROIDismissCommand - }; - - static const CommandType - *Commands[ApplyMenus] = - { - FileCommands, - EditCommands, - TransformCommands, - EnhanceCommands, - EffectsCommands, - FXCommands, - MiscellanyCommands - }; - - char - command[MagickPathExtent], - text[MagickPathExtent]; - - CommandType - command_type; - - Cursor - cursor; - - Image - *roi_image; - - int - entry, - id, - x, - y; - - double - scale_factor; - - MagickProgressMonitor - progress_monitor; - - RectangleInfo - crop_info, - highlight_info, - roi_info; - - unsigned int - height, - width; - - size_t - state; - - XEvent - event; - - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"ROI"); - windows->command.data=0; - (void) XCommandWidget(display,windows,ROIMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Track pointer until button 1 is pressed. - */ - XQueryPosition(display,windows->image.id,&x,&y); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask | PointerMotionMask); - roi_info.x=(ssize_t) windows->image.x+x; - roi_info.y=(ssize_t) windows->image.y+y; - roi_info.width=0; - roi_info.height=0; - cursor=XCreateFontCursor(display,XC_fleur); - state=DefaultState; - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent," %+ld%+ld ", - (long) roi_info.x,(long) roi_info.y); - XInfoWidget(display,windows,text); - } - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,ROIMenu,&event); - if (id < 0) - continue; - switch (ROICommands[id]) - { - case ROIHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Region of Interest",ImageROIHelp); - break; - } - case ROIDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - Note first corner of region of interest rectangle-- exit loop. - */ - (void) XCheckDefineCursor(display,windows->image.id,cursor); - roi_info.x=(ssize_t) windows->image.x+event.xbutton.x; - roi_info.y=(ssize_t) windows->image.y+event.xbutton.y; - state|=ExitState; - break; - } - case ButtonRelease: - break; - case Expose: - break; - case KeyPress: - { - KeySym - key_symbol; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Region of Interest",ImageROIHelp); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - roi_info.x=(ssize_t) windows->image.x+x; - roi_info.y=(ssize_t) windows->image.y+y; - break; - } - default: - break; - } - } while ((state & ExitState) == 0); - (void) XSelectInput(display,windows->image.id, - windows->image.attributes.event_mask); - if ((state & EscapeState) != 0) - { - /* - User want to exit without region of interest. - */ - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - (void) XFreeCursor(display,cursor); - return(MagickTrue); - } - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - do - { - /* - Size rectangle as pointer moves until the mouse button is released. - */ - x=(int) roi_info.x; - y=(int) roi_info.y; - roi_info.width=0; - roi_info.height=0; - state=DefaultState; - do - { - highlight_info=roi_info; - highlight_info.x=roi_info.x-windows->image.x; - highlight_info.y=roi_info.y-windows->image.y; - if ((highlight_info.width > 3) && (highlight_info.height > 3)) - { - /* - Display info and draw region of interest rectangle. - */ - if (windows->info.mapped == MagickFalse) - (void) XMapWindow(display,windows->info.id); - (void) FormatLocaleString(text,MagickPathExtent, - " %.20gx%.20g%+.20g%+.20g",(double) roi_info.width,(double) - roi_info.height,(double) roi_info.x,(double) roi_info.y); - XInfoWidget(display,windows,text); - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - } - else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if ((highlight_info.width > 3) && (highlight_info.height > 3)) - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - switch (event.type) - { - case ButtonPress: - { - roi_info.x=(ssize_t) windows->image.x+event.xbutton.x; - roi_info.y=(ssize_t) windows->image.y+event.xbutton.y; - break; - } - case ButtonRelease: - { - /* - User has committed to region of interest rectangle. - */ - roi_info.x=(ssize_t) windows->image.x+event.xbutton.x; - roi_info.y=(ssize_t) windows->image.y+event.xbutton.y; - XSetCursorState(display,windows,MagickFalse); - state|=ExitState; - if (LocaleCompare(windows->command.name,"Apply") == 0) - break; - (void) CloneString(&windows->command.name,"Apply"); - windows->command.data=ApplyMenus; - (void) XCommandWidget(display,windows,ApplyMenu,(XEvent *) NULL); - break; - } - case Expose: - break; - case MotionNotify: - { - roi_info.x=(ssize_t) windows->image.x+event.xmotion.x; - roi_info.y=(ssize_t) windows->image.y+event.xmotion.y; - } - default: - break; - } - if ((((int) roi_info.x != x) && ((int) roi_info.y != y)) || - ((state & ExitState) != 0)) - { - /* - Check boundary conditions. - */ - if (roi_info.x < 0) - roi_info.x=0; - else - if (roi_info.x > (ssize_t) windows->image.ximage->width) - roi_info.x=(ssize_t) windows->image.ximage->width; - if ((int) roi_info.x < x) - roi_info.width=(unsigned int) (x-roi_info.x); - else - { - roi_info.width=(unsigned int) (roi_info.x-x); - roi_info.x=(ssize_t) x; - } - if (roi_info.y < 0) - roi_info.y=0; - else - if (roi_info.y > (ssize_t) windows->image.ximage->height) - roi_info.y=(ssize_t) windows->image.ximage->height; - if ((int) roi_info.y < y) - roi_info.height=(unsigned int) (y-roi_info.y); - else - { - roi_info.height=(unsigned int) (roi_info.y-y); - roi_info.y=(ssize_t) y; - } - } - } while ((state & ExitState) == 0); - /* - Wait for user to grab a corner of the rectangle or press return. - */ - state=DefaultState; - command_type=NullCommand; - crop_info.x=0; - crop_info.y=0; - (void) XMapWindow(display,windows->info.id); - do - { - if (windows->info.mapped != MagickFalse) - { - /* - Display pointer position. - */ - (void) FormatLocaleString(text,MagickPathExtent, - " %.20gx%.20g%+.20g%+.20g",(double) roi_info.width,(double) - roi_info.height,(double) roi_info.x,(double) roi_info.y); - XInfoWidget(display,windows,text); - } - highlight_info=roi_info; - highlight_info.x=roi_info.x-windows->image.x; - highlight_info.y=roi_info.y-windows->image.y; - if ((highlight_info.width <= 3) || (highlight_info.height <= 3)) - { - state|=EscapeState; - state|=ExitState; - break; - } - if ((state & UpdateRegionState) != 0) - { - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - switch (command_type) - { - case UndoCommand: - case RedoCommand: - { - (void) XMagickCommand(display,resource_info,windows,command_type, - image,exception); - break; - } - default: - { - /* - Region of interest is relative to image configuration. - */ - progress_monitor=SetImageProgressMonitor(*image, - (MagickProgressMonitor) NULL,(*image)->client_data); - crop_info=roi_info; - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - x=0; - y=0; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y, - &width,&height); - scale_factor=(double) width/windows->image.ximage->width; - crop_info.x+=x; - crop_info.x=(ssize_t) (scale_factor*crop_info.x+0.5); - crop_info.width=(unsigned int) (scale_factor*crop_info.width+0.5); - scale_factor=(double) - height/windows->image.ximage->height; - crop_info.y+=y; - crop_info.y=(ssize_t) (scale_factor*crop_info.y+0.5); - crop_info.height=(unsigned int) - (scale_factor*crop_info.height+0.5); - roi_image=CropImage(*image,&crop_info,exception); - (void) SetImageProgressMonitor(*image,progress_monitor, - (*image)->client_data); - if (roi_image == (Image *) NULL) - continue; - /* - Apply image processing technique to the region of interest. - */ - windows->image.orphan=MagickTrue; - (void) XMagickCommand(display,resource_info,windows,command_type, - &roi_image,exception); - progress_monitor=SetImageProgressMonitor(*image, - (MagickProgressMonitor) NULL,(*image)->client_data); - (void) XMagickCommand(display,resource_info,windows, - SaveToUndoBufferCommand,image,exception); - windows->image.orphan=MagickFalse; - (void) CompositeImage(*image,roi_image,CopyCompositeOp, - MagickTrue,crop_info.x,crop_info.y,exception); - roi_image=DestroyImage(roi_image); - (void) SetImageProgressMonitor(*image,progress_monitor, - (*image)->client_data); - break; - } - } - if (command_type != InfoCommand) - { - XConfigureImageColormap(display,resource_info,windows,*image, - exception); - (void) XConfigureImage(display,resource_info,windows,*image, - exception); - } - XCheckRefreshWindows(display,windows); - XInfoWidget(display,windows,text); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - state&=(~UpdateRegionState); - } - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - XScreenEvent(display,windows,&event,exception); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - command_type=NullCommand; - id=XCommandWidget(display,windows,ApplyMenu,&event); - if (id >= 0) - { - (void) CopyMagickString(command,ApplyMenu[id],MagickPathExtent); - command_type=ApplyCommands[id]; - if (id < ApplyMenus) - { - /* - Select a command from a pop-up menu. - */ - entry=XMenuWidget(display,windows,ApplyMenu[id], - (const char **) Menus[id],command); - if (entry >= 0) - { - (void) CopyMagickString(command,Menus[id][entry], - MagickPathExtent); - command_type=Commands[id][entry]; - } - } - } - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - if (command_type == HelpCommand) - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Region of Interest",ImageROIHelp); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - continue; - } - if (command_type == QuitCommand) - { - /* - exit. - */ - state|=EscapeState; - state|=ExitState; - continue; - } - if (command_type != NullCommand) - state|=UpdateRegionState; - continue; - } - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - switch (event.type) - { - case ButtonPress: - { - x=windows->image.x; - y=windows->image.y; - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - x=windows->image.x+event.xbutton.x; - y=windows->image.y+event.xbutton.y; - if ((x < (int) (roi_info.x+RoiDelta)) && - (x > (int) (roi_info.x-RoiDelta)) && - (y < (int) (roi_info.y+RoiDelta)) && - (y > (int) (roi_info.y-RoiDelta))) - { - roi_info.x=(ssize_t) (roi_info.x+roi_info.width); - roi_info.y=(ssize_t) (roi_info.y+roi_info.height); - state|=UpdateConfigurationState; - break; - } - if ((x < (int) (roi_info.x+RoiDelta)) && - (x > (int) (roi_info.x-RoiDelta)) && - (y < (int) (roi_info.y+roi_info.height+RoiDelta)) && - (y > (int) (roi_info.y+roi_info.height-RoiDelta))) - { - roi_info.x=(ssize_t) (roi_info.x+roi_info.width); - state|=UpdateConfigurationState; - break; - } - if ((x < (int) (roi_info.x+roi_info.width+RoiDelta)) && - (x > (int) (roi_info.x+roi_info.width-RoiDelta)) && - (y < (int) (roi_info.y+RoiDelta)) && - (y > (int) (roi_info.y-RoiDelta))) - { - roi_info.y=(ssize_t) (roi_info.y+roi_info.height); - state|=UpdateConfigurationState; - break; - } - if ((x < (int) (roi_info.x+roi_info.width+RoiDelta)) && - (x > (int) (roi_info.x+roi_info.width-RoiDelta)) && - (y < (int) (roi_info.y+roi_info.height+RoiDelta)) && - (y > (int) (roi_info.y+roi_info.height-RoiDelta))) - { - state|=UpdateConfigurationState; - break; - } - } - case ButtonRelease: - { - if (event.xbutton.window == windows->pan.id) - if ((highlight_info.x != crop_info.x-windows->image.x) || - (highlight_info.y != crop_info.y-windows->image.y)) - XHighlightRectangle(display,windows->image.id, - windows->image.highlight_context,&highlight_info); - (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id, - event.xbutton.time); - break; - } - case Expose: - { - if (event.xexpose.window == windows->image.id) - if (event.xexpose.count == 0) - { - event.xexpose.x=(int) highlight_info.x; - event.xexpose.y=(int) highlight_info.y; - event.xexpose.width=(int) highlight_info.width; - event.xexpose.height=(int) highlight_info.height; - XRefreshWindow(display,&windows->image,&event); - } - if (event.xexpose.window == windows->info.id) - if (event.xexpose.count == 0) - XInfoWidget(display,windows,text); - break; - } - case KeyPress: - { - KeySym - key_symbol; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Shift_L: - case XK_Shift_R: - break; - case XK_Escape: - case XK_F20: - state|=EscapeState; - case XK_Return: - { - state|=ExitState; - break; - } - case XK_Home: - case XK_KP_Home: - { - roi_info.x=(ssize_t) (windows->image.width/2L-roi_info.width/2L); - roi_info.y=(ssize_t) (windows->image.height/2L- - roi_info.height/2L); - break; - } - case XK_Left: - case XK_KP_Left: - { - roi_info.x--; - break; - } - case XK_Up: - case XK_KP_Up: - case XK_Next: - { - roi_info.y--; - break; - } - case XK_Right: - case XK_KP_Right: - { - roi_info.x++; - break; - } - case XK_Prior: - case XK_Down: - case XK_KP_Down: - { - roi_info.y++; - break; - } - case XK_F1: - case XK_Help: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Region of Interest",ImageROIHelp); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - default: - { - command_type=XImageWindowCommand(display,resource_info,windows, - event.xkey.state,key_symbol,image,exception); - if (command_type != NullCommand) - state|=UpdateRegionState; - break; - } - } - (void) XSetSelectionOwner(display,XA_PRIMARY,windows->image.id, - event.xkey.time); - break; - } - case KeyRelease: - break; - case MotionNotify: - { - if (event.xbutton.window != windows->image.id) - break; - /* - Map and unmap Info widget as text cursor crosses its boundaries. - */ - x=event.xmotion.x; - y=event.xmotion.y; - if (windows->info.mapped != MagickFalse) - { - if ((x < (int) (windows->info.x+windows->info.width)) && - (y < (int) (windows->info.y+windows->info.height))) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - } - else - if ((x > (int) (windows->info.x+windows->info.width)) || - (y > (int) (windows->info.y+windows->info.height))) - (void) XMapWindow(display,windows->info.id); - roi_info.x=(ssize_t) windows->image.x+event.xmotion.x; - roi_info.y=(ssize_t) windows->image.y+event.xmotion.y; - break; - } - case SelectionRequest: - { - XSelectionEvent - notify; - - XSelectionRequestEvent - *request; - - /* - Set primary selection. - */ - (void) FormatLocaleString(text,MagickPathExtent, - "%.20gx%.20g%+.20g%+.20g",(double) roi_info.width,(double) - roi_info.height,(double) roi_info.x,(double) roi_info.y); - request=(&(event.xselectionrequest)); - (void) XChangeProperty(request->display,request->requestor, - request->property,request->target,8,PropModeReplace, - (unsigned char *) text,(int) strlen(text)); - notify.type=SelectionNotify; - notify.display=request->display; - notify.requestor=request->requestor; - notify.selection=request->selection; - notify.target=request->target; - notify.time=request->time; - if (request->property == None) - notify.property=request->target; - else - notify.property=request->property; - (void) XSendEvent(request->display,request->requestor,False,0, - (XEvent *) ¬ify); - } - default: - break; - } - if ((state & UpdateConfigurationState) != 0) - { - (void) XPutBackEvent(display,&event); - (void) XCheckDefineCursor(display,windows->image.id,cursor); - break; - } - } while ((state & ExitState) == 0); - } while ((state & ExitState) == 0); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - XSetCursorState(display,windows,MagickFalse); - if ((state & EscapeState) != 0) - return(MagickTrue); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X R o t a t e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XRotateImage() rotates the X image. If the degrees parameter if zero, the -% rotation angle is computed from the slope of a line drawn by the user. -% -% The format of the XRotateImage method is: -% -% MagickBooleanType XRotateImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,double degrees, -% Image **image,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o degrees: Specifies the number of degrees to rotate the image. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XRotateImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,double degrees,Image **image, - ExceptionInfo *exception) -{ - const char - *const RotateMenu[] = - { - "Pixel Color", - "Direction", - "Help", - "Dismiss", - (char *) NULL - }; - - static ModeType - direction = HorizontalRotateCommand; - - static const ModeType - DirectionCommands[] = - { - HorizontalRotateCommand, - VerticalRotateCommand - }, - RotateCommands[] = - { - RotateColorCommand, - RotateDirectionCommand, - RotateHelpCommand, - RotateDismissCommand - }; - - static unsigned int - pen_id = 0; - - char - command[MagickPathExtent], - text[MagickPathExtent]; - - Image - *rotate_image; - - int - id, - x, - y; - - double - normalized_degrees; - - int - i; - - unsigned int - height, - rotations, - width; - - if (degrees == 0.0) - { - unsigned int - distance; - - size_t - state; - - XEvent - event; - - XSegment - rotate_info; - - /* - Map Command widget. - */ - (void) CloneString(&windows->command.name,"Rotate"); - windows->command.data=2; - (void) XCommandWidget(display,windows,RotateMenu,(XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_update_widget,CurrentTime); - /* - Wait for first button press. - */ - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - XQueryPosition(display,windows->image.id,&x,&y); - rotate_info.x1=x; - rotate_info.y1=y; - rotate_info.x2=x; - rotate_info.y2=y; - state=DefaultState; - do - { - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&rotate_info); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&rotate_info); - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,RotateMenu,&event); - if (id < 0) - continue; - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - switch (RotateCommands[id]) - { - case RotateColorCommand: - { - const char - *ColorMenu[MaxNumberPens]; - - int - pen_number; - - XColor - color; - - /* - Initialize menu selections. - */ - for (i=0; i < (int) (MaxNumberPens-2); i++) - ColorMenu[i]=resource_info->pen_colors[i]; - ColorMenu[MaxNumberPens-2]="Browser..."; - ColorMenu[MaxNumberPens-1]=(const char *) NULL; - /* - Select a pen color from the pop-up menu. - */ - pen_number=XMenuWidget(display,windows,RotateMenu[id], - (const char **) ColorMenu,command); - if (pen_number < 0) - break; - if (pen_number == (MaxNumberPens-2)) - { - static char - color_name[MagickPathExtent] = "gray"; - - /* - Select a pen color from a dialog. - */ - resource_info->pen_colors[pen_number]=color_name; - XColorBrowserWidget(display,windows,"Select",color_name); - if (*color_name == '\0') - break; - } - /* - Set pen color. - */ - (void) XParseColor(display,windows->map_info->colormap, - resource_info->pen_colors[pen_number],&color); - XBestPixel(display,windows->map_info->colormap,(XColor *) NULL, - (unsigned int) MaxColors,&color); - windows->pixel_info->pen_colors[pen_number]=color; - pen_id=(unsigned int) pen_number; - break; - } - case RotateDirectionCommand: - { - const char - *Directions[] = - { - "horizontal", - "vertical", - (char *) NULL, - }; - - /* - Select a command from the pop-up menu. - */ - id=XMenuWidget(display,windows,RotateMenu[id], - Directions,command); - if (id >= 0) - direction=DirectionCommands[id]; - break; - } - case RotateHelpCommand: - { - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Rotation",ImageRotateHelp); - break; - } - case RotateDismissCommand: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - default: - break; - } - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (event.xbutton.button != Button1) - break; - if (event.xbutton.window != windows->image.id) - break; - /* - exit loop. - */ - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - rotate_info.x1=event.xbutton.x; - rotate_info.y1=event.xbutton.y; - state|=ExitState; - break; - } - case ButtonRelease: - break; - case Expose: - break; - case KeyPress: - { - char - command[MagickPathExtent]; - - KeySym - key_symbol; - - if (event.xkey.window != windows->image.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - switch ((int) key_symbol) - { - case XK_Escape: - case XK_F20: - { - /* - Prematurely exit. - */ - state|=EscapeState; - state|=ExitState; - break; - } - case XK_F1: - case XK_Help: - { - (void) XSetFunction(display,windows->image.highlight_context, - GXcopy); - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Rotation",ImageRotateHelp); - (void) XSetFunction(display,windows->image.highlight_context, - GXinvert); - break; - } - default: - { - (void) XBell(display,0); - break; - } - } - break; - } - case MotionNotify: - { - rotate_info.x1=event.xmotion.x; - rotate_info.y1=event.xmotion.y; - } - } - rotate_info.x2=rotate_info.x1; - rotate_info.y2=rotate_info.y1; - if (direction == HorizontalRotateCommand) - rotate_info.x2+=32; - else - rotate_info.y2-=32; - } while ((state & ExitState) == 0); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if ((state & EscapeState) != 0) - return(MagickTrue); - /* - Draw line as pointer moves until the mouse button is released. - */ - distance=0; - (void) XSetFunction(display,windows->image.highlight_context,GXinvert); - state=DefaultState; - do - { - if (distance > 9) - { - /* - Display info and draw rotation line. - */ - if (windows->info.mapped == MagickFalse) - (void) XMapWindow(display,windows->info.id); - (void) FormatLocaleString(text,MagickPathExtent," %g", - direction == VerticalRotateCommand ? degrees-90.0 : degrees); - XInfoWidget(display,windows,text); - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&rotate_info); - } - else - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - /* - Wait for next event. - */ - XScreenEvent(display,windows,&event,exception); - if (distance > 9) - XHighlightLine(display,windows->image.id, - windows->image.highlight_context,&rotate_info); - switch (event.type) - { - case ButtonPress: - break; - case ButtonRelease: - { - /* - User has committed to rotation line. - */ - rotate_info.x2=event.xbutton.x; - rotate_info.y2=event.xbutton.y; - state|=ExitState; - break; - } - case Expose: - break; - case MotionNotify: - { - rotate_info.x2=event.xmotion.x; - rotate_info.y2=event.xmotion.y; - } - default: - break; - } - /* - Check boundary conditions. - */ - if (rotate_info.x2 < 0) - rotate_info.x2=0; - else - if (rotate_info.x2 > (int) windows->image.width) - rotate_info.x2=(short) windows->image.width; - if (rotate_info.y2 < 0) - rotate_info.y2=0; - else - if (rotate_info.y2 > (int) windows->image.height) - rotate_info.y2=(short) windows->image.height; - /* - Compute rotation angle from the slope of the line. - */ - degrees=0.0; - distance=(unsigned int) - ((rotate_info.x2-rotate_info.x1+1)*(rotate_info.x2-rotate_info.x1+1))+ - ((rotate_info.y2-rotate_info.y1+1)*(rotate_info.y2-rotate_info.y1+1)); - if (distance > 9) - degrees=RadiansToDegrees(-atan2((double) (rotate_info.y2- - rotate_info.y1),(double) (rotate_info.x2-rotate_info.x1))); - } while ((state & ExitState) == 0); - (void) XSetFunction(display,windows->image.highlight_context,GXcopy); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if (distance <= 9) - return(MagickTrue); - } - if (direction == VerticalRotateCommand) - degrees-=90.0; - if (degrees == 0.0) - return(MagickTrue); - /* - Rotate image. - */ - normalized_degrees=degrees; - while (normalized_degrees < -45.0) - normalized_degrees+=360.0; - for (rotations=0; normalized_degrees > 45.0; rotations++) - normalized_degrees-=90.0; - if (normalized_degrees != 0.0) - (void) XMagickCommand(display,resource_info,windows,ApplyCommand,image, - exception); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - (*image)->background_color.red=(double) ScaleShortToQuantum( - windows->pixel_info->pen_colors[pen_id].red); - (*image)->background_color.green=(double) ScaleShortToQuantum( - windows->pixel_info->pen_colors[pen_id].green); - (*image)->background_color.blue=(double) ScaleShortToQuantum( - windows->pixel_info->pen_colors[pen_id].blue); - rotate_image=RotateImage(*image,degrees,exception); - XSetCursorState(display,windows,MagickFalse); - if (rotate_image == (Image *) NULL) - return(MagickFalse); - *image=DestroyImage(*image); - *image=rotate_image; - if (windows->image.crop_geometry != (char *) NULL) - { - /* - Rotate crop geometry. - */ - width=(unsigned int) (*image)->columns; - height=(unsigned int) (*image)->rows; - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - switch (rotations % 4) - { - default: - case 0: - break; - case 1: - { - /* - Rotate 90 degrees. - */ - (void) FormatLocaleString(windows->image.crop_geometry, - MagickPathExtent,"%ux%u%+d%+d",height,width,(int) (*image)->columns- - (int) height-y,x); - break; - } - case 2: - { - /* - Rotate 180 degrees. - */ - (void) FormatLocaleString(windows->image.crop_geometry, - MagickPathExtent,"%ux%u%+d%+d",width,height,(int) width-x,(int) - height-y); - break; - } - case 3: - { - /* - Rotate 270 degrees. - */ - (void) FormatLocaleString(windows->image.crop_geometry, - MagickPathExtent,"%ux%u%+d%+d",height,width,y,(int) (*image)->rows- - (int) width-x); - break; - } - } - } - if (windows->image.orphan != MagickFalse) - return(MagickTrue); - if (normalized_degrees != 0.0) - { - /* - Update image colormap. - */ - windows->image.window_changes.width=(int) (*image)->columns; - windows->image.window_changes.height=(int) (*image)->rows; - if (windows->image.crop_geometry != (char *) NULL) - { - /* - Obtain dimensions of image from crop geometry. - */ - (void) XParseGeometry(windows->image.crop_geometry,&x,&y, - &width,&height); - windows->image.window_changes.width=(int) width; - windows->image.window_changes.height=(int) height; - } - XConfigureImageColormap(display,resource_info,windows,*image,exception); - } - else - if (((rotations % 4) == 1) || ((rotations % 4) == 3)) - { - windows->image.window_changes.width=windows->image.ximage->height; - windows->image.window_changes.height=windows->image.ximage->width; - } - /* - Update image configuration. - */ - (void) XConfigureImage(display,resource_info,windows,*image,exception); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X S a v e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XSaveImage() saves an image to a file. -% -% The format of the XSaveImage method is: -% -% MagickBooleanType XSaveImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XSaveImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - ExceptionInfo *exception) -{ - char - filename[MagickPathExtent], - geometry[MagickPathExtent]; - - Image - *save_image; - - ImageInfo - *image_info; - - MagickStatusType - status; - - /* - Request file name from user. - */ - if (resource_info->write_filename != (char *) NULL) - (void) CopyMagickString(filename,resource_info->write_filename, - MagickPathExtent); - else - { - char - path[MagickPathExtent]; - - int - status; - - GetPathComponent(image->filename,HeadPath,path); - GetPathComponent(image->filename,TailPath,filename); - if (*path != '\0') - { - status=chdir(path); - if (status == -1) - (void) ThrowMagickException(exception,GetMagickModule(), - FileOpenError,"UnableToOpenFile","%s",path); - } - } - XFileBrowserWidget(display,windows,"Save",filename); - if (*filename == '\0') - return(MagickTrue); - if (IsPathAccessible(filename) != MagickFalse) - { - int - status; - - /* - File exists-- seek user's permission before overwriting. - */ - status=XConfirmWidget(display,windows,"Overwrite",filename); - if (status <= 0) - return(MagickTrue); - } - image_info=CloneImageInfo(resource_info->image_info); - (void) CopyMagickString(image_info->filename,filename,MagickPathExtent); - (void) SetImageInfo(image_info,1,exception); - if ((LocaleCompare(image_info->magick,"JPEG") == 0) || - (LocaleCompare(image_info->magick,"JPG") == 0)) - { - char - quality[MagickPathExtent]; - - int - status; - - /* - Request JPEG quality from user. - */ - (void) FormatLocaleString(quality,MagickPathExtent,"%.20g",(double) - image->quality); - status=XDialogWidget(display,windows,"Save","Enter JPEG quality:", - quality); - if (*quality == '\0') - return(MagickTrue); - image->quality=StringToUnsignedLong(quality); - image_info->interlace=status != 0 ? NoInterlace : PlaneInterlace; - } - if ((LocaleCompare(image_info->magick,"EPS") == 0) || - (LocaleCompare(image_info->magick,"PDF") == 0) || - (LocaleCompare(image_info->magick,"PS") == 0) || - (LocaleCompare(image_info->magick,"PS2") == 0)) - { - char - geometry[MagickPathExtent]; - - const char - *const PageSizes[] = - { - "Letter", - "Tabloid", - "Ledger", - "Legal", - "Statement", - "Executive", - "A3", - "A4", - "A5", - "B4", - "B5", - "Folio", - "Quarto", - "10x14", - (char *) NULL - }; - - /* - Request page geometry from user. - */ - (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent); - if (LocaleCompare(image_info->magick,"PDF") == 0) - (void) CopyMagickString(geometry,PSPageGeometry,MagickPathExtent); - if (image_info->page != (char *) NULL) - (void) CopyMagickString(geometry,image_info->page,MagickPathExtent); - XListBrowserWidget(display,windows,&windows->widget,PageSizes,"Select", - "Select page geometry:",geometry); - if (*geometry != '\0') - image_info->page=GetPageGeometry(geometry); - } - /* - Apply image transforms. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - save_image=CloneImage(image,0,0,MagickTrue,exception); - if (save_image == (Image *) NULL) - return(MagickFalse); - (void) FormatLocaleString(geometry,MagickPathExtent,"%dx%d!", - windows->image.ximage->width,windows->image.ximage->height); - (void) TransformImage(&save_image,windows->image.crop_geometry,geometry, - exception); - /* - Write image. - */ - (void) CopyMagickString(save_image->filename,filename,MagickPathExtent); - status=WriteImage(image_info,save_image,exception); - if (status != MagickFalse) - image->taint=MagickFalse; - save_image=DestroyImage(save_image); - image_info=DestroyImageInfo(image_info); - XSetCursorState(display,windows,MagickFalse); - return(status != 0 ? MagickTrue : MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X S c r e e n E v e n t % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XScreenEvent() handles global events associated with the Pan and Magnify -% windows. -% -% The format of the XScreenEvent function is: -% -% void XScreenEvent(Display *display,XWindows *windows,XEvent *event, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a pointer to the Display structure; returned from -% XOpenDisplay. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o event: Specifies a pointer to a X11 XEvent structure. -% -% o exception: return any errors or warnings in this structure. -% -*/ - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -static int XPredicate(Display *magick_unused(display),XEvent *event,char *data) -{ - XWindows - *windows; - - windows=(XWindows *) data; - if ((event->type == ClientMessage) && - (event->xclient.window == windows->image.id)) - return(MagickFalse); - return(MagickTrue); -} - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -static void XScreenEvent(Display *display,XWindows *windows,XEvent *event, - ExceptionInfo *exception) -{ - int - x, - y; - - (void) XIfEvent(display,event,XPredicate,(char *) windows); - if (event->xany.window == windows->command.id) - return; - switch (event->type) - { - case ButtonPress: - case ButtonRelease: - { - if ((event->xbutton.button == Button3) && - (event->xbutton.state & Mod1Mask)) - { - /* - Convert Alt-Button3 to Button2. - */ - event->xbutton.button=Button2; - event->xbutton.state&=(~Mod1Mask); - } - if (event->xbutton.window == windows->backdrop.id) - { - (void) XSetInputFocus(display,event->xbutton.window,RevertToParent, - event->xbutton.time); - break; - } - if (event->xbutton.window == windows->pan.id) - { - XPanImage(display,windows,event,exception); - break; - } - if (event->xbutton.window == windows->image.id) - if (event->xbutton.button == Button2) - { - /* - Update magnified image. - */ - x=event->xbutton.x; - y=event->xbutton.y; - if (x < 0) - x=0; - else - if (x >= (int) windows->image.width) - x=(int) (windows->image.width-1); - windows->magnify.x=(int) windows->image.x+x; - if (y < 0) - y=0; - else - if (y >= (int) windows->image.height) - y=(int) (windows->image.height-1); - windows->magnify.y=windows->image.y+y; - if (windows->magnify.mapped == MagickFalse) - (void) XMapRaised(display,windows->magnify.id); - XMakeMagnifyImage(display,windows,exception); - if (event->type == ButtonRelease) - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - break; - } - break; - } - case ClientMessage: - { - /* - If client window delete message, exit. - */ - if (event->xclient.message_type != windows->wm_protocols) - break; - if (*event->xclient.data.l != (long) windows->wm_delete_window) - break; - if (event->xclient.window == windows->magnify.id) - { - (void) XWithdrawWindow(display,windows->magnify.id, - windows->magnify.screen); - break; - } - break; - } - case ConfigureNotify: - { - if (event->xconfigure.window == windows->magnify.id) - { - unsigned int - magnify; - - /* - Magnify window has a new configuration. - */ - windows->magnify.width=(unsigned int) event->xconfigure.width; - windows->magnify.height=(unsigned int) event->xconfigure.height; - if (windows->magnify.mapped == MagickFalse) - break; - magnify=1; - while ((int) magnify <= event->xconfigure.width) - magnify<<=1; - while ((int) magnify <= event->xconfigure.height) - magnify<<=1; - magnify>>=1; - if (((int) magnify != event->xconfigure.width) || - ((int) magnify != event->xconfigure.height)) - { - XWindowChanges - window_changes; - - window_changes.width=(int) magnify; - window_changes.height=(int) magnify; - (void) XReconfigureWMWindow(display,windows->magnify.id, - windows->magnify.screen,(unsigned int) (CWWidth | CWHeight), - &window_changes); - break; - } - XMakeMagnifyImage(display,windows,exception); - break; - } - break; - } - case Expose: - { - if (event->xexpose.window == windows->image.id) - { - XRefreshWindow(display,&windows->image,event); - break; - } - if (event->xexpose.window == windows->pan.id) - if (event->xexpose.count == 0) - { - XDrawPanRectangle(display,windows); - break; - } - if (event->xexpose.window == windows->magnify.id) - if (event->xexpose.count == 0) - { - XMakeMagnifyImage(display,windows,exception); - break; - } - break; - } - case KeyPress: - { - char - command[MagickPathExtent]; - - KeySym - key_symbol; - - if (event->xkey.window != windows->magnify.id) - break; - /* - Respond to a user key press. - */ - (void) XLookupString((XKeyEvent *) &event->xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - XMagnifyWindowCommand(display,windows,event->xkey.state,key_symbol, - exception); - break; - } - case MapNotify: - { - if (event->xmap.window == windows->magnify.id) - { - windows->magnify.mapped=MagickTrue; - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - break; - } - if (event->xmap.window == windows->info.id) - { - windows->info.mapped=MagickTrue; - break; - } - break; - } - case MotionNotify: - { - while (XCheckMaskEvent(display,ButtonMotionMask,event)) ; - if (event->xmotion.window == windows->image.id) - if (windows->magnify.mapped != MagickFalse) - { - /* - Update magnified image. - */ - x=event->xmotion.x; - y=event->xmotion.y; - if (x < 0) - x=0; - else - if (x >= (int) windows->image.width) - x=(int) (windows->image.width-1); - windows->magnify.x=(int) windows->image.x+x; - if (y < 0) - y=0; - else - if (y >= (int) windows->image.height) - y=(int) (windows->image.height-1); - windows->magnify.y=windows->image.y+y; - XMakeMagnifyImage(display,windows,exception); - } - break; - } - case UnmapNotify: - { - if (event->xunmap.window == windows->magnify.id) - { - windows->magnify.mapped=MagickFalse; - break; - } - if (event->xunmap.window == windows->info.id) - { - windows->info.mapped=MagickFalse; - break; - } - break; - } - default: - break; - } -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X S e t C r o p G e o m e t r y % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XSetCropGeometry() accepts a cropping geometry relative to the Image window -% and translates it to a cropping geometry relative to the image. -% -% The format of the XSetCropGeometry method is: -% -% void XSetCropGeometry(Display *display,XWindows *windows, -% RectangleInfo *crop_info,Image *image) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o crop_info: A pointer to a RectangleInfo that defines a region of the -% Image window to crop. -% -% o image: the image. -% -*/ -static void XSetCropGeometry(Display *display,XWindows *windows, - RectangleInfo *crop_info,Image *image) -{ - char - text[MagickPathExtent]; - - int - x, - y; - - double - scale_factor; - - unsigned int - height, - width; - - if (windows->info.mapped != MagickFalse) - { - /* - Display info on cropping rectangle. - */ - (void) FormatLocaleString(text,MagickPathExtent," %.20gx%.20g%+.20g%+.20g", - (double) crop_info->width,(double) crop_info->height,(double) - crop_info->x,(double) crop_info->y); - XInfoWidget(display,windows,text); - } - /* - Cropping geometry is relative to any previous crop geometry. - */ - x=0; - y=0; - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - else - windows->image.crop_geometry=AcquireString((char *) NULL); - /* - Define the crop geometry string from the cropping rectangle. - */ - scale_factor=(double) width/windows->image.ximage->width; - if (crop_info->x > 0) - x+=(int) (scale_factor*crop_info->x+0.5); - width=(unsigned int) (scale_factor*crop_info->width+0.5); - if (width == 0) - width=1; - scale_factor=(double) height/windows->image.ximage->height; - if (crop_info->y > 0) - y+=(int) (scale_factor*crop_info->y+0.5); - height=(unsigned int) (scale_factor*crop_info->height+0.5); - if (height == 0) - height=1; - (void) FormatLocaleString(windows->image.crop_geometry,MagickPathExtent, - "%ux%u%+d%+d",width,height,x,y); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X T i l e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XTileImage() loads or deletes a selected tile from a visual image directory. -% The load or delete command is chosen from a menu. -% -% The format of the XTileImage method is: -% -% Image *XTileImage(Display *display,XResourceInfo *resource_info, -% XWindows *windows,Image *image,XEvent *event,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o tile_image: XTileImage reads or deletes the tile image -% and returns it. A null image is returned if an error occurs. -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image; returned from ReadImage. -% -% o event: Specifies a pointer to a XEvent structure. If it is NULL, -% the entire image is refreshed. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static Image *XTileImage(Display *display,XResourceInfo *resource_info, - XWindows *windows,Image *image,XEvent *event,ExceptionInfo *exception) -{ - const char - *const VerbMenu[] = - { - "Load", - "Next", - "Former", - "Delete", - "Update", - (char *) NULL, - }; - - static const ModeType - TileCommands[] = - { - TileLoadCommand, - TileNextCommand, - TileFormerCommand, - TileDeleteCommand, - TileUpdateCommand - }; - - char - command[MagickPathExtent], - filename[MagickPathExtent]; - - Image - *tile_image; - - int - id, - status, - tile, - x, - y; - - double - scale_factor; - - char - *p, - *q; - - int - i; - - unsigned int - height, - width; - - /* - Tile image is relative to montage image configuration. - */ - x=0; - y=0; - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - if (windows->image.crop_geometry != (char *) NULL) - (void) XParseGeometry(windows->image.crop_geometry,&x,&y,&width,&height); - scale_factor=(double) width/windows->image.ximage->width; - event->xbutton.x+=windows->image.x; - event->xbutton.x=(int) (scale_factor*event->xbutton.x+x+0.5); - scale_factor=(double) height/windows->image.ximage->height; - event->xbutton.y+=windows->image.y; - event->xbutton.y=(int) (scale_factor*event->xbutton.y+y+0.5); - /* - Determine size and location of each tile in the visual image directory. - */ - width=(unsigned int) image->columns; - height=(unsigned int) image->rows; - x=0; - y=0; - (void) XParseGeometry(image->montage,&x,&y,&width,&height); - tile=((event->xbutton.y-y)/height)*(((int) image->columns-x)/width)+ - (event->xbutton.x-x)/width; - if (tile < 0) - { - /* - Button press is outside any tile. - */ - (void) XBell(display,0); - return((Image *) NULL); - } - /* - Determine file name from the tile directory. - */ - p=image->directory; - for (i=tile; (i != 0) && (*p != '\0'); ) - { - if (*p == '\xff') - i--; - p++; - } - if (*p == '\0') - { - /* - Button press is outside any tile. - */ - (void) XBell(display,0); - return((Image *) NULL); - } - /* - Select a command from the pop-up menu. - */ - id=XMenuWidget(display,windows,"Tile Verb",VerbMenu,command); - if (id < 0) - return((Image *) NULL); - q=p; - while ((*q != '\xff') && (*q != '\0')) - q++; - (void) CopyMagickString(filename,p,(size_t) (q-p+1)); - /* - Perform command for the selected tile. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - tile_image=NewImageList(); - switch (TileCommands[id]) - { - case TileLoadCommand: - { - /* - Load tile image. - */ - XCheckRefreshWindows(display,windows); - (void) CopyMagickString(resource_info->image_info->magick,"MIFF", - MagickPathExtent); - (void) CopyMagickString(resource_info->image_info->filename,filename, - MagickPathExtent); - tile_image=ReadImage(resource_info->image_info,exception); - CatchException(exception); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - break; - } - case TileNextCommand: - { - /* - Display next image. - */ - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - break; - } - case TileFormerCommand: - { - /* - Display former image. - */ - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_former_image,CurrentTime); - break; - } - case TileDeleteCommand: - { - /* - Delete tile image. - */ - if (IsPathAccessible(filename) == MagickFalse) - { - XNoticeWidget(display,windows,"Image file does not exist:",filename); - break; - } - status=XConfirmWidget(display,windows,"Really delete tile",filename); - if (status <= 0) - break; - status=ShredFile(filename); - status|=remove_utf8(filename); - if (status != MagickFalse) - { - XNoticeWidget(display,windows,"Unable to delete image file:", - filename); - break; - } - } - case TileUpdateCommand: - { - int - x_offset, - y_offset; - - PixelInfo - pixel; - - int - j; - - Quantum - *s; - - /* - Ensure all the images exist. - */ - tile=0; - GetPixelInfo(image,&pixel); - for (p=image->directory; *p != '\0'; p++) - { - CacheView - *image_view; - - q=p; - while ((*q != '\xff') && (*q != '\0')) - q++; - (void) CopyMagickString(filename,p,(size_t) (q-p+1)); - p=q; - if (IsPathAccessible(filename) != MagickFalse) - { - tile++; - continue; - } - /* - Overwrite tile with background color. - */ - x_offset=(int) (width*(tile % (((int) image->columns-x)/width))+x); - y_offset=(int) (height*(tile/(((int) image->columns-x)/width))+y); - image_view=AcquireAuthenticCacheView(image,exception); - (void) GetOneCacheViewVirtualPixelInfo(image_view,0,0,&pixel,exception); - for (i=0; i < (int) height; i++) - { - s=GetCacheViewAuthenticPixels(image_view,(ssize_t) x_offset,(ssize_t) - y_offset+i,width,1,exception); - if (s == (Quantum *) NULL) - break; - for (j=0; j < (int) width; j++) - { - SetPixelViaPixelInfo(image,&pixel,s); - s+=GetPixelChannels(image); - } - if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) - break; - } - image_view=DestroyCacheView(image_view); - tile++; - } - windows->image.window_changes.width=(int) image->columns; - windows->image.window_changes.height=(int) image->rows; - XConfigureImageColormap(display,resource_info,windows,image,exception); - (void) XConfigureImage(display,resource_info,windows,image,exception); - break; - } - default: - break; - } - XSetCursorState(display,windows,MagickFalse); - return(tile_image); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X T r a n s l a t e I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XTranslateImage() translates the image within an Image window by one pixel -% as specified by the key symbol. If the image has a montage string the -% translation is respect to the width and height contained within the string. -% -% The format of the XTranslateImage method is: -% -% void XTranslateImage(Display *display,XWindows *windows, -% Image *image,const KeySym key_symbol) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o key_symbol: Specifies a KeySym which indicates which side of the image -% to trim. -% -*/ -static void XTranslateImage(Display *display,XWindows *windows, - Image *image,const KeySym key_symbol) -{ - char - text[MagickPathExtent]; - - int - x, - y; - - unsigned int - x_offset, - y_offset; - - /* - User specified a pan position offset. - */ - x_offset=windows->image.width; - y_offset=windows->image.height; - if (image->montage != (char *) NULL) - (void) XParseGeometry(image->montage,&x,&y,&x_offset,&y_offset); - switch ((int) key_symbol) - { - case XK_Home: - case XK_KP_Home: - { - windows->image.x=(int) windows->image.width/2; - windows->image.y=(int) windows->image.height/2; - break; - } - case XK_Left: - case XK_KP_Left: - { - windows->image.x-=x_offset; - break; - } - case XK_Next: - case XK_Up: - case XK_KP_Up: - { - windows->image.y-=y_offset; - break; - } - case XK_Right: - case XK_KP_Right: - { - windows->image.x+=x_offset; - break; - } - case XK_Prior: - case XK_Down: - case XK_KP_Down: - { - windows->image.y+=y_offset; - break; - } - default: - return; - } - /* - Check boundary conditions. - */ - if (windows->image.x < 0) - windows->image.x=0; - else - if ((int) (windows->image.x+windows->image.width) > - windows->image.ximage->width) - windows->image.x=(int) windows->image.ximage->width-windows->image.width; - if (windows->image.y < 0) - windows->image.y=0; - else - if ((int) (windows->image.y+windows->image.height) > - windows->image.ximage->height) - windows->image.y=(int) windows->image.ximage->height-windows->image.height; - /* - Refresh Image window. - */ - (void) FormatLocaleString(text,MagickPathExtent," %ux%u%+d%+d ", - windows->image.width,windows->image.height,windows->image.x, - windows->image.y); - XInfoWidget(display,windows,text); - XCheckRefreshWindows(display,windows); - XDrawPanRectangle(display,windows); - XRefreshWindow(display,&windows->image,(XEvent *) NULL); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X T r i m I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XTrimImage() trims the edges from the Image window. -% -% The format of the XTrimImage method is: -% -% MagickBooleanType XTrimImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows,Image *image, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static MagickBooleanType XTrimImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,Image *image, - ExceptionInfo *exception) -{ - RectangleInfo - trim_info; - - int - x, - y; - - size_t - background, - pixel; - - /* - Trim edges from image. - */ - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - /* - Crop the left edge. - */ - background=XGetPixel(windows->image.ximage,0,0); - trim_info.width=(size_t) windows->image.ximage->width; - for (x=0; x < windows->image.ximage->width; x++) - { - for (y=0; y < windows->image.ximage->height; y++) - { - pixel=XGetPixel(windows->image.ximage,x,y); - if (pixel != background) - break; - } - if (y < windows->image.ximage->height) - break; - } - trim_info.x=(ssize_t) x; - if (trim_info.x == (ssize_t) windows->image.ximage->width) - { - XSetCursorState(display,windows,MagickFalse); - return(MagickFalse); - } - /* - Crop the right edge. - */ - background=XGetPixel(windows->image.ximage,windows->image.ximage->width-1,0); - for (x=windows->image.ximage->width-1; x != 0; x--) - { - for (y=0; y < windows->image.ximage->height; y++) - { - pixel=XGetPixel(windows->image.ximage,x,y); - if (pixel != background) - break; - } - if (y < windows->image.ximage->height) - break; - } - trim_info.width=(size_t) (x-trim_info.x+1); - /* - Crop the top edge. - */ - background=XGetPixel(windows->image.ximage,0,0); - trim_info.height=(size_t) windows->image.ximage->height; - for (y=0; y < windows->image.ximage->height; y++) - { - for (x=0; x < windows->image.ximage->width; x++) - { - pixel=XGetPixel(windows->image.ximage,x,y); - if (pixel != background) - break; - } - if (x < windows->image.ximage->width) - break; - } - trim_info.y=(ssize_t) y; - /* - Crop the bottom edge. - */ - background=XGetPixel(windows->image.ximage,0,windows->image.ximage->height-1); - for (y=windows->image.ximage->height-1; y != 0; y--) - { - for (x=0; x < windows->image.ximage->width; x++) - { - pixel=XGetPixel(windows->image.ximage,x,y); - if (pixel != background) - break; - } - if (x < windows->image.ximage->width) - break; - } - trim_info.height=(size_t) y-trim_info.y+1; - if (((unsigned int) trim_info.width != windows->image.width) || - ((unsigned int) trim_info.height != windows->image.height)) - { - /* - Reconfigure Image window as defined by the trimming rectangle. - */ - XSetCropGeometry(display,windows,&trim_info,image); - windows->image.window_changes.width=(int) trim_info.width; - windows->image.window_changes.height=(int) trim_info.height; - (void) XConfigureImage(display,resource_info,windows,image,exception); - } - XSetCursorState(display,windows,MagickFalse); - return(MagickTrue); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X V i s u a l D i r e c t o r y I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XVisualDirectoryImage() creates a Visual Image Directory. -% -% The format of the XVisualDirectoryImage method is: -% -% Image *XVisualDirectoryImage(Display *display, -% XResourceInfo *resource_info,XWindows *windows, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o windows: Specifies a pointer to a XWindows structure. -% -% o exception: return any errors or warnings in this structure. -% -*/ -static Image *XVisualDirectoryImage(Display *display, - XResourceInfo *resource_info,XWindows *windows,ExceptionInfo *exception) -{ -#define TileImageTag "Scale/Image" -#define XClientName "montage" - - char - **filelist; - - Image - *images, - *montage_image, - *next_image, - *thumbnail_image; - - ImageInfo - *read_info; - - int - number_files; - - MagickBooleanType - backdrop; - - MagickStatusType - status; - - MontageInfo - *montage_info; - - RectangleInfo - geometry; - - int - i; - - static char - filename[MagickPathExtent] = "\0", - filenames[MagickPathExtent] = "*"; - - XResourceInfo - background_resources; - - /* - Request file name from user. - */ - XFileBrowserWidget(display,windows,"Directory",filenames); - if (*filenames == '\0') - return((Image *) NULL); - /* - Expand the filenames. - */ - filelist=(char **) AcquireMagickMemory(sizeof(*filelist)); - if (filelist == (char **) NULL) - { - ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", - filenames); - return((Image *) NULL); - } - number_files=1; - filelist[0]=filenames; - status=ExpandFilenames(&number_files,&filelist); - if ((status == MagickFalse) || (number_files == 0)) - { - if (number_files == 0) - ThrowXWindowException(ImageError,"NoImagesWereFound",filenames) - else - ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed", - filenames); - return((Image *) NULL); - } - /* - Set image background resources. - */ - background_resources=(*resource_info); - background_resources.window_id=AcquireString(""); - (void) FormatLocaleString(background_resources.window_id,MagickPathExtent, - "0x%lx",windows->image.id); - background_resources.backdrop=MagickTrue; - /* - Read each image and convert them to a tile. - */ - backdrop=((windows->visual_info->klass == TrueColor) || - (windows->visual_info->klass == DirectColor)) ? MagickTrue : MagickFalse; - read_info=CloneImageInfo(resource_info->image_info); - (void) SetImageOption(read_info,"jpeg:size","120x120"); - (void) CloneString(&read_info->size,DefaultTileGeometry); - (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL, - (void *) NULL); - images=NewImageList(); - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - for (i=0; i < (int) number_files; i++) - { - (void) CopyMagickString(read_info->filename,filelist[i],MagickPathExtent); - filelist[i]=DestroyString(filelist[i]); - *read_info->magick='\0'; - next_image=ReadImage(read_info,exception); - CatchException(exception); - if (next_image != (Image *) NULL) - { - (void) DeleteImageProperty(next_image,"label"); - (void) SetImageProperty(next_image,"label",InterpretImageProperties( - read_info,next_image,DefaultTileLabel,exception),exception); - (void) ParseRegionGeometry(next_image,read_info->size,&geometry, - exception); - thumbnail_image=ThumbnailImage(next_image,geometry.width, - geometry.height,exception); - if (thumbnail_image != (Image *) NULL) - { - next_image=DestroyImage(next_image); - next_image=thumbnail_image; - } - if (backdrop) - { - (void) XDisplayBackgroundImage(display,&background_resources, - next_image,exception); - XSetCursorState(display,windows,MagickTrue); - } - AppendImageToList(&images,next_image); - if (images->progress_monitor != (MagickProgressMonitor) NULL) - { - MagickBooleanType - proceed; - - proceed=SetImageProgress(images,LoadImageTag,(MagickOffsetType) i, - (MagickSizeType) number_files); - if (proceed == MagickFalse) - break; - } - } - } - filelist=(char **) RelinquishMagickMemory(filelist); - if (images == (Image *) NULL) - { - read_info=DestroyImageInfo(read_info); - XSetCursorState(display,windows,MagickFalse); - ThrowXWindowException(ImageError,"NoImagesWereLoaded",filenames); - return((Image *) NULL); - } - /* - Create the Visual Image Directory. - */ - montage_info=CloneMontageInfo(read_info,(MontageInfo *) NULL); - montage_info->pointsize=10; - if (resource_info->font != (char *) NULL) - (void) CloneString(&montage_info->font,resource_info->font); - (void) CopyMagickString(montage_info->filename,filename,MagickPathExtent); - montage_image=MontageImageList(read_info,montage_info,GetFirstImageInList( - images),exception); - images=DestroyImageList(images); - montage_info=DestroyMontageInfo(montage_info); - read_info=DestroyImageInfo(read_info); - XSetCursorState(display,windows,MagickFalse); - if (montage_image == (Image *) NULL) - return(montage_image); - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_next_image,CurrentTime); - return(montage_image); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -% X D i s p l a y B a c k g r o u n d I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XDisplayBackgroundImage() displays an image in the background of a window. -% -% The format of the XDisplayBackgroundImage method is: -% -% MagickBooleanType XDisplayBackgroundImage(Display *display, -% XResourceInfo *resource_info,Image *image,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType XDisplayBackgroundImage(Display *display, - XResourceInfo *resource_info,Image *image,ExceptionInfo *exception) -{ - char - geometry[MagickPathExtent], - visual_type[MagickPathExtent]; - - int - height, - status, - width; - - RectangleInfo - geometry_info; - - static XPixelInfo - pixel; - - static XStandardColormap - *map_info; - - static XVisualInfo - *visual_info = (XVisualInfo *) NULL; - - static XWindowInfo - window_info; - - size_t - delay; - - Window - root_window; - - XGCValues - context_values; - - XResourceInfo - resources; - - XWindowAttributes - window_attributes; - - /* - Determine target window. - */ - assert(image != (Image *) NULL); - assert(image->signature == MagickCoreSignature); - if (IsEventLogging() != MagickFalse) - (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); - resources=(*resource_info); - window_info.id=(Window) NULL; - root_window=XRootWindow(display,XDefaultScreen(display)); - if (LocaleCompare(resources.window_id,"root") == 0) - window_info.id=root_window; - else - { - if (isdigit((int) ((unsigned char) *resources.window_id)) != 0) - window_info.id=XWindowByID(display,root_window, - (Window) strtol((char *) resources.window_id,(char **) NULL,0)); - if (window_info.id == (Window) NULL) - window_info.id=XWindowByName(display,root_window,resources.window_id); - } - if (window_info.id == (Window) NULL) - { - ThrowXWindowException(XServerError,"NoWindowWithSpecifiedIDExists", - resources.window_id); - return(MagickFalse); - } - /* - Determine window visual id. - */ - window_attributes.width=XDisplayWidth(display,XDefaultScreen(display)); - window_attributes.height=XDisplayHeight(display,XDefaultScreen(display)); - (void) CopyMagickString(visual_type,"default",MagickPathExtent); - status=XGetWindowAttributes(display,window_info.id,&window_attributes); - if (status != 0) - (void) FormatLocaleString(visual_type,MagickPathExtent,"0x%lx", - XVisualIDFromVisual(window_attributes.visual)); - if (visual_info == (XVisualInfo *) NULL) - { - /* - Allocate standard colormap. - */ - map_info=XAllocStandardColormap(); - if (map_info == (XStandardColormap *) NULL) - ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed", - image->filename); - map_info->colormap=(Colormap) NULL; - pixel.pixels=(unsigned long *) NULL; - /* - Initialize visual info. - */ - resources.map_type=(char *) NULL; - resources.visual_type=visual_type; - visual_info=XBestVisualInfo(display,map_info,&resources); - if (visual_info == (XVisualInfo *) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToGetVisual", - resources.visual_type); - /* - Initialize window info. - */ - window_info.ximage=(XImage *) NULL; - window_info.matte_image=(XImage *) NULL; - window_info.pixmap=(Pixmap) NULL; - window_info.matte_pixmap=(Pixmap) NULL; - } - /* - Free previous root colors. - */ - if (window_info.id == root_window) - (void) XDestroyWindowColors(display,root_window); - /* - Initialize Standard Colormap. - */ - resources.colormap=SharedColormap; - XMakeStandardColormap(display,visual_info,&resources,image,map_info,&pixel, - exception); - /* - Graphic context superclass. - */ - context_values.background=pixel.foreground_color.pixel; - context_values.foreground=pixel.background_color.pixel; - pixel.annotate_context=XCreateGC(display,window_info.id, - (size_t) (GCBackground | GCForeground),&context_values); - if (pixel.annotate_context == (GC) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", - image->filename); - /* - Initialize Image window attributes. - */ - window_info.name=AcquireString("\0"); - window_info.icon_name=AcquireString("\0"); - XGetWindowInfo(display,visual_info,map_info,&pixel,(XFontStruct *) NULL, - &resources,&window_info); - /* - Create the X image. - */ - window_info.width=(unsigned int) image->columns; - window_info.height=(unsigned int) image->rows; - if ((image->columns != window_info.width) || - (image->rows != window_info.height)) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", - image->filename); - (void) FormatLocaleString(geometry,MagickPathExtent,"%ux%u+0+0>", - window_attributes.width,window_attributes.height); - geometry_info.width=window_info.width; - geometry_info.height=window_info.height; - geometry_info.x=(ssize_t) window_info.x; - geometry_info.y=(ssize_t) window_info.y; - (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y, - &geometry_info.width,&geometry_info.height); - window_info.width=(unsigned int) geometry_info.width; - window_info.height=(unsigned int) geometry_info.height; - window_info.x=(int) geometry_info.x; - window_info.y=(int) geometry_info.y; - status=XMakeImage(display,&resources,&window_info,image,window_info.width, - window_info.height,exception); - if (status == MagickFalse) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", - image->filename); - window_info.x=0; - window_info.y=0; - if (resource_info->debug != MagickFalse) - { - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Image: %s[%.20g] %.20gx%.20g ",image->filename,(double) image->scene, - (double) image->columns,(double) image->rows); - if (image->colors != 0) - (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double) - image->colors); - (void) LogMagickEvent(X11Event,GetMagickModule(),"%s",image->magick); - } - /* - Adjust image dimensions as specified by backdrop or geometry options. - */ - width=(int) window_info.width; - height=(int) window_info.height; - if (resources.backdrop != MagickFalse) - { - /* - Center image on window. - */ - window_info.x=(window_attributes.width/2)-(window_info.ximage->width/2); - window_info.y=(window_attributes.height/2)-(window_info.ximage->height/2); - width=window_attributes.width; - height=window_attributes.height; - } - if ((resources.image_geometry != (char *) NULL) && - (*resources.image_geometry != '\0')) - { - char - default_geometry[MagickPathExtent]; - - int - flags, - gravity; - - XSizeHints - *size_hints; - - /* - User specified geometry. - */ - size_hints=XAllocSizeHints(); - if (size_hints == (XSizeHints *) NULL) - ThrowXWindowFatalException(ResourceLimitFatalError, - "MemoryAllocationFailed",image->filename); - size_hints->flags=0L; - (void) FormatLocaleString(default_geometry,MagickPathExtent,"%dx%d", - width,height); - flags=XWMGeometry(display,visual_info->screen,resources.image_geometry, - default_geometry,window_info.border_width,size_hints,&window_info.x, - &window_info.y,&width,&height,&gravity); - if (flags & (XValue | YValue)) - { - width=window_attributes.width; - height=window_attributes.height; - } - (void) XFree((void *) size_hints); - } - /* - Create the X pixmap. - */ - window_info.pixmap=XCreatePixmap(display,window_info.id,(unsigned int) width, - (unsigned int) height,window_info.depth); - if (window_info.pixmap == (Pixmap) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXPixmap", - image->filename); - /* - Display pixmap on the window. - */ - if (((unsigned int) width > window_info.width) || - ((unsigned int) height > window_info.height)) - (void) XFillRectangle(display,window_info.pixmap, - window_info.annotate_context,0,0,(unsigned int) width, - (unsigned int) height); - (void) XPutImage(display,window_info.pixmap,window_info.annotate_context, - window_info.ximage,0,0,window_info.x,window_info.y,(unsigned int) - window_info.width,(unsigned int) window_info.height); - (void) XSetWindowBackgroundPixmap(display,window_info.id,window_info.pixmap); - (void) XClearWindow(display,window_info.id); - delay=1000*image->delay/MagickMax(image->ticks_per_second,1L); - XDelay(display,delay == 0UL ? 10UL : delay); - (void) XSync(display,MagickFalse); - return(window_info.id == root_window ? MagickTrue : MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ X D i s p l a y I m a g e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% XDisplayImage() displays an image via X11. A new image is created and -% returned if the user interactively transforms the displayed image. -% -% The format of the XDisplayImage method is: -% -% Image *XDisplayImage(Display *display,XResourceInfo *resource_info, -% char **argv,int argc,Image **image,size_t *state, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o nexus: Method XDisplayImage returns an image when the -% user chooses 'Open Image' from the command menu or picks a tile -% from the image directory. Otherwise a null image is returned. -% -% o display: Specifies a connection to an X server; returned from -% XOpenDisplay. -% -% o resource_info: Specifies a pointer to a X11 XResourceInfo structure. -% -% o argv: Specifies the application's argument list. -% -% o argc: Specifies the number of arguments. -% -% o image: Specifies an address to an address of an Image structure; -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport Image *XDisplayImage(Display *display,XResourceInfo *resource_info, - char **argv,int argc,Image **image,size_t *state,ExceptionInfo *exception) -{ -#define MagnifySize 256 /* must be a power of 2 */ -#define MagickMenus 10 -#define MagickTitle "Commands" - - const char - *const CommandMenu[] = - { - "File", - "Edit", - "View", - "Transform", - "Enhance", - "Effects", - "F/X", - "Image Edit", - "Miscellany", - "Help", - (char *) NULL - }, - *const FileMenu[] = - { - "Open...", - "Next", - "Former", - "Select...", - "Save...", - "Print...", - "Delete...", - "New...", - "Visual Directory...", - "Quit", - (char *) NULL - }, - *const EditMenu[] = - { - "Undo", - "Redo", - "Cut", - "Copy", - "Paste", - (char *) NULL - }, - *const ViewMenu[] = - { - "Half Size", - "Original Size", - "Double Size", - "Resize...", - "Apply", - "Refresh", - "Restore", - (char *) NULL - }, - *const TransformMenu[] = - { - "Crop", - "Chop", - "Flop", - "Flip", - "Rotate Right", - "Rotate Left", - "Rotate...", - "Shear...", - "Roll...", - "Trim Edges", - (char *) NULL - }, - *const EnhanceMenu[] = - { - "Hue...", - "Saturation...", - "Brightness...", - "Gamma...", - "Spiff", - "Dull", - "Contrast Stretch...", - "Sigmoidal Contrast...", - "Normalize", - "Equalize", - "Negate", - "Grayscale", - "Map...", - "Quantize...", - (char *) NULL - }, - *const EffectsMenu[] = - { - "Despeckle", - "Emboss", - "Reduce Noise", - "Add Noise...", - "Sharpen...", - "Blur...", - "Threshold...", - "Edge Detect...", - "Spread...", - "Shade...", - "Raise...", - "Segment...", - (char *) NULL - }, - *const FXMenu[] = - { - "Solarize...", - "Sepia Tone...", - "Swirl...", - "Implode...", - "Vignette...", - "Wave...", - "Oil Paint...", - "Charcoal Draw...", - (char *) NULL - }, - *const ImageEditMenu[] = - { - "Annotate...", - "Draw...", - "Color...", - "Matte...", - "Composite...", - "Add Border...", - "Add Frame...", - "Comment...", - "Launch...", - "Region of Interest...", - (char *) NULL - }, - *const MiscellanyMenu[] = - { - "Image Info", - "Zoom Image", - "Show Preview...", - "Show Histogram", - "Show Matte", - "Background...", - "Slide Show...", - "Preferences...", - (char *) NULL - }, - *const HelpMenu[] = - { - "Overview", - "Browse Documentation", - "About Display", - (char *) NULL - }, - *const ShortCutsMenu[] = - { - "Next", - "Former", - "Open...", - "Save...", - "Print...", - "Undo", - "Restore", - "Image Info", - "Quit", - (char *) NULL - }, - *const VirtualMenu[] = - { - "Image Info", - "Print", - "Next", - "Quit", - (char *) NULL - }; - - const char - *const *Menus[MagickMenus] = - { - FileMenu, - EditMenu, - ViewMenu, - TransformMenu, - EnhanceMenu, - EffectsMenu, - FXMenu, - ImageEditMenu, - MiscellanyMenu, - HelpMenu - }; - - static CommandType - CommandMenus[] = - { - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - NullCommand, - }, - FileCommands[] = - { - OpenCommand, - NextCommand, - FormerCommand, - SelectCommand, - SaveCommand, - PrintCommand, - DeleteCommand, - NewCommand, - VisualDirectoryCommand, - QuitCommand - }, - EditCommands[] = - { - UndoCommand, - RedoCommand, - CutCommand, - CopyCommand, - PasteCommand - }, - ViewCommands[] = - { - HalfSizeCommand, - OriginalSizeCommand, - DoubleSizeCommand, - ResizeCommand, - ApplyCommand, - RefreshCommand, - RestoreCommand - }, - TransformCommands[] = - { - CropCommand, - ChopCommand, - FlopCommand, - FlipCommand, - RotateRightCommand, - RotateLeftCommand, - RotateCommand, - ShearCommand, - RollCommand, - TrimCommand - }, - EnhanceCommands[] = - { - HueCommand, - SaturationCommand, - BrightnessCommand, - GammaCommand, - SpiffCommand, - DullCommand, - ContrastStretchCommand, - SigmoidalContrastCommand, - NormalizeCommand, - EqualizeCommand, - NegateCommand, - GrayscaleCommand, - MapCommand, - QuantizeCommand - }, - EffectsCommands[] = - { - DespeckleCommand, - EmbossCommand, - ReduceNoiseCommand, - AddNoiseCommand, - SharpenCommand, - BlurCommand, - ThresholdCommand, - EdgeDetectCommand, - SpreadCommand, - ShadeCommand, - RaiseCommand, - SegmentCommand - }, - FXCommands[] = - { - SolarizeCommand, - SepiaToneCommand, - SwirlCommand, - ImplodeCommand, - VignetteCommand, - WaveCommand, - OilPaintCommand, - CharcoalDrawCommand - }, - ImageEditCommands[] = - { - AnnotateCommand, - DrawCommand, - ColorCommand, - MatteCommand, - CompositeCommand, - AddBorderCommand, - AddFrameCommand, - CommentCommand, - LaunchCommand, - RegionOfInterestCommand - }, - MiscellanyCommands[] = - { - InfoCommand, - ZoomCommand, - ShowPreviewCommand, - ShowHistogramCommand, - ShowMatteCommand, - BackgroundCommand, - SlideShowCommand, - PreferencesCommand - }, - HelpCommands[] = - { - HelpCommand, - BrowseDocumentationCommand, - VersionCommand - }, - ShortCutsCommands[] = - { - NextCommand, - FormerCommand, - OpenCommand, - SaveCommand, - PrintCommand, - UndoCommand, - RestoreCommand, - InfoCommand, - QuitCommand - }, - VirtualCommands[] = - { - InfoCommand, - PrintCommand, - NextCommand, - QuitCommand - }; - - static CommandType - *Commands[MagickMenus] = - { - FileCommands, - EditCommands, - ViewCommands, - TransformCommands, - EnhanceCommands, - EffectsCommands, - FXCommands, - ImageEditCommands, - MiscellanyCommands, - HelpCommands - }; - - char - command[MagickPathExtent], - *directory, - geometry[MagickPathExtent], - resource_name[MagickPathExtent]; - - CommandType - command_type; - - Image - *display_image, - *nexus; - - int - entry, - id; - - KeySym - key_symbol; - - MagickStatusType - context_mask, - status; - - RectangleInfo - geometry_info; - - int - i; - - static char - working_directory[MagickPathExtent]; - - static XPoint - vid_info; - - static XWindowInfo - *magick_windows[MaxXWindows]; - - static unsigned int - number_windows; - - struct stat - attributes; - - time_t - timer, - timestamp, - update_time; - - unsigned int - height, - width; - - size_t - delay; - - WarningHandler - warning_handler; - - Window - root_window; - - XClassHint - *class_hints; - - XEvent - event; - - XFontStruct - *font_info; - - XGCValues - context_values; - - XPixelInfo - *icon_pixel, - *pixel; - - XResourceInfo - *icon_resources; - - XStandardColormap - *icon_map, - *map_info; - - XVisualInfo - *icon_visual, - *visual_info; - - XWindowChanges - window_changes; - - XWindows - *windows; - - XWMHints - *manager_hints; - - assert(image != (Image **) NULL); - assert((*image)->signature == MagickCoreSignature); - if (IsEventLogging() != MagickFalse) - (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename); - display_image=(*image); - warning_handler=(WarningHandler) NULL; - windows=XSetWindows((XWindows *) ~0); - if (windows != (XWindows *) NULL) - { - int - status; - - if (*working_directory == '\0') - (void) CopyMagickString(working_directory,".",MagickPathExtent); - status=chdir(working_directory); - if (status == -1) - (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError, - "UnableToOpenFile","%s",working_directory); - warning_handler=resource_info->display_warnings ? - SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL); - warning_handler=resource_info->display_warnings ? - SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL); - } - else - { - /* - Allocate windows structure. - */ - resource_info->colors=display_image->colors; - windows=XSetWindows(XInitializeWindows(display,resource_info)); - if (windows == (XWindows *) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateWindow", - (*image)->filename); - /* - Initialize window id's. - */ - number_windows=0; - magick_windows[number_windows++]=(&windows->icon); - magick_windows[number_windows++]=(&windows->backdrop); - magick_windows[number_windows++]=(&windows->image); - magick_windows[number_windows++]=(&windows->info); - magick_windows[number_windows++]=(&windows->command); - magick_windows[number_windows++]=(&windows->widget); - magick_windows[number_windows++]=(&windows->popup); - magick_windows[number_windows++]=(&windows->magnify); - magick_windows[number_windows++]=(&windows->pan); - for (i=0; i < (int) number_windows; i++) - magick_windows[i]->id=(Window) NULL; - vid_info.x=0; - vid_info.y=0; - } - /* - Initialize font info. - */ - if (windows->font_info != (XFontStruct *) NULL) - (void) XFreeFont(display,windows->font_info); - windows->font_info=XBestFont(display,resource_info,MagickFalse); - if (windows->font_info == (XFontStruct *) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToLoadFont", - resource_info->font); - /* - Initialize Standard Colormap. - */ - map_info=windows->map_info; - icon_map=windows->icon_map; - visual_info=windows->visual_info; - icon_visual=windows->icon_visual; - pixel=windows->pixel_info; - icon_pixel=windows->icon_pixel; - font_info=windows->font_info; - icon_resources=windows->icon_resources; - class_hints=windows->class_hints; - manager_hints=windows->manager_hints; - root_window=XRootWindow(display,visual_info->screen); - nexus=NewImageList(); - if (resource_info->debug != MagickFalse) - { - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Image: %s[%.20g] %.20gx%.20g ",display_image->filename, - (double) display_image->scene,(double) display_image->columns, - (double) display_image->rows); - if (display_image->colors != 0) - (void) LogMagickEvent(X11Event,GetMagickModule(),"%.20gc ",(double) - display_image->colors); - (void) LogMagickEvent(X11Event,GetMagickModule(),"%s", - display_image->magick); - } - XMakeStandardColormap(display,visual_info,resource_info,display_image, - map_info,pixel,exception); - display_image->taint=MagickFalse; - /* - Initialize graphic context. - */ - windows->context.id=(Window) NULL; - XGetWindowInfo(display,visual_info,map_info,pixel,font_info, - resource_info,&windows->context); - (void) CloneString(&class_hints->res_name,resource_info->client_name); - (void) CloneString(&class_hints->res_class,resource_info->client_name); - class_hints->res_class[0]=(char) LocaleToUppercase((int) - class_hints->res_class[0]); - manager_hints->flags=InputHint | StateHint; - manager_hints->input=MagickFalse; - manager_hints->initial_state=WithdrawnState; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->context); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Window id: 0x%lx (context)",windows->context.id); - context_values.background=pixel->background_color.pixel; - context_values.font=font_info->fid; - context_values.foreground=pixel->foreground_color.pixel; - context_values.graphics_exposures=MagickFalse; - context_mask=(MagickStatusType) - (GCBackground | GCFont | GCForeground | GCGraphicsExposures); - if (pixel->annotate_context != (GC) NULL) - (void) XFreeGC(display,pixel->annotate_context); - pixel->annotate_context=XCreateGC(display,windows->context.id, - context_mask,&context_values); - if (pixel->annotate_context == (GC) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", - display_image->filename); - context_values.background=pixel->depth_color.pixel; - if (pixel->widget_context != (GC) NULL) - (void) XFreeGC(display,pixel->widget_context); - pixel->widget_context=XCreateGC(display,windows->context.id,context_mask, - &context_values); - if (pixel->widget_context == (GC) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", - display_image->filename); - context_values.background=pixel->foreground_color.pixel; - context_values.foreground=pixel->background_color.pixel; - context_values.plane_mask=context_values.background ^ - context_values.foreground; - if (pixel->highlight_context != (GC) NULL) - (void) XFreeGC(display,pixel->highlight_context); - pixel->highlight_context=XCreateGC(display,windows->context.id, - (size_t) (context_mask | GCPlaneMask),&context_values); - if (pixel->highlight_context == (GC) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", - display_image->filename); - (void) XDestroyWindow(display,windows->context.id); - /* - Initialize icon window. - */ - XGetWindowInfo(display,icon_visual,icon_map,icon_pixel,(XFontStruct *) NULL, - icon_resources,&windows->icon); - windows->icon.geometry=resource_info->icon_geometry; - XBestIconSize(display,&windows->icon,display_image); - windows->icon.attributes.colormap=XDefaultColormap(display, - icon_visual->screen); - windows->icon.attributes.event_mask=ExposureMask | StructureNotifyMask; - manager_hints->flags=InputHint | StateHint; - manager_hints->input=MagickFalse; - manager_hints->initial_state=IconicState; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->icon); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (icon)", - windows->icon.id); - /* - Initialize graphic context for icon window. - */ - if (icon_pixel->annotate_context != (GC) NULL) - (void) XFreeGC(display,icon_pixel->annotate_context); - context_values.background=icon_pixel->background_color.pixel; - context_values.foreground=icon_pixel->foreground_color.pixel; - icon_pixel->annotate_context=XCreateGC(display,windows->icon.id, - (size_t) (GCBackground | GCForeground),&context_values); - if (icon_pixel->annotate_context == (GC) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateGraphicContext", - display_image->filename); - windows->icon.annotate_context=icon_pixel->annotate_context; - /* - Initialize Image window. - */ - XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info, - &windows->image); - windows->image.shape=MagickTrue; /* non-rectangular shape hint */ - if (resource_info->use_shared_memory == MagickFalse) - windows->image.shared_memory=MagickFalse; - if ((resource_info->title != (char *) NULL) && !(*state & MontageImageState)) - { - char - *title; - - title=InterpretImageProperties(resource_info->image_info,display_image, - resource_info->title,exception); - (void) CloneString(&windows->image.name,title); - (void) CloneString(&windows->image.icon_name,title); - title=DestroyString(title); - } - else - { - char - filename[MagickPathExtent], - window_name[MagickPathExtent]; - - /* - Window name is the base of the filename. - */ - GetPathComponent(display_image->magick_filename,TailPath,filename); - if (display_image->scene == 0) - (void) FormatLocaleString(window_name,MagickPathExtent,"%s: %s", - MagickPackageName,filename); - else - (void) FormatLocaleString(window_name,MagickPathExtent, - "%s: %s[scene: %.20g frames: %.20g]",MagickPackageName,filename, - (double) display_image->scene,(double) GetImageListLength( - display_image)); - (void) CloneString(&windows->image.name,window_name); - (void) CloneString(&windows->image.icon_name,filename); - } - if (resource_info->immutable) - windows->image.immutable=MagickTrue; - windows->image.use_pixmap=resource_info->use_pixmap; - windows->image.geometry=resource_info->image_geometry; - (void) FormatLocaleString(geometry,MagickPathExtent,"%ux%u+0+0>!", - XDisplayWidth(display,visual_info->screen), - XDisplayHeight(display,visual_info->screen)); - geometry_info.width=display_image->columns; - geometry_info.height=display_image->rows; - geometry_info.x=0; - geometry_info.y=0; - (void) ParseMetaGeometry(geometry,&geometry_info.x,&geometry_info.y, - &geometry_info.width,&geometry_info.height); - windows->image.width=(unsigned int) geometry_info.width; - windows->image.height=(unsigned int) geometry_info.height; - windows->image.attributes.event_mask=ButtonMotionMask | ButtonPressMask | - ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask | - KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask | - PropertyChangeMask | StructureNotifyMask | SubstructureNotifyMask; - XGetWindowInfo(display,visual_info,map_info,pixel,font_info, - resource_info,&windows->backdrop); - if ((resource_info->backdrop) || (windows->backdrop.id != (Window) NULL)) - { - /* - Initialize backdrop window. - */ - windows->backdrop.x=0; - windows->backdrop.y=0; - (void) CloneString(&windows->backdrop.name,"Backdrop"); - windows->backdrop.flags=(size_t) (USSize | USPosition); - windows->backdrop.width=(unsigned int) - XDisplayWidth(display,visual_info->screen); - windows->backdrop.height=(unsigned int) - XDisplayHeight(display,visual_info->screen); - windows->backdrop.border_width=0; - windows->backdrop.immutable=MagickTrue; - windows->backdrop.attributes.do_not_propagate_mask=ButtonPressMask | - ButtonReleaseMask; - windows->backdrop.attributes.event_mask=ButtonPressMask | KeyPressMask | - StructureNotifyMask; - manager_hints->flags=IconWindowHint | InputHint | StateHint; - manager_hints->icon_window=windows->icon.id; - manager_hints->input=MagickTrue; - manager_hints->initial_state=resource_info->iconic ? IconicState : - NormalState; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->backdrop); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Window id: 0x%lx (backdrop)",windows->backdrop.id); - (void) XMapWindow(display,windows->backdrop.id); - (void) XClearWindow(display,windows->backdrop.id); - if (windows->image.id != (Window) NULL) - { - (void) XDestroyWindow(display,windows->image.id); - windows->image.id=(Window) NULL; - } - /* - Position image in the center the backdrop. - */ - windows->image.flags|=USPosition; - windows->image.x=(XDisplayWidth(display,visual_info->screen)/2)- - (windows->image.width/2); - windows->image.y=(XDisplayHeight(display,visual_info->screen)/2)- - (windows->image.height/2); - } - manager_hints->flags=IconWindowHint | InputHint | StateHint; - manager_hints->icon_window=windows->icon.id; - manager_hints->input=MagickTrue; - manager_hints->initial_state=resource_info->iconic ? IconicState : - NormalState; - if (windows->group_leader.id != (Window) NULL) - { - /* - Follow the leader. - */ - manager_hints->flags|=WindowGroupHint; - manager_hints->window_group=windows->group_leader.id; - (void) XSelectInput(display,windows->group_leader.id,StructureNotifyMask); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Window id: 0x%lx (group leader)",windows->group_leader.id); - } - XMakeWindow(display, - (Window) (resource_info->backdrop ? windows->backdrop.id : root_window), - argv,argc,class_hints,manager_hints,&windows->image); - (void) XChangeProperty(display,windows->image.id,windows->im_protocols, - XA_STRING,8,PropModeReplace,(unsigned char *) NULL,0); - if (windows->group_leader.id != (Window) NULL) - (void) XSetTransientForHint(display,windows->image.id, - windows->group_leader.id); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (image)", - windows->image.id); - /* - Initialize Info widget. - */ - XGetWindowInfo(display,visual_info,map_info,pixel,font_info,resource_info, - &windows->info); - (void) CloneString(&windows->info.name,"Info"); - (void) CloneString(&windows->info.icon_name,"Info"); - windows->info.border_width=1; - windows->info.x=2; - windows->info.y=2; - windows->info.flags|=PPosition; - windows->info.attributes.win_gravity=UnmapGravity; - windows->info.attributes.event_mask=ButtonPressMask | ExposureMask | - StructureNotifyMask; - manager_hints->flags=InputHint | StateHint | WindowGroupHint; - manager_hints->input=MagickFalse; - manager_hints->initial_state=NormalState; - manager_hints->window_group=windows->image.id; - XMakeWindow(display,windows->image.id,argv,argc,class_hints,manager_hints, - &windows->info); - windows->info.highlight_stipple=XCreateBitmapFromData(display, - windows->info.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight); - windows->info.shadow_stipple=XCreateBitmapFromData(display, - windows->info.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); - (void) XSetTransientForHint(display,windows->info.id,windows->image.id); - if (windows->image.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (info)", - windows->info.id); - /* - Initialize Command widget. - */ - XGetWindowInfo(display,visual_info,map_info,pixel,font_info, - resource_info,&windows->command); - windows->command.data=MagickMenus; - (void) XCommandWidget(display,windows,CommandMenu,(XEvent *) NULL); - (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.command", - resource_info->client_name); - windows->command.geometry=XGetResourceClass(resource_info->resource_database, - resource_name,"geometry",(char *) NULL); - (void) CloneString(&windows->command.name,MagickTitle); - windows->command.border_width=0; - windows->command.flags|=PPosition; - windows->command.attributes.event_mask=ButtonMotionMask | ButtonPressMask | - ButtonReleaseMask | EnterWindowMask | ExposureMask | LeaveWindowMask | - OwnerGrabButtonMask | StructureNotifyMask; - manager_hints->flags=InputHint | StateHint | WindowGroupHint; - manager_hints->input=MagickTrue; - manager_hints->initial_state=NormalState; - manager_hints->window_group=windows->image.id; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->command); - windows->command.highlight_stipple=XCreateBitmapFromData(display, - windows->command.id,(char *) HighlightBitmap,HighlightWidth, - HighlightHeight); - windows->command.shadow_stipple=XCreateBitmapFromData(display, - windows->command.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); - (void) XSetTransientForHint(display,windows->command.id,windows->image.id); - if (windows->command.mapped != MagickFalse) - (void) XMapRaised(display,windows->command.id); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Window id: 0x%lx (command)",windows->command.id); - /* - Initialize Widget window. - */ - XGetWindowInfo(display,visual_info,map_info,pixel,font_info, - resource_info,&windows->widget); - (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.widget", - resource_info->client_name); - windows->widget.geometry=XGetResourceClass(resource_info->resource_database, - resource_name,"geometry",(char *) NULL); - windows->widget.border_width=0; - windows->widget.flags|=PPosition; - windows->widget.attributes.event_mask=ButtonMotionMask | ButtonPressMask | - ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask | - KeyReleaseMask | LeaveWindowMask | OwnerGrabButtonMask | - StructureNotifyMask; - manager_hints->flags=InputHint | StateHint | WindowGroupHint; - manager_hints->input=MagickTrue; - manager_hints->initial_state=NormalState; - manager_hints->window_group=windows->image.id; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->widget); - windows->widget.highlight_stipple=XCreateBitmapFromData(display, - windows->widget.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight); - windows->widget.shadow_stipple=XCreateBitmapFromData(display, - windows->widget.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); - (void) XSetTransientForHint(display,windows->widget.id,windows->image.id); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Window id: 0x%lx (widget)",windows->widget.id); - /* - Initialize popup window. - */ - XGetWindowInfo(display,visual_info,map_info,pixel,font_info, - resource_info,&windows->popup); - windows->popup.border_width=0; - windows->popup.flags|=PPosition; - windows->popup.attributes.event_mask=ButtonMotionMask | ButtonPressMask | - ButtonReleaseMask | EnterWindowMask | ExposureMask | KeyPressMask | - KeyReleaseMask | LeaveWindowMask | StructureNotifyMask; - manager_hints->flags=InputHint | StateHint | WindowGroupHint; - manager_hints->input=MagickTrue; - manager_hints->initial_state=NormalState; - manager_hints->window_group=windows->image.id; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->popup); - windows->popup.highlight_stipple=XCreateBitmapFromData(display, - windows->popup.id,(char *) HighlightBitmap,HighlightWidth,HighlightHeight); - windows->popup.shadow_stipple=XCreateBitmapFromData(display, - windows->popup.id,(char *) ShadowBitmap,ShadowWidth,ShadowHeight); - (void) XSetTransientForHint(display,windows->popup.id,windows->image.id); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Window id: 0x%lx (pop up)",windows->popup.id); - /* - Initialize Magnify window and cursor. - */ - XGetWindowInfo(display,visual_info,map_info,pixel,font_info, - resource_info,&windows->magnify); - if (resource_info->use_shared_memory == MagickFalse) - windows->magnify.shared_memory=MagickFalse; - (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.magnify", - resource_info->client_name); - windows->magnify.geometry=XGetResourceClass(resource_info->resource_database, - resource_name,"geometry",(char *) NULL); - (void) FormatLocaleString(windows->magnify.name,MagickPathExtent, - "Magnify %uX",resource_info->magnify); - if (windows->magnify.cursor != (Cursor) NULL) - (void) XFreeCursor(display,windows->magnify.cursor); - windows->magnify.cursor=XMakeCursor(display,windows->image.id, - map_info->colormap,resource_info->background_color, - resource_info->foreground_color); - if (windows->magnify.cursor == (Cursor) NULL) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateCursor", - display_image->filename); - windows->magnify.width=MagnifySize; - windows->magnify.height=MagnifySize; - windows->magnify.flags|=PPosition; - windows->magnify.min_width=MagnifySize; - windows->magnify.min_height=MagnifySize; - windows->magnify.width_inc=MagnifySize; - windows->magnify.height_inc=MagnifySize; - windows->magnify.data=resource_info->magnify; - windows->magnify.attributes.cursor=windows->magnify.cursor; - windows->magnify.attributes.event_mask=ButtonPressMask | ButtonReleaseMask | - ExposureMask | KeyPressMask | KeyReleaseMask | OwnerGrabButtonMask | - StructureNotifyMask; - manager_hints->flags=InputHint | StateHint | WindowGroupHint; - manager_hints->input=MagickTrue; - manager_hints->initial_state=NormalState; - manager_hints->window_group=windows->image.id; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->magnify); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Window id: 0x%lx (magnify)",windows->magnify.id); - (void) XSetTransientForHint(display,windows->magnify.id,windows->image.id); - /* - Initialize panning window. - */ - XGetWindowInfo(display,visual_info,map_info,pixel,font_info, - resource_info,&windows->pan); - (void) CloneString(&windows->pan.name,"Pan Icon"); - windows->pan.width=windows->icon.width; - windows->pan.height=windows->icon.height; - (void) FormatLocaleString(resource_name,MagickPathExtent,"%s.pan", - resource_info->client_name); - windows->pan.geometry=XGetResourceClass(resource_info->resource_database, - resource_name,"geometry",(char *) NULL); - (void) XParseGeometry(windows->pan.geometry,&windows->pan.x,&windows->pan.y, - &windows->pan.width,&windows->pan.height); - windows->pan.flags|=PPosition; - windows->pan.immutable=MagickTrue; - windows->pan.attributes.event_mask=ButtonMotionMask | ButtonPressMask | - ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask | - StructureNotifyMask; - manager_hints->flags=InputHint | StateHint | WindowGroupHint; - manager_hints->input=MagickFalse; - manager_hints->initial_state=NormalState; - manager_hints->window_group=windows->image.id; - XMakeWindow(display,root_window,argv,argc,class_hints,manager_hints, - &windows->pan); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Window id: 0x%lx (pan)", - windows->pan.id); - (void) XSetTransientForHint(display,windows->pan.id,windows->image.id); - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if ((windows->image.mapped == MagickFalse) || - (windows->backdrop.id != (Window) NULL)) - (void) XMapWindow(display,windows->image.id); - /* - Set our progress monitor and warning handlers. - */ - if (warning_handler == (WarningHandler) NULL) - { - warning_handler=resource_info->display_warnings ? - SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL); - warning_handler=resource_info->display_warnings ? - SetWarningHandler(XWarning) : SetWarningHandler((WarningHandler) NULL); - } - /* - Initialize Image and Magnify X images. - */ - windows->image.x=0; - windows->image.y=0; - windows->magnify.shape=MagickFalse; - width=(unsigned int) display_image->columns; - height=(unsigned int) display_image->rows; - if ((display_image->columns != width) || (display_image->rows != height)) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", - display_image->filename); - status=XMakeImage(display,resource_info,&windows->image,display_image, - width,height,exception); - if (status == MagickFalse) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", - display_image->filename); - status=XMakeImage(display,resource_info,&windows->magnify,(Image *) NULL, - windows->magnify.width,windows->magnify.height,exception); - if (status == MagickFalse) - ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage", - display_image->filename); - if (windows->magnify.mapped != MagickFalse) - (void) XMapRaised(display,windows->magnify.id); - if (windows->pan.mapped != MagickFalse) - (void) XMapRaised(display,windows->pan.id); - windows->image.window_changes.width=(int) display_image->columns; - windows->image.window_changes.height=(int) display_image->rows; - (void) XConfigureImage(display,resource_info,windows,display_image,exception); - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - (void) XSync(display,MagickFalse); - /* - Respond to events. - */ - delay=display_image->delay/MagickMax(display_image->ticks_per_second,1L); - timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1; - update_time=0; - if (resource_info->update != MagickFalse) - { - MagickBooleanType - status; - - /* - Determine when file data was last modified. - */ - status=GetPathAttributes(display_image->filename,&attributes); - if (status != MagickFalse) - update_time=attributes.st_mtime; - } - *state&=(~FormerImageState); - *state&=(~MontageImageState); - *state&=(~NextImageState); - do - { - /* - Handle a window event. - */ - if (windows->image.mapped != MagickFalse) - if ((display_image->delay != 0) || (resource_info->update != 0)) - { - if (timer < GetMagickTime()) - { - if (resource_info->update == MagickFalse) - *state|=NextImageState | ExitState; - else - { - MagickBooleanType - status; - - /* - Determine if image file was modified. - */ - status=GetPathAttributes(display_image->filename,&attributes); - if (status != MagickFalse) - if (update_time != attributes.st_mtime) - { - /* - Redisplay image. - */ - (void) FormatLocaleString( - resource_info->image_info->filename,MagickPathExtent, - "%s:%s",display_image->magick, - display_image->filename); - nexus=ReadImage(resource_info->image_info,exception); - if (nexus != (Image *) NULL) - *state|=NextImageState | ExitState; - } - delay=display_image->delay/MagickMax( - display_image->ticks_per_second,1L); - timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1; - } - } - if (XEventsQueued(display,QueuedAfterFlush) == 0) - { - /* - Do not block if delay > 0. - */ - XDelay(display,SuspendTime << 2); - continue; - } - } - timestamp=GetMagickTime(); - (void) XNextEvent(display,&event); - if ((windows->image.stasis == MagickFalse) || - (windows->magnify.stasis == MagickFalse)) - { - if ((GetMagickTime()-timestamp) > 0) - { - windows->image.stasis=MagickTrue; - windows->magnify.stasis=MagickTrue; - } - } - if (event.xany.window == windows->command.id) - { - /* - Select a command from the Command widget. - */ - id=XCommandWidget(display,windows,CommandMenu,&event); - if (id < 0) - continue; - (void) CopyMagickString(command,CommandMenu[id],MagickPathExtent); - command_type=CommandMenus[id]; - if (id < MagickMenus) - { - /* - Select a command from a pop-up menu. - */ - entry=XMenuWidget(display,windows,CommandMenu[id],Menus[id], - command); - if (entry < 0) - continue; - (void) CopyMagickString(command,Menus[id][entry],MagickPathExtent); - command_type=Commands[id][entry]; - } - if (command_type != NullCommand) - nexus=XMagickCommand(display,resource_info,windows,command_type, - &display_image,exception); - continue; - } - switch (event.type) - { - case ButtonPress: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Button Press: 0x%lx %u +%d+%d",event.xbutton.window, - event.xbutton.button,event.xbutton.x,event.xbutton.y); - if ((event.xbutton.button == Button3) && - (event.xbutton.state & Mod1Mask)) - { - /* - Convert Alt-Button3 to Button2. - */ - event.xbutton.button=Button2; - event.xbutton.state&=(~Mod1Mask); - } - if (event.xbutton.window == windows->backdrop.id) - { - (void) XSetInputFocus(display,event.xbutton.window,RevertToParent, - event.xbutton.time); - break; - } - if (event.xbutton.window == windows->image.id) - { - switch (event.xbutton.button) - { - case Button1: - { - if (resource_info->immutable) + if (nexus->montage != (char *) NULL) { /* - Select a command from the Virtual menu. + User selected a visual directory image (montage). */ - entry=XMenuWidget(display,windows,"Commands",VirtualMenu, - command); - if (entry >= 0) - nexus=XMagickCommand(display,resource_info,windows, - VirtualCommands[entry],&display_image,exception); + display_image=nexus; break; } - /* - Map/unmap Command widget. - */ - if (windows->command.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->command.id, - windows->command.screen); + next=XDisplayImage(display,&resource_info,argv,argc,&nexus, + &state,exception); + if ((next == (Image *) NULL) && + (GetNextImageInList(nexus) != (Image *) NULL)) + { + display_image=GetNextImageInList(nexus); + nexus=NewImageList(); + } else { - (void) XCommandWidget(display,windows,CommandMenu, - (XEvent *) NULL); - (void) XMapRaised(display,windows->command.id); + if (nexus != display_image) + nexus=DestroyImageList(nexus); + nexus=next; } - break; } - case Button2: - { - /* - User pressed the image magnify button. - */ - (void) XMagickCommand(display,resource_info,windows,ZoomCommand, - &display_image,exception); - XMagnifyImage(display,windows,&event,exception); - break; - } - case Button3: - { - if (resource_info->immutable) - { - /* - Select a command from the Virtual menu. - */ - entry=XMenuWidget(display,windows,"Commands",VirtualMenu, - command); - if (entry >= 0) - nexus=XMagickCommand(display,resource_info,windows, - VirtualCommands[entry],&display_image,exception); - break; - } - if (display_image->montage != (char *) NULL) - { - /* - Open or delete a tile from a visual image directory. - */ - nexus=XTileImage(display,resource_info,windows, - display_image,&event,exception); - if (nexus != (Image *) NULL) - *state|=MontageImageState | NextImageState | ExitState; - vid_info.x=(short int) windows->image.x; - vid_info.y=(short int) windows->image.y; - break; - } - /* - Select a command from the Short Cuts menu. - */ - entry=XMenuWidget(display,windows,"Short Cuts",ShortCutsMenu, - command); - if (entry >= 0) - nexus=XMagickCommand(display,resource_info,windows, - ShortCutsCommands[entry],&display_image,exception); - break; - } - case Button4: - { - /* - Wheel up. - */ - XTranslateImage(display,windows,*image,XK_Up); - break; - } - case Button5: - { - /* - Wheel down. - */ - XTranslateImage(display,windows,*image,XK_Down); - break; - } - default: - break; - } - break; - } - if (event.xbutton.window == windows->magnify.id) - { - const char - *const MagnifyMenu[] = - { - "2", - "4", - "5", - "6", - "7", - "8", - "9", - "3", - (char *) NULL, - }; - - int - factor; - - static KeySym - MagnifyCommands[] = - { - XK_2, - XK_4, - XK_5, - XK_6, - XK_7, - XK_8, - XK_9, - XK_3 - }; - - /* - Select a magnify factor from the pop-up menu. - */ - factor=XMenuWidget(display,windows,"Magnify",MagnifyMenu,command); - if (factor >= 0) - XMagnifyWindowCommand(display,windows,0,MagnifyCommands[factor], - exception); - break; - } - if (event.xbutton.window == windows->pan.id) - { - switch (event.xbutton.button) + } while ((state & ExitState) == 0); + if (resource_info.write_filename != (char *) NULL) { - case Button4: - { - /* - Wheel up. - */ - XTranslateImage(display,windows,*image,XK_Up); - break; - } - case Button5: - { - /* - Wheel down. - */ - XTranslateImage(display,windows,*image,XK_Down); - break; - } - default: - { - XPanImage(display,windows,&event,exception); - break; - } + /* + Write image. + */ + (void) CopyMagickString(display_image->filename, + resource_info.write_filename,MagickPathExtent); + (void) SetImageInfo(image_info,1,exception); + status&=WriteImage(image_info,display_image,exception); } + /* + Proceed to next/previous image. + */ + if ((state & FormerImageState) != 0) + for (l=0; l < (ssize_t) resource_info.quantum; l++) + { + if (GetPreviousImageInList(display_image) == (Image *) NULL) + break; + display_image=GetPreviousImageInList(display_image); + } + else + for (l=0; l < (ssize_t) resource_info.quantum; l++) + { + if (GetNextImageInList(display_image) == (Image *) NULL) + break; + display_image=GetNextImageInList(display_image); + } + if (l < (ssize_t) resource_info.quantum) break; - } - delay=display_image->delay/MagickMax(display_image->ticks_per_second, - 1L); - timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1; - break; - } - case ButtonRelease: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Button Release: 0x%lx %u +%d+%d",event.xbutton.window, - event.xbutton.button,event.xbutton.x,event.xbutton.y); - break; - } - case ClientMessage: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Client Message: 0x%lx 0x%lx %d 0x%lx",event.xclient.window, - event.xclient.message_type,event.xclient.format,(unsigned long) - event.xclient.data.l[0]); - if (event.xclient.message_type == windows->im_protocols) + } while ((display_image != (Image *) NULL) && ((state & ExitState) == 0)); + /* + Free image resources. + */ + display_image=DestroyImageList(display_image); + if ((state & FormerImageState) == 0) { - if (*event.xclient.data.l == (long) windows->im_update_widget) - { - (void) CloneString(&windows->command.name,MagickTitle); - windows->command.data=MagickMenus; - (void) XCommandWidget(display,windows,CommandMenu, - (XEvent *) NULL); - break; - } - if (*event.xclient.data.l == (long) windows->im_update_colormap) - { - /* - Update graphic context and window colormap. - */ - for (i=0; i < (int) number_windows; i++) - { - if (magick_windows[i]->id == windows->icon.id) - continue; - context_values.background=pixel->background_color.pixel; - context_values.foreground=pixel->foreground_color.pixel; - (void) XChangeGC(display,magick_windows[i]->annotate_context, - context_mask,&context_values); - (void) XChangeGC(display,magick_windows[i]->widget_context, - context_mask,&context_values); - context_values.background=pixel->foreground_color.pixel; - context_values.foreground=pixel->background_color.pixel; - context_values.plane_mask=context_values.background ^ - context_values.foreground; - (void) XChangeGC(display,magick_windows[i]->highlight_context, - (size_t) (context_mask | GCPlaneMask), - &context_values); - magick_windows[i]->attributes.background_pixel= - pixel->background_color.pixel; - magick_windows[i]->attributes.border_pixel= - pixel->border_color.pixel; - magick_windows[i]->attributes.colormap=map_info->colormap; - (void) XChangeWindowAttributes(display,magick_windows[i]->id, - (unsigned long) magick_windows[i]->mask, - &magick_windows[i]->attributes); - } - if (windows->pan.mapped != MagickFalse) - { - (void) XSetWindowBackgroundPixmap(display,windows->pan.id, - windows->pan.pixmap); - (void) XClearWindow(display,windows->pan.id); - XDrawPanRectangle(display,windows); - } - if (windows->backdrop.id != (Window) NULL) - (void) XInstallColormap(display,map_info->colormap); - break; - } - if (*event.xclient.data.l == (long) windows->im_former_image) - { - *state|=FormerImageState | ExitState; - break; - } - if (*event.xclient.data.l == (long) windows->im_next_image) - { - *state|=NextImageState | ExitState; - break; - } - if (*event.xclient.data.l == (long) windows->im_retain_colors) - { - *state|=RetainColorsState; - break; - } - if (*event.xclient.data.l == (long) windows->im_exit) - { - *state|=ExitState; - break; - } - break; + last_image=(size_t) image_number; + image_marker[i]=(size_t) image_number++; } - if (event.xclient.message_type == windows->dnd_protocols) + else { - Atom - selection, + /* + Proceed to previous image. + */ + for (i--; i > 0; i--) + if (image_marker[i] == (size_t) (image_number-2)) + break; + image_number--; + } + if ((i == (ssize_t) argc) && ((state & ExitState) == 0)) + i=0; + if ((state & ExitState) != 0) + break; + /* + Determine if we should proceed to the first image. + */ + if (image_number < 0) + { + if ((state & FormerImageState) != 0) + { + + for (i=1; i < (ssize_t) (argc-2); i++) + if (last_image == image_marker[i]) + break; + image_number=(ssize_t) image_marker[i]+1; + } + continue; + } + if (resource_info.window_id != (char *) NULL) + state|=ExitState; + if (iterations != 0) + { + if (++iteration == (ssize_t) iterations) + state|=ExitState; + i=0; + } + if (LocaleCompare(filename,"-") == 0) + state|=ExitState; + RemoveAllImageStack(); + continue; + } + pend=image != (Image *) NULL ? MagickTrue : MagickFalse; + switch (*(option+1)) + { + case 'a': + { + if (LocaleCompare("alpha",option+1) == 0) + { + ssize_t type; - int - format, - status; - - unsigned char - *data; - - unsigned long - after, - length; - - /* - Display image named by the Drag-and-Drop selection. - */ - if ((*event.xclient.data.l != 2) && (*event.xclient.data.l != 128)) + if (*option == '+') break; - selection=XInternAtom(display,"DndSelection",MagickFalse); - status=XGetWindowProperty(display,root_window,selection,0L,(long) - MagickPathExtent,MagickFalse,(Atom) AnyPropertyType,&type,&format, - &length,&after,&data); - if ((status != Success) || (length == 0)) - break; - if (*event.xclient.data.l == 2) - { - /* - Offix DND. - */ - (void) CopyMagickString(resource_info->image_info->filename, - (char *) data,MagickPathExtent); - } - else - { - /* - XDND. - */ - if (strncmp((char *) data, "file:", 5) != 0) - { - (void) XFree((void *) data); - break; - } - (void) CopyMagickString(resource_info->image_info->filename, - ((char *) data)+5,MagickPathExtent); - } - nexus=ReadImage(resource_info->image_info,exception); - CatchException(exception); - if (nexus != (Image *) NULL) - *state|=NextImageState | ExitState; - (void) XFree((void *) data); + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + type=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse, + argv[i]); + if (type < 0) + ThrowDisplayException(OptionError, + "UnrecognizedAlphaChannelOption",argv[i]); break; } - /* - If client window delete message, exit. - */ - if (event.xclient.message_type != windows->wm_protocols) + if (LocaleCompare("antialias",option+1) == 0) break; - if (*event.xclient.data.l != (long) windows->wm_delete_window) - break; - (void) XWithdrawWindow(display,event.xclient.window, - visual_info->screen); - if (event.xclient.window == windows->image.id) + if (LocaleCompare("authenticate",option+1) == 0) { - *state|=ExitState; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); break; } - if (event.xclient.window == windows->pan.id) - { - /* - Restore original image size when pan window is deleted. - */ - windows->image.window_changes.width=windows->image.ximage->width; - windows->image.window_changes.height=windows->image.ximage->height; - (void) XConfigureImage(display,resource_info,windows, - display_image,exception); - } - break; + if (LocaleCompare("auto-level",option+1) == 0) + break; + if (LocaleCompare("auto-orient",option+1) == 0) + break; + ThrowDisplayException(OptionError,"UnrecognizedOption",option); } - case ConfigureNotify: + case 'b': { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Configure Notify: 0x%lx %dx%d+%d+%d %d",event.xconfigure.window, - event.xconfigure.width,event.xconfigure.height,event.xconfigure.x, - event.xconfigure.y,event.xconfigure.send_event); - if (event.xconfigure.window == windows->image.id) + if (LocaleCompare("backdrop",option+1) == 0) { - /* - Image window has a new configuration. - */ - if (event.xconfigure.send_event != 0) - { - XWindowChanges - window_changes; - - /* - Position the transient windows relative of the Image window. - */ - if (windows->command.geometry == (char *) NULL) - if (windows->command.mapped == MagickFalse) - { - windows->command.x=event.xconfigure.x- - windows->command.width-25; - windows->command.y=event.xconfigure.y; - XConstrainWindowPosition(display,&windows->command); - window_changes.x=windows->command.x; - window_changes.y=windows->command.y; - (void) XReconfigureWMWindow(display,windows->command.id, - windows->command.screen,(unsigned int) (CWX | CWY), - &window_changes); - } - if (windows->widget.geometry == (char *) NULL) - if (windows->widget.mapped == MagickFalse) - { - windows->widget.x=event.xconfigure.x+ - event.xconfigure.width/10; - windows->widget.y=event.xconfigure.y+ - event.xconfigure.height/10; - XConstrainWindowPosition(display,&windows->widget); - window_changes.x=windows->widget.x; - window_changes.y=windows->widget.y; - (void) XReconfigureWMWindow(display,windows->widget.id, - windows->widget.screen,(unsigned int) (CWX | CWY), - &window_changes); - } - if (windows->magnify.geometry == (char *) NULL) - if (windows->magnify.mapped == MagickFalse) - { - windows->magnify.x=event.xconfigure.x+ - event.xconfigure.width+25; - windows->magnify.y=event.xconfigure.y; - XConstrainWindowPosition(display,&windows->magnify); - window_changes.x=windows->magnify.x; - window_changes.y=windows->magnify.y; - (void) XReconfigureWMWindow(display,windows->magnify.id, - windows->magnify.screen,(unsigned int) (CWX | CWY), - &window_changes); - } - if (windows->pan.geometry == (char *) NULL) - if (windows->pan.mapped == MagickFalse) - { - windows->pan.x=event.xconfigure.x+ - event.xconfigure.width+25; - windows->pan.y=event.xconfigure.y+ - windows->magnify.height+50; - XConstrainWindowPosition(display,&windows->pan); - window_changes.x=windows->pan.x; - window_changes.y=windows->pan.y; - (void) XReconfigureWMWindow(display,windows->pan.id, - windows->pan.screen,(unsigned int) (CWX | CWY), - &window_changes); - } - } - if ((event.xconfigure.width == (int) windows->image.width) && - (event.xconfigure.height == (int) windows->image.height)) - break; - windows->image.width=(unsigned int) event.xconfigure.width; - windows->image.height=(unsigned int) event.xconfigure.height; - windows->image.x=0; - windows->image.y=0; - if (display_image->montage != (char *) NULL) - { - windows->image.x=vid_info.x; - windows->image.y=vid_info.y; - } - if (windows->image.mapped != MagickFalse && - windows->image.stasis != MagickFalse) - { - /* - Update image window configuration. - */ - windows->image.window_changes.width=event.xconfigure.width; - windows->image.window_changes.height=event.xconfigure.height; - (void) XConfigureImage(display,resource_info,windows, - display_image,exception); - } - /* - Update pan window configuration. - */ - if ((event.xconfigure.width < windows->image.ximage->width) || - (event.xconfigure.height < windows->image.ximage->height)) - { - (void) XMapRaised(display,windows->pan.id); - XDrawPanRectangle(display,windows); - } - else - if (windows->pan.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->pan.id, - windows->pan.screen); + resource_info.backdrop=(*option == '-') ? MagickTrue : MagickFalse; break; } - if (event.xconfigure.window == windows->magnify.id) + if (LocaleCompare("background",option+1) == 0) { - unsigned int - magnify; - - /* - Magnify window has a new configuration. - */ - windows->magnify.width=(unsigned int) event.xconfigure.width; - windows->magnify.height=(unsigned int) event.xconfigure.height; - if (windows->magnify.mapped == MagickFalse) + if (*option == '+') break; - magnify=1; - while ((int) magnify <= event.xconfigure.width) - magnify<<=1; - while ((int) magnify <= event.xconfigure.height) - magnify<<=1; - magnify>>=1; - if (((int) magnify != event.xconfigure.width) || - ((int) magnify != event.xconfigure.height)) + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.background_color=argv[i]; + break; + } + if (LocaleCompare("border",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("bordercolor",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.border_color=argv[i]; + break; + } + if (LocaleCompare("borderwidth",option+1) == 0) + { + resource_info.border_width=0; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + resource_info.border_width=(unsigned int) + StringToUnsignedLong(argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'c': + { + if (LocaleCompare("cache",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("channel",option+1) == 0) + { + ssize_t + channel; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + channel=ParseChannelOption(argv[i]); + if (channel < 0) + ThrowDisplayException(OptionError,"UnrecognizedChannelType", + argv[i]); + break; + } + if (LocaleCompare("clip",option+1) == 0) + break; + if (LocaleCompare("clip-path",option+1) == 0) + { + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("coalesce",option+1) == 0) + break; + if (LocaleCompare("colormap",option+1) == 0) + { + resource_info.colormap=PrivateColormap; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.colormap=UndefinedColormap; + if (LocaleCompare("private",argv[i]) == 0) + resource_info.colormap=PrivateColormap; + if (LocaleCompare("shared",argv[i]) == 0) + resource_info.colormap=SharedColormap; + if (resource_info.colormap == UndefinedColormap) + ThrowDisplayException(OptionError,"UnrecognizedColormapType", + argv[i]); + break; + } + if (LocaleCompare("colors",option+1) == 0) + { + quantize_info->number_colors=0; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + quantize_info->number_colors=StringToUnsignedLong(argv[i]); + break; + } + if (LocaleCompare("colorspace",option+1) == 0) + { + ssize_t + colorspace; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + colorspace=ParseCommandOption(MagickColorspaceOptions, + MagickFalse,argv[i]); + if (colorspace < 0) + ThrowDisplayException(OptionError,"UnrecognizedColorspace", + argv[i]); + break; + } + if (LocaleCompare("comment",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("compress",option+1) == 0) + { + ssize_t + compress; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + compress=ParseCommandOption(MagickCompressOptions,MagickFalse, + argv[i]); + if (compress < 0) + ThrowDisplayException(OptionError,"UnrecognizedImageCompression", + argv[i]); + break; + } + if (LocaleCompare("concurrent",option+1) == 0) + break; + if (LocaleCompare("contrast",option+1) == 0) + break; + if (LocaleCompare("crop",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'd': + { + if (LocaleCompare("debug",option+1) == 0) + { + ssize_t + event; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]); + if (event < 0) + ThrowDisplayException(OptionError,"UnrecognizedEventType", + argv[i]); + (void) SetLogEventMask(argv[i]); + break; + } + if (LocaleCompare("decipher",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("define",option+1) == 0) + { + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (*option == '+') { - window_changes.width=(int) magnify; - window_changes.height=(int) magnify; - (void) XReconfigureWMWindow(display,windows->magnify.id, - windows->magnify.screen,(unsigned int) (CWWidth | CWHeight), - &window_changes); + const char + *define; + + define=GetImageOption(image_info,argv[i]); + if (define == (const char *) NULL) + ThrowDisplayException(OptionError,"NoSuchOption",argv[i]); break; } - if (windows->magnify.mapped != MagickFalse && - windows->magnify.stasis != MagickFalse) - { - status=XMakeImage(display,resource_info,&windows->magnify, - display_image,windows->magnify.width,windows->magnify.height, - exception); - XMakeMagnifyImage(display,windows,exception); - } break; } - if (windows->magnify.mapped != MagickFalse && - (event.xconfigure.window == windows->pan.id)) + if (LocaleCompare("delay",option+1) == 0) { - /* - Pan icon window has a new configuration. - */ - if (event.xconfigure.send_event != 0) - { - windows->pan.x=event.xconfigure.x; - windows->pan.y=event.xconfigure.y; - } - windows->pan.width=(unsigned int) event.xconfigure.width; - windows->pan.height=(unsigned int) event.xconfigure.height; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); break; } - if (event.xconfigure.window == windows->icon.id) + if (LocaleCompare("density",option+1) == 0) { - /* - Icon window has a new configuration. - */ - windows->icon.width=(unsigned int) event.xconfigure.width; - windows->icon.height=(unsigned int) event.xconfigure.height; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); break; } - break; - } - case DestroyNotify: - { - /* - Group leader has exited. - */ - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Destroy Notify: 0x%lx",event.xdestroywindow.window); - if (event.xdestroywindow.window == windows->group_leader.id) + if (LocaleCompare("depth",option+1) == 0) { - *state|=ExitState; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); break; } - break; - } - case EnterNotify: - { - /* - Selectively install colormap. - */ - if (map_info->colormap != XDefaultColormap(display,visual_info->screen)) - if (event.xcrossing.mode != NotifyUngrab) - XInstallColormap(display,map_info->colormap); - break; - } - case Expose: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Expose: 0x%lx %dx%d+%d+%d",event.xexpose.window, - event.xexpose.width,event.xexpose.height,event.xexpose.x, - event.xexpose.y); - /* - Refresh windows that are now exposed. - */ - if ((event.xexpose.window == windows->image.id) && - windows->image.mapped != MagickFalse) + if (LocaleCompare("deskew",option+1) == 0) { - XRefreshWindow(display,&windows->image,&event); - delay=display_image->delay/MagickMax( - display_image->ticks_per_second,1L); - timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); break; } - if ((event.xexpose.window == windows->magnify.id) && - windows->magnify.mapped != MagickFalse) - { - XMakeMagnifyImage(display,windows,exception); - break; - } - if (event.xexpose.window == windows->pan.id) - { - XDrawPanRectangle(display,windows); - break; - } - if (event.xexpose.window == windows->icon.id) - { - XRefreshWindow(display,&windows->icon,&event); - break; - } - break; - } - case KeyPress: - { - int - length; - - /* - Respond to a user key press. - */ - length=XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - *(command+length)='\0'; - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Key press: %d 0x%lx (%s)",event.xkey.state,(unsigned long) - key_symbol,command); - if (event.xkey.window == windows->image.id) - { - command_type=XImageWindowCommand(display,resource_info,windows, - event.xkey.state,key_symbol,&display_image,exception); - if (command_type != NullCommand) - nexus=XMagickCommand(display,resource_info,windows,command_type, - &display_image,exception); - } - if (event.xkey.window == windows->magnify.id) - XMagnifyWindowCommand(display,windows,event.xkey.state,key_symbol, - exception); - if (event.xkey.window == windows->pan.id) - { - if ((key_symbol == XK_q) || (key_symbol == XK_Escape)) - (void) XWithdrawWindow(display,windows->pan.id, - windows->pan.screen); - else - if ((key_symbol == XK_F1) || (key_symbol == XK_Help)) - XTextViewHelp(display,resource_info,windows,MagickFalse, - "Help Viewer - Image Pan",ImagePanHelp); - else - XTranslateImage(display,windows,*image,key_symbol); - } - delay=display_image->delay/MagickMax( - display_image->ticks_per_second,1L); - timer=GetMagickTime()+(delay == 0 ? 1 : delay)+1; - break; - } - case KeyRelease: - { - /* - Respond to a user key release. - */ - (void) XLookupString((XKeyEvent *) &event.xkey,command,(int) - sizeof(command),&key_symbol,(XComposeStatus *) NULL); - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Key release: 0x%lx (%c)",(unsigned long) key_symbol,*command); - break; - } - case LeaveNotify: - { - /* - Selectively uninstall colormap. - */ - if (map_info->colormap != XDefaultColormap(display,visual_info->screen)) - if (event.xcrossing.mode != NotifyUngrab) - XUninstallColormap(display,map_info->colormap); - break; - } - case MapNotify: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Map Notify: 0x%lx", - event.xmap.window); - if (event.xmap.window == windows->backdrop.id) - { - (void) XSetInputFocus(display,event.xmap.window,RevertToParent, - CurrentTime); - windows->backdrop.mapped=MagickTrue; - break; - } - if (event.xmap.window == windows->image.id) - { - if (windows->backdrop.id != (Window) NULL) - (void) XInstallColormap(display,map_info->colormap); - if (LocaleCompare(display_image->magick,"LOGO") == 0) - { - if (LocaleCompare(display_image->filename,"LOGO") == 0) - nexus=XOpenImage(display,resource_info,windows,MagickFalse); - } - if (((int) windows->image.width < windows->image.ximage->width) || - ((int) windows->image.height < windows->image.ximage->height)) - (void) XMapRaised(display,windows->pan.id); - windows->image.mapped=MagickTrue; - break; - } - if (event.xmap.window == windows->magnify.id) - { - XMakeMagnifyImage(display,windows,exception); - windows->magnify.mapped=MagickTrue; - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - break; - } - if (event.xmap.window == windows->pan.id) - { - XMakePanImage(display,resource_info,windows,display_image, - exception); - windows->pan.mapped=MagickTrue; - break; - } - if (event.xmap.window == windows->info.id) - { - windows->info.mapped=MagickTrue; - break; - } - if (event.xmap.window == windows->icon.id) - { - MagickBooleanType - taint; - - /* - Create an icon image. - */ - taint=display_image->taint; - XMakeStandardColormap(display,icon_visual,icon_resources, - display_image,icon_map,icon_pixel,exception); - (void) XMakeImage(display,icon_resources,&windows->icon, - display_image,windows->icon.width,windows->icon.height, - exception); - display_image->taint=taint; - (void) XSetWindowBackgroundPixmap(display,windows->icon.id, - windows->icon.pixmap); - (void) XClearWindow(display,windows->icon.id); - (void) XWithdrawWindow(display,windows->info.id, - windows->info.screen); - windows->icon.mapped=MagickTrue; - break; - } - if (event.xmap.window == windows->command.id) - { - windows->command.mapped=MagickTrue; - break; - } - if (event.xmap.window == windows->popup.id) - { - windows->popup.mapped=MagickTrue; - break; - } - if (event.xmap.window == windows->widget.id) - { - windows->widget.mapped=MagickTrue; - break; - } - break; - } - case MappingNotify: - { - (void) XRefreshKeyboardMapping(&event.xmapping); - break; - } - case NoExpose: - break; - case PropertyNotify: - { - Atom - type; - - int - format, - status; - - unsigned char - *data; - - unsigned long - after, - length; - - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Property Notify: 0x%lx 0x%lx %d",event.xproperty.window, - event.xproperty.atom,event.xproperty.state); - if (event.xproperty.atom != windows->im_remote_command) + if (LocaleCompare("despeckle",option+1) == 0) break; - /* - Display image named by the remote command protocol. - */ - status=XGetWindowProperty(display,event.xproperty.window, - event.xproperty.atom,0L,(long) MagickPathExtent,MagickFalse,(Atom) - AnyPropertyType,&type,&format,&length,&after,&data); - if ((status != Success) || (length == 0)) + if (LocaleCompare("display",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("dispose",option+1) == 0) + { + ssize_t + dispose; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]); + if (dispose < 0) + ThrowDisplayException(OptionError,"UnrecognizedDisposeMethod", + argv[i]); + break; + } + if (LocaleCompare("dither",option+1) == 0) + { + ssize_t + method; + + quantize_info->dither_method=NoDitherMethod; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]); + if (method < 0) + ThrowDisplayException(OptionError,"UnrecognizedDitherMethod", + argv[i]); + quantize_info->dither_method=(DitherMethod) method; + break; + } + if (LocaleCompare("duration",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'e': + { + if (LocaleCompare("edge",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("endian",option+1) == 0) + { + ssize_t + endian; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + endian=ParseCommandOption(MagickEndianOptions,MagickFalse, + argv[i]); + if (endian < 0) + ThrowDisplayException(OptionError,"UnrecognizedEndianType", + argv[i]); + break; + } + if (LocaleCompare("enhance",option+1) == 0) break; - if (LocaleCompare((char *) data,"-quit") == 0) + if (LocaleCompare("equalize",option+1) == 0) + break; + if (LocaleCompare("extent",option+1) == 0) { - XClientMessage(display,windows->image.id,windows->im_protocols, - windows->im_exit,CurrentTime); - (void) XFree((void *) data); + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); break; } - (void) CopyMagickString(resource_info->image_info->filename, - (char *) data,MagickPathExtent); - (void) XFree((void *) data); - nexus=ReadImage(resource_info->image_info,exception); - CatchException(exception); - if (nexus != (Image *) NULL) - *state|=NextImageState | ExitState; - break; + if (LocaleCompare("extract",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); } - case ReparentNotify: + case 'f': { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Reparent Notify: 0x%lx=>0x%lx",event.xreparent.parent, - event.xreparent.window); - break; + if (LocaleCompare("filter",option+1) == 0) + { + ssize_t + filter; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]); + if (filter < 0) + ThrowDisplayException(OptionError,"UnrecognizedImageFilter", + argv[i]); + break; + } + if (LocaleCompare("flatten",option+1) == 0) + break; + if (LocaleCompare("flip",option+1) == 0) + break; + if (LocaleCompare("flop",option+1) == 0) + break; + if (LocaleCompare("font",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.font=XGetResourceClass(resource_database, + GetClientName(),"font",argv[i]); + break; + } + if (LocaleCompare("foreground",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.foreground_color=argv[i]; + break; + } + if (LocaleCompare("format",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("frame",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("fuzz",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); } - case UnmapNotify: + case 'g': { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(), - "Unmap Notify: 0x%lx",event.xunmap.window); - if (event.xunmap.window == windows->backdrop.id) + if (LocaleCompare("gamma",option+1) == 0) { - windows->backdrop.mapped=MagickFalse; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); break; } - if (event.xunmap.window == windows->image.id) + if (LocaleCompare("geometry",option+1) == 0) { - windows->image.mapped=MagickFalse; + resource_info.image_geometry=(char *) NULL; + if (*option == '+') + break; + (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent); + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + resource_info.image_geometry=ConstantString(argv[i]); break; } - if (event.xunmap.window == windows->magnify.id) + if (LocaleCompare("gravity",option+1) == 0) { - windows->magnify.mapped=MagickFalse; + ssize_t + gravity; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + gravity=ParseCommandOption(MagickGravityOptions,MagickFalse, + argv[i]); + if (gravity < 0) + ThrowDisplayException(OptionError,"UnrecognizedGravityType", + argv[i]); break; } - if (event.xunmap.window == windows->pan.id) - { - windows->pan.mapped=MagickFalse; - break; - } - if (event.xunmap.window == windows->info.id) - { - windows->info.mapped=MagickFalse; - break; - } - if (event.xunmap.window == windows->icon.id) - { - if (map_info->colormap == icon_map->colormap) - XConfigureImageColormap(display,resource_info,windows, - display_image,exception); - (void) XFreeStandardColormap(display,icon_visual,icon_map, - icon_pixel); - windows->icon.mapped=MagickFalse; - break; - } - if (event.xunmap.window == windows->command.id) - { - windows->command.mapped=MagickFalse; - break; - } - if (event.xunmap.window == windows->popup.id) - { - if (windows->backdrop.id != (Window) NULL) - (void) XSetInputFocus(display,windows->image.id,RevertToParent, - CurrentTime); - windows->popup.mapped=MagickFalse; - break; - } - if (event.xunmap.window == windows->widget.id) - { - if (windows->backdrop.id != (Window) NULL) - (void) XSetInputFocus(display,windows->image.id,RevertToParent, - CurrentTime); - windows->widget.mapped=MagickFalse; - break; - } - break; + ThrowDisplayException(OptionError,"UnrecognizedOption",option); } + case 'h': + { + if ((LocaleCompare("help",option+1) == 0) || + (LocaleCompare("-help",option+1) == 0)) + break; + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'i': + { + if (LocaleCompare("identify",option+1) == 0) + break; + if (LocaleCompare("iconGeometry",option+1) == 0) + { + resource_info.icon_geometry=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + resource_info.icon_geometry=argv[i]; + break; + } + if (LocaleCompare("iconic",option+1) == 0) + { + resource_info.iconic=(*option == '-') ? MagickTrue : MagickFalse; + break; + } + if (LocaleCompare("immutable",option+1) == 0) + { + resource_info.immutable=(*option == '-') ? MagickTrue : MagickFalse; + break; + } + if (LocaleCompare("interlace",option+1) == 0) + { + ssize_t + interlace; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse, + argv[i]); + if (interlace < 0) + ThrowDisplayException(OptionError,"UnrecognizedInterlaceType", + argv[i]); + break; + } + if (LocaleCompare("interpolate",option+1) == 0) + { + ssize_t + interpolate; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse, + argv[i]); + if (interpolate < 0) + ThrowDisplayException(OptionError,"UnrecognizedInterpolateMethod", + argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'l': + { + if (LocaleCompare("label",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("limit",option+1) == 0) + { + char + *p; + + double + value; + + ssize_t + resource; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource=ParseCommandOption(MagickResourceOptions,MagickFalse, + argv[i]); + if (resource < 0) + ThrowDisplayException(OptionError,"UnrecognizedResourceType", + argv[i]); + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + value=StringToDouble(argv[i],&p); + (void) value; + if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0)) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("list",option+1) == 0) + { + ssize_t + list; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]); + if (list < 0) + ThrowDisplayException(OptionError,"UnrecognizedListType",argv[i]); + status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **) + argv+j,exception); + DestroyDisplay(); + return(status == 0 ? MagickFalse : MagickTrue); + } + if (LocaleCompare("log",option+1) == 0) + { + if (*option == '+') + break; + i++; + if ((i == (ssize_t) argc) || + (strchr(argv[i],'%') == (char *) NULL)) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("loop",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + iterations=StringToUnsignedLong(argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'm': + { + if (LocaleCompare("magnify",option+1) == 0) + { + resource_info.magnify=2; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + resource_info.magnify=(unsigned int) StringToUnsignedLong(argv[i]); + break; + } + if (LocaleCompare("map",option+1) == 0) + { + resource_info.map_type=(char *) NULL; + if (*option == '+') + break; + (void) CopyMagickString(argv[i]+1,"sans",strlen(argv[i]+1)+1); + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.map_type=argv[i]; + break; + } + if (LocaleCompare("matte",option+1) == 0) + break; + if (LocaleCompare("mattecolor",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.matte_color=argv[i]; + break; + } + if (LocaleCompare("monitor",option+1) == 0) + break; + if (LocaleCompare("monochrome",option+1) == 0) + { + if (*option == '+') + break; + quantize_info->number_colors=2; + quantize_info->colorspace=GRAYColorspace; + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'n': + { + if (LocaleCompare("name",option+1) == 0) + { + resource_info.name=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.name=ConstantString(argv[i]); + break; + } + if (LocaleCompare("negate",option+1) == 0) + break; + if (LocaleCompare("noop",option+1) == 0) + break; + if (LocaleCompare("normalize",option+1) == 0) + break; + if (LocaleCompare("nostdin",option+1) == 0) + break; + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'p': + { + if (LocaleCompare("page",option+1) == 0) + { + resource_info.image_geometry=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.image_geometry=ConstantString(argv[i]); + break; + } + if (LocaleCompare("profile",option+1) == 0) + { + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'q': + { + if (LocaleCompare("quality",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("quantize",option+1) == 0) + { + ssize_t + colorspace; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + colorspace=ParseCommandOption(MagickColorspaceOptions, + MagickFalse,argv[i]); + if (colorspace < 0) + ThrowDisplayException(OptionError,"UnrecognizedColorspace", + argv[i]); + break; + } + if (LocaleCompare("quiet",option+1) == 0) + break; + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'r': + { + if (LocaleCompare("raise",option+1) == 0) + { + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("regard-warnings",option+1) == 0) + break; + if (LocaleCompare("remote",option+1) == 0) + { + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (XRemoteCommand(display,resource_info.window_id,argv[i]) != 0) + { + DestroyDisplay(); + return(MagickFalse); + } + i--; + break; + } + if (LocaleCompare("repage",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("resample",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("resize",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleNCompare("respect-parentheses",option+1,17) == 0) + { + respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse; + break; + } + if (LocaleCompare("roll",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("rotate",option+1) == 0) + { + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 's': + { + if (LocaleCompare("sample",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("sampling-factor",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("scenes",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("seed",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("segment",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("set",option+1) == 0) + { + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("sharpen",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("shared-memory",option+1) == 0) + { + resource_info.use_shared_memory= (*option == '-') ? MagickTrue : + MagickFalse; + break; + } + if (LocaleCompare("size",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("strip",option+1) == 0) + break; + if (LocaleCompare("support",option+1) == 0) + { + i++; /* deprecated */ + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 't': + { + if (LocaleCompare("text-font",option+1) == 0) + { + resource_info.text_font=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.text_font=XGetResourceClass(resource_database, + GetClientName(),"font",argv[i]); + break; + } + if (LocaleCompare("texture",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("threshold",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("thumbnail",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + break; + } + if (LocaleCompare("title",option+1) == 0) + { + resource_info.title=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.title=argv[i]; + break; + } + if (LocaleCompare("transparent-color",option+1) == 0) + { + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + break; + } + if (LocaleCompare("treedepth",option+1) == 0) + { + quantize_info->tree_depth=0; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + quantize_info->tree_depth=StringToUnsignedLong(argv[i]); + break; + } + if (LocaleCompare("trim",option+1) == 0) + break; + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'u': + { + if (LocaleCompare("update",option+1) == 0) + { + resource_info.update=(unsigned int) (*option == '-'); + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (IsGeometry(argv[i]) == MagickFalse) + ThrowDisplayInvalidArgumentException(option,argv[i]); + resource_info.update=(unsigned int) StringToUnsignedLong(argv[i]); + break; + } + if (LocaleCompare("use-pixmap",option+1) == 0) + { + resource_info.use_pixmap=(*option == '-') ? MagickTrue : + MagickFalse; + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'v': + { + if (LocaleCompare("verbose",option+1) == 0) + break; + if ((LocaleCompare("version",option+1) == 0) || + (LocaleCompare("-version",option+1) == 0)) + { + ListMagickVersion(stdout); + break; + } + if (LocaleCompare("visual",option+1) == 0) + { + resource_info.visual_type=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.visual_type=argv[i]; + break; + } + if (LocaleCompare("virtual-pixel",option+1) == 0) + { + ssize_t + method; + + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse, + argv[i]); + if (method < 0) + ThrowDisplayException(OptionError, + "UnrecognizedVirtualPixelMethod",argv[i]); + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case 'w': + { + if (LocaleCompare("window",option+1) == 0) + { + resource_info.window_id=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.window_id=argv[i]; + break; + } + if (LocaleCompare("window-group",option+1) == 0) + { + resource_info.window_group=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + if (StringToDouble(argv[i],(char **) NULL) != 0) + resource_info.window_group=argv[i]; + break; + } + if (LocaleCompare("write",option+1) == 0) + { + resource_info.write_filename=(char *) NULL; + if (*option == '+') + break; + i++; + if (i == (ssize_t) argc) + ThrowDisplayException(OptionError,"MissingArgument",option); + resource_info.write_filename=argv[i]; + if (IsPathAccessible(resource_info.write_filename) != MagickFalse) + { + char + answer[2], + *p; + + (void) FormatLocaleFile(stderr,"Overwrite %s? ", + resource_info.write_filename); + p=fgets(answer,(int) sizeof(answer),stdin); + (void) p; + if (((*answer != 'y') && (*answer != 'Y'))) + { + DestroyDisplay(); + return(MagickFalse); + } + } + break; + } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); + } + case '?': + break; default: - { - if (resource_info->debug != MagickFalse) - (void) LogMagickEvent(X11Event,GetMagickModule(),"Event type: %d", - event.type); - break; - } + ThrowDisplayException(OptionError,"UnrecognizedOption",option); } - } while (!(*state & ExitState)); - if ((*state & ExitState) == 0) - (void) XMagickCommand(display,resource_info,windows,FreeBuffersCommand, - &display_image,exception); - else - if (resource_info->confirm_edit != MagickFalse) - { - /* - Query user if image has changed. - */ - if ((resource_info->immutable == MagickFalse) && - display_image->taint != MagickFalse) - { - int - status; - - status=XConfirmWidget(display,windows,"Your image changed.", - "Do you want to save it"); - if (status == 0) - *state&=(~ExitState); - else - if (status > 0) - (void) XMagickCommand(display,resource_info,windows,SaveCommand, - &display_image,exception); - } - } - if ((windows->visual_info->klass == GrayScale) || - (windows->visual_info->klass == PseudoColor) || - (windows->visual_info->klass == DirectColor)) - { - /* - Withdraw pan and Magnify window. - */ - if (windows->info.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->info.id,windows->info.screen); - if (windows->magnify.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->magnify.id, - windows->magnify.screen); - if (windows->command.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->command.id, - windows->command.screen); - } - if (windows->pan.mapped != MagickFalse) - (void) XWithdrawWindow(display,windows->pan.id,windows->pan.screen); - if (resource_info->backdrop == MagickFalse) - if (windows->backdrop.mapped) - { - (void) XWithdrawWindow(display,windows->backdrop.id, - windows->backdrop.screen); - (void) XDestroyWindow(display,windows->backdrop.id); - windows->backdrop.id=(Window) NULL; - (void) XWithdrawWindow(display,windows->image.id, - windows->image.screen); - (void) XDestroyWindow(display,windows->image.id); - windows->image.id=(Window) NULL; - } - XSetCursorState(display,windows,MagickTrue); - XCheckRefreshWindows(display,windows); - if (((*state & FormerImageState) != 0) || ((*state & NextImageState) != 0)) - *state&=(~ExitState); - if (*state & ExitState) - { - /* - Free Standard Colormap. - */ - (void) XFreeStandardColormap(display,icon_visual,icon_map,icon_pixel); - if (resource_info->map_type == (char *) NULL) - (void) XFreeStandardColormap(display,visual_info,map_info,pixel); - /* - Free X resources. - */ - if (resource_info->copy_image != (Image *) NULL) - { - resource_info->copy_image=DestroyImage(resource_info->copy_image); - resource_info->copy_image=NewImageList(); - } - DestroyXResources(); - } - (void) XSync(display,MagickFalse); - /* - Restore our progress monitor and warning handlers. - */ - (void) SetErrorHandler(warning_handler); - (void) SetWarningHandler(warning_handler); - /* - Change to home directory. - */ - directory=getcwd(working_directory,MagickPathExtent); - (void) directory; - { - int - status; - - if (*resource_info->home_directory == '\0') - (void) CopyMagickString(resource_info->home_directory,".",MagickPathExtent); - status=chdir(resource_info->home_directory); - if (status == -1) - (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError, - "UnableToOpenFile","%s",resource_info->home_directory); + fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) & + FireOptionFlag) == 0 ? MagickFalse : MagickTrue; + if (fire != MagickFalse) + FireImageStack(MagickFalse,MagickTrue,MagickTrue); } - *image=display_image; - return(nexus); -} + if (k != 0) + ThrowDisplayException(OptionError,"UnbalancedParenthesis",argv[i]); + if (state & RetainColorsState) + { + XRetainWindowColors(display,XRootWindow(display,XDefaultScreen(display))); + (void) XSync(display,MagickFalse); + } + DestroyDisplay(); + return(status != 0 ? MagickTrue : MagickFalse); #else - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ D i s p l a y I m a g e s % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% DisplayImages() displays an image sequence to any X window screen. It -% returns a value other than 0 if successful. Check the exception member -% of image to determine the reason for any failure. -% -% The format of the DisplayImages method is: -% -% MagickBooleanType DisplayImages(const ImageInfo *image_info, -% Image *images,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o image_info: the image info. -% -% o image: the image. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType DisplayImages(const ImageInfo *image_info, - Image *image,ExceptionInfo *exception) -{ - assert(image_info != (const ImageInfo *) NULL); - assert(image_info->signature == MagickCoreSignature); - assert(image != (Image *) NULL); - assert(image->signature == MagickCoreSignature); - (void) image_info; - if (IsEventLogging() != MagickFalse) - (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); - (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError, - "DelegateLibrarySupportNotBuiltIn","'%s' (X11)",image->filename); - return(MagickFalse); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -+ R e m o t e D i s p l a y C o m m a n d % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% RemoteDisplayCommand() encourages a remote display program to display the -% specified image filename. -% -% The format of the RemoteDisplayCommand method is: -% -% MagickBooleanType RemoteDisplayCommand(const ImageInfo *image, -% const char *window,const char *filename,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o image_info: the image info. -% -% o window: Specifies the name or id of an X window. -% -% o filename: the name of the image filename to display. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType RemoteDisplayCommand(const ImageInfo *image_info, - const char *window,const char *filename,ExceptionInfo *exception) -{ - assert(image_info != (const ImageInfo *) NULL); - assert(image_info->signature == MagickCoreSignature); - assert(filename != (char *) NULL); - if (IsEventLogging() != MagickFalse) - (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); - (void) window; + wand_unreferenced(argc); + wand_unreferenced(argv); + wand_unreferenced(metadata); (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError, "DelegateLibrarySupportNotBuiltIn","'%s' (X11)",image_info->filename); - return(MagickFalse); -} + return(DisplayUsage()); #endif +} diff --git a/magick.sh b/magick.sh new file mode 100755 index 0000000000..801de52238 --- /dev/null +++ b/magick.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright © 1999 ImageMagick Studio LLC, a non-profit organization +# dedicated to making software imaging solutions freely available. +# +# You may not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://imagemagick.org/script/license.php +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Convenience script to verify the ImageMagick build before you install. For +# example: +# +# magick.sh magick -size 640x480 gradient:black-yellow gradient.png + +top_srcdir='/home/cristy/ImageMagick-7' +top_builddir='/home/cristy/ImageMagick-7' + +MAGICK_CODER_MODULE_PATH='/home/cristy/ImageMagick-7/coders' +MAGICK_CONFIGURE_SRC_PATH='/home/cristy/ImageMagick-7/config' +MAGICK_CONFIGURE_BUILD_PATH='/home/cristy/ImageMagick-7/config' +MAGICK_FILTER_MODULE_PATH='/home/cristy/ImageMagick-7/filters' +DIRSEP=':' + +PATH="${top_builddir}/utilities:${PATH}" + +if test -n "$VERBOSE"; then + printf "$@" +fi +env \ + LD_LIBRARY_PATH="${top_builddir}/MagickCore/.libs:${top_builddir}/MagickWand/.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \ + MAGICK_CODER_MODULE_PATH="${MAGICK_CODER_MODULE_PATH}" \ + MAGICK_CONFIGURE_PATH="${MAGICK_CONFIGURE_BUILD_PATH}${DIRSEP}${MAGICK_CONFIGURE_SRC_PATH}" \ + MAGICK_FILTER_MODULE_PATH="${MAGICK_FILTER_MODULE_PATH}" \ + PATH="${PATH}" \ + "$@" diff --git a/winpath.sh b/winpath.sh index ffa1a742db..dd188ad4c1 100644 --- a/winpath.sh +++ b/winpath.sh @@ -17,15 +17,13 @@ # Written by Bob Friesenhahn, June 2002 # arg="$1" -escapes=0 -if test -n "$2" -then +escapes=4 +if test -n "$2"; then escapes="$2" -fi -if test $escapes -gt 3 -then - echo "$0: escape level must in range 0 - 3" - exit 1 + if test $escapes -gt 3; then + printf "$0: escape level must in range 0 - 3\n" + exit 1 + fi fi result='' length=0 @@ -34,9 +32,9 @@ mount | sed -e 's:\\:/:g' | ( IFS="\n" while read mount_entry do - win_mount_path=`echo "$mount_entry" | sed -e 's: .*::g'` - unix_mount_path=`echo "$mount_entry" | sed -e 's:.* on ::;s: type .*::'` - temp=`echo "$arg" | sed -e "s!^$unix_mount_path!$win_mount_path/!"` + win_mount_path=`printf "$mount_entry\n" | sed -e 's: .*::g'` + unix_mount_path=`printf "$mount_entry\n" | sed -e 's:.* on ::;s: type .*::'` + temp=`printf "$arg" | sed -e "s!^$unix_mount_path!$win_mount_path!"` if test "$temp" != "$arg" then candidate="$temp" @@ -50,21 +48,24 @@ mount | sed -e 's:\\:/:g' | ( done if test -z "$result" then - echo "$0: path \"$arg\" is not mounted" + printf "$0: path \"$arg\" is not mounted\n" exit 1 fi - case $escapes in + case "$escapes" in 0) - echo "$result" | sed -e 's:/:\\:g' + printf "${result}" | sed -e 's:/:\\:g' ;; 1) - echo "$result" | sed -e 's:/:\\\\:g' + printf "${result}" | sed -e 's:/:\\\\:g' ;; 2) - echo "$result" | sed -e 's:/:\\\\\\\\:g' + printf "${result}" | sed -e 's:/:\\\\\\\\:g' ;; 3) - echo "$result" | sed -e 's:/:\\\\\\\\\\\\\\\\:g' + printf "${result}" | sed -e 's:/:\\\\\\\\\\\\\\\\:g' + ;; + *) + printf "${result}" ;; esac exit 0;