home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / tgif / patch3.01 < prev    next >
Internet Message Format  |  1990-08-20  |  52KB

  1. Path: uunet!decwrl!sun-barr!newstop!sun!CS.UCLA.EDU
  2. From: william@CS.UCLA.EDU (William Cheng)
  3. Newsgroups: comp.sources.x
  4. Subject: v08i087: tgif, Patch3, Part01/03
  5. Message-ID: <140968@sun.Eng.Sun.COM>
  6. Date: 20 Aug 90 18:13:26 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1702
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: william@CS.UCLA.EDU (William Cheng)
  12. Posting-number: Volume 8, Issue 87
  13. Archive-name: tgif/patch3.01
  14. Patch-To: Volume 7, Issue 56-76 (original: tgif-1.2)
  15. Patch-To: Volume 8, Issue 46-48 (Patch1: tgif-1.2 => tgif-1.9)
  16. Patch-To: Volume 8, Issue 58-60 (Patch2: tgif-1.9 => tgif-1.12)
  17.  
  18. Patch3 of tgif takes tgif-1.12 to tgif-1.13.  Below is a list of
  19. added features/bug fixes, followed by the actual patch.
  20.  
  21. tgif-1.12 => tgif-1.13
  22.  
  23. 1) Fix a bug to set the font of the active cursor correctly when adding
  24.    or deleting points.
  25. 2) Fix a bug for ``prtgif'' so that it works correctly when the page
  26.    style is not portrait.
  27. 3) Every object can have attributes, and attribute's name field can be empty.
  28. 4) Add copy and paste operations.  Support copy and paste between multiple
  29.    tgifs.  Thanks to Kouichi Matsuda@NEC in Japan for his contribution to
  30.    the code.
  31.  
  32. ---------------------------------> cut here <---------------------------------
  33. *** attr.c.orig    Fri Aug 17 13:45:27 1990
  34. --- attr.c    Fri Aug 17 13:45:29 1990
  35. ***************
  36. *** 6,10 ****
  37.   #ifndef lint
  38.   static char RCSid[] =
  39. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/attr.c,v 1.6 90/07/30 11:09:21 william Exp $";
  40.   #endif
  41.   
  42. --- 6,10 ----
  43.   #ifndef lint
  44.   static char RCSid[] =
  45. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/attr.c,v 1.9 90/08/13 09:23:13 william Exp $";
  46.   #endif
  47.   
  48. ***************
  49. *** 75,93 ****
  50.      own_ptr = AttrPtr->owner;
  51.    
  52. !    if (own_ptr->type == OBJ_POLY)
  53. !    {
  54. !       top_attr_ad = &(own_ptr->detail.p->fattr);
  55. !       bot_attr_ad = &(own_ptr->detail.p->lattr);
  56. !    }
  57. !    else
  58. !    {
  59. !       top_attr_ad = &(own_ptr->detail.r->fattr);
  60. !       bot_attr_ad = &(own_ptr->detail.r->lattr);
  61. !    }
  62.        
  63.      if (*top_attr_ad == AttrPtr)
  64. !          *top_attr_ad = AttrPtr->next;
  65. !       else
  66. !          AttrPtr->prev->next = AttrPtr->next;
  67.   
  68.      if (*bot_attr_ad == AttrPtr)
  69. --- 75,85 ----
  70.      own_ptr = AttrPtr->owner;
  71.    
  72. !    top_attr_ad = &(own_ptr->fattr);
  73. !    bot_attr_ad = &(own_ptr->lattr);
  74.        
  75.      if (*top_attr_ad == AttrPtr)
  76. !       *top_attr_ad = AttrPtr->next;
  77. !    else
  78. !       AttrPtr->prev->next = AttrPtr->next;
  79.   
  80.      if (*bot_attr_ad == AttrPtr)
  81. ***************
  82. *** 106,110 ****
  83.   
  84.   static
  85. ! short ParseAttrStr(Str, name, s)
  86.      char    * Str, * name, * s;
  87.   {
  88. --- 98,102 ----
  89.   
  90.   static
  91. ! void ParseAttrStr(Str, name, s)
  92.      char    * Str, * name, * s;
  93.   {
  94. ***************
  95. *** 134,142 ****
  96.   
  97.         *ptr = '\0';
  98. -        
  99. -       return (TRUE);
  100.      }
  101.      else
  102. !       return (FALSE);
  103.   } 
  104.   
  105. --- 126,135 ----
  106.   
  107.         *ptr = '\0';
  108.      }
  109.      else
  110. !    {
  111. !       *name = '\0';
  112. !       strcpy (s, Str);
  113. !    }
  114.   } 
  115.   
  116. ***************
  117. *** 267,278 ****
  118.   
  119.      topAttr = botAttr = NULL;
  120. !    switch (ToObjPtr->type)
  121. !    {
  122. !       case OBJ_POLY: from_attr_ptr = FromObjPtr->detail.p->fattr; break;
  123. !       case OBJ_SYM:
  124. !       case OBJ_GROUP:
  125. !       case OBJ_ICON: from_attr_ptr = FromObjPtr->detail.r->fattr; break;
  126. !    }
  127.      for ( ; from_attr_ptr != NULL; from_attr_ptr = from_attr_ptr->next)
  128.      {
  129. --- 260,264 ----
  130.   
  131.      topAttr = botAttr = NULL;
  132. !    from_attr_ptr = FromObjPtr->fattr;
  133.      for ( ; from_attr_ptr != NULL; from_attr_ptr = from_attr_ptr->next)
  134.      {
  135. ***************
  136. *** 282,302 ****
  137.         LinkInAttr (NULL, topAttr, to_attr_ptr);
  138.      }
  139. !    switch (ToObjPtr->type)
  140. !    {
  141. !       case OBJ_POLY:
  142. !          ToObjPtr->detail.p->fattr = topAttr;
  143. !          ToObjPtr->detail.p->lattr = botAttr;
  144. !          break;
  145. !       case OBJ_SYM:
  146. !       case OBJ_GROUP:
  147. !       case OBJ_ICON:
  148. !          ToObjPtr->detail.r->fattr = topAttr;
  149. !          ToObjPtr->detail.r->lattr = botAttr;
  150. !          break;
  151. !    }
  152.   }
  153.   
  154.   static
  155. ! int AddAttr(ObjPtr, TextObjPtr)
  156.      struct ObjRec    * ObjPtr, * TextObjPtr;
  157.   {
  158. --- 268,277 ----
  159.         LinkInAttr (NULL, topAttr, to_attr_ptr);
  160.      }
  161. !    ToObjPtr->fattr = topAttr;
  162. !    ToObjPtr->lattr = botAttr;
  163.   }
  164.   
  165.   static
  166. ! void AddAttr(ObjPtr, TextObjPtr)
  167.      struct ObjRec    * ObjPtr, * TextObjPtr;
  168.   {
  169. ***************
  170. *** 309,351 ****
  171.      text_ptr = TextObjPtr->detail.t; 
  172.   
  173. !    if (ParseAttrStr(text_ptr->first->s, name, value))
  174. !    {
  175. !       switch (ObjPtr->type)
  176. !       {
  177. !          case OBJ_POLY:
  178. !             topAttr = ObjPtr->detail.p->fattr;
  179. !             botAttr = ObjPtr->detail.p->lattr;
  180. !             break;
  181. !          case OBJ_SYM:
  182. !          case OBJ_GROUP:
  183. !          case OBJ_ICON:
  184. !             topAttr = ObjPtr->detail.r->fattr;
  185. !             botAttr = ObjPtr->detail.r->lattr;
  186. !             break;
  187. !       }
  188.   
  189. !       UnlinkObj (TextObjPtr);
  190. !       TextObjPtr->next = TextObjPtr->prev = NULL;
  191. !       attr_ptr = NewAttr (ObjPtr, TextObjPtr, FALSE); 
  192. !       UpdateAttr (text_ptr, attr_ptr); 
  193. !       LinkInAttr (NULL, topAttr, attr_ptr);
  194.   
  195. !       switch (ObjPtr->type)
  196. !       {
  197. !          case OBJ_POLY:
  198. !             ObjPtr->detail.p->fattr = topAttr;
  199. !             ObjPtr->detail.p->lattr = botAttr;
  200. !             break;
  201. !          case OBJ_SYM:
  202. !          case OBJ_GROUP:
  203. !          case OBJ_ICON:
  204. !             ObjPtr->detail.r->fattr = topAttr;
  205. !             ObjPtr->detail.r->lattr = botAttr;
  206. !             break;
  207. !       }
  208. !       return (TRUE);
  209. !    }
  210. !    else
  211. !       return (FALSE);
  212.   }
  213.   
  214. --- 284,299 ----
  215.      text_ptr = TextObjPtr->detail.t; 
  216.   
  217. !    ParseAttrStr(text_ptr->first->s, name, value);
  218. !    topAttr = ObjPtr->fattr;
  219. !    botAttr = ObjPtr->lattr;
  220.   
  221. !    UnlinkObj (TextObjPtr);
  222. !    TextObjPtr->next = TextObjPtr->prev = NULL;
  223. !    attr_ptr = NewAttr (ObjPtr, TextObjPtr, FALSE); 
  224. !    UpdateAttr (text_ptr, attr_ptr); 
  225. !    LinkInAttr (NULL, topAttr, attr_ptr);
  226.   
  227. !    ObjPtr->fattr = topAttr;
  228. !    ObjPtr->lattr = botAttr;
  229.   }
  230.   
  231. ***************
  232. *** 354,367 ****
  233.      struct AttrRec    * attr_ptr;
  234.      struct ObjRec    * owner_ptr = NULL, * attr_obj_ptr;
  235. !    struct SelRec    * sel_ptr, * tmp_top_sel = NULL, * tmp_bot_sel = NULL;
  236. !    struct SelRec    * new_sel_ptr;
  237. !    int            still_valid = TRUE, text_count = 0;
  238. !    int            sel_ltx, sel_lty, sel_rbx, sel_rby;
  239.   
  240. !    for (sel_ptr = topSel; (sel_ptr!=NULL) && (still_valid);
  241. !          sel_ptr = sel_ptr->next)
  242.         switch (sel_ptr->obj->type)
  243.         {
  244.            case OBJ_TEXT: text_count++; break;
  245.            case OBJ_POLY:
  246.            case OBJ_SYM:
  247. --- 302,316 ----
  248.      struct AttrRec    * attr_ptr;
  249.      struct ObjRec    * owner_ptr = NULL, * attr_obj_ptr;
  250. !    struct SelRec    * sel_ptr, * new_sel_ptr;
  251. !    int            text_count = 0, sel_ltx, sel_lty, sel_rbx, sel_rby;
  252.   
  253. !    for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
  254.         switch (sel_ptr->obj->type)
  255.         {
  256.            case OBJ_TEXT: text_count++; break;
  257. +          case OBJ_BOX:
  258. +          case OBJ_OVAL:
  259. +          case OBJ_POLYGON:
  260.            case OBJ_POLY:
  261.            case OBJ_SYM:
  262. ***************
  263. *** 368,442 ****
  264.            case OBJ_GROUP:
  265.            case OBJ_ICON:
  266. !             if (owner_ptr == NULL)
  267. !                owner_ptr = sel_ptr->obj;
  268. !             else
  269.               {
  270. !                still_valid = FALSE;
  271. !                Msg("Too many icon, group, symbol, or poly objects selected.");
  272.               }
  273.               break; 
  274. -          case OBJ_BOX:
  275. -          case OBJ_OVAL:
  276. -          case OBJ_POLYGON:
  277. -             still_valid = FALSE;
  278. -             Msg("Only icons, groups, symbols, and polys can have attributes");
  279. -             break;
  280.         }
  281.    
  282. !    if (still_valid)
  283.      {
  284. !       if (text_count == 0)
  285. !          Msg("No text objects selected to add as attributes.");
  286. !       else
  287. !       {
  288. !          if (owner_ptr != NULL)
  289. !          {
  290. !             HighLightReverse ();
  291. !             sel_ltx = selLtX; sel_lty = selLtY;
  292. !             sel_rbx = selRbX; sel_rby = selRbY;
  293.   
  294. !             for (sel_ptr = botSel;  sel_ptr != NULL; sel_ptr = sel_ptr->prev)
  295. !                if (sel_ptr->obj->type == OBJ_TEXT)
  296. !                   if (!AddAttr(owner_ptr, sel_ptr->obj))
  297. !                   { /* bad format for the text to be an attribute */
  298. !                      new_sel_ptr = (struct SelRec *) calloc (1,
  299. !                            sizeof(struct SelRec));
  300. !                      new_sel_ptr->obj = sel_ptr->obj;
  301.   
  302. !                      new_sel_ptr->prev = NULL;
  303. !                      new_sel_ptr->next = tmp_top_sel;
  304. !                      if (tmp_top_sel == NULL)
  305. !                         tmp_bot_sel = new_sel_ptr;
  306. !                      else
  307. !                         tmp_top_sel->prev = new_sel_ptr;
  308. !                      tmp_top_sel = new_sel_ptr;
  309. !                   }
  310.   
  311. !             RemoveAllSel ();
  312. !             UnlinkObj (owner_ptr);
  313. !             AddObj (NULL, topObj, owner_ptr);
  314. !             topSel = botSel = (struct SelRec *) calloc (1,
  315. !                   sizeof(struct SelRec));
  316. !             topSel->obj = owner_ptr;
  317. !             topSel->prev = NULL;
  318. !             botSel->next = tmp_top_sel;
  319. !             if (tmp_top_sel != NULL)
  320. !             {
  321. !                tmp_top_sel->prev = topSel;
  322. !                botSel = tmp_bot_sel;
  323. !             }
  324. !             AdjObjBBox (owner_ptr);
  325. !             UpdSelBBox ();
  326. !             RedrawAreas (botObj, sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
  327. !                   sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
  328. !                   selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
  329. !                   selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
  330. !             HighLightForward ();
  331. !             justDupped = FALSE;
  332. !          } 
  333. !          else
  334. !             Msg("No icon, group, symbol, poly objects selected.");
  335. !       }
  336. !    }
  337.   }
  338.   
  339. --- 317,363 ----
  340.            case OBJ_GROUP:
  341.            case OBJ_ICON:
  342. !             if (owner_ptr != NULL)
  343.               {
  344. !                Msg("Too non-text objects selected.");
  345. !                return;
  346.               }
  347. +             owner_ptr = sel_ptr->obj;
  348.               break; 
  349.         }
  350.    
  351. !    if (text_count == 0)
  352.      {
  353. !       Msg("No text objects selected to add as attributes.");
  354. !       return;
  355. !    }
  356. !    if (owner_ptr == NULL)
  357. !    {
  358. !       Msg("No objects (other than TEXT objects) selected.");
  359. !       return;
  360. !    }
  361.   
  362. !    HighLightReverse ();
  363. !    sel_ltx = selLtX; sel_lty = selLtY;
  364. !    sel_rbx = selRbX; sel_rby = selRbY;
  365.   
  366. !    for (sel_ptr = botSel;  sel_ptr != NULL; sel_ptr = sel_ptr->prev)
  367. !       if (sel_ptr->obj->type == OBJ_TEXT)
  368. !          AddAttr(owner_ptr, sel_ptr->obj);
  369.   
  370. !    RemoveAllSel ();
  371. !    UnlinkObj (owner_ptr);
  372. !    AddObj (NULL, topObj, owner_ptr);
  373. !    topSel = botSel = (struct SelRec *) calloc (1, sizeof(struct SelRec));
  374. !    topSel->obj = owner_ptr;
  375. !    topSel->prev = NULL;
  376. !    botSel->next = NULL;
  377. !    AdjObjBBox (owner_ptr);
  378. !    UpdSelBBox ();
  379. !    RedrawAreas (botObj, sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
  380. !          sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
  381. !          selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
  382. !          selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
  383. !    HighLightForward ();
  384. !    justDupped = FALSE;
  385.   }
  386.   
  387. ***************
  388. *** 446,452 ****
  389.      struct AttrRec    * AttrPtr;
  390.   {
  391. - /* fprintf (FP, "attr(\"%s\", \"%s\", %1d, %1d, %1d,\n", */
  392. - /*       AttrPtr->name, AttrPtr->s, AttrPtr->shown, */
  393. - /*       AttrPtr->nameshown, AttrPtr->inherited); */
  394.      fprintf (FP, "attr(\"");
  395.      SaveString (FP, AttrPtr->name);
  396. --- 367,370 ----
  397. ***************
  398. *** 542,547 ****
  399.   
  400.   static
  401. ! int ShowAndUpdAttrNames ()
  402. !    /* returns TRUE if any attribute names are updated */
  403.      /* This routine concatinate the 'name' and 's' first of every        */
  404.      /*    attribute of the selected object and assign that to the        */
  405. --- 460,468 ----
  406.   
  407.   static
  408. ! int ShowAndUpdAttrNames (Force)
  409. !    int    Force;
  410. !    /* Force will force attribute name to be shown whether the attribute */
  411. !    /*    is inherited or not.                                           */
  412. !    /* returns TRUE if any attribute names are updated                   */
  413.      /* This routine concatinate the 'name' and 's' first of every        */
  414.      /*    attribute of the selected object and assign that to the        */
  415. ***************
  416. *** 551,555 ****
  417.      struct ObjRec    * obj_ptr;
  418.      struct AttrRec    * attr_ptr;
  419. !    int            has_attr, picture_changed = FALSE, obj_changed;
  420.      int            len1, len2;
  421.      char            * s, msg[80];
  422. --- 472,476 ----
  423.      struct ObjRec    * obj_ptr;
  424.      struct AttrRec    * attr_ptr;
  425. !    int            picture_changed = FALSE, obj_changed;
  426.      int            len1, len2;
  427.      char            * s, msg[80];
  428. ***************
  429. *** 558,576 ****
  430.      {
  431.         obj_ptr = sel_ptr->obj;
  432. !       has_attr = TRUE;
  433. !       switch (obj_ptr->type)
  434.         {
  435. -          case OBJ_POLY: attr_ptr = obj_ptr->detail.p->fattr; break;
  436. -          case OBJ_GROUP:
  437. -          case OBJ_SYM:
  438. -          case OBJ_ICON: attr_ptr = obj_ptr->detail.r->fattr; break;
  439. -          default: has_attr = FALSE;
  440. -       }
  441. -       if (has_attr && attr_ptr != NULL)
  442. -       {
  443.            obj_changed = FALSE;
  444.            for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
  445.            {
  446. !             if (!(attr_ptr->nameshown))
  447.               {
  448.                  s = attr_ptr->obj->detail.t->first->s;
  449. --- 479,489 ----
  450.      {
  451.         obj_ptr = sel_ptr->obj;
  452. !       attr_ptr = obj_ptr->fattr;
  453. !       if (attr_ptr != NULL)
  454.         {
  455.            obj_changed = FALSE;
  456.            for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
  457.            {
  458. !             if (!(attr_ptr->nameshown) && (Force || !(attr_ptr->inherited)))
  459.               {
  460.                  s = attr_ptr->obj->detail.t->first->s;
  461. ***************
  462. *** 601,605 ****
  463.   void ShowAllAttrNames ()
  464.   {
  465. !    if (ShowAndUpdAttrNames ())
  466.      {
  467.         HighLightReverse ();
  468. --- 514,518 ----
  469.   void ShowAllAttrNames ()
  470.   {
  471. !    if (ShowAndUpdAttrNames (TRUE))
  472.      {
  473.         HighLightReverse ();
  474. ***************
  475. *** 621,625 ****
  476.      struct ObjRec    * obj_ptr;
  477.      struct AttrRec    * attr_ptr;
  478. !    int            has_attr, picture_changed = FALSE, obj_changed;
  479.      char            * s;
  480.   
  481. --- 534,538 ----
  482.      struct ObjRec    * obj_ptr;
  483.      struct AttrRec    * attr_ptr;
  484. !    int            picture_changed = FALSE, obj_changed;
  485.      char            * s;
  486.   
  487. ***************
  488. *** 627,649 ****
  489.      {
  490.         obj_ptr = sel_ptr->obj;
  491. !       has_attr = TRUE;
  492. !       switch (obj_ptr->type)
  493.         {
  494. -          case OBJ_POLY: attr_ptr = obj_ptr->detail.p->fattr; break;
  495. -          case OBJ_GROUP:
  496. -          case OBJ_SYM:
  497. -          case OBJ_ICON: attr_ptr = obj_ptr->detail.r->fattr; break;
  498. -          default: has_attr = FALSE;
  499. -       }
  500. -       if (has_attr && attr_ptr != NULL)
  501. -       {
  502.            obj_changed = FALSE;
  503.            for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
  504.            {
  505. !             if (attr_ptr->nameshown)
  506.               {
  507.                  s = attr_ptr->obj->detail.t->first->s;
  508.                  strcpy (s, attr_ptr->s);
  509. -                attr_ptr->nameshown = FALSE;
  510.                  UpdTextBBox (attr_ptr->obj);
  511.                  if (attr_ptr->shown) obj_changed = picture_changed = TRUE;
  512. --- 540,554 ----
  513.      {
  514.         obj_ptr = sel_ptr->obj;
  515. !       attr_ptr = obj_ptr->fattr;
  516. !       if (attr_ptr != NULL)
  517.         {
  518.            obj_changed = FALSE;
  519.            for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
  520.            {
  521. !             if (attr_ptr->nameshown && *(attr_ptr->name) != '\0')
  522.               {
  523. +                attr_ptr->nameshown = FALSE;
  524.                  s = attr_ptr->obj->detail.t->first->s;
  525.                  strcpy (s, attr_ptr->s);
  526.                  UpdTextBBox (attr_ptr->obj);
  527.                  if (attr_ptr->shown) obj_changed = picture_changed = TRUE;
  528. ***************
  529. *** 677,681 ****
  530.      struct SelRec    * * TopSelPtr, * * BotSelPtr;
  531.   {
  532. !    struct AttrRec    * attr_ptr = ObjPtr->detail.r->fattr;
  533.      struct SelRec    * new_sel_ptr;
  534.      int            len1, len2;
  535. --- 582,586 ----
  536.      struct SelRec    * * TopSelPtr, * * BotSelPtr;
  537.   {
  538. !    struct AttrRec    * attr_ptr = ObjPtr->fattr;
  539.      struct SelRec    * new_sel_ptr;
  540.      int            len1, len2;
  541. ***************
  542. *** 735,743 ****
  543.      struct ObjRec    * obj_ptr;
  544.      struct AttrRec    * attr_ptr, * attr_ptr_next;
  545. !    int            has_attr, picture_changed, obj_changed;
  546.      char            * s;
  547.   
  548.      HighLightReverse ();
  549. !    picture_changed = ShowAndUpdAttrNames ();
  550.   
  551.      for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
  552. --- 640,648 ----
  553.      struct ObjRec    * obj_ptr;
  554.      struct AttrRec    * attr_ptr, * attr_ptr_next;
  555. !    int            picture_changed, obj_changed;
  556.      char            * s;
  557.   
  558.      HighLightReverse ();
  559. !    picture_changed = ShowAndUpdAttrNames (FALSE);
  560.   
  561.      for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
  562. ***************
  563. *** 744,758 ****
  564.      {
  565.         obj_ptr = sel_ptr->obj;
  566. !       has_attr = TRUE;
  567. !       switch (obj_ptr->type)
  568.         {
  569. -          case OBJ_POLY: attr_ptr = obj_ptr->detail.p->fattr; break;
  570. -          case OBJ_GROUP:
  571. -          case OBJ_SYM:
  572. -          case OBJ_ICON: attr_ptr = obj_ptr->detail.r->fattr; break;
  573. -          default: has_attr = FALSE;
  574. -       }
  575. -       if (has_attr && attr_ptr != NULL)
  576. -       {
  577.            topAttr = botAttr = NULL;
  578.            for ( ; attr_ptr != NULL; attr_ptr = attr_ptr_next)
  579. --- 649,655 ----
  580.      {
  581.         obj_ptr = sel_ptr->obj;
  582. !       attr_ptr = obj_ptr->fattr;
  583. !       if (attr_ptr != NULL)
  584.         {
  585.            topAttr = botAttr = NULL;
  586.            for ( ; attr_ptr != NULL; attr_ptr = attr_ptr_next)
  587. ***************
  588. *** 773,789 ****
  589.               cfree (attr_ptr);
  590.            }
  591. !          switch (obj_ptr->type)
  592. !          {
  593. !             case OBJ_POLY:
  594. !                obj_ptr->detail.p->fattr = topAttr;
  595. !                obj_ptr->detail.p->lattr = botAttr;
  596. !                break;
  597. !             case OBJ_GROUP:
  598. !             case OBJ_SYM:
  599. !             case OBJ_ICON:
  600. !                obj_ptr->detail.r->fattr = topAttr;
  601. !                obj_ptr->detail.r->lattr = botAttr;
  602. !                break;
  603. !          }
  604.            AdjObjBBox (obj_ptr);
  605.         }
  606. --- 670,675 ----
  607.               cfree (attr_ptr);
  608.            }
  609. !          obj_ptr->fattr = topAttr;
  610. !          obj_ptr->lattr = botAttr;
  611.            AdjObjBBox (obj_ptr);
  612.         }
  613. ***************
  614. *** 906,910 ****
  615.                  break;
  616.               case Button2:
  617. !                AttrPtr->nameshown = !AttrPtr->nameshown;
  618.                  UpdAttr (AttrPtr);
  619.                  if (AttrPtr->shown)
  620. --- 792,797 ----
  621.                  break;
  622.               case Button2:
  623. !                if (!(AttrPtr->nameshown) || *(AttrPtr->name) != '\0')
  624. !                   AttrPtr->nameshown = !AttrPtr->nameshown;
  625.                  UpdAttr (AttrPtr);
  626.                  if (AttrPtr->shown)
  627. ***************
  628. *** 1012,1016 ****
  629.      struct ObjRec    * obj_ptr;
  630.      struct AttrRec    * attr_ptr, * attr_ptr1;
  631. !    int            has_attr = TRUE, num_attrs = 0, i, index, x, y;
  632.      int            picture_changed, sel_ltx, sel_lty, sel_rbx, sel_rby;
  633.      int            * fore_colors, * pixel_ptr, * valid, * flag_ptr;
  634. --- 899,903 ----
  635.      struct ObjRec    * obj_ptr;
  636.      struct AttrRec    * attr_ptr, * attr_ptr1;
  637. !    int            num_attrs = 0, i, index, x, y;
  638.      int            picture_changed, sel_ltx, sel_lty, sel_rbx, sel_rby;
  639.      int            * fore_colors, * pixel_ptr, * valid, * flag_ptr;
  640. ***************
  641. *** 1023,1037 ****
  642.   
  643.      obj_ptr = topSel->obj;
  644. !    has_attr = TRUE;
  645. !    switch (obj_ptr->type)
  646. !    {
  647. !       case OBJ_POLY: attr_ptr1 = attr_ptr = obj_ptr->detail.p->fattr; break;
  648. !       case OBJ_GROUP:
  649. !       case OBJ_SYM:
  650. !       case OBJ_ICON: attr_ptr1 = attr_ptr = obj_ptr->detail.r->fattr; break;
  651. !       default: has_attr = FALSE;
  652. !    }
  653. !    if (!has_attr)
  654. !    { Msg ("Please select one poly, group, symbol, or icon object."); return; }
  655.   
  656.      for ( ; attr_ptr1 != NULL; attr_ptr1 = attr_ptr1->next, num_attrs++) ;
  657. --- 910,914 ----
  658.   
  659.      obj_ptr = topSel->obj;
  660. !    attr_ptr1 = attr_ptr = obj_ptr->fattr;
  661.   
  662.      for ( ; attr_ptr1 != NULL; attr_ptr1 = attr_ptr1->next, num_attrs++) ;
  663. *** box.c.orig    Fri Aug 17 13:45:37 1990
  664. --- box.c    Fri Aug 17 13:45:38 1990
  665. ***************
  666. *** 6,10 ****
  667.   #ifndef lint
  668.   static char RCSid[] =
  669. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/box.c,v 1.5 90/07/16 10:29:15 william Exp $";
  670.   #endif
  671.   
  672. --- 6,10 ----
  673.   #ifndef lint
  674.   static char RCSid[] =
  675. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/box.c,v 1.7 90/08/13 09:23:32 william Exp $";
  676.   #endif
  677.   
  678. ***************
  679. *** 247,251 ****
  680. --- 247,254 ----
  681.      obj_ptr->type = OBJ_BOX;
  682.      obj_ptr->color = colorIndex;
  683. +    obj_ptr->id = objId++;
  684. +    obj_ptr->dirty = FALSE;
  685.      obj_ptr->detail.b = box_ptr;
  686. +    obj_ptr->fattr = obj_ptr->lattr = NULL;
  687.      AddObj (NULL, topObj, obj_ptr);
  688.   }
  689. ***************
  690. *** 339,345 ****
  691.   {
  692.      fprintf (FP, "box(%s,", colorMenuItems[ObjPtr->color]);
  693. !    fprintf (FP, "%1d,%1d,%1d,%1d,%1d,%1d,%1d)", ObjPtr->obbox.ltx,
  694.            ObjPtr->obbox.lty, ObjPtr->obbox.rbx, ObjPtr->obbox.rby,
  695. !          ObjPtr->detail.b->fill, ObjPtr->detail.b->width, ObjPtr->detail.b->pen);
  696.   }
  697.   
  698. --- 342,351 ----
  699.   {
  700.      fprintf (FP, "box(%s,", colorMenuItems[ObjPtr->color]);
  701. !    fprintf (FP, "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,", ObjPtr->obbox.ltx,
  702.            ObjPtr->obbox.lty, ObjPtr->obbox.rbx, ObjPtr->obbox.rby,
  703. !          ObjPtr->detail.b->fill, ObjPtr->detail.b->width,
  704. !          ObjPtr->detail.b->pen, ObjPtr->id);
  705. !    SaveAttrs (FP, ObjPtr->lattr);
  706. !    fprintf (FP, ")");
  707.   }
  708.   
  709. ***************
  710. *** 366,373 ****
  711.            case 2: width = 6; break;
  712.         }
  713.      }
  714. !    else
  715.         sscanf (s, "%d , %d , %d , %d , %d , %d , %d",
  716.               <x, <y, &rbx, &rby, &fill, &width, &pen);
  717.   
  718.      box_ptr->fill = fill;
  719. --- 372,389 ----
  720.            case 2: width = 6; break;
  721.         }
  722. +       (*ObjPtr)->id = objId++;
  723.      }
  724. !    else if (fileVersion <= 7)
  725. !    {
  726.         sscanf (s, "%d , %d , %d , %d , %d , %d , %d",
  727.               <x, <y, &rbx, &rby, &fill, &width, &pen);
  728. +       (*ObjPtr)->id = objId++;
  729. +    }
  730. +    else
  731. +    {
  732. +       sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d",
  733. +             <x, <y, &rbx, &rby, &fill, &width, &pen, &((*ObjPtr)->id));
  734. +       if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1;
  735. +    }
  736.   
  737.      box_ptr->fill = fill;
  738. ***************
  739. *** 377,380 ****
  740. --- 393,397 ----
  741.      (*ObjPtr)->y = lty;
  742.      (*ObjPtr)->color = FindColorIndex (color_str);
  743. +    (*ObjPtr)->dirty = FALSE;
  744.      (*ObjPtr)->type = OBJ_BOX;
  745.      (*ObjPtr)->obbox.ltx = ltx;
  746. *** choice.c.orig    Fri Aug 17 13:45:45 1990
  747. --- choice.c    Fri Aug 17 13:45:46 1990
  748. ***************
  749. *** 6,10 ****
  750.   #ifndef lint
  751.   static char RCSid[] =
  752. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/choice.c,v 1.5 90/06/26 15:22:27 william Exp $";
  753.   #endif
  754.   
  755. --- 6,10 ----
  756.   #ifndef lint
  757.   static char RCSid[] =
  758. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/choice.c,v 1.6 90/08/15 16:01:40 william Exp $";
  759.   #endif
  760.   
  761. *** copypaste.c.orig    Fri Aug 17 13:45:49 1990
  762. --- copypaste.c    Fri Aug 17 13:45:51 1990
  763. ***************
  764. *** 0 ****
  765. --- 1,298 ----
  766. + /*
  767. +  * Author:    Kou1 Ma2da (matsuda@ccs.mt.nec.co.jp)
  768. +  * Modified By:    William Chia-Wei Cheng (william@cs.ucla.edu)
  769. +  *
  770. +  * Copyright (C) 1990, William Cheng.
  771. +  */
  772. + #ifndef lint
  773. + static char RCSid[] =
  774. +       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/copypaste.c,v 1.7 90/08/16 13:32:44 william Exp $";
  775. + #endif
  776. + #include <sys/types.h>
  777. + #include <sys/stat.h>
  778. + #include <stdio.h>
  779. + #include <X11/Xlib.h>
  780. + #include "const.h"
  781. + #include "types.h"
  782. + #include "choice.e"
  783. + #include "color.e"
  784. + #include "dup.e"
  785. + #include "file.e"
  786. + #include "font.e"
  787. + #include "obj.e"
  788. + #include "pattern.e"
  789. + #include "select.e"
  790. + #include "setup.e"
  791. + #include "special.e"
  792. + #include "text.e"
  793. + #define TGIF_HEADER 0x80
  794. + extern char * mktemp();
  795. + static char * cutBuffer = NULL;
  796. + void CopyToCutBuffer ()
  797. + {
  798. +    FILE                * fp;
  799. +    register struct SelRec     * sel_ptr;
  800. +    struct ObjRec        * obj_ptr, * top_obj, * bot_obj;
  801. +    char             * tmpfile, message[MAXSTRING];
  802. +    struct stat             stat;
  803. +    unsigned char         header = TGIF_HEADER;
  804. +    int level;
  805. +     
  806. +    if (topSel == NULL)
  807. +    {
  808. +       Msg ("No object selected for the COPY operation.");
  809. +       return;
  810. +    }
  811. +    tmpfile = mktemp ("/tmp/TgifXXXXXX");
  812. +    if ((fp = fopen (tmpfile, "w+")) == NULL)
  813. +    {
  814. +       sprintf (message, "Can not open %s.", tmpfile);
  815. +       Msg (message);
  816. +       return;
  817. +    }
  818. +    write (fileno(fp), &header, 1);
  819. +    top_obj = bot_obj = NULL;
  820. +    for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
  821. +    {
  822. +       obj_ptr = DupObj (sel_ptr->obj);
  823. +       obj_ptr->prev = NULL;
  824. +       obj_ptr->next = top_obj;
  825. +       if (top_obj == NULL)
  826. +          bot_obj = obj_ptr;
  827. +       else
  828. +          top_obj->prev = obj_ptr;
  829. +       top_obj = obj_ptr;
  830. +    }
  831. +    Save (fp, bot_obj, 0);
  832. +    fflush (fp);
  833. +    if (fstat (fileno(fp), &stat) < 0)
  834. +    {
  835. +       fclose (fp);
  836. +       unlink (tmpfile);
  837. +       sprintf (message, "FSTAT error in %s.  Copy aborted!", tmpfile);
  838. +       Msg (message);
  839. +       return;
  840. +    }
  841. +    if (cutBuffer != NULL) cfree (cutBuffer);
  842. +    cutBuffer = (char *) calloc (stat.st_size, sizeof(char));
  843. +    if (rewind (fp) < 0)
  844. +    {
  845. +       sprintf (message, "Error in rewinding %s.  Copy aborted!", tmpfile);
  846. +       Msg (message);
  847. +    }
  848. +    else if (read (fileno(fp), cutBuffer, stat.st_size) < stat.st_size)
  849. +    {
  850. +       sprintf (message, "READ error in %s.  Copy aborted!", tmpfile);
  851. +       Msg (message);
  852. +    }
  853. +    else
  854. +    {
  855. +       XStoreBytes (mainDisplay, cutBuffer, stat.st_size);
  856. +       Msg ("Copy buffer updated.");
  857. +    }
  858. +    fclose (fp);
  859. +    unlink (tmpfile);
  860. + }
  861. + static
  862. + void PasteString (CutBuffer)
  863. +    char    * CutBuffer;
  864. + {
  865. +    register char    * c_ptr, * dest_c_ptr;
  866. +    int            x, y, w, num_lines, char_count, max_len = 0;
  867. +    int            root_x, root_y, grid_x, grid_y;
  868. +    unsigned int        status;
  869. +    char            line[MAXSTRING], msg[MAXSTRING];
  870. +    struct StrRec    * first_str, * last_str, *str_ptr;
  871. +    struct ObjRec    * obj_ptr;
  872. +    struct TextRec    * text_ptr;
  873. +    Window        root_win, child_win;
  874. +    if (*CutBuffer == '\0') { Msg ("Cut buffer is empty"); return; }
  875. +    TieLooseEnds ();
  876. +    SetCurChoice (NOTHING);
  877. +    if (topSel != NULL) { HighLightReverse (); RemoveAllSel (); }
  878. +    Msg ("Paste from a non-tgif tool.");
  879. +    XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
  880. +          &root_x, &root_y, &x, &y, &status);
  881. +    GridXY (x, y, &grid_x, &grid_y);
  882. +    text_ptr = (struct TextRec *) calloc (1, sizeof(struct TextRec));
  883. +    text_ptr->font = curFont;
  884. +    text_ptr->dpi = curFontDPI;
  885. +    text_ptr->style = curStyle;
  886. +    text_ptr->attr = NULL;
  887. +    text_ptr->size = curSize;
  888. +    text_ptr->just = textJust;
  889. +    text_ptr->rotate = curRotate;
  890. +    text_ptr->pen = penPat;
  891. +    first_str = last_str = NULL;
  892. +    for (c_ptr = CutBuffer, num_lines = 0; *c_ptr != '\0'; num_lines++)
  893. +    {
  894. +       str_ptr = (struct StrRec *) calloc (1, sizeof(struct StrRec));
  895. +       char_count = 0;
  896. +       dest_c_ptr = str_ptr->s;
  897. +       while (*c_ptr != '\0' && *c_ptr != '\n' && *c_ptr != '\r')
  898. +       {
  899. +          *dest_c_ptr++ = *c_ptr++;
  900. +          if (++char_count == MAXSTRING)
  901. +          {
  902. +             sprintf (msg, "String length exceeds $1d.  String truncated.",
  903. +                   MAXSTRING);
  904. +             Msg (msg);
  905. +             while (*c_ptr != '\0' && *c_ptr != '\n' && *c_ptr != '\r') c_ptr++;
  906. +             break;
  907. +          }
  908. +       }
  909. +       *dest_c_ptr = '\0';
  910. +       str_ptr->prev = last_str;
  911. +       str_ptr->next = NULL;
  912. +       if (last_str == NULL)
  913. +          first_str = str_ptr;
  914. +       else
  915. +          last_str->next = str_ptr;
  916. +       last_str = str_ptr;
  917. +       w = XTextWidth (canvasFontPtr, str_ptr->s, strlen (str_ptr->s));
  918. +       if (w > max_len) max_len = w;
  919. +       if (*c_ptr == '\n' || *c_ptr == '\r') c_ptr++;
  920. +    }
  921. +    text_ptr->lines = num_lines;
  922. +    text_ptr->first = first_str;
  923. +    text_ptr->last = last_str;
  924. +    obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
  925. +    obj_ptr->x = grid_x;
  926. +    obj_ptr->y = grid_y;
  927. +    obj_ptr->type = OBJ_TEXT;
  928. +    obj_ptr->color = colorIndex;
  929. +    obj_ptr->id = objId++;;
  930. +    obj_ptr->dirty = FALSE;
  931. +    obj_ptr->detail.t = text_ptr;
  932. +    obj_ptr->fattr = obj_ptr->lattr = NULL;
  933. +    SetTextBBox (obj_ptr, textJust, max_len, num_lines*textCursorH, curRotate);
  934. +    AddObj (NULL, topObj, obj_ptr);
  935. +    AdjObjBBox (obj_ptr);
  936. +    PlaceTopObj ();
  937. +    if (topObj != NULL) SelectTopObj ();
  938. +    SetFileModified (TRUE);
  939. +    justDupped = FALSE;
  940. + }
  941. + void PasteFromCutBuffer ()
  942. + {
  943. +    FILE         * fp;
  944. +    int             len;
  945. +    register char     * d;
  946. +    char         * tmpfile, * cut_buffer, message[MAXSTRING];
  947. +    unsigned char     header = TGIF_HEADER;
  948. +    struct ObjRec    * obj_ptr, * saved_top_obj, * saved_bot_obj;
  949. +    cut_buffer = (char *) XFetchBytes (mainDisplay, &len);
  950. +    if (len == 0)
  951. +    {
  952. +       Msg ("Cut buffer is empty");
  953. +       return;
  954. +    }
  955. +    if (((unsigned char)(*cut_buffer)) != header)
  956. +    {
  957. +       PasteString (cut_buffer);
  958. +       return;
  959. +    }
  960. + #ifdef KANJI
  961. +       myPasteKanji (cut_buffer, len);
  962. + #endif
  963. +    cut_buffer++;
  964. +    len--;
  965. +    tmpfile = mktemp ("/tmp/TgifXXXXXX");
  966. +    if ((fp = fopen (tmpfile, "w+")) == NULL)
  967. +    {
  968. +       sprintf (message, "Can not open %s for write.", tmpfile);
  969. +       Msg (message);
  970. +       return;
  971. +    }
  972. +    if (write (fileno(fp), cut_buffer, len) < len)
  973. +    {
  974. +       fclose (fp);
  975. +       unlink (tmpfile);
  976. +       sprintf (message, "FWRITE error in writing to %s.  Paste aborted!",
  977. +             tmpfile);
  978. +       Msg (message);
  979. +       return;
  980. +    }
  981. +    fflush (fp);
  982. +    if (rewind (fp) < 0)
  983. +    {
  984. +       fclose (fp);
  985. +       unlink (tmpfile);
  986. +       sprintf (message, "Error in rewinding %s.  Paste aborted!", tmpfile);
  987. +       Msg (message);
  988. +       return;
  989. +    }
  990. +    TieLooseEnds ();
  991. +    SetCurChoice (NOTHING);
  992. +    saved_top_obj = topObj;
  993. +    saved_bot_obj = botObj;
  994. +    topObj = botObj = NULL;
  995. +     
  996. +    importingFile = TRUE;
  997. +    while (ReadObj (fp, &obj_ptr, FALSE))
  998. +       if (obj_ptr != NULL)
  999. +          AddObj (NULL, topObj, obj_ptr);
  1000. +     
  1001. +    fclose (fp);
  1002. +    importingFile = FALSE;
  1003. +    if (topObj != NULL) SetFileModified (TRUE);
  1004. +     
  1005. +    RedrawDrawWindow (botObj);
  1006. +    SelAllObj ();
  1007. +     
  1008. +    if (botObj != NULL)
  1009. +       botObj->next = saved_top_obj;
  1010. +    else
  1011. +       topObj = saved_top_obj;
  1012. +    if (saved_top_obj != NULL)
  1013. +    {
  1014. +       saved_top_obj->prev = botObj;
  1015. +       botObj = saved_bot_obj;
  1016. +    }
  1017. +    unlink (tmpfile);
  1018. +    Msg ("Objects pasted from tgif.");
  1019. + }        
  1020. + void CleanUpCutBuffer ()
  1021. + {
  1022. +    if (cutBuffer != NULL)
  1023. +    {
  1024. +       *cutBuffer = '\0';
  1025. +       cfree (cutBuffer);
  1026. +       cutBuffer = NULL;
  1027. +    }
  1028. + }
  1029. *** drawing.c.orig    Fri Aug 17 13:46:02 1990
  1030. --- drawing.c    Fri Aug 17 13:46:04 1990
  1031. ***************
  1032. *** 6,10 ****
  1033.   #ifndef lint
  1034.   static char RCSid[] =
  1035. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/drawing.c,v 1.8 90/07/29 15:34:38 william Exp $";
  1036.   #endif
  1037.   
  1038. --- 6,10 ----
  1039.   #ifndef lint
  1040.   static char RCSid[] =
  1041. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/drawing.c,v 1.11 90/08/16 09:34:54 william Exp $";
  1042.   #endif
  1043.   
  1044. ***************
  1045. *** 19,22 ****
  1046. --- 19,23 ----
  1047.   #include "box.e"
  1048.   #include "choice.e"
  1049. + #include "copypaste.e"
  1050.   #include "cursor.e"
  1051.   #include "dialog.e"
  1052. ***************
  1053. *** 143,152 ****
  1054.         case OBJ_POLY:
  1055.            DrawPolyObj (Win, drawOrigX, drawOrigY, ObjPtr); 
  1056. !          DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->detail.p->fattr);
  1057.            break;
  1058. !       case OBJ_BOX: DrawBoxObj (Win, drawOrigX, drawOrigY, ObjPtr); break;
  1059. !       case OBJ_OVAL: DrawOvalObj (Win, drawOrigX, drawOrigY, ObjPtr); break;
  1060.         case OBJ_TEXT: DrawTextObj (Win, drawOrigX, drawOrigY, ObjPtr); break;
  1061. !       case OBJ_POLYGON: DrawPolygonObj (Win, drawOrigX, drawOrigY, ObjPtr);
  1062.            break;
  1063.   
  1064. --- 144,161 ----
  1065.         case OBJ_POLY:
  1066.            DrawPolyObj (Win, drawOrigX, drawOrigY, ObjPtr); 
  1067. !          DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
  1068.            break;
  1069. !       case OBJ_BOX:
  1070. !          DrawBoxObj (Win, drawOrigX, drawOrigY, ObjPtr);
  1071. !          DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
  1072. !          break;
  1073. !       case OBJ_OVAL:
  1074. !          DrawOvalObj (Win, drawOrigX, drawOrigY, ObjPtr);
  1075. !          DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
  1076. !          break;
  1077.         case OBJ_TEXT: DrawTextObj (Win, drawOrigX, drawOrigY, ObjPtr); break;
  1078. !       case OBJ_POLYGON:
  1079. !          DrawPolygonObj (Win, drawOrigX, drawOrigY, ObjPtr);
  1080. !          DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
  1081.            break;
  1082.   
  1083. ***************
  1084. *** 158,164 ****
  1085.               if (BBoxIntersect (obj_ptr->bbox, drawWinBBox))
  1086.                  DrawObj (Win, obj_ptr);
  1087. !          if (ObjPtr->type == OBJ_ICON && ObjPtr->detail.r->dirty)
  1088.            {
  1089. !             attr_ptr = ObjPtr->detail.r->fattr;
  1090.               for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
  1091.                  UpdTextBBox (attr_ptr->obj);
  1092. --- 167,173 ----
  1093.               if (BBoxIntersect (obj_ptr->bbox, drawWinBBox))
  1094.                  DrawObj (Win, obj_ptr);
  1095. !          if (ObjPtr->type == OBJ_ICON && ObjPtr->dirty)
  1096.            {
  1097. !             attr_ptr = ObjPtr->fattr;
  1098.               for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
  1099.                  UpdTextBBox (attr_ptr->obj);
  1100. ***************
  1101. *** 165,171 ****
  1102.               AdjObjBBox (ObjPtr);
  1103.               UpdSelBBox ();
  1104. !             ObjPtr->detail.r->dirty = FALSE;
  1105.            }
  1106. !          DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->detail.r->fattr);
  1107.            if (ObjPtr->type == OBJ_SYM) DrawSymOutline (Win, drawOrigX, drawOrigY,
  1108.                  ObjPtr);
  1109. --- 174,180 ----
  1110.               AdjObjBBox (ObjPtr);
  1111.               UpdSelBBox ();
  1112. !             ObjPtr->dirty = FALSE;
  1113.            }
  1114. !          DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr);
  1115.            if (ObjPtr->type == OBJ_SYM) DrawSymOutline (Win, drawOrigX, drawOrigY,
  1116.                  ObjPtr);
  1117. ***************
  1118. *** 480,484 ****
  1119.               case '\027': /*^W*/ SetCurChoice (DRAWTEXT); break;
  1120.               case '\030': /*^X*/ DelAllSelObj (); break;
  1121. !             case '\031': /*^Y*/ break;
  1122.               case '\032': /*^Z*/ return (AnimateProc ()); break;
  1123.               case ',': /*^,*/ ScrollLeft (); break;
  1124. --- 489,493 ----
  1125.               case '\027': /*^W*/ SetCurChoice (DRAWTEXT); break;
  1126.               case '\030': /*^X*/ DelAllSelObj (); break;
  1127. !             case '\031': /*^Y*/ CopyToCutBuffer (); break;
  1128.               case '\032': /*^Z*/ return (AnimateProc ()); break;
  1129.               case ',': /*^,*/ ScrollLeft (); break;
  1130. ***************
  1131. *** 554,558 ****
  1132.               case '\027': /*^#W*/ ToggleAllSelLineType (); break;
  1133.               case '\030': /*^#X*/ break;
  1134. !             case '\031': /*^#Y*/ break;
  1135.               case '\032': /*^#Z*/ break;
  1136.            }
  1137. --- 563,567 ----
  1138.               case '\027': /*^#W*/ ToggleAllSelLineType (); break;
  1139.               case '\030': /*^#X*/ break;
  1140. !             case '\031': /*^#Y*/ PasteFromCutBuffer (); break;
  1141.               case '\032': /*^#Z*/ break;
  1142.            }
  1143. ***************
  1144. *** 569,573 ****
  1145.   
  1146.      for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->next)
  1147. !       if (obj_ptr->type == OBJ_ICON && obj_ptr->detail.r->dirty)
  1148.            return (TRUE);
  1149.      return (FALSE);
  1150. --- 578,582 ----
  1151.   
  1152.      for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->next)
  1153. !       if (obj_ptr->type == OBJ_ICON && obj_ptr->dirty)
  1154.            return (TRUE);
  1155.      return (FALSE);
  1156. *** dup.c.orig    Fri Aug 17 13:46:11 1990
  1157. --- dup.c    Fri Aug 17 13:46:12 1990
  1158. ***************
  1159. *** 6,10 ****
  1160.   #ifndef lint
  1161.   static char RCSid[] =
  1162. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/dup.c,v 1.3 90/07/08 00:29:43 william Exp $";
  1163.   #endif
  1164.   
  1165. --- 6,10 ----
  1166.   #ifndef lint
  1167.   static char RCSid[] =
  1168. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/dup.c,v 1.6 90/08/16 09:35:11 william Exp $";
  1169.   #endif
  1170.   
  1171. ***************
  1172. *** 20,23 ****
  1173. --- 20,25 ----
  1174.   #include "setup.e"
  1175.   
  1176. + extern struct ObjRec    * DupObj ();
  1177.   int    justDupped = FALSE;
  1178.   int    dupDx = INVALID, dupDy = INVALID;
  1179. ***************
  1180. *** 29,32 ****
  1181. --- 31,36 ----
  1182.      ToObjPtr->y = FromObjPtr->y;
  1183.      ToObjPtr->color = FromObjPtr->color;
  1184. +    ToObjPtr->id = objId++;
  1185. +    ToObjPtr->dirty = FALSE;
  1186.      ToObjPtr->type = FromObjPtr->type;
  1187.      ToObjPtr->bbox.ltx = FromObjPtr->bbox.ltx;
  1188. ***************
  1189. *** 62,66 ****
  1190.      poly_ptr->pen = PolyPtr->pen;
  1191.      poly_ptr->fill = PolyPtr->fill;
  1192. -    poly_ptr->id = objId++;
  1193.      if ((poly_ptr->curved = PolyPtr->curved) == LT_SPLINE)
  1194.      {
  1195. --- 66,69 ----
  1196. ***************
  1197. *** 173,176 ****
  1198. --- 176,180 ----
  1199.   
  1200.      text_ptr->font = TextPtr->font;
  1201. +    text_ptr->dpi = TextPtr->dpi;
  1202.      text_ptr->style = TextPtr->style;
  1203.      text_ptr->size = TextPtr->size;
  1204. ***************
  1205. *** 190,194 ****
  1206.      struct ObjRec        * top_obj, * bot_obj;
  1207.      struct ObjRec        * from_obj_ptr, * to_obj_ptr;
  1208. -    static struct ObjRec        * DupObj ();
  1209.   
  1210.      group_ptr = (struct GroupRec *) calloc (1, sizeof(struct GroupRec));
  1211. --- 194,197 ----
  1212. ***************
  1213. *** 211,215 ****
  1214.   }
  1215.   
  1216. - static
  1217.   struct ObjRec * DupObj (ObjPtr)
  1218.      struct ObjRec    * ObjPtr;
  1219. --- 214,217 ----
  1220. ***************
  1221. *** 226,233 ****
  1222.            DupAttrs (ObjPtr, obj_ptr);
  1223.            break;
  1224. !       case OBJ_BOX: DupBoxObj (ObjPtr->detail.b, obj_ptr); break;
  1225. !       case OBJ_OVAL: DupOvalObj (ObjPtr->detail.o, obj_ptr); break;
  1226.         case OBJ_TEXT: DupTextObj (ObjPtr->detail.t, obj_ptr); break;
  1227. !       case OBJ_POLYGON: DupPolygonObj (ObjPtr->detail.g, obj_ptr); break;
  1228.         case OBJ_SYM:
  1229.         case OBJ_GROUP:
  1230. --- 228,244 ----
  1231.            DupAttrs (ObjPtr, obj_ptr);
  1232.            break;
  1233. !       case OBJ_BOX:
  1234. !          DupBoxObj (ObjPtr->detail.b, obj_ptr);
  1235. !          DupAttrs (ObjPtr, obj_ptr);
  1236. !          break;
  1237. !       case OBJ_OVAL:
  1238. !          DupOvalObj (ObjPtr->detail.o, obj_ptr);
  1239. !          DupAttrs (ObjPtr, obj_ptr);
  1240. !          break;
  1241.         case OBJ_TEXT: DupTextObj (ObjPtr->detail.t, obj_ptr); break;
  1242. !       case OBJ_POLYGON:
  1243. !          DupPolygonObj (ObjPtr->detail.g, obj_ptr);
  1244. !          DupAttrs (ObjPtr, obj_ptr);
  1245. !          break;
  1246.         case OBJ_SYM:
  1247.         case OBJ_GROUP:
  1248. ***************
  1249. *** 234,242 ****
  1250.         case OBJ_ICON:
  1251.            DupGroupObj (ObjPtr->detail.r, obj_ptr);
  1252. -          if (ObjPtr->type == OBJ_ICON)
  1253. -          {
  1254. -             obj_ptr->detail.r->id = objId++;
  1255. -             obj_ptr->detail.r->dirty = FALSE;
  1256. -          }
  1257.            DupAttrs (ObjPtr, obj_ptr);
  1258.            if (obj_ptr->type == OBJ_ICON)
  1259. --- 245,248 ----
  1260. *** edit.c.orig    Fri Aug 17 13:46:32 1990
  1261. --- edit.c    Fri Aug 17 13:46:34 1990
  1262. ***************
  1263. *** 6,10 ****
  1264.   #ifndef lint
  1265.   static char RCSid[] =
  1266. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/edit.c,v 1.6 90/07/13 12:51:58 william Exp $";
  1267.   #endif
  1268.   
  1269. --- 6,10 ----
  1270.   #ifndef lint
  1271.   static char RCSid[] =
  1272. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/edit.c,v 1.9 90/08/16 09:35:06 william Exp $";
  1273.   #endif
  1274.   
  1275. ***************
  1276. *** 17,20 ****
  1277. --- 17,21 ----
  1278.   #include "align.e"
  1279.   #include "color.e"
  1280. + #include "copypaste.e"
  1281.   #include "cursor.e"
  1282.   #include "drawing.e"
  1283. ***************
  1284. *** 45,50 ****
  1285.   #define EDIT_DEL_POINT 5
  1286.   #define EDIT_ADD_POINT 6
  1287.   
  1288. ! #define MAXEDITMENUS 7
  1289.   
  1290.   static char * editMenuStr[] =
  1291. --- 46,53 ----
  1292.   #define EDIT_DEL_POINT 5
  1293.   #define EDIT_ADD_POINT 6
  1294. + #define EDIT_COPY 7
  1295. + #define EDIT_PASTE 8
  1296.   
  1297. ! #define MAXEDITMENUS 9
  1298.   
  1299.   static char * editMenuStr[] =
  1300. ***************
  1301. *** 55,59 ****
  1302.           "UndoDelete   #U",
  1303.           "DeletePoint ^#D",
  1304. !         "AddPoint    ^#A"
  1305.         };
  1306.   
  1307. --- 58,64 ----
  1308.           "UndoDelete   #U",
  1309.           "DeletePoint ^#D",
  1310. !         "AddPoint    ^#A",
  1311. !         "Copy         ^Y",
  1312. !         "Paste       ^#Y"
  1313.         };
  1314.   
  1315. ***************
  1316. *** 91,94 ****
  1317. --- 96,100 ----
  1318.      XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
  1319.            &root_x, &root_y, &old_x, &old_y, &status);
  1320. +    XSetFont (mainDisplay, revDefaultGC, defaultFontPtr->fid);
  1321.      XDrawString (mainDisplay, drawWindow, revDefaultGC,
  1322.            old_x+4, old_y+defaultFontAsc, "DEL", 3);
  1323. ***************
  1324. *** 613,616 ****
  1325. --- 619,623 ----
  1326.      XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
  1327.            &root_x, &root_y, &old_x, &old_y, &status);
  1328. +    XSetFont (mainDisplay, revDefaultGC, defaultFontPtr->fid);
  1329.      XDrawString (mainDisplay, drawWindow, revDefaultGC,
  1330.            old_x+4, old_y+defaultFontAsc, "ADD", 3);
  1331. ***************
  1332. *** 679,682 ****
  1333. --- 686,691 ----
  1334.         case EDIT_DEL_POINT: DeletePoint (); break;
  1335.         case EDIT_ADD_POINT: AddPoint (); break;
  1336. +       case EDIT_COPY: CopyToCutBuffer (); break;
  1337. +       case EDIT_PASTE: PasteFromCutBuffer (); break;
  1338.      }
  1339.   }
  1340. *** file.c.orig    Fri Aug 17 13:47:13 1990
  1341. --- file.c    Fri Aug 17 13:47:14 1990
  1342. ***************
  1343. *** 6,10 ****
  1344.   #ifndef lint
  1345.   static char RCSid[] =
  1346. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/file.c,v 1.28 90/07/30 16:08:30 william Exp $";
  1347.   #endif
  1348.   
  1349. --- 6,10 ----
  1350.   #ifndef lint
  1351.   static char RCSid[] =
  1352. !       "@(#)$Header: /n/kona/u/tangram/u/william/X11/TGIF/RCS/file.c,v 1.32 90/08/15 16:00:43 william Exp $";
  1353.   #endif
  1354.   
  1355. ***************
  1356. *** 46,50 ****
  1357.   #include "text.e"
  1358.   
  1359. ! #define CUR_VERSION 7
  1360.   
  1361.   char    curFileName[MAXPATHLENGTH];
  1362. --- 46,51 ----
  1363.   #include "text.e"
  1364.   
  1365. ! #define CUR_VERSION 8
  1366. ! #define START_HAVING_ATTRS 8
  1367.   
  1368.   char    curFileName[MAXPATHLENGTH];
  1369. ***************
  1370. *** 102,107 ****
  1371.         fprintf (FP, "%1d,%1d,%1d,", horiAlign, vertAlign, lineWidth);
  1372.         fprintf (FP, "%1d,%1d,%1d,%1d,", curSpline, lineStyle, objFill, penPat);
  1373. !       fprintf (FP, "%1d,%1d,%1d,%1d", textJust, curFont, curStyle, curSize);
  1374. !       fprintf (FP, ").\n");
  1375.      }
  1376.   
  1377. --- 103,108 ----
  1378.         fprintf (FP, "%1d,%1d,%1d,", horiAlign, vertAlign, lineWidth);
  1379.         fprintf (FP, "%1d,%1d,%1d,%1d,", curSpline, lineStyle, objFill, penPat);
  1380. !       fprintf (FP, "%1d,%1d,%1d,%1d,", textJust, curFont, curStyle, curSize);
  1381. !       fprintf (FP, "%1d).\n", curFontDPI);
  1382.      }
  1383.   
  1384. ***************
  1385. *** 374,378 ****
  1386.         sscanf (s, "%d", &fileVersion);
  1387.   
  1388. !    if (PRTGIF) return;
  1389.   
  1390.      if (!importingFile)
  1391. --- 375,383 ----
  1392.         sscanf (s, "%d", &fileVersion);
  1393.   
  1394. !    if (PRTGIF)
  1395. !    {
  1396. !       pageStyle = page_style;
  1397. !       return;
  1398. !    }
  1399.   
  1400.      if (!importingFile)
  1401. ***************
  1402. *** 396,401 ****
  1403.               else
  1404.                  curSpline = LT_STRAIGHT;
  1405.            }
  1406. !          else
  1407.            {
  1408.               sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \
  1409. --- 401,407 ----
  1410.               else
  1411.                  curSpline = LT_STRAIGHT;
  1412. +             curFontDPI = FONT_DPI_75;
  1413.            }
  1414. !          else if (fileVersion <= 7)
  1415.            {
  1416.               sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \
  1417. ***************
  1418. *** 405,409 ****
  1419. --- 411,425 ----
  1420.                     &lineStyle, &objFill, &penPat, &textJust, &curFont,
  1421.                     &curStyle, &curSize);
  1422. +             curFontDPI = FONT_DPI_75;
  1423.            }
  1424. +          else
  1425. +          {
  1426. +             sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \
  1427. +                   %d , %d , %d , %d , %d , %d , %d , %d , %d",
  1428. +                   &drawOrigX, &drawOrigY, &zoomScale, &xyGrid, &gridOn,
  1429. +                   &colorIndex, &horiAlign, &vertAlign, &lineWidth, &curSpline,
  1430. +                   &lineStyle, &objFill, &penPat, &textJust, &curFont,
  1431. +                   &curStyle, &curSize, &curFontDPI);
  1432. +          }
  1433.            if (colorIndex >= maxColors)
  1434.            {
  1435. ***************
  1436. *** 426,429 ****
  1437. --- 442,470 ----
  1438.   }
  1439.   
  1440. + void ReadObjAttrs (MinFileVersion, FP, ObjPtr, PRTGIF)
  1441. +    FILE            * FP;
  1442. +    struct ObjRec    * * ObjPtr;
  1443. +    int            PRTGIF;
  1444. + {
  1445. +    struct AttrRec    * top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  1446. +    if (fileVersion <= MinFileVersion) return;
  1447. +    while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1448. +    {
  1449. +       attr_ptr->owner = *ObjPtr;
  1450. +       attr_ptr->prev = NULL;
  1451. +       attr_ptr->next = top_attr;
  1452. +       if (top_attr == NULL)
  1453. +          bot_attr = attr_ptr;
  1454. +       else
  1455. +          top_attr->prev = attr_ptr;
  1456. +       top_attr = attr_ptr;
  1457. +    }
  1458. +    if (bot_attr != NULL) bot_attr->next = NULL;
  1459. +    (*ObjPtr)->fattr = top_attr;
  1460. +    (*ObjPtr)->lattr = bot_attr;
  1461. + }
  1462.   int ReadObj (FP, ObjPtr, PRTGIF)
  1463.      FILE            * FP;
  1464. ***************
  1465. *** 434,438 ****
  1466.      char            * line = NULL, * c_ptr, * s, * s1;
  1467.      int            len, id, cur_size, done = FALSE, allocated = FALSE;
  1468. -    struct AttrRec    * top_attr = NULL, * bot_attr = NULL, * attr_ptr;
  1469.   
  1470.      while (fgets (inbuf, MAXSTRING, FP) != NULL)
  1471. --- 475,478 ----
  1472. ***************
  1473. *** 482,500 ****
  1474.         {
  1475.            ReadPolyObj (line, ObjPtr);
  1476. !          if (fileVersion != INVALID)
  1477. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1478. !             {
  1479. !                attr_ptr->owner = *ObjPtr;
  1480. !                attr_ptr->prev = NULL;
  1481. !                attr_ptr->next = top_attr;
  1482. !                if (top_attr == NULL)
  1483. !                   bot_attr = attr_ptr;
  1484. !                else
  1485. !                   top_attr->prev = attr_ptr;
  1486. !                top_attr = attr_ptr;
  1487. !             }
  1488. !          if (bot_attr != NULL) bot_attr->next = NULL;
  1489. !          (*ObjPtr)->detail.p->fattr = top_attr;
  1490. !          (*ObjPtr)->detail.p->lattr = bot_attr;
  1491.            AdjObjBBox (*ObjPtr);
  1492.            if (allocated) cfree (line);
  1493. --- 522,526 ----
  1494.         {
  1495.            ReadPolyObj (line, ObjPtr);
  1496. !          ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
  1497.            AdjObjBBox (*ObjPtr);
  1498.            if (allocated) cfree (line);
  1499. ***************
  1500. *** 504,507 ****
  1501. --- 530,535 ----
  1502.         {
  1503.            ReadBoxObj (line, ObjPtr);
  1504. +          ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
  1505. +          AdjObjBBox (*ObjPtr);
  1506.            if (allocated) cfree (line);
  1507.            return (TRUE);
  1508. ***************
  1509. *** 510,513 ****
  1510. --- 538,543 ----
  1511.         {
  1512.            ReadOvalObj (line, ObjPtr);
  1513. +          ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
  1514. +          AdjObjBBox (*ObjPtr);
  1515.            if (allocated) cfree (line);
  1516.            return (TRUE);
  1517. ***************
  1518. *** 522,525 ****
  1519. --- 552,557 ----
  1520.         {
  1521.            ReadPolygonObj (line, ObjPtr);
  1522. +          ReadObjAttrs (START_HAVING_ATTRS-1, FP, ObjPtr, PRTGIF);
  1523. +          AdjObjBBox (*ObjPtr);
  1524.            if (allocated) cfree (line);
  1525.            return (TRUE);
  1526. ***************
  1527. *** 528,546 ****
  1528.         {
  1529.            ReadGroupObj (FP, ObjPtr, PRTGIF);
  1530. !          if (fileVersion != INVALID)
  1531. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1532. !             {
  1533. !                attr_ptr->owner = *ObjPtr;
  1534. !                attr_ptr->prev = NULL;
  1535. !                attr_ptr->next = top_attr;
  1536. !                if (top_attr == NULL)
  1537. !                   bot_attr = attr_ptr;
  1538. !                else
  1539. !                   top_attr->prev = attr_ptr;
  1540. !                top_attr = attr_ptr;
  1541. !             }
  1542. !          if (bot_attr != NULL) bot_attr->next = NULL;
  1543. !          (*ObjPtr)->detail.r->fattr = top_attr;
  1544. !          (*ObjPtr)->detail.r->lattr = bot_attr;
  1545.            AdjObjBBox (*ObjPtr);
  1546.            if (allocated) cfree (line);
  1547. --- 560,564 ----
  1548.         {
  1549.            ReadGroupObj (FP, ObjPtr, PRTGIF);
  1550. !          ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
  1551.            AdjObjBBox (*ObjPtr);
  1552.            if (allocated) cfree (line);
  1553. ***************
  1554. *** 551,569 ****
  1555.            ReadGroupObj (FP, ObjPtr, PRTGIF);
  1556.            (*ObjPtr)->type = OBJ_SYM;
  1557. !          if (fileVersion != INVALID)
  1558. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1559. !             {
  1560. !                attr_ptr->owner = *ObjPtr;
  1561. !                attr_ptr->prev = NULL;
  1562. !                attr_ptr->next = top_attr;
  1563. !                if (top_attr == NULL)
  1564. !                   bot_attr = attr_ptr;
  1565. !                else
  1566. !                   top_attr->prev = attr_ptr;
  1567. !                top_attr = attr_ptr;
  1568. !             }
  1569. !          if (bot_attr != NULL) bot_attr->next = NULL;
  1570. !          (*ObjPtr)->detail.r->fattr = top_attr;
  1571. !          (*ObjPtr)->detail.r->lattr = bot_attr;
  1572.            AdjObjBBox (*ObjPtr);
  1573.            if (allocated) cfree (line);
  1574. --- 569,573 ----
  1575.            ReadGroupObj (FP, ObjPtr, PRTGIF);
  1576.            (*ObjPtr)->type = OBJ_SYM;
  1577. !          ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
  1578.            AdjObjBBox (*ObjPtr);
  1579.            if (allocated) cfree (line);
  1580. ***************
  1581. *** 587,610 ****
  1582.               sscanf (s1, "%d", &id);
  1583.               if (id >= objId) objId = id+1;
  1584. !             (*ObjPtr)->detail.r->id = id;
  1585.            }
  1586. !          (*ObjPtr)->detail.r->dirty = FALSE;
  1587.            *(--s) = '\0';
  1588.            strcpy ((*ObjPtr)->detail.r->s, tmp_str);
  1589. !          if (fileVersion != INVALID)
  1590. !             while (ReadAttr (FP, &attr_ptr, PRTGIF))
  1591. !             {
  1592. !                attr_ptr->owner = *ObjPtr;
  1593. !                attr_ptr->prev = NULL;
  1594. !                attr_ptr->next = top_attr;
  1595. !                if (top_attr == NULL)
  1596. !                   bot_attr = attr_ptr;
  1597. !                else
  1598. !                   top_attr->prev = attr_ptr;
  1599. !                top_attr = attr_ptr;
  1600. !             }
  1601. !          if (bot_attr != NULL) bot_attr->next = NULL;
  1602. !          (*ObjPtr)->detail.r->fattr = top_attr;
  1603. !          (*ObjPtr)->detail.r->lattr = bot_attr;
  1604.            AdjObjBBox (*ObjPtr);
  1605.            if (allocated) cfree (line);
  1606. --- 591,600 ----
  1607.               sscanf (s1, "%d", &id);
  1608.               if (id >= objId) objId = id+1;
  1609. !             (*ObjPtr)->id = id;
  1610.            }
  1611. !          (*ObjPtr)->dirty = FALSE;
  1612.            *(--s) = '\0';
  1613.            strcpy ((*ObjPtr)->detail.r->s, tmp_str);
  1614. !          ReadObjAttrs (INVALID, FP, ObjPtr, PRTGIF);
  1615.            AdjObjBBox (*ObjPtr);
  1616.            if (allocated) cfree (line);
  1617. ***************
  1618. *** 820,829 ****
  1619.         case OBJ_POLY:
  1620.            DumpPolyObj (FP, ObjPtr);
  1621. !          DumpAttrs (FP, ObjPtr->detail.p->lattr, PRTGIF);
  1622.            break;
  1623. !       case OBJ_BOX: DumpBoxObj (FP, ObjPtr); break;
  1624. !       case OBJ_OVAL: DumpOvalObj (FP, ObjPtr); break;
  1625.         case OBJ_TEXT: DumpTextObj (FP, ObjPtr, PRTGIF); break;
  1626. !       case OBJ_POLYGON: DumpPolygonObj (FP, ObjPtr); break;
  1627.         case OBJ_SYM:
  1628.         case OBJ_ICON:
  1629. --- 810,828 ----
  1630.         case OBJ_POLY:
  1631.            DumpPolyObj (FP, ObjPtr);
  1632. !          DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
  1633.            break;
  1634. !       case OBJ_BOX:
  1635. !          DumpBoxObj (FP, ObjPtr);
  1636. !          DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
  1637. !          break;
  1638. !       case OBJ_OVAL:
  1639. !          DumpOvalObj (FP, ObjPtr);
  1640. !          DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
  1641. !          break;
  1642.         case OBJ_TEXT: DumpTextObj (FP, ObjPtr, PRTGIF); break;
  1643. !       case OBJ_POLYGON:
  1644. !          DumpPolygonObj (FP, ObjPtr);
  1645. !          DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
  1646. !          break;
  1647.         case OBJ_SYM:
  1648.         case OBJ_ICON:
  1649. ***************
  1650. *** 832,836 ****
  1651.            for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
  1652.               DumpAllObj (FP, obj_ptr, PRTGIF);
  1653. !          DumpAttrs (FP, ObjPtr->detail.r->lattr, PRTGIF);
  1654.            if (ObjPtr->type == OBJ_SYM) DumpSymOutline (FP, ObjPtr);
  1655.            break;
  1656. --- 831,835 ----
  1657.            for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev)
  1658.               DumpAllObj (FP, obj_ptr, PRTGIF);
  1659. !          DumpAttrs (FP, ObjPtr->lattr, PRTGIF);
  1660.            if (ObjPtr->type == OBJ_SYM) DumpSymOutline (FP, ObjPtr);
  1661.            break;
  1662. ---------------------------------> cut here <---------------------------------
  1663. --
  1664. Bill Cheng // UCLA Computer Science Department // (213) 206-7135
  1665. 3277 Boelter Hall // Los Angeles, California 90024 // USA
  1666. william@CS.UCLA.EDU      ...!{uunet|ucbvax}!cs.ucla.edu!william
  1667.  
  1668. dan
  1669. ----------------------------------------------------
  1670. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1671. Opinions expressed reflect those of the author only.
  1672.