home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / sources / misc / 4181 < prev    next >
Encoding:
Text File  |  1992-12-14  |  57.5 KB  |  1,879 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: cristy@eplrx7.es.duPont.com (John Cristy)
  4. Subject:  v34i041:  imagemagick - X11 image processing and display v2.2, Part13/26
  5. Message-ID: <1992Dec15.035211.21619@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: a86318d02685a3ab0d7e26a5d116ddfb
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. References: <csm-v34i028=imagemagick.141926@sparky.IMD.Sterling.COM>
  11. Date: Tue, 15 Dec 1992 03:52:11 GMT
  12. Approved: kent@sparky.imd.sterling.com
  13. Lines: 1864
  14.  
  15. Submitted-by: cristy@eplrx7.es.duPont.com (John Cristy)
  16. Posting-number: Volume 34, Issue 41
  17. Archive-name: imagemagick/part13
  18. Environment: UNIX, VMS, X11, SGI, DEC, Cray, Sun, Vax
  19.  
  20. #!/bin/sh
  21. # this is Part.13 (part 13 of a multipart archive)
  22. # do not concatenate these parts, unpack them in order with /bin/sh
  23. # file ImageMagick/display.c continued
  24. #
  25. if test ! -r _shar_seq_.tmp; then
  26.     echo 'Please unpack part 1 first!'
  27.     exit 1
  28. fi
  29. (read Scheck
  30.  if test "$Scheck" != 13; then
  31.     echo Please unpack part "$Scheck" next!
  32.     exit 1
  33.  else
  34.     exit 0
  35.  fi
  36. ) < _shar_seq_.tmp || exit 1
  37. if test ! -f _shar_wnt_.tmp; then
  38.     echo 'x - still skipping ImageMagick/display.c'
  39. else
  40. echo 'x - continuing file ImageMagick/display.c'
  41. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/display.c' &&
  42. X    {
  43. X      XWindowChanges
  44. X        window_changes;
  45. X
  46. X      if (resource_info->debug)
  47. X        (void) fprintf(stderr,"Update Configuration\n");
  48. X      /*
  49. X        Update panning icon configuration.
  50. X      */
  51. X      XBestIconSize(display,&window->pan,displayed_image);
  52. X      window_changes.width=window->pan.width;
  53. X      window_changes.height=window->pan.height;
  54. X      XReconfigureWMWindow(display,window->pan.id,window->pan.screen,CWWidth |
  55. X        CWHeight,&window_changes);
  56. X      if (*state & PanIconMappedState)
  57. X        XWithdrawWindow(display,window->pan.id,window->pan.screen);
  58. X      if ((window->image.width < window->image.ximage->width) ||
  59. X          (window->image.height < window->image.ximage->height))
  60. X        XMapRaised(display,window->pan.id);
  61. X      /*
  62. X        Update magnifier configuration.
  63. X      */
  64. X      window->magnify.x=window->image.width >> 1;
  65. X      window->magnify.y=window->image.height >> 1;
  66. X      if (*state & MagnifyMappedState)
  67. X        XMakeMagnifyImage(display,resource_info,window);
  68. X      /*
  69. X        Update icon configuration.
  70. X      */
  71. X      XBestIconSize(display,&window->icon,displayed_image);
  72. X      window_changes.width=window->icon.width;
  73. X      window_changes.height=window->icon.height;
  74. X      XReconfigureWMWindow(display,window->icon.id,window->icon.screen,CWWidth |
  75. X        CWHeight,&window_changes);
  76. X      /*
  77. X        Update font configuration.
  78. X      */
  79. X      (void) sprintf(text," [%u] %s %ux%u %s \0",displayed_image->scene,
  80. X        displayed_image->filename,displayed_image->columns,
  81. X        displayed_image->rows,XVisualClassName(visual_info));
  82. X      if (displayed_image->colors > 0)
  83. X        (void) sprintf(text,"%s%uc \0",text,displayed_image->colors);
  84. X      XFreeFont(display,font_info);
  85. X      font_info=XBestFont(display,resource_info,text,window->image.width);
  86. X      if (font_info == (XFontStruct *) NULL)
  87. X        Error("unable to load font",resource_info->font);
  88. X      for (i=0; i < number_windows; i++)
  89. X      {
  90. X        magick_windows[i]->font_info=font_info;
  91. X        XSetFont(display,magick_windows[i]->graphic_context,font_info->fid);
  92. X        XSetFont(display,magick_windows[i]->highlight_context,font_info->fid);
  93. X      }
  94. X      XRefreshWindow(display,&window->image,(XEvent *) NULL);
  95. X      *state&=(~UpdateConfigurationState);
  96. X    }
  97. X  }
  98. X  while ((timeout > time((time_t *) 0)) && !(*state & ExitState));
  99. X  if ((*state & LastImageState) || (*state & NextImageState))
  100. X    *state&=(~ExitState);
  101. X  if (*state & PanIconMappedState)
  102. X    XWithdrawWindow(display,window->pan.id,window->pan.screen);
  103. X  if (*state & MagnifyMappedState)
  104. X    XWithdrawWindow(display,window->magnify.id,window->magnify.screen);
  105. X  /*
  106. X    Alert user we are busy.
  107. X  */
  108. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  109. X  XFlush(display);
  110. X  if ((resource_info->print_filename != (char *) NULL) ||
  111. X      (resource_info->write_filename != (char *) NULL))
  112. X    {
  113. X      /*
  114. X        Update image with user transforms.
  115. X      */
  116. X      if ((window->image.clip_geometry != (char *) NULL) ||
  117. X          (displayed_image->columns != window->image.ximage->width) ||
  118. X          (displayed_image->rows != window->image.ximage->height))
  119. X        {
  120. X          char
  121. X            image_geometry[2048];
  122. X
  123. X          /*
  124. X            Clip and/or scale displayed_image.
  125. X          */
  126. X          (void) sprintf(image_geometry,"%dx%d\0",window->image.ximage->width,
  127. X            window->image.ximage->height);
  128. X          TransformImage(&displayed_image,window->image.clip_geometry,
  129. X            image_geometry,(char *) NULL);
  130. X        }
  131. X      if (resource_info->colorspace == GRAYColorspace)
  132. X        QuantizeImage(displayed_image,256,8,resource_info->dither,
  133. X          GRAYColorspace,True);
  134. X      if (resource_info->monochrome)
  135. X        QuantizeImage(displayed_image,2,8,resource_info->dither,GRAYColorspace,
  136. X          True);
  137. X      if (resource_info->number_colors > 0)
  138. X        if ((displayed_image->class == DirectClass) ||
  139. X            (displayed_image->colors > resource_info->number_colors))
  140. X          QuantizeImage(displayed_image,resource_info->number_colors,
  141. X            resource_info->tree_depth,resource_info->dither,
  142. X            resource_info->colorspace,True);
  143. X    }
  144. X  /*
  145. X    Free X resources.
  146. X  */
  147. X  XFreeCursor(display,window->magnify.cursor);
  148. X  (void) free((char *) window->magnify.name);
  149. X  (void) free((char *) window->image.name);
  150. X  (void) free((char *) window->image.icon_name);
  151. X  if (resource_info->backdrop)
  152. X    XFreeCursor(display,window->backdrop.cursor);
  153. X  XFreeGC(display,window->superclass.graphic_context);
  154. X  XFreeGC(display,window->superclass.highlight_context);
  155. X  XFreeFont(display,font_info);
  156. X  if (*state & ExitState)
  157. X    {
  158. X      /*
  159. X        Destroy X windows.
  160. X      */
  161. X      for (i=0; i < number_windows; i++)
  162. X      {
  163. X        if (magick_windows[i]->id != (Window) NULL)
  164. X          XDestroyWindow(display,magick_windows[i]->id);
  165. X        if (magick_windows[i]->ximage != (XImage *) NULL)
  166. X          XDestroyImage(magick_windows[i]->ximage);
  167. X        if (magick_windows[i]->pixmap != (Pixmap) NULL)
  168. X          XFreePixmap(display,magick_windows[i]->pixmap);
  169. X      }
  170. X      /*
  171. X        Free Standard Colormap.
  172. X      */
  173. X      if (resource_info->map_type == (char *) NULL)
  174. X        XFreeStandardColormap(display,visual_info,&pixel_info,map_info);
  175. X      XFreeCursor(display,arrow_cursor);
  176. X      XFreeCursor(display,watch_cursor);
  177. X      (void) free((void *) window);
  178. X      XFree((void *) manager_hints);
  179. X      XFree((void *) class_hint);
  180. X      XFree((void *) visual_info);
  181. X      XFree((void *) map_info);
  182. X      visual_info=(XVisualInfo *) NULL;
  183. X    }
  184. X  XFlush(display);
  185. X  *image=displayed_image;
  186. X  return(tile_image);
  187. }
  188. X
  189. /*
  190. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  191. %                                                                             %
  192. %                                                                             %
  193. %                                                                             %
  194. %   X D r a w P a n R e c t a n g l e                                         %
  195. %                                                                             %
  196. %                                                                             %
  197. %                                                                             %
  198. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  199. %
  200. %  Function XDrawPanRectangle draws a rectangle in the pan window.  The pan
  201. %  window displays a scaled image and the rectangle shows which portion of
  202. %  the image is displayed in the image window.
  203. %
  204. %  The format of the XDrawPanRectangle routine is:
  205. %
  206. %    XDrawPanRectangle(display,window)
  207. %
  208. %  A description of each parameter follows:
  209. %
  210. %    o display: Specifies a connection to an X server;  returned from
  211. %      XOpenDisplay.
  212. %
  213. %    o window: Specifies a pointer to a XWindows structure.
  214. %
  215. %
  216. */
  217. static void XDrawPanRectangle(display,window)
  218. Display
  219. X  *display;
  220. X
  221. XXWindows
  222. X  *window;
  223. {
  224. X  unsigned long
  225. X    scale_factor;
  226. X
  227. X  int
  228. X    x,
  229. X    y;
  230. X
  231. X  unsigned int
  232. X    height,
  233. X    width;
  234. X
  235. X  /*
  236. X    Determine dimensions of the panning rectangle.
  237. X  */
  238. X  scale_factor=(unsigned long)
  239. X    (UpShift(window->pan.width)/window->image.ximage->width);
  240. X  x=DownShift(window->image.x*scale_factor);
  241. X  width=DownShift(window->image.width*scale_factor);
  242. X  scale_factor=(unsigned long)
  243. X    (UpShift(window->pan.height)/window->image.ximage->height);
  244. X  y=DownShift(window->image.y*scale_factor);
  245. X  height=DownShift(window->image.height*scale_factor);
  246. X  /*
  247. X    Display the panning rectangle.
  248. X  */
  249. X  XClearWindow(display,window->pan.id);
  250. X  XSetForeground(display,window->pan.graphic_context,
  251. X    window->image.pixel_info->background_color.pixel);
  252. X  XDrawRectangle(display,window->pan.id,window->pan.graphic_context,x+1,y+1,
  253. X    width-2,height-2);
  254. X  XSetForeground(display,window->pan.graphic_context,
  255. X    window->image.pixel_info->foreground_color.pixel);
  256. X  XDrawRectangle(display,window->pan.id,window->pan.graphic_context,x,y,
  257. X    width,height);
  258. }
  259. X
  260. /*
  261. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  262. %                                                                             %
  263. %                                                                             %
  264. %                                                                             %
  265. %   X M a g n i f y I m a g e W i n d o w                                     %
  266. %                                                                             %
  267. %                                                                             %
  268. %                                                                             %
  269. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  270. %
  271. %  Function XMagnifyImageWindow magnifies portions of the image as indicated
  272. %  by the pointer.  The magnified portion is displayed in a separate window.
  273. %
  274. %  The format of the XMagnifyImageWindow routine is:
  275. %
  276. %    XMagnifyImageWindow(display,resource_info,window,event)
  277. %
  278. %  A description of each parameter follows:
  279. %
  280. %    o display: Specifies a connection to an X server;  returned from
  281. %      XOpenDisplay.
  282. %
  283. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  284. %
  285. %    o window: Specifies a pointer to a XWindows structure.
  286. %
  287. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  288. %      the entire image is refreshed.
  289. %
  290. %
  291. */
  292. static void XMagnifyImageWindow(display,resource_info,window,event)
  293. Display
  294. X  *display;
  295. X
  296. XXResourceInfo
  297. X  *resource_info;
  298. X
  299. XXWindows
  300. X  *window;
  301. X
  302. XXEvent
  303. X  *event;
  304. {
  305. X  char
  306. X    text[2048];
  307. X
  308. X  register int
  309. X    x,
  310. X    y;
  311. X
  312. X  unsigned long int
  313. X    state;
  314. X
  315. X  /*
  316. X    Map info window.
  317. X  */
  318. X  state=DefaultState;
  319. X  (void) sprintf(text," %+u%+u \0",window->image.width,window->image.height);
  320. X  XSetWindowExtents(window->info,text,2);
  321. X  XMapWindow(display,window->info.id);
  322. X  state|=InfoMappedState;
  323. X  /*
  324. X    Update magnified image until the mouse button is released.
  325. X  */
  326. X  XDefineCursor(display,window->image.id,window->magnify.cursor);
  327. X  x=event->xbutton.x;
  328. X  y=event->xbutton.y;
  329. X  window->magnify.x=x+1;
  330. X  window->magnify.y=y+1;
  331. X  do
  332. X  {
  333. X    /*
  334. X      Check boundary conditions.
  335. X    */
  336. X    if (x < 0)
  337. X      x=0;
  338. X    else
  339. X      if (x >= window->image.width)
  340. X        x=window->image.width-1;
  341. X    if (y < 0)
  342. X      y=0;
  343. X    else
  344. X     if (y >= window->image.height)
  345. X       y=window->image.height-1;
  346. X    if ((window->magnify.x != (window->image.x+x)) ||
  347. X        (window->magnify.y != (window->image.y+y)))
  348. X      {
  349. X        window->magnify.x=window->image.x+x;
  350. X        window->magnify.y=window->image.y+y;
  351. X        /*
  352. X          Map and unmap info window as text cursor crosses its boundaries.
  353. X        */
  354. X        if (state & InfoMappedState)
  355. X          {
  356. X            if ((x < (window->info.x+window->info.width)) &&
  357. X                (y < (window->info.y+window->info.height)))
  358. X              {
  359. X                XWithdrawWindow(display,window->info.id,window->info.screen);
  360. X                state&=(~InfoMappedState);
  361. X              }
  362. X          }
  363. X        else
  364. X          if ((x > (window->info.x+window->info.width)) ||
  365. X              (y > (window->info.y+window->info.height)))
  366. X            {
  367. X              XMapWindow(display,window->info.id);
  368. X              state|=InfoMappedState;
  369. X            }
  370. X        if (state & InfoMappedState)
  371. X          {
  372. X            /*
  373. X              Display pointer position.
  374. X            */
  375. X            (void) sprintf(text," %+d%+d \0",window->magnify.x,
  376. X              window->magnify.y);
  377. X            XClearWindow(display,window->info.id);
  378. X            XDrawImageString(display,window->info.id,
  379. X              window->info.graphic_context,2,window->info.font_info->ascent+2,
  380. X              text,strlen(text));
  381. X          }
  382. X        /*
  383. X          Display magnified image.
  384. X        */
  385. X        XMakeMagnifyImage(display,resource_info,window);
  386. X      }
  387. X    /*
  388. X      Wait for next event.
  389. X    */
  390. X    XWindowEvent(display,window->image.id,ButtonPressMask | Button3MotionMask |
  391. X      ButtonReleaseMask | ExposureMask,event);
  392. X    switch (event->type)
  393. X    {
  394. X      case ButtonPress:
  395. X        break;
  396. X      case ButtonRelease:
  397. X      {
  398. X        /*
  399. X          User has finished magnifying image.
  400. X        */
  401. X        if (event->xbutton.button != Button3)
  402. X          break;
  403. X        x=event->xbutton.x;
  404. X        y=event->xbutton.y;
  405. X        state|=ExitState;
  406. X        break;
  407. X      }
  408. X      case Expose:
  409. X      {
  410. X        /*
  411. X          Refresh image window.
  412. X        */
  413. X        XRefreshWindow(display,&window->image,event);
  414. X        break;
  415. X      }
  416. X      case MotionNotify:
  417. X      {
  418. X        /*
  419. X          Discard pending button motion events.
  420. X        */
  421. X        while (XCheckMaskEvent(display,Button3MotionMask,event));
  422. X        x=event->xmotion.x;
  423. X        y=event->xmotion.y;
  424. X        break;
  425. X      }
  426. X      default:
  427. X        break;
  428. X    }
  429. X  } while (!(state & ExitState));
  430. X  /*
  431. X    Check boundary conditions.
  432. X  */
  433. X  if (x < 0)
  434. X    x=0;
  435. X  else
  436. X    if (x >= window->image.width)
  437. X      x=window->image.width-1;
  438. X  window->magnify.x=window->image.x+x;
  439. X  if (y < 0)
  440. X    y=0;
  441. X  else
  442. X   if (y >= window->image.height)
  443. X     y=window->image.height-1;
  444. X  window->magnify.y=window->image.y+y;
  445. X  /*
  446. X    Display magnified image.
  447. X  */
  448. X  XMakeMagnifyImage(display,resource_info,window);
  449. X  /*
  450. X    Restore cursor.
  451. X  */
  452. X  XDefineCursor(display,window->image.id,window->image.cursor);
  453. X  if (state & InfoMappedState)
  454. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  455. }
  456. X
  457. /*
  458. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  459. %                                                                             %
  460. %                                                                             %
  461. %                                                                             %
  462. %   X M a k e C u r s o r                                                     %
  463. %                                                                             %
  464. %                                                                             %
  465. %                                                                             %
  466. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  467. %
  468. %  Function XMakeCursor creates a crosshairs X11 cursor.
  469. %
  470. %  The format of the XMakeCursor routine is:
  471. %
  472. %      XMakeCursor(display,window,colormap,background_color,foreground_color)
  473. %
  474. %  A description of each parameter follows:
  475. %
  476. %    o display: Specifies a connection to an X server;  returned from
  477. %      XOpenDisplay.
  478. %
  479. %    o window: Specifies the ID of the window for which the cursor is
  480. %      assigned.
  481. %
  482. %    o colormap: Specifies the ID of the colormap from which the background
  483. %      and foreground color will be retrieved.
  484. %
  485. %    o background_color: Specifies the color to use for the cursor background.
  486. %
  487. %    o foreground_color: Specifies the color to use for the cursor foreground.
  488. %
  489. %
  490. */
  491. static Cursor XMakeCursor(display,window,colormap,background_color,
  492. X  foreground_color)
  493. Display
  494. X  *display;
  495. X
  496. Window
  497. X  window;
  498. X
  499. Colormap
  500. X  colormap;
  501. X
  502. char
  503. X  *background_color,
  504. X  *foreground_color;
  505. {
  506. #define scope_height 17
  507. #define scope_mask_width 17
  508. #define scope_mask_height 17
  509. #define scope_x_hot 8
  510. #define scope_y_hot 8
  511. #define scope_width 17
  512. X
  513. X  static unsigned char scope_bit[] =
  514. X    {
  515. X      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
  516. X      0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  517. X      0x7e, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
  518. X      0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
  519. X      0x00, 0x00, 0x00
  520. X    };
  521. X
  522. X  static unsigned char scope_mask_bit[] =
  523. X    {
  524. X      0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00,
  525. X      0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x7f, 0xfc, 0x01,
  526. X      0x7f, 0xfc, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00,
  527. X      0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00, 0x80, 0x03, 0x00,
  528. X      0x80, 0x03, 0x00
  529. X    };
  530. X
  531. X  Cursor
  532. X    cursor;
  533. X
  534. X  Pixmap
  535. X    mask,
  536. X    source;
  537. X
  538. X  XColor
  539. X    background,
  540. X    foreground;
  541. X
  542. X  source=XCreateBitmapFromData(display,window,(char *) scope_bit,scope_width,
  543. X    scope_height);
  544. X  mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bit,
  545. X    scope_width,scope_height);
  546. X  if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
  547. X    Error("unable to create pixmap",(char *) NULL);
  548. X  XParseColor(display,colormap,background_color,&background);
  549. X  XParseColor(display,colormap,foreground_color,&foreground);
  550. X  cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
  551. X    scope_x_hot,scope_y_hot);
  552. X  XFreePixmap(display,source);
  553. X  XFreePixmap(display,mask);
  554. X  return(cursor);
  555. }
  556. X
  557. /*
  558. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  559. %                                                                             %
  560. %                                                                             %
  561. %                                                                             %
  562. %   X M a k e M a g n i f y I m a g e                                         %
  563. %                                                                             %
  564. %                                                                             %
  565. %                                                                             %
  566. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  567. %
  568. %  Function XMakeMagnifyImage magnifies a region of an X image and returns it.
  569. %
  570. %  The format of the XMakeMagnifyImage routine is:
  571. %
  572. %      XMakeMagnifyImage(display,resource_info,window)
  573. %
  574. %  A description of each parameter follows:
  575. %
  576. %    o window: Specifies a pointer to a XWindows structure.
  577. %
  578. %
  579. */
  580. static void XMakeMagnifyImage(display,resource_info,window)
  581. Display
  582. X  *display;
  583. X
  584. XXResourceInfo
  585. X  *resource_info;
  586. X
  587. XXWindows
  588. X  *window;
  589. {
  590. X  register int
  591. X    x,
  592. X    y;
  593. X
  594. X  register unsigned char
  595. X    *p,
  596. X    *q;
  597. X
  598. X  register unsigned int
  599. X    j,
  600. X    k,
  601. X    l;
  602. X
  603. X  static char
  604. X    text[2048];
  605. X
  606. X  static unsigned int
  607. X    previous_magnify=0;
  608. X
  609. X  static XWindowInfo
  610. X    magnify_window;
  611. X
  612. X  unsigned int
  613. X    height,
  614. X    i,
  615. X    magnify,
  616. X    scanline_pad,
  617. X    width;
  618. X
  619. X  XColor
  620. X    color;
  621. X
  622. X  XImage
  623. X    *ximage;
  624. X
  625. X  /*
  626. X    Check boundry conditions.
  627. X  */
  628. X  magnify=1;
  629. X  for (i=1; i < resource_info->magnify; i++)
  630. X    magnify<<=1;
  631. X  while ((magnify*window->image.ximage->width) < window->magnify.width)
  632. X    magnify<<=1;
  633. X  while ((magnify*window->image.ximage->height) < window->magnify.height)
  634. X    magnify<<=1;
  635. X  while (magnify > window->magnify.width)
  636. X    magnify>>=1;
  637. X  while (magnify > window->magnify.height)
  638. X    magnify>>=1;
  639. X  if (magnify != previous_magnify)
  640. X    {
  641. X      unsigned int
  642. X        status;
  643. X
  644. X      XTextProperty
  645. X        window_name;
  646. X
  647. X      /*
  648. X        New magnify factor:  update magnify window name.
  649. X      */
  650. X      i=0;
  651. X      while ((1 << i) <= magnify)
  652. X        i++;
  653. X      (void) sprintf(window->magnify.name,"Magnify %uX",i);
  654. X      status=XStringListToTextProperty(&window->magnify.name,1,&window_name);
  655. X      if (status != 0)
  656. X        XSetWMName(display,window->magnify.id,&window_name);
  657. X    }
  658. X  previous_magnify=magnify;
  659. X  ximage=window->image.ximage;
  660. X  width=window->magnify.ximage->width;
  661. X  height=window->magnify.ximage->height;
  662. X  x=window->magnify.x-(width/magnify/2);
  663. X  if (x < 0)
  664. X    x=0;
  665. X  else
  666. X    if (x > (ximage->width-(width/magnify)))
  667. X      x=ximage->width-width/magnify;
  668. X  y=window->magnify.y-(height/magnify/2);
  669. X  if (y < 0)
  670. X    y=0;
  671. X  else
  672. X    if (y > (ximage->height-(height/magnify)))
  673. X      y=ximage->height-height/magnify;
  674. X  q=(unsigned char *) window->magnify.ximage->data;
  675. X  scanline_pad=window->magnify.ximage->bytes_per_line-
  676. X    ((width*window->magnify.ximage->bits_per_pixel) >> 3);
  677. X  if (ximage->bits_per_pixel < 8)
  678. X    {
  679. X      register unsigned char
  680. X        byte,
  681. X        p_bit,
  682. X        q_bit;
  683. X
  684. X      register unsigned int
  685. X        plane;
  686. X
  687. X      switch (ximage->bitmap_bit_order)
  688. X      {
  689. X        case LSBFirst:
  690. X        {
  691. X          /*
  692. X            Magnify little-endian bitmap.
  693. X          */
  694. X          for (i=0; i < height; i+=magnify)
  695. X          {
  696. X            /*
  697. X              Propogate pixel magnify rows.
  698. X            */
  699. X            for (j=0; j < magnify; j++)
  700. X            {
  701. X              p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  702. X                ((x*ximage->bits_per_pixel) >> 3);
  703. X              p_bit=(x*ximage->bits_per_pixel) & 0x07;
  704. X              q_bit=0;
  705. X              byte=0;
  706. X              for (k=0; k < width; k+=magnify)
  707. X              {
  708. X                /*
  709. X                  Propogate pixel magnify columns.
  710. X                */
  711. X                for (l=0; l < magnify; l++)
  712. X                {
  713. X                  /*
  714. X                    Propogate each bit plane.
  715. X                  */
  716. X                  for (plane=0; plane < ximage->bits_per_pixel; plane++)
  717. X                  {
  718. X                    byte>>=1;
  719. X                    if (*p & (0x01 << (p_bit+plane)))
  720. X                      byte|=0x80;
  721. X                    q_bit++;
  722. X                    if (q_bit == 8)
  723. X                      {
  724. X                        *q++=byte;
  725. X                        q_bit=0;
  726. X                        byte=0;
  727. X                      }
  728. X                  }
  729. X                }
  730. X                p_bit+=ximage->bits_per_pixel;
  731. X                if (p_bit == 8)
  732. X                  {
  733. X                    p++;
  734. X                    p_bit=0;
  735. X                  }
  736. X                if (q_bit > 0)
  737. X                  *q=byte >> (8-q_bit);
  738. X                q+=scanline_pad;
  739. X              }
  740. X            }
  741. X            y++;
  742. X          }
  743. X          break;
  744. X        }
  745. X        case MSBFirst:
  746. X        default:
  747. X        {
  748. X          /*
  749. X            Magnify big-endian bitmap.
  750. X          */
  751. X          for (i=0; i < height; i+=magnify)
  752. X          {
  753. X            /*
  754. X              Propogate pixel magnify rows.
  755. X            */
  756. X            for (j=0; j < magnify; j++)
  757. X            {
  758. X              p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  759. X                ((x*ximage->bits_per_pixel) >> 3);
  760. X              p_bit=(x*ximage->bits_per_pixel) & 0x07;
  761. X              q_bit=0;
  762. X              byte=0;
  763. X              for (k=0; k < width; k+=magnify)
  764. X              {
  765. X                /*
  766. X                  Propogate pixel magnify columns.
  767. X                */
  768. X                for (l=0; l < magnify; l++)
  769. X                {
  770. X                  /*
  771. X                    Propogate each bit plane.
  772. X                  */
  773. X                  for (plane=0; plane < ximage->bits_per_pixel; plane++)
  774. X                  {
  775. X                    byte<<=1;
  776. X                    if (*p & (0x80 >> (p_bit+plane)))
  777. X                      byte|=0x01;
  778. X                    q_bit++;
  779. X                    if (q_bit == 8)
  780. X                      {
  781. X                        *q++=byte;
  782. X                        q_bit=0;
  783. X                        byte=0;
  784. X                      }
  785. X                  }
  786. X                }
  787. X                p_bit+=ximage->bits_per_pixel;
  788. X                if (p_bit == 8)
  789. X                  {
  790. X                    p++;
  791. X                    p_bit=0;
  792. X                  }
  793. X                if (q_bit > 0)
  794. X                  *q=byte << (8-q_bit);
  795. X                q+=scanline_pad;
  796. X              }
  797. X            }
  798. X            y++;
  799. X          }
  800. X          break;
  801. X        }
  802. X      }
  803. X    }
  804. X  else
  805. X    switch (ximage->bits_per_pixel)
  806. X    {
  807. X      case 8:
  808. X      {
  809. X        /*
  810. X          Magnify 8 bit X image.
  811. X        */
  812. X        for (i=0; i < height; i+=magnify)
  813. X        {
  814. X          /*
  815. X            Propogate pixel magnify rows.
  816. X          */
  817. X          for (j=0; j < magnify; j++)
  818. X          {
  819. X            p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  820. X              ((x*ximage->bits_per_pixel) >> 3);
  821. X            for (k=0; k < width; k+=magnify)
  822. X            {
  823. X              /*
  824. X                Propogate pixel magnify columns.
  825. X              */
  826. X              for (l=0; l < magnify; l++)
  827. X                *q++=(*p);
  828. X              p++;
  829. X            }
  830. X            q+=scanline_pad;
  831. X          }
  832. X          y++;
  833. X        }
  834. X        break;
  835. X      }
  836. X      default:
  837. X      {
  838. X        register unsigned int
  839. X          bytes_per_pixel,
  840. X          m;
  841. X
  842. X        /*
  843. X          Magnify multi-byte X image.
  844. X        */
  845. X        bytes_per_pixel=ximage->bits_per_pixel >> 3;
  846. X        for (i=0; i < height; i+=magnify)
  847. X        {
  848. X          /*
  849. X            Propogate pixel magnify rows.
  850. X          */
  851. X          for (j=0; j < magnify; j++)
  852. X          {
  853. X            p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  854. X              ((x*ximage->bits_per_pixel) >> 3);
  855. X            for (k=0; k < width; k+=magnify)
  856. X            {
  857. X              /*
  858. X                Propogate pixel magnify columns.
  859. X              */
  860. X              for (l=0; l < magnify; l++)
  861. X                for (m=0; m < bytes_per_pixel; m++)
  862. X                  *q++=(*(p+m));
  863. X              p+=bytes_per_pixel;
  864. X            }
  865. X            q+=scanline_pad;
  866. X          }
  867. X          y++;
  868. X        }
  869. X        break;
  870. X      }
  871. X    }
  872. X  /*
  873. X    Copy X image to magnify pixmap.
  874. X  */
  875. X  x=window->magnify.x-(width/magnify/2);
  876. X  if (x < 0)
  877. X    x=width/2-window->magnify.x*magnify;
  878. X  else
  879. X    if (x > (ximage->width-(width/magnify)))
  880. X      x=(ximage->width-window->magnify.x)*magnify-width/2;
  881. X    else
  882. X      x=0;
  883. X  y=window->magnify.y-(height/magnify/2);
  884. X  if (y < 0)
  885. X    y=height/2-window->magnify.y*magnify;
  886. X  else
  887. X    if (y > (ximage->height-(height/magnify)))
  888. X      y=(ximage->height-window->magnify.y)*magnify-height/2;
  889. X    else
  890. X      y=0;
  891. X  if ((x != 0) || (y != 0))
  892. X    XFillRectangle(display,window->magnify.pixmap,
  893. X      window->magnify.highlight_context,0,0,width,height);
  894. X  XPutImage(display,window->magnify.pixmap,window->magnify.graphic_context,
  895. X    window->magnify.ximage,0,0,x,y,width-x,height-y);
  896. X  if ((magnify > 1) && ((magnify <= (width/2)) && (magnify <= (height/2))))
  897. X    {
  898. X      /*
  899. X        Highlight center pixel.
  900. X      */
  901. X      x=window->magnify.width/2;
  902. X      y=window->magnify.height/2;
  903. X      XSetForeground(display,window->magnify.graphic_context,
  904. X        window->magnify.pixel_info->background_color.pixel);
  905. X      XDrawRectangle(display,window->magnify.pixmap,
  906. X        window->magnify.graphic_context,x+1,y+1,magnify-2,magnify-2);
  907. X      XSetForeground(display,window->magnify.graphic_context,
  908. X        window->magnify.pixel_info->foreground_color.pixel);
  909. X      XDrawRectangle(display,window->magnify.pixmap,
  910. X        window->magnify.graphic_context,x,y,magnify,magnify);
  911. X    }
  912. X  /*
  913. X    Show center pixel color.
  914. X  */
  915. X  color.pixel=
  916. X    XGetPixel(window->image.ximage,window->magnify.x,window->magnify.y);
  917. X  XQueryColor(display,window->image.map_info->colormap,&color);
  918. X  (void) sprintf(text,"(%3u,%3u,%3u)\0",color.red >> 8,color.green >> 8,
  919. X    color.blue >> 8);
  920. X  XDrawImageString(display,window->magnify.pixmap,
  921. X    window->magnify.graphic_context,2,window->magnify.font_info->ascent+2,text,
  922. X    strlen(text));
  923. X  /*
  924. X    Refresh magnify window.
  925. X  */
  926. X  magnify_window=window->magnify;
  927. X  magnify_window.x=0;
  928. X  magnify_window.y=0;
  929. X  XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
  930. }
  931. X
  932. /*
  933. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  934. %                                                                             %
  935. %                                                                             %
  936. %                                                                             %
  937. %   X P a n I m a g e W i n d o w                                             %
  938. %                                                                             %
  939. %                                                                             %
  940. %                                                                             %
  941. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  942. %
  943. %  Function XPanImageWindow pans the image until the mouse button is released.
  944. %
  945. %  The format of the XPanImageWindow routine is:
  946. %
  947. %    XPanImageWindow(display,window,event)
  948. %
  949. %  A description of each parameter follows:
  950. %
  951. %    o display: Specifies a connection to an X server;  returned from
  952. %      XOpenDisplay.
  953. %
  954. %    o window: Specifies a pointer to a XWindows structure.
  955. %
  956. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  957. %      the entire image is refreshed.
  958. %
  959. */
  960. static void XPanImageWindow(display,window,event)
  961. Display
  962. X  *display;
  963. X
  964. XXWindows
  965. X  *window;
  966. X
  967. XXEvent
  968. X  *event;
  969. {
  970. X  char
  971. X    text[2048];
  972. X
  973. X  Cursor
  974. X    cursor;
  975. X
  976. X  unsigned long int
  977. X    state;
  978. X
  979. X  unsigned long
  980. X    x_factor,
  981. X    y_factor;
  982. X
  983. X  XRectangle
  984. X    pan_info;
  985. X
  986. X  /*
  987. X    Map info window.
  988. X  */
  989. X  state=DefaultState;
  990. X  (void) sprintf(text," %dx%d%+d%+d  \0",window->image.ximage->width,
  991. X    window->image.ximage->height,window->image.ximage->width,
  992. X    window->image.ximage->height);
  993. X  XSetWindowExtents(window->info,text,2);
  994. X  XMapWindow(display,window->info.id);
  995. X  state|=InfoMappedState;
  996. X  /*
  997. X    Define cursor.
  998. X  */
  999. X  if ((window->image.ximage->width > window->image.width) &&
  1000. X      (window->image.ximage->height > window->image.height))
  1001. X    cursor=XCreateFontCursor(display,XC_fleur);
  1002. X  else
  1003. X    if (window->image.ximage->width > window->image.width)
  1004. X      cursor=XCreateFontCursor(display,XC_sb_h_double_arrow);
  1005. X    else
  1006. X      if (window->image.ximage->height > window->image.height)
  1007. X        cursor=XCreateFontCursor(display,XC_sb_v_double_arrow);
  1008. X      else
  1009. X        cursor=XCreateFontCursor(display,XC_arrow);
  1010. X  if (cursor == (Cursor) NULL)
  1011. X    Error("unable to create cursor",(char *) NULL);
  1012. X  XRecolorCursor(display,cursor,&window->image.pixel_info->background_color,
  1013. X    &window->image.pixel_info->foreground_color);
  1014. X  XDefineCursor(display,window->pan.id,cursor);
  1015. X  /*
  1016. X    Pan image as pointer moves until the mouse button is released.
  1017. X  */
  1018. X  x_factor=(unsigned long)
  1019. X    UpShift(window->image.ximage->width)/window->pan.width;
  1020. X  y_factor=(unsigned long)
  1021. X    UpShift(window->image.ximage->height)/window->pan.height;
  1022. X  pan_info.x=event->xbutton.x;
  1023. X  pan_info.y=event->xbutton.y;
  1024. X  pan_info.width=(unsigned short int) (UpShift(window->image.width)/x_factor);
  1025. X  pan_info.height=(unsigned short int) (UpShift(window->image.height)/y_factor);
  1026. X  window->image.x=pan_info.x+1;
  1027. X  window->image.y=pan_info.y+1;
  1028. X  do
  1029. X  {
  1030. X    /*
  1031. X      Check boundary conditions.
  1032. X    */
  1033. X    pan_info.x=DownShift((pan_info.x-pan_info.width/2)*x_factor);
  1034. X    if (pan_info.x < 0)
  1035. X      pan_info.x=0;
  1036. X    else
  1037. X      if ((pan_info.x+window->image.width) > window->image.ximage->width)
  1038. X        pan_info.x=window->image.ximage->width-window->image.width;
  1039. X    pan_info.y=DownShift((pan_info.y-pan_info.height/2)*y_factor);
  1040. X    if (pan_info.y < 0)
  1041. X      pan_info.y=0;
  1042. X    else
  1043. X      if ((pan_info.y+window->image.height) > window->image.ximage->height)
  1044. X        pan_info.y=window->image.ximage->height-window->image.height;
  1045. X    if ((window->image.x != pan_info.x) || (window->image.y != pan_info.y))
  1046. X      {
  1047. X        /*
  1048. X          Display image pan offset.
  1049. X        */
  1050. X        window->image.x=pan_info.x;
  1051. X        window->image.y=pan_info.y;
  1052. X        (void) sprintf(text," %dx%d%+d%+d \0",window->image.ximage->width,
  1053. X          window->image.ximage->height,window->image.x,window->image.y);
  1054. X        XClearWindow(display,window->info.id);
  1055. X        XDrawImageString(display,window->info.id,window->info.graphic_context,2,
  1056. X          window->info.font_info->ascent+2,text,strlen(text));
  1057. X        /*
  1058. X          Refresh image window.
  1059. X        */
  1060. X        XDrawPanRectangle(display,window);
  1061. X        XRefreshWindow(display,&window->image,(XEvent *) NULL);
  1062. X      }
  1063. X    /*
  1064. X      Wait for next event.
  1065. X    */
  1066. X    XWindowEvent(display,window->pan.id,ButtonPressMask | ButtonMotionMask |
  1067. X      ButtonReleaseMask,event);
  1068. X    switch (event->type)
  1069. X    {
  1070. X      case ButtonRelease:
  1071. X      {
  1072. X        /*
  1073. X          User has finished panning the image.
  1074. X        */
  1075. X        pan_info.x=event->xbutton.x;
  1076. X        pan_info.y=event->xbutton.y;
  1077. X        state|=ExitState;
  1078. X        break;
  1079. X      }
  1080. X      case MotionNotify:
  1081. X      {
  1082. X        /*
  1083. X          Discard pending button motion events.
  1084. X        */
  1085. X        while (XCheckMaskEvent(display,ButtonMotionMask,event));
  1086. X        pan_info.x=event->xmotion.x;
  1087. X        pan_info.y=event->xmotion.y;
  1088. X      }
  1089. X      default:
  1090. X        break;
  1091. X    }
  1092. X  } while (!(state & ExitState));
  1093. X  /*
  1094. X    Check boundary conditions.
  1095. X  */
  1096. X  pan_info.x=DownShift((pan_info.x-pan_info.width/2)*x_factor);
  1097. X  if (pan_info.x < 0)
  1098. X    pan_info.x=0;
  1099. X  else
  1100. X    if ((pan_info.x+window->image.width) > window->image.ximage->width)
  1101. X      pan_info.x=window->image.ximage->width-window->image.width;
  1102. X  pan_info.y=DownShift((pan_info.y-pan_info.height/2)*y_factor);
  1103. X  if (pan_info.y < 0)
  1104. X    pan_info.y=0;
  1105. X  else
  1106. X    if ((pan_info.y+window->image.height) > window->image.ximage->height)
  1107. X      pan_info.y=window->image.ximage->height-window->image.height;
  1108. X  if ((window->image.x != pan_info.x) || (window->image.y != pan_info.y))
  1109. X    {
  1110. X      /*
  1111. X        Refresh image window.
  1112. X      */
  1113. X      window->image.x=pan_info.x;
  1114. X      window->image.y=pan_info.y;
  1115. X      XDrawPanRectangle(display,window);
  1116. X      XRefreshWindow(display,&window->image,(XEvent *) NULL);
  1117. X    }
  1118. X  /*
  1119. X    Restore cursor.
  1120. X  */
  1121. X  XDefineCursor(display,window->pan.id,window->pan.cursor);
  1122. X  XFreeCursor(display,cursor);
  1123. X  XWithdrawWindow(display,window->info.id,window->info.screen);
  1124. }
  1125. X
  1126. /*
  1127. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1128. %                                                                             %
  1129. %                                                                             %
  1130. %                                                                             %
  1131. %   X R e f l e c t I m a g e W i n d o w                                     %
  1132. %                                                                             %
  1133. %                                                                             %
  1134. %                                                                             %
  1135. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1136. %
  1137. %  Function XReflectImageWindow reflects the scanlines of an image.
  1138. %
  1139. %  The format of the XReflectImageWindow routine is:
  1140. %
  1141. %    status=XReflectImageWindow(display,window,image)
  1142. %
  1143. %  A description of each parameter follows:
  1144. %
  1145. %    o status: Function XReflectImageWindow return True if the window scanlines
  1146. %      reverse.  False is returned is there is a memory shortage or if the
  1147. %      window scanlines fails to reverse.
  1148. %
  1149. %    o display: Specifies a connection to an X server; returned from
  1150. %      XOpenDisplay.
  1151. %
  1152. %    o window: Specifies a pointer to a XWindows structure.
  1153. %
  1154. %    o image: Specifies a pointer to a Image structure;  returned from
  1155. %      ReadImage.
  1156. %
  1157. %
  1158. */
  1159. static unsigned int XReflectImageWindow(display,window,image)
  1160. Display
  1161. X  *display;
  1162. X
  1163. XXWindows
  1164. X  *window;
  1165. X
  1166. Image
  1167. X  **image;
  1168. {
  1169. X  char
  1170. X    text[2048];
  1171. X
  1172. X  Image
  1173. X    *reflected_image;
  1174. X
  1175. X  unsigned long int
  1176. X    state;
  1177. X
  1178. X  state=DefaultState;
  1179. X  if (((*image)->columns*(*image)->rows) > MinInfoSize)
  1180. X    {
  1181. X      /*
  1182. X        Map image window.
  1183. X      */
  1184. X      (void) strcpy(text," Reflecting image... ");
  1185. X      XSetWindowExtents(window->info,text,2);
  1186. X      XMapWindow(display,window->info.id);
  1187. X      XDrawImageString(display,window->info.id,window->info.graphic_context,2,
  1188. X        window->info.font_info->ascent+2,text,strlen(text));
  1189. X      state|=InfoMappedState;
  1190. X    }
  1191. X  /*
  1192. X    Reflect image scanlines.
  1193. X  */
  1194. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1195. X  XFlush(display);
  1196. X  reflected_image=ReflectImage(*image);
  1197. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1198. X  if (state & InfoMappedState)
  1199. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  1200. X  if (reflected_image == (Image *) NULL)
  1201. X    return(False);
  1202. X  DestroyImage(*image);
  1203. X  *image=reflected_image;
  1204. X  if (window->image.clip_geometry != (char *) NULL)
  1205. X    {
  1206. X      int
  1207. X        x,
  1208. X        y;
  1209. X
  1210. X      unsigned int
  1211. X        height,
  1212. X        width;
  1213. X
  1214. X      /*
  1215. X        Reverse clip geometry.
  1216. X      */
  1217. X      (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  1218. X      (void) sprintf(window->image.clip_geometry,"%ux%u%+d%+d\0",width,height,
  1219. X        (int) (*image)->columns-(int) width-x,y);
  1220. X    }
  1221. X  return(True);
  1222. }
  1223. X
  1224. /*
  1225. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1226. %                                                                             %
  1227. %                                                                             %
  1228. %                                                                             %
  1229. %   X R o t a t e I m a g e W i n d o w                                       %
  1230. %                                                                             %
  1231. %                                                                             %
  1232. %                                                                             %
  1233. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1234. %
  1235. %  Function XRotateImageWindow rotates the X image left or right 90 degrees.
  1236. %
  1237. %  The format of the XRotateImageWindow routine is:
  1238. %
  1239. %    status=XRotateImageWindow(display,window,degrees,image)
  1240. %
  1241. %  A description of each parameter follows:
  1242. %
  1243. %    o status: Function XRotateImageWindow return True if the window is
  1244. %      rotated.  False is returned is there is a memory shortage or if the
  1245. %      window fails to rotate.
  1246. %
  1247. %    o display: Specifies a connection to an X server; returned from
  1248. %      XOpenDisplay.
  1249. %
  1250. %    o window: Specifies a pointer to a XWindows structure.
  1251. %
  1252. %    o degrees: Specifies the number of degrees to rotate the image.
  1253. %
  1254. %    o image: Specifies a pointer to a Image structure;  returned from
  1255. %      ReadImage.
  1256. %
  1257. %
  1258. */
  1259. static unsigned int XRotateImageWindow(display,window,degrees,image)
  1260. Display
  1261. X  *display;
  1262. X
  1263. XXWindows
  1264. X  *window;
  1265. X
  1266. unsigned int
  1267. X  degrees;
  1268. X
  1269. Image
  1270. X  **image;
  1271. {
  1272. X  char
  1273. X    text[2048];
  1274. X
  1275. X  int
  1276. X    x,
  1277. X    y;
  1278. X
  1279. X  Image
  1280. X    *rotated_image;
  1281. X
  1282. X  unsigned long int
  1283. X    state;
  1284. X
  1285. X  state=DefaultState;
  1286. X  if (((*image)->columns*(*image)->rows) > MinInfoSize)
  1287. X    {
  1288. X      /*
  1289. X        Map info window.
  1290. X      */
  1291. X      (void) strcpy(text," Rotating image... ");
  1292. X      XSetWindowExtents(window->info,text,2);
  1293. X      XMapWindow(display,window->info.id);
  1294. X      XDrawImageString(display,window->info.id,window->info.graphic_context,2,
  1295. X        window->info.font_info->ascent+2,text,strlen(text));
  1296. X      state|=InfoMappedState;
  1297. X    }
  1298. X  /*
  1299. X    Rotate image.
  1300. X  */
  1301. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1302. X  XFlush(display);
  1303. X  rotated_image=RotateImage(*image,(double) degrees,True);
  1304. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1305. X  if (state & InfoMappedState)
  1306. X    XWithdrawWindow(display,window->info.id,window->info.screen);
  1307. X  if (rotated_image == (Image *) NULL)
  1308. X    return(False);
  1309. X  DestroyImage(*image);
  1310. X  *image=rotated_image;
  1311. X  if (window->image.clip_geometry != (char *) NULL)
  1312. X    {
  1313. X      unsigned int
  1314. X        height,
  1315. X        width;
  1316. X
  1317. X      /*
  1318. X        Rotate clip geometry.
  1319. X      */
  1320. X      (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  1321. X      if (degrees < 180.0)
  1322. X        (void) sprintf(window->image.clip_geometry,"%ux%u%+d%+d\0",height,
  1323. X          width,(int) (*image)->columns-(int) height-y,x);
  1324. X      else
  1325. X        (void) sprintf(window->image.clip_geometry,"%ux%u%+d%+d\0",height,
  1326. X          width,y,(int) (*image)->rows-(int) width-x);
  1327. X    }
  1328. X  return(True);
  1329. }
  1330. X
  1331. /*
  1332. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1333. %                                                                             %
  1334. %                                                                             %
  1335. %                                                                             %
  1336. %   X T i l e I m a g e W i n d o w                                           %
  1337. %                                                                             %
  1338. %                                                                             %
  1339. %                                                                             %
  1340. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1341. %
  1342. %  Function XTileImageWindow determines which individual tile of a composite
  1343. %  image was choosen with a button press and then displays it.
  1344. %
  1345. %  The format of the XTileImageWindow routine is:
  1346. %
  1347. %    tile_image=XTileImageWindow(display,resource_info,window,image,event)
  1348. %
  1349. %  A description of each parameter follows:
  1350. %
  1351. %    o tile_image:  XTileImageWindow reads the tiled image and returns
  1352. %      it.  A null image is returned if an error occurs.
  1353. %
  1354. %    o display: Specifies a connection to an X server;  returned from
  1355. %      XOpenDisplay.
  1356. %
  1357. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1358. %
  1359. %    o window: Specifies a pointer to a XWindows structure.
  1360. %
  1361. %    o image: Specifies a pointer to a Image structure; returned from
  1362. %      ReadImage.
  1363. %
  1364. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  1365. %      the entire image is refreshed.
  1366. %
  1367. %
  1368. */
  1369. static Image *XTileImageWindow(display,resource_info,window,image,event)
  1370. Display
  1371. X  *display;
  1372. X
  1373. XXResourceInfo
  1374. X  *resource_info;
  1375. X
  1376. XXWindows
  1377. X  *window;
  1378. X
  1379. Image
  1380. X  *image;
  1381. X
  1382. XXEvent
  1383. X  *event;
  1384. {
  1385. X  AlienInfo
  1386. X    alien_info;
  1387. X
  1388. X  char
  1389. X    *p,
  1390. X    *q;
  1391. X
  1392. X  Image
  1393. X    *tile_image;
  1394. X
  1395. X  int
  1396. X    tile,
  1397. X    x,
  1398. X    y;
  1399. X
  1400. X  unsigned int
  1401. X    height,
  1402. X    width;
  1403. X
  1404. X  unsigned long int
  1405. X    scale_factor;
  1406. X
  1407. X  /*
  1408. X    Tile image is relative to composite image configuration.
  1409. X  */
  1410. X  x=0;
  1411. X  y=0;
  1412. X  width=image->columns;
  1413. X  height=image->rows;
  1414. X  if (window->image.clip_geometry != (char *) NULL)
  1415. X    (void) XParseGeometry(window->image.clip_geometry,&x,&y,&width,&height);
  1416. X  scale_factor=UpShift(width)/window->image.ximage->width;
  1417. X  event->xbutton.x+=window->image.x;
  1418. X  event->xbutton.x=DownShift(event->xbutton.x*scale_factor)+x;
  1419. X  scale_factor=UpShift(height)/window->image.ximage->height;
  1420. X  event->xbutton.y+=window->image.y;
  1421. X  event->xbutton.y=DownShift(event->xbutton.y*scale_factor)+y;
  1422. X  /*
  1423. X    Determine size and location of individual tiles of the composite.
  1424. X  */
  1425. X  x=0;
  1426. X  y=0;
  1427. X  width=image->columns;
  1428. X  height=image->rows;
  1429. X  (void) XParseGeometry(image->montage,&x,&y,&width,&height);
  1430. X  tile=((event->xbutton.y-y)/height)*((image->columns-x)/width)+
  1431. X    (event->xbutton.x-x)/width;
  1432. X  if (tile < 0)
  1433. X    {
  1434. X      /*
  1435. X        Button press is outside any tile.
  1436. X      */
  1437. X      XBell(display,0);
  1438. X      return((Image *) NULL);
  1439. X    }
  1440. X  /*
  1441. X    Determine file name from the tile directory.
  1442. X  */
  1443. X  p=image->directory;
  1444. X  while ((tile != 0) && (*p != '\0'))
  1445. X  {
  1446. X    if (*p == '\n')
  1447. X      tile--;
  1448. X    p++;
  1449. X  }
  1450. X  if (*p == '\0')
  1451. X    {
  1452. X      /*
  1453. X        Button press is outside any tile.
  1454. X      */
  1455. X      XBell(display,0);
  1456. X      return((Image *) NULL);
  1457. X    }
  1458. X  /*
  1459. X    Read tile image.
  1460. X  */
  1461. X  XDefineCursor(display,window->image.id,window->image.busy_cursor);
  1462. X  XFlush(display);
  1463. X  GetAlienInfo(&alien_info);
  1464. X  q=p;
  1465. X  while ((*q != '\n') && (*q != '\0'))
  1466. X    q++;
  1467. X  (void) strncpy(alien_info.filename,p,q-p);
  1468. X  alien_info.filename[q-p]='\0';
  1469. X  alien_info.server_name=resource_info->server_name;
  1470. X  alien_info.font=resource_info->font;
  1471. X  tile_image=ReadAlienImage(&alien_info);
  1472. X  XDefineCursor(display,window->image.id,window->image.cursor);
  1473. X  if (tile_image == (Image *) NULL)
  1474. X    {
  1475. X      XPopupAlert(display,&window->popup,"unable to read image",
  1476. X        alien_info.filename);
  1477. X      return((Image *) NULL);
  1478. X    }
  1479. X  return(tile_image);
  1480. }
  1481. X
  1482. /*
  1483. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1484. %                                                                             %
  1485. %                                                                             %
  1486. %                                                                             %
  1487. %    M a i n                                                                  %
  1488. %                                                                             %
  1489. %                                                                             %
  1490. %                                                                             %
  1491. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1492. %
  1493. %
  1494. */
  1495. int main(argc,argv)
  1496. int
  1497. X  argc;
  1498. X
  1499. char
  1500. X  **argv;
  1501. {
  1502. X  AlienInfo
  1503. X    alien_info;
  1504. X
  1505. X  char
  1506. X    *clip_geometry,
  1507. X    *option,
  1508. X    *resource_value,
  1509. X    *scale_geometry,
  1510. X    *server_name,
  1511. X    *window_id;
  1512. X
  1513. X  Display
  1514. X    *display;
  1515. X
  1516. X  double
  1517. X    gamma;
  1518. X
  1519. X  int
  1520. X    degrees,
  1521. X    i,
  1522. X    x;
  1523. X
  1524. X  unsigned int
  1525. X    compression,
  1526. X    enhance,
  1527. X    *image_marker,
  1528. X    image_number,
  1529. X    inverse,
  1530. X    noise,
  1531. X    normalize,
  1532. X    reflect,
  1533. X    scene,
  1534. X    verbose;
  1535. X
  1536. X  unsigned long int
  1537. X    state;
  1538. X
  1539. X  XrmDatabase
  1540. X    resource_database,
  1541. X    server_database;
  1542. X
  1543. X  XResourceInfo
  1544. X    resource_info;
  1545. X
  1546. X  /*
  1547. X    Display usage profile if there are no command line arguments.
  1548. X  */
  1549. X  application_name=(*argv);
  1550. X  if (argc < 2)
  1551. X    Usage(True);
  1552. X  /*
  1553. X    Set defaults.
  1554. X  */
  1555. X  GetAlienInfo(&alien_info);
  1556. X  display=(Display *) NULL;
  1557. X  image_marker=(unsigned int *) malloc(argc*sizeof(unsigned int));
  1558. X  if (image_marker == (unsigned int *) NULL)
  1559. X    Error("unable to display image","memory allocation failed");
  1560. X  for (i=0; i < argc; i++)
  1561. X    image_marker[i]=argc;
  1562. X  image_number=0;
  1563. X  resource_database=(XrmDatabase) NULL;
  1564. X  server_name=(char *) NULL;
  1565. X  state=DefaultState;
  1566. X  window_id=(char *) NULL;
  1567. X  /*
  1568. X    Check for server name specified on the command line.
  1569. X  */
  1570. X  for (i=1; i < argc; i++)
  1571. X  {
  1572. X    /*
  1573. X      Check command line for server name.
  1574. X    */
  1575. X    option=argv[i];
  1576. X    if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  1577. X      if (strncmp("display",option+1,3) == 0)
  1578. X        {
  1579. X          /*
  1580. X            User specified server name.
  1581. X          */
  1582. X          i++;
  1583. X          if (i == argc)
  1584. X            Error("missing server name on -display",(char *) NULL);
  1585. X          server_name=argv[i];
  1586. X          break;
  1587. X        }
  1588. X  }
  1589. X  /*
  1590. X    Open X server connection.
  1591. X  */
  1592. X  display=XOpenDisplay(server_name);
  1593. X  if (display == (Display *) NULL)
  1594. X    Error("unable to connect to X server",XDisplayName(server_name));
  1595. X  /*
  1596. X    Set our forgiving error handler.
  1597. X  */
  1598. X  XSetErrorHandler(XError);
  1599. X  /*
  1600. X    Initialize resource database.
  1601. X  */
  1602. X  XrmInitialize();
  1603. X  XGetDefault(display,application_name,"dummy");
  1604. X  resource_database=XrmGetDatabase(display);
  1605. X  resource_value=XResourceManagerString(display);
  1606. X  if (resource_value == (char *) NULL)
  1607. X    resource_value="";
  1608. X  server_database=XrmGetStringDatabase(resource_value);
  1609. X  XrmMergeDatabases(server_database,&resource_database);
  1610. X  /*
  1611. X    Get user defaults from X resource database.
  1612. X  */
  1613. X  XGetResourceInfo(resource_database,application_name,&resource_info);
  1614. X  clip_geometry=XGetResource(resource_database,application_name,"clipGeometry",
  1615. X    "ClipGeometry",(char *) NULL);
  1616. X  resource_value=XGetResource(resource_database,application_name,"compression",
  1617. X    (char *) NULL,"RunlengthEncoded");
  1618. X  if (Latin1Compare("qencoded",resource_value) == 0)
  1619. X    compression=QEncodedCompression;
  1620. X  else
  1621. X    compression=RunlengthEncodedCompression;
  1622. X  resource_value=XGetResource(resource_database,application_name,"enhance",
  1623. X    (char *) NULL,"False");
  1624. X  enhance=IsTrue(resource_value);
  1625. X  resource_value=XGetResource(resource_database,application_name,"gamma",
  1626. X    (char *) NULL,"0.0");
  1627. X  gamma=atof(resource_value);
  1628. X  resource_value=XGetResource(resource_database,application_name,"inverse",
  1629. X    (char *) NULL,"False");
  1630. X  inverse=IsTrue(resource_value);
  1631. X  resource_value=XGetResource(resource_database,application_name,"noise",
  1632. X    (char *) NULL,"False");
  1633. X  noise=IsTrue(resource_value);
  1634. X  resource_value=XGetResource(resource_database,application_name,"normalize",
  1635. X    (char *) NULL,"False");
  1636. X  normalize=IsTrue(resource_value);
  1637. X  resource_value=XGetResource(resource_database,application_name,"reflect",
  1638. X    (char *) NULL,"False");
  1639. X  reflect=IsTrue(resource_value);
  1640. X  resource_value=XGetResource(resource_database,application_name,"rotate",
  1641. X    (char *) NULL,"0");
  1642. X  degrees=atoi(resource_value);
  1643. X  scale_geometry=XGetResource(resource_database,application_name,
  1644. X    "scaleGeometry","ScaleGeometry",(char *) NULL);
  1645. X  resource_value=XGetResource(resource_database,application_name,"scene",
  1646. X    (char *) NULL,"0");
  1647. X  scene=atoi(resource_value);
  1648. X  resource_value=XGetResource(resource_database,application_name,"verbose",
  1649. X    (char *) NULL,"False");
  1650. X  verbose=IsTrue(resource_value);
  1651. X  window_id=XGetResource(resource_database,application_name,"windowId",
  1652. X    "WindowId",(char *) NULL);
  1653. X  /*
  1654. X    Parse command line.
  1655. X  */
  1656. X  for (i=1; ((i < argc) && !(state & ExitState)); i++)
  1657. X  {
  1658. X    option=argv[i];
  1659. X    if (((int) strlen(option) > 1) && ((*option == '-') || (*option == '+')))
  1660. X      switch (*(option+1))
  1661. X      {
  1662. X        case 'b':
  1663. X        {
  1664. X          if (strncmp("backdrop",option+1,5) == 0)
  1665. X            {
  1666. X              resource_info.backdrop=(*option == '-');
  1667. X              break;
  1668. X            }
  1669. X          if (strncmp("background",option+1,5) == 0)
  1670. X            {
  1671. X              resource_info.background_color=(char *) NULL;
  1672. X              if (*option == '-')
  1673. X                {
  1674. X                  i++;
  1675. X                  if (i == argc)
  1676. X                    Error("missing color on -background",(char *) NULL);
  1677. X                  resource_info.background_color=argv[i];
  1678. X                }
  1679. X              break;
  1680. X            }
  1681. X          if (strncmp("bordercolor",option+1,7) == 0)
  1682. X            {
  1683. X              resource_info.border_color=(char *) NULL;
  1684. X              if (*option == '-')
  1685. X                {
  1686. X                  i++;
  1687. X                  if (i == argc)
  1688. X                    Error("missing color on -bordercolor",(char *) NULL);
  1689. X                  resource_info.border_color=argv[i];
  1690. X                }
  1691. X              break;
  1692. X            }
  1693. X          if (strncmp("borderwidth",option+1,7) == 0)
  1694. X            {
  1695. X              resource_info.border_width=0;
  1696. X              if (*option == '-')
  1697. X                {
  1698. X                  i++;
  1699. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1700. X                    Error("missing width on -borderwidth",(char *) NULL);
  1701. X                  resource_info.border_width=atoi(argv[i]);
  1702. X                }
  1703. X              break;
  1704. X            }
  1705. X          Error("unrecognized option",option);
  1706. X          break;
  1707. X        }
  1708. X        case 'c':
  1709. X        {
  1710. X          if (strncmp("clip",option+1,2) == 0)
  1711. X            {
  1712. X              clip_geometry=(char *) NULL;
  1713. X              if (*option == '-')
  1714. X                {
  1715. X                  i++;
  1716. X                  if (i == argc)
  1717. X                    Error("missing geometry on -clip",(char *) NULL);
  1718. X                  clip_geometry=argv[i];
  1719. X                }
  1720. X              break;
  1721. X            }
  1722. X          if (strncmp("colormap",option+1,6) == 0)
  1723. X            {
  1724. X              resource_info.colormap=PrivateColormap;
  1725. X              if (*option == '-')
  1726. X                {
  1727. X                  i++;
  1728. X                  if (i == argc)
  1729. X                    Error("missing type on -colormap",(char *) NULL);
  1730. X                  option=argv[i];
  1731. X                  resource_info.colormap=UndefinedColormap;
  1732. X                  if (Latin1Compare("private",option) == 0)
  1733. X                    resource_info.colormap=PrivateColormap;
  1734. X                  if (Latin1Compare("shared",option) == 0)
  1735. X                    resource_info.colormap=SharedColormap;
  1736. X                  if (resource_info.colormap == UndefinedColormap)
  1737. X                    Error("invalid colormap type on -colormap",option);
  1738. X                }
  1739. X              break;
  1740. X            }
  1741. X          if (strncmp("colors",option+1,7) == 0)
  1742. X            {
  1743. X              resource_info.number_colors=0;
  1744. X              if (*option == '-')
  1745. X                {
  1746. X                  i++;
  1747. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1748. X                    Error("missing colors on -colors",(char *) NULL);
  1749. X                  resource_info.number_colors=atoi(argv[i]);
  1750. X                }
  1751. X              break;
  1752. X            }
  1753. X          if (strncmp("colorspace",option+1,7) == 0)
  1754. X            {
  1755. X              resource_info.colorspace=RGBColorspace;
  1756. X              if (*option == '-')
  1757. X                {
  1758. X                  i++;
  1759. X                  if (i == argc)
  1760. X                    Error("missing type on -colorspace",(char *) NULL);
  1761. X                  option=argv[i];
  1762. X                  resource_info.colorspace=UndefinedColorspace;
  1763. X                  if (Latin1Compare("gray",option) == 0)
  1764. X                    resource_info.colorspace=GRAYColorspace;
  1765. X                  if (Latin1Compare("rgb",option) == 0)
  1766. X                    resource_info.colorspace=RGBColorspace;
  1767. X                  if (Latin1Compare("yiq",option) == 0)
  1768. X                    resource_info.colorspace=YIQColorspace;
  1769. X                  if (Latin1Compare("yuv",option) == 0)
  1770. X                    resource_info.colorspace=YUVColorspace;
  1771. X                  if (Latin1Compare("xyz",option) == 0)
  1772. X                    resource_info.colorspace=XYZColorspace;
  1773. X                  if (resource_info.colorspace == UndefinedColorspace)
  1774. X                    Error("invalid colorspace type on -colorspace",option);
  1775. X                }
  1776. X              break;
  1777. X            }
  1778. X          if (strncmp("compress",option+1,3) == 0)
  1779. X            {
  1780. X              compression=NoCompression;
  1781. X              if (*option == '-')
  1782. X                {
  1783. X                  i++;
  1784. X                  if (i == argc)
  1785. X                    Error("missing type on -compress",(char *) NULL);
  1786. X                  option=argv[i];
  1787. X                  if (Latin1Compare("runlengthencoded",option) == 0)
  1788. X                    compression=RunlengthEncodedCompression;
  1789. X                  else
  1790. X                    if (Latin1Compare("qencoded",option) == 0)
  1791. X                      compression=QEncodedCompression;
  1792. X                    else
  1793. X                      Error("invalid compression type on -compress",option);
  1794. X                }
  1795. X              break;
  1796. X            }
  1797. X          Error("unrecognized option",option);
  1798. X          break;
  1799. X        }
  1800. X        case 'd':
  1801. X        {
  1802. X          if (strncmp("debug",option+1,3) == 0)
  1803. X            {
  1804. X              resource_info.debug=(*option == '-');
  1805. X              break;
  1806. X            }
  1807. X          if (strncmp("delay",option+1,3) == 0)
  1808. X            {
  1809. X              resource_info.delay=0;
  1810. X              if (*option == '-')
  1811. X                {
  1812. X                  i++;
  1813. X                  if ((i == argc) || !sscanf(argv[i],"%d",&x))
  1814. X                    Error("missing seconds on -delay",(char *) NULL);
  1815. X                  resource_info.delay=atoi(argv[i]);
  1816. X                }
  1817. X              break;
  1818. X            }
  1819. X          if (strncmp("density",option+1,3) == 0)
  1820. X            {
  1821. X              alien_info.density=(char *) NULL;
  1822. X              if (*option == '-')
  1823. X                {
  1824. X                  i++;
  1825. X                  if (i == argc)
  1826. X                    Error("missing density on -density",(char *) NULL);
  1827. X                  alien_info.density=argv[i];
  1828. X                }
  1829. X              break;
  1830. X            }
  1831. X          if (strncmp("display",option+1,3) == 0)
  1832. X            {
  1833. X              server_name=(char *) NULL;
  1834. X              if (*option == '-')
  1835. X                {
  1836. X                  i++;
  1837. X                  if (i == argc)
  1838. X                    Error("missing server name on -display",(char *) NULL);
  1839. X                  server_name=argv[i];
  1840. X                }
  1841. X              resource_info.server_name=server_name;
  1842. X              alien_info.server_name=server_name;
  1843. X              break;
  1844. X            }
  1845. X          if (strncmp("dither",option+1,3) == 0)
  1846. X            {
  1847. X              resource_info.dither=(*option == '-');
  1848. X              break;
  1849. X            }
  1850. X          Error("unrecognized option",option);
  1851. X          break;
  1852. X        }
  1853. X        case 'e':
  1854. X        {
  1855. X          enhance=(*option == '-');
  1856. X          break;
  1857. X        }
  1858. X        case 'f':
  1859. X        {
  1860. X          if (strncmp("font",option+1,3) == 0)
  1861. X            {
  1862. X              resource_info.font=(char *) NULL;
  1863. X              if (*option == '-')
  1864. X                {
  1865. X                  i++;
  1866. X                  if (i == argc)
  1867. X                    Error("missing font name on -font",(char *) NULL);
  1868. X                  resource_info.font=argv[i];
  1869. X                }
  1870. X              alien_info.font=resource_info.font;
  1871. SHAR_EOF
  1872. true || echo 'restore of ImageMagick/display.c failed'
  1873. fi
  1874. echo 'End of  part 13'
  1875. echo 'File ImageMagick/display.c is continued in part 14'
  1876. echo 14 > _shar_seq_.tmp
  1877. exit 0
  1878. exit 0 # Just in case...
  1879.