Fossil

Check-in [7c28d11d]
Login

Check-in [7c28d11d]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:New pikchr.c file that fixes alignment of chopped lines.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 7c28d11d9ad2dc13a3b291a04972923bcd5f4a6a75af0caa4f7bc9c5249143c8
User & Date: drh 2020-09-16 19:01:04
Context
2020-09-16
20:49
In pikchr: fix minor details on drawing filled "file" objects and the "fit" operator on "cylinder" objects. ... (check-in: db02f9b8 user: drh tags: trunk)
19:01
New pikchr.c file that fixes alignment of chopped lines. ... (check-in: 7c28d11d user: drh tags: trunk)
15:30
Bug fixes in the pikchr.c tokenizer. ... (check-in: 36765403 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pikchr.c.

122
123
124
125
126
127
128




129
130
131
132
133
134
135
#include <ctype.h>
#include <math.h>
#include <assert.h>
#define count(X) (sizeof(X)/sizeof(X[0]))
#ifndef M_PI
# define M_PI 3.1415926535897932385
#endif





typedef struct Pik Pik;          /* Complete parsing context */
typedef struct PToken PToken;    /* A single token */
typedef struct PElem PElem;      /* A single diagram object or "element" */
typedef struct PEList PEList;    /* A list of elements */
typedef struct PClass PClass;    /* Description of elements types */
typedef double PNum;             /* Numeric value */







>
>
>
>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <ctype.h>
#include <math.h>
#include <assert.h>
#define count(X) (sizeof(X)/sizeof(X[0]))
#ifndef M_PI
# define M_PI 3.1415926535897932385
#endif

/* Tag intentionally unused parameters with this macro to prevent
** compiler warnings with -Wextra */
#define UNUSED_PARAMETER(X)  (void)(X)

typedef struct Pik Pik;          /* Complete parsing context */
typedef struct PToken PToken;    /* A single token */
typedef struct PElem PElem;      /* A single diagram object or "element" */
typedef struct PEList PEList;    /* A list of elements */
typedef struct PClass PClass;    /* Description of elements types */
typedef double PNum;             /* Numeric value */
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
static void pik_append_xy(Pik*,const char*,PNum,PNum);
static void pik_append_dis(Pik*,const char*,PNum,const char*);
static void pik_append_arc(Pik*,PNum,PNum,PNum,PNum);
static void pik_append_clr(Pik*,const char*,PNum,const char*);
static void pik_append_style(Pik*,PElem*);
static void pik_append_txt(Pik*,PElem*, PBox*);
static void pik_draw_arrowhead(Pik*,PPoint*pFrom,PPoint*pTo,PElem*);
static void pik_chop(Pik*,PPoint*pFrom,PPoint*pTo,PNum);
static void pik_error(Pik*,PToken*,const char*);
static void pik_elist_free(Pik*,PEList*);
static void pik_elem_free(Pik*,PElem*);
static void pik_render(Pik*,PEList*);
static PEList *pik_elist_append(Pik*,PEList*,PElem*);
static PElem *pik_elem_new(Pik*,PToken*,PToken*,PEList*);
static void pik_set_direction(Pik*,int);
static void pik_elem_setname(Pik*,PElem*,PToken*);
static void pik_set_var(Pik*,PToken*,PNum,PToken*);
static PNum pik_value(Pik*,const char*,int,int*);
static PNum pik_lookup_color(Pik*,PToken*);
static PNum pik_get_var(Pik*,PToken*);
static PNum pik_atof(Pik*,PToken*);
static void pik_after_adding_attributes(Pik*,PElem*);
static void pik_elem_move(PElem*,PNum dx, PNum dy);
static void pik_elist_move(PEList*,PNum dx, PNum dy);
static void pik_set_numprop(Pik*,PToken*,PRel*);
static void pik_set_clrprop(Pik*,PToken*,PNum);
static void pik_set_dashed(Pik*,PToken*,PNum*);
static void pik_then(Pik*,PToken*,PElem*);







|












|







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
static void pik_append_xy(Pik*,const char*,PNum,PNum);
static void pik_append_dis(Pik*,const char*,PNum,const char*);
static void pik_append_arc(Pik*,PNum,PNum,PNum,PNum);
static void pik_append_clr(Pik*,const char*,PNum,const char*);
static void pik_append_style(Pik*,PElem*);
static void pik_append_txt(Pik*,PElem*, PBox*);
static void pik_draw_arrowhead(Pik*,PPoint*pFrom,PPoint*pTo,PElem*);
static void pik_chop(PPoint*pFrom,PPoint*pTo,PNum);
static void pik_error(Pik*,PToken*,const char*);
static void pik_elist_free(Pik*,PEList*);
static void pik_elem_free(Pik*,PElem*);
static void pik_render(Pik*,PEList*);
static PEList *pik_elist_append(Pik*,PEList*,PElem*);
static PElem *pik_elem_new(Pik*,PToken*,PToken*,PEList*);
static void pik_set_direction(Pik*,int);
static void pik_elem_setname(Pik*,PElem*,PToken*);
static void pik_set_var(Pik*,PToken*,PNum,PToken*);
static PNum pik_value(Pik*,const char*,int,int*);
static PNum pik_lookup_color(Pik*,PToken*);
static PNum pik_get_var(Pik*,PToken*);
static PNum pik_atof(PToken*);
static void pik_after_adding_attributes(Pik*,PElem*);
static void pik_elem_move(PElem*,PNum dx, PNum dy);
static void pik_elist_move(PEList*,PNum dx, PNum dy);
static void pik_set_numprop(Pik*,PToken*,PRel*);
static void pik_set_clrprop(Pik*,PToken*,PNum);
static void pik_set_dashed(Pik*,PToken*,PNum*);
static void pik_then(Pik*,PToken*,PElem*);
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
static void pik_bbox_init(PBox*);
static void pik_bbox_addbox(PBox*,PBox*);
static void pik_bbox_add_xy(PBox*,PNum,PNum);
static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
static void pik_add_txt(Pik*,PToken*,int);
static int pik_text_length(const PToken *pToken);
static void pik_size_to_fit(Pik*,PToken*);
static int pik_text_position(Pik*,int,PToken*);
static PNum pik_property_of(Pik*,PElem*,PToken*);
static PNum pik_func(Pik*,PToken*,PNum,PNum);
static PPoint pik_position_between(Pik *p, PNum x, PPoint p1, PPoint p2);
static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt);
static PPoint pik_position_at_hdg(Pik *p, PNum dist, PToken *pD, PPoint pt);
static void pik_same(Pik *p, PElem*, PToken*);
static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pElem);
static PToken pik_next_semantic_token(Pik *p, PToken *pThis);
static void pik_compute_layout_settings(Pik*);
static void pik_behind(Pik*,PElem*);
static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
static PElem *pik_place_assert(Pik*,PPoint*,PToken*,PPoint*);


#line 483 "pikchr.c"
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols.
***************** Begin token definitions *************************************/
#ifndef T_ID
#define T_ID                              1
#define T_EDGEPT                          2
#define T_OF                              3







|
|

|
|
|


|






|







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
static void pik_bbox_init(PBox*);
static void pik_bbox_addbox(PBox*,PBox*);
static void pik_bbox_add_xy(PBox*,PNum,PNum);
static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
static void pik_add_txt(Pik*,PToken*,int);
static int pik_text_length(const PToken *pToken);
static void pik_size_to_fit(Pik*,PToken*);
static int pik_text_position(int,PToken*);
static PNum pik_property_of(PElem*,PToken*);
static PNum pik_func(Pik*,PToken*,PNum,PNum);
static PPoint pik_position_between(PNum x, PPoint p1, PPoint p2);
static PPoint pik_position_at_angle(PNum dist, PNum r, PPoint pt);
static PPoint pik_position_at_hdg(PNum dist, PToken *pD, PPoint pt);
static void pik_same(Pik *p, PElem*, PToken*);
static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pElem);
static PToken pik_next_semantic_token(PToken *pThis);
static void pik_compute_layout_settings(Pik*);
static void pik_behind(Pik*,PElem*);
static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
static PElem *pik_place_assert(Pik*,PPoint*,PToken*,PPoint*);


#line 487 "pikchr.c"
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols.
***************** Begin token definitions *************************************/
#ifndef T_ID
#define T_ID                              1
#define T_EDGEPT                          2
#define T_OF                              3
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
    ** Note: during a reduce, the only symbols destroyed are those
    ** which appear on the RHS of the rule, but which are *not* used
    ** inside the C code.
    */
/********* Begin destructor definitions ***************************************/
    case 94: /* element_list */
{
#line 472 "pikchr.y"
pik_elist_free(p,(yypminor->yy72));
#line 1660 "pikchr.c"
}
      break;
    case 95: /* element */
    case 96: /* unnamed_element */
    case 97: /* basetype */
{
#line 474 "pikchr.y"
pik_elem_free(p,(yypminor->yy254));
#line 1669 "pikchr.c"
}
      break;
/********* End destructor definitions *****************************************/
    default:  break;   /* If no destructor action specified: do nothing */
  }
}








|

|






|

|







1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
    ** Note: during a reduce, the only symbols destroyed are those
    ** which appear on the RHS of the rule, but which are *not* used
    ** inside the C code.
    */
/********* Begin destructor definitions ***************************************/
    case 94: /* element_list */
{
#line 476 "pikchr.y"
pik_elist_free(p,(yypminor->yy72));
#line 1664 "pikchr.c"
}
      break;
    case 95: /* element */
    case 96: /* unnamed_element */
    case 97: /* basetype */
{
#line 478 "pikchr.y"
pik_elem_free(p,(yypminor->yy254));
#line 1673 "pikchr.c"
}
      break;
/********* End destructor definitions *****************************************/
    default:  break;   /* If no destructor action specified: do nothing */
  }
}

1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
#endif /* NDEBUG */
          return yy_action[j];
        }
      }
#endif /* YYWILDCARD */
      return yy_default[stateno];
    }else{
      assert( i>=0 && i<sizeof(yy_action)/sizeof(yy_action[0]) );
      return yy_action[i];
    }
  }while(1);
}

/*
** Find the appropriate action for a parser given the non-terminal







|







1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
#endif /* NDEBUG */
          return yy_action[j];
        }
      }
#endif /* YYWILDCARD */
      return yy_default[stateno];
    }else{
      assert( i>=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) );
      return yy_action[i];
    }
  }while(1);
}

/*
** Find the appropriate action for a parser given the non-terminal
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
     fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
   }
#endif
   while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
   /* Here code is inserted which will execute if the parser
   ** stack every overflows */
/******** Begin %stack_overflow code ******************************************/
#line 505 "pikchr.y"

  pik_error(p, 0, "parser stack overflow");
#line 1890 "pikchr.c"
/******** End %stack_overflow code ********************************************/
   pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
   pik_parserCTX_STORE
}

/*
** Print tracing information for a SHIFT action







|


|







1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
     fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
   }
#endif
   while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
   /* Here code is inserted which will execute if the parser
   ** stack every overflows */
/******** Begin %stack_overflow code ******************************************/
#line 510 "pikchr.y"

  pik_error(p, 0, "parser stack overflow");
#line 1894 "pikchr.c"
/******** End %stack_overflow code ********************************************/
   pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
   pik_parserCTX_STORE
}

/*
** Print tracing information for a SHIFT action
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
  **     { ... }           // User supplied code
  **  #line <lineno> <thisfile>
  **     break;
  */
/********** Begin reduce actions **********************************************/
        YYMINORTYPE yylhsminor;
      case 0: /* document ::= element_list */
#line 509 "pikchr.y"
{pik_render(p,yymsp[0].minor.yy72);}
#line 2361 "pikchr.c"
        break;
      case 1: /* element_list ::= element */
#line 512 "pikchr.y"
{ yylhsminor.yy72 = pik_elist_append(p,0,yymsp[0].minor.yy254); }
#line 2366 "pikchr.c"
  yymsp[0].minor.yy72 = yylhsminor.yy72;
        break;
      case 2: /* element_list ::= element_list EOL element */
#line 514 "pikchr.y"
{ yylhsminor.yy72 = pik_elist_append(p,yymsp[-2].minor.yy72,yymsp[0].minor.yy254); }
#line 2372 "pikchr.c"
  yymsp[-2].minor.yy72 = yylhsminor.yy72;
        break;
      case 3: /* element ::= */
#line 517 "pikchr.y"
{ yymsp[1].minor.yy254 = 0; }
#line 2378 "pikchr.c"
        break;
      case 4: /* element ::= direction */
#line 518 "pikchr.y"
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode);  yylhsminor.yy254=0; }
#line 2383 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 5: /* element ::= lvalue ASSIGN rvalue */
#line 519 "pikchr.y"
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy73,&yymsp[-1].minor.yy0); yylhsminor.yy254=0;}
#line 2389 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 6: /* element ::= PLACENAME COLON unnamed_element */
#line 521 "pikchr.y"
{ yylhsminor.yy254 = yymsp[0].minor.yy254;  pik_elem_setname(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0); }
#line 2395 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 7: /* element ::= PLACENAME COLON position */
#line 523 "pikchr.y"
{ yylhsminor.yy254 = pik_elem_new(p,0,0,0);
                 if(yylhsminor.yy254){ yylhsminor.yy254->ptAt = yymsp[0].minor.yy139; pik_elem_setname(p,yylhsminor.yy254,&yymsp[-2].minor.yy0); }}
#line 2402 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 8: /* element ::= unnamed_element */
#line 525 "pikchr.y"
{yylhsminor.yy254 = yymsp[0].minor.yy254;}
#line 2408 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 9: /* element ::= print prlist */
#line 526 "pikchr.y"
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy254=0;}
#line 2414 "pikchr.c"
        break;
      case 10: /* element ::= ASSERT LP expr EQ expr RP */
#line 531 "pikchr.y"
{yymsp[-5].minor.yy254=pik_assert(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy73);}
#line 2419 "pikchr.c"
        break;
      case 11: /* element ::= ASSERT LP place EQ place RP */
#line 533 "pikchr.y"
{yymsp[-5].minor.yy254=pik_place_assert(p,&yymsp[-3].minor.yy139,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy139);}
#line 2424 "pikchr.c"
        break;
      case 12: /* rvalue ::= PLACENAME */
#line 544 "pikchr.y"
{yylhsminor.yy73 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
#line 2429 "pikchr.c"
  yymsp[0].minor.yy73 = yylhsminor.yy73;
        break;
      case 13: /* pritem ::= FILL */
      case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
      case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
#line 549 "pikchr.y"
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
#line 2437 "pikchr.c"
        break;
      case 16: /* pritem ::= rvalue */
#line 552 "pikchr.y"
{pik_append_num(p,"",yymsp[0].minor.yy73);}
#line 2442 "pikchr.c"
        break;
      case 17: /* pritem ::= STRING */
#line 553 "pikchr.y"
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
#line 2447 "pikchr.c"
        break;
      case 18: /* prsep ::= COMMA */
#line 554 "pikchr.y"
{pik_append(p, " ", 1);}
#line 2452 "pikchr.c"
        break;
      case 19: /* unnamed_element ::= basetype attribute_list */
#line 557 "pikchr.y"
{yylhsminor.yy254 = yymsp[-1].minor.yy254; pik_after_adding_attributes(p,yylhsminor.yy254);}
#line 2457 "pikchr.c"
  yymsp[-1].minor.yy254 = yylhsminor.yy254;
        break;
      case 20: /* basetype ::= CLASSNAME */
#line 559 "pikchr.y"
{yylhsminor.yy254 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
#line 2463 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 21: /* basetype ::= STRING textposition */
#line 561 "pikchr.y"
{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy74; yylhsminor.yy254 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
#line 2469 "pikchr.c"
  yymsp[-1].minor.yy254 = yylhsminor.yy254;
        break;
      case 22: /* basetype ::= LB savelist element_list RB */
#line 563 "pikchr.y"
{ p->list = yymsp[-2].minor.yy72; yymsp[-3].minor.yy254 = pik_elem_new(p,0,0,yymsp[-1].minor.yy72); if(yymsp[-3].minor.yy254) yymsp[-3].minor.yy254->errTok = yymsp[0].minor.yy0; }
#line 2475 "pikchr.c"
        break;
      case 23: /* savelist ::= */
#line 568 "pikchr.y"
{yymsp[1].minor.yy72 = p->list; p->list = 0;}
#line 2480 "pikchr.c"
        break;
      case 24: /* relexpr ::= expr */
#line 575 "pikchr.y"
{yylhsminor.yy60.rAbs = yymsp[0].minor.yy73; yylhsminor.yy60.rRel = 0;}
#line 2485 "pikchr.c"
  yymsp[0].minor.yy60 = yylhsminor.yy60;
        break;
      case 25: /* relexpr ::= expr PERCENT */
#line 576 "pikchr.y"
{yylhsminor.yy60.rAbs = 0; yylhsminor.yy60.rRel = yymsp[-1].minor.yy73/100;}
#line 2491 "pikchr.c"
  yymsp[-1].minor.yy60 = yylhsminor.yy60;
        break;
      case 26: /* optrelexpr ::= */
#line 578 "pikchr.y"
{yymsp[1].minor.yy60.rAbs = 0; yymsp[1].minor.yy60.rRel = 1.0;}
#line 2497 "pikchr.c"
        break;
      case 27: /* attribute_list ::= relexpr alist */
#line 580 "pikchr.y"
{pik_add_direction(p,0,&yymsp[-1].minor.yy60);}
#line 2502 "pikchr.c"
        break;
      case 28: /* attribute ::= numproperty relexpr */
#line 584 "pikchr.y"
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60); }
#line 2507 "pikchr.c"
        break;
      case 29: /* attribute ::= dashproperty expr */
#line 585 "pikchr.y"
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy73); }
#line 2512 "pikchr.c"
        break;
      case 30: /* attribute ::= dashproperty */
#line 586 "pikchr.y"
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0);  }
#line 2517 "pikchr.c"
        break;
      case 31: /* attribute ::= colorproperty rvalue */
#line 587 "pikchr.y"
{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73); }
#line 2522 "pikchr.c"
        break;
      case 32: /* attribute ::= go direction optrelexpr */
#line 588 "pikchr.y"
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60);}
#line 2527 "pikchr.c"
        break;
      case 33: /* attribute ::= go direction even position */
#line 589 "pikchr.y"
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139);}
#line 2532 "pikchr.c"
        break;
      case 34: /* attribute ::= CLOSE */
#line 590 "pikchr.y"
{ pik_close_path(p,&yymsp[0].minor.yy0); }
#line 2537 "pikchr.c"
        break;
      case 35: /* attribute ::= CHOP */
#line 591 "pikchr.y"
{ p->cur->bChop = 1; }
#line 2542 "pikchr.c"
        break;
      case 36: /* attribute ::= FROM position */
#line 592 "pikchr.y"
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
#line 2547 "pikchr.c"
        break;
      case 37: /* attribute ::= TO position */
#line 593 "pikchr.y"
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
#line 2552 "pikchr.c"
        break;
      case 38: /* attribute ::= THEN */
#line 594 "pikchr.y"
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
#line 2557 "pikchr.c"
        break;
      case 39: /* attribute ::= THEN optrelexpr HEADING expr */
      case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
#line 596 "pikchr.y"
{pik_move_hdg(p,&yymsp[-2].minor.yy60,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73,0,&yymsp[-3].minor.yy0);}
#line 2563 "pikchr.c"
        break;
      case 40: /* attribute ::= THEN optrelexpr EDGEPT */
      case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
#line 597 "pikchr.y"
{pik_move_hdg(p,&yymsp[-1].minor.yy60,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
#line 2569 "pikchr.c"
        break;
      case 43: /* attribute ::= AT position */
#line 602 "pikchr.y"
{ pik_set_at(p,0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
#line 2574 "pikchr.c"
        break;
      case 44: /* attribute ::= SAME */
#line 604 "pikchr.y"
{pik_same(p,0,&yymsp[0].minor.yy0);}
#line 2579 "pikchr.c"
        break;
      case 45: /* attribute ::= SAME AS object */
#line 605 "pikchr.y"
{pik_same(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
#line 2584 "pikchr.c"
        break;
      case 46: /* attribute ::= STRING textposition */
#line 606 "pikchr.y"
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy74);}
#line 2589 "pikchr.c"
        break;
      case 47: /* attribute ::= FIT */
#line 607 "pikchr.y"
{pik_size_to_fit(p,&yymsp[0].minor.yy0); }
#line 2594 "pikchr.c"
        break;
      case 48: /* attribute ::= BEHIND object */
#line 608 "pikchr.y"
{pik_behind(p,yymsp[0].minor.yy254);}
#line 2599 "pikchr.c"
        break;
      case 49: /* withclause ::= DOT_E edge AT position */
      case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
#line 616 "pikchr.y"
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
#line 2605 "pikchr.c"
        break;
      case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
#line 620 "pikchr.y"
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
#line 2610 "pikchr.c"
  yymsp[0].minor.yy0 = yylhsminor.yy0;
        break;
      case 52: /* boolproperty ::= CW */
#line 631 "pikchr.y"
{p->cur->cw = 1;}
#line 2616 "pikchr.c"
        break;
      case 53: /* boolproperty ::= CCW */
#line 632 "pikchr.y"
{p->cur->cw = 0;}
#line 2621 "pikchr.c"
        break;
      case 54: /* boolproperty ::= LARROW */
#line 633 "pikchr.y"
{p->cur->larrow=1; p->cur->rarrow=0; }
#line 2626 "pikchr.c"
        break;
      case 55: /* boolproperty ::= RARROW */
#line 634 "pikchr.y"
{p->cur->larrow=0; p->cur->rarrow=1; }
#line 2631 "pikchr.c"
        break;
      case 56: /* boolproperty ::= LRARROW */
#line 635 "pikchr.y"
{p->cur->larrow=1; p->cur->rarrow=1; }
#line 2636 "pikchr.c"
        break;
      case 57: /* boolproperty ::= INVIS */
#line 636 "pikchr.y"
{p->cur->sw = 0.0;}
#line 2641 "pikchr.c"
        break;
      case 58: /* boolproperty ::= THICK */
#line 637 "pikchr.y"
{p->cur->sw *= 1.5;}
#line 2646 "pikchr.c"
        break;
      case 59: /* boolproperty ::= THIN */
#line 638 "pikchr.y"
{p->cur->sw *= 0.67;}
#line 2651 "pikchr.c"
        break;
      case 60: /* textposition ::= */
#line 640 "pikchr.y"
{yymsp[1].minor.yy74 = 0;}
#line 2656 "pikchr.c"
        break;
      case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
#line 643 "pikchr.y"
{yylhsminor.yy74 = pik_text_position(p,yymsp[-1].minor.yy74,&yymsp[0].minor.yy0);}
#line 2661 "pikchr.c"
  yymsp[-1].minor.yy74 = yylhsminor.yy74;
        break;
      case 62: /* position ::= expr COMMA expr */
#line 646 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[0].minor.yy73;}
#line 2667 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 63: /* position ::= place PLUS expr COMMA expr */
#line 648 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-4].minor.yy139.x+yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y+yymsp[0].minor.yy73;}
#line 2673 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 64: /* position ::= place MINUS expr COMMA expr */
#line 649 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-4].minor.yy139.x-yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y-yymsp[0].minor.yy73;}
#line 2679 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 65: /* position ::= place PLUS LP expr COMMA expr RP */
#line 651 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-6].minor.yy139.x+yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y+yymsp[-1].minor.yy73;}
#line 2685 "pikchr.c"
  yymsp[-6].minor.yy139 = yylhsminor.yy139;
        break;
      case 66: /* position ::= place MINUS LP expr COMMA expr RP */
#line 653 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-6].minor.yy139.x-yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y-yymsp[-1].minor.yy73;}
#line 2691 "pikchr.c"
  yymsp[-6].minor.yy139 = yylhsminor.yy139;
        break;
      case 67: /* position ::= LP position COMMA position RP */
#line 654 "pikchr.y"
{yymsp[-4].minor.yy139.x=yymsp[-3].minor.yy139.x; yymsp[-4].minor.yy139.y=yymsp[-1].minor.yy139.y;}
#line 2697 "pikchr.c"
        break;
      case 68: /* position ::= LP position RP */
#line 655 "pikchr.y"
{yymsp[-2].minor.yy139=yymsp[-1].minor.yy139;}
#line 2702 "pikchr.c"
        break;
      case 69: /* position ::= expr between position AND position */
#line 657 "pikchr.y"
{yylhsminor.yy139 = pik_position_between(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy139,yymsp[0].minor.yy139);}
#line 2707 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 70: /* position ::= expr LT position COMMA position GT */
#line 659 "pikchr.y"
{yylhsminor.yy139 = pik_position_between(p,yymsp[-5].minor.yy73,yymsp[-3].minor.yy139,yymsp[-1].minor.yy139);}
#line 2713 "pikchr.c"
  yymsp[-5].minor.yy139 = yylhsminor.yy139;
        break;
      case 71: /* position ::= expr ABOVE position */
#line 660 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y += yymsp[-2].minor.yy73;}
#line 2719 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 72: /* position ::= expr BELOW position */
#line 661 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y -= yymsp[-2].minor.yy73;}
#line 2725 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 73: /* position ::= expr LEFT OF position */
#line 662 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x -= yymsp[-3].minor.yy73;}
#line 2731 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 74: /* position ::= expr RIGHT OF position */
#line 663 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x += yymsp[-3].minor.yy73;}
#line 2737 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 75: /* position ::= expr ON HEADING EDGEPT OF position */
#line 665 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-5].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
#line 2743 "pikchr.c"
  yymsp[-5].minor.yy139 = yylhsminor.yy139;
        break;
      case 76: /* position ::= expr HEADING EDGEPT OF position */
#line 667 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-4].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
#line 2749 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 77: /* position ::= expr EDGEPT OF position */
#line 669 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_hdg(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
#line 2755 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 78: /* position ::= expr ON HEADING expr FROM position */
#line 671 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-5].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
#line 2761 "pikchr.c"
  yymsp[-5].minor.yy139 = yylhsminor.yy139;
        break;
      case 79: /* position ::= expr HEADING expr FROM position */
#line 673 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_angle(p,yymsp[-4].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
#line 2767 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 80: /* place ::= edge OF object */
#line 685 "pikchr.y"
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
#line 2773 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 81: /* place2 ::= object */
#line 686 "pikchr.y"
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,0);}
#line 2779 "pikchr.c"
  yymsp[0].minor.yy139 = yylhsminor.yy139;
        break;
      case 82: /* place2 ::= object DOT_E edge */
#line 687 "pikchr.y"
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
#line 2785 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 83: /* place2 ::= NTH VERTEX OF object */
#line 688 "pikchr.y"
{yylhsminor.yy139 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy254);}
#line 2791 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 84: /* object ::= nth */
#line 700 "pikchr.y"
{yylhsminor.yy254 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
#line 2797 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 85: /* object ::= nth OF|IN object */
#line 701 "pikchr.y"
{yylhsminor.yy254 = pik_find_nth(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
#line 2803 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 86: /* objectname ::= PLACENAME */
#line 703 "pikchr.y"
{yylhsminor.yy254 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
#line 2809 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 87: /* objectname ::= objectname DOT_U PLACENAME */
#line 705 "pikchr.y"
{yylhsminor.yy254 = pik_find_byname(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
#line 2815 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 88: /* nth ::= NTH CLASSNAME */
#line 707 "pikchr.y"
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
#line 2821 "pikchr.c"
  yymsp[-1].minor.yy0 = yylhsminor.yy0;
        break;
      case 89: /* nth ::= NTH LAST CLASSNAME */
#line 708 "pikchr.y"
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
#line 2827 "pikchr.c"
  yymsp[-2].minor.yy0 = yylhsminor.yy0;
        break;
      case 90: /* nth ::= LAST CLASSNAME */
#line 709 "pikchr.y"
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
#line 2833 "pikchr.c"
        break;
      case 91: /* nth ::= LAST */
#line 710 "pikchr.y"
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
#line 2838 "pikchr.c"
  yymsp[0].minor.yy0 = yylhsminor.yy0;
        break;
      case 92: /* nth ::= NTH LB RB */
#line 711 "pikchr.y"
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
#line 2844 "pikchr.c"
  yymsp[-2].minor.yy0 = yylhsminor.yy0;
        break;
      case 93: /* nth ::= NTH LAST LB RB */
#line 712 "pikchr.y"
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
#line 2850 "pikchr.c"
  yymsp[-3].minor.yy0 = yylhsminor.yy0;
        break;
      case 94: /* nth ::= LAST LB RB */
#line 713 "pikchr.y"
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
#line 2856 "pikchr.c"
        break;
      case 95: /* expr ::= expr PLUS expr */
#line 715 "pikchr.y"
{yylhsminor.yy73=yymsp[-2].minor.yy73+yymsp[0].minor.yy73;}
#line 2861 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 96: /* expr ::= expr MINUS expr */
#line 716 "pikchr.y"
{yylhsminor.yy73=yymsp[-2].minor.yy73-yymsp[0].minor.yy73;}
#line 2867 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 97: /* expr ::= expr STAR expr */
#line 717 "pikchr.y"
{yylhsminor.yy73=yymsp[-2].minor.yy73*yymsp[0].minor.yy73;}
#line 2873 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 98: /* expr ::= expr SLASH expr */
#line 718 "pikchr.y"
{
  if( yymsp[0].minor.yy73==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy73 = 0.0; }
  else{ yylhsminor.yy73 = yymsp[-2].minor.yy73/yymsp[0].minor.yy73; }
}
#line 2882 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 99: /* expr ::= MINUS expr */
#line 722 "pikchr.y"
{yymsp[-1].minor.yy73=-yymsp[0].minor.yy73;}
#line 2888 "pikchr.c"
        break;
      case 100: /* expr ::= PLUS expr */
#line 723 "pikchr.y"
{yymsp[-1].minor.yy73=yymsp[0].minor.yy73;}
#line 2893 "pikchr.c"
        break;
      case 101: /* expr ::= LP expr RP */
#line 724 "pikchr.y"
{yymsp[-2].minor.yy73=yymsp[-1].minor.yy73;}
#line 2898 "pikchr.c"
        break;
      case 102: /* expr ::= NUMBER */
#line 725 "pikchr.y"
{yylhsminor.yy73=pik_atof(p,&yymsp[0].minor.yy0);}
#line 2903 "pikchr.c"
  yymsp[0].minor.yy73 = yylhsminor.yy73;
        break;
      case 103: /* expr ::= ID */
#line 726 "pikchr.y"
{yylhsminor.yy73=pik_get_var(p,&yymsp[0].minor.yy0);}
#line 2909 "pikchr.c"
  yymsp[0].minor.yy73 = yylhsminor.yy73;
        break;
      case 104: /* expr ::= FUNC1 LP expr RP */
#line 727 "pikchr.y"
{yylhsminor.yy73 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy73,0.0);}
#line 2915 "pikchr.c"
  yymsp[-3].minor.yy73 = yylhsminor.yy73;
        break;
      case 105: /* expr ::= FUNC2 LP expr COMMA expr RP */
#line 728 "pikchr.y"
{yylhsminor.yy73 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy73,yymsp[-1].minor.yy73);}
#line 2921 "pikchr.c"
  yymsp[-5].minor.yy73 = yylhsminor.yy73;
        break;
      case 106: /* expr ::= place2 DOT_XY X */
#line 729 "pikchr.y"
{yylhsminor.yy73 = yymsp[-2].minor.yy139.x;}
#line 2927 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 107: /* expr ::= place2 DOT_XY Y */
#line 730 "pikchr.y"
{yylhsminor.yy73 = yymsp[-2].minor.yy139.y;}
#line 2933 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 108: /* expr ::= object DOT_L numproperty */
      case 109: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==109);
      case 110: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==110);
#line 731 "pikchr.y"
{yylhsminor.yy73=pik_property_of(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
#line 2941 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      default:
      /* (111) lvalue ::= ID */ yytestcase(yyruleno==111);
      /* (112) lvalue ::= FILL */ yytestcase(yyruleno==112);
      /* (113) lvalue ::= COLOR */ yytestcase(yyruleno==113);
      /* (114) lvalue ::= THICKNESS */ yytestcase(yyruleno==114);







|

|


|

|



|

|



|

|


|

|



|

|



|

|



|


|



|

|



|

|


|

|


|

|


|

|





|

|


|

|


|

|


|

|


|

|



|

|



|

|



|

|


|

|


|

|



|

|



|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|



|

|



|

|


|

|


|

|


|

|


|

|


|

|


|

|



|

|


|

|



|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|


|

|


|
|
|



|

|



|

|



|

|



|

|



|

|



|

|


|

|


|
|
|



|
|
|



|

|



|

|



|

|



|

|



|
|
|



|
|
|



|
|
|



|
|
|



|
|
|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|



|

|


|

|



|

|



|

|



|

|


|

|



|

|



|

|



|




|



|

|


|

|


|

|


|
|
|



|

|



|

|



|

|



|

|



|

|





|
|
|







2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
  **     { ... }           // User supplied code
  **  #line <lineno> <thisfile>
  **     break;
  */
/********** Begin reduce actions **********************************************/
        YYMINORTYPE yylhsminor;
      case 0: /* document ::= element_list */
#line 514 "pikchr.y"
{pik_render(p,yymsp[0].minor.yy72);}
#line 2365 "pikchr.c"
        break;
      case 1: /* element_list ::= element */
#line 517 "pikchr.y"
{ yylhsminor.yy72 = pik_elist_append(p,0,yymsp[0].minor.yy254); }
#line 2370 "pikchr.c"
  yymsp[0].minor.yy72 = yylhsminor.yy72;
        break;
      case 2: /* element_list ::= element_list EOL element */
#line 519 "pikchr.y"
{ yylhsminor.yy72 = pik_elist_append(p,yymsp[-2].minor.yy72,yymsp[0].minor.yy254); }
#line 2376 "pikchr.c"
  yymsp[-2].minor.yy72 = yylhsminor.yy72;
        break;
      case 3: /* element ::= */
#line 522 "pikchr.y"
{ yymsp[1].minor.yy254 = 0; }
#line 2382 "pikchr.c"
        break;
      case 4: /* element ::= direction */
#line 523 "pikchr.y"
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode);  yylhsminor.yy254=0; }
#line 2387 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 5: /* element ::= lvalue ASSIGN rvalue */
#line 524 "pikchr.y"
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy73,&yymsp[-1].minor.yy0); yylhsminor.yy254=0;}
#line 2393 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 6: /* element ::= PLACENAME COLON unnamed_element */
#line 526 "pikchr.y"
{ yylhsminor.yy254 = yymsp[0].minor.yy254;  pik_elem_setname(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0); }
#line 2399 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 7: /* element ::= PLACENAME COLON position */
#line 528 "pikchr.y"
{ yylhsminor.yy254 = pik_elem_new(p,0,0,0);
                 if(yylhsminor.yy254){ yylhsminor.yy254->ptAt = yymsp[0].minor.yy139; pik_elem_setname(p,yylhsminor.yy254,&yymsp[-2].minor.yy0); }}
#line 2406 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 8: /* element ::= unnamed_element */
#line 530 "pikchr.y"
{yylhsminor.yy254 = yymsp[0].minor.yy254;}
#line 2412 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 9: /* element ::= print prlist */
#line 531 "pikchr.y"
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy254=0;}
#line 2418 "pikchr.c"
        break;
      case 10: /* element ::= ASSERT LP expr EQ expr RP */
#line 536 "pikchr.y"
{yymsp[-5].minor.yy254=pik_assert(p,yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy73);}
#line 2423 "pikchr.c"
        break;
      case 11: /* element ::= ASSERT LP place EQ place RP */
#line 538 "pikchr.y"
{yymsp[-5].minor.yy254=pik_place_assert(p,&yymsp[-3].minor.yy139,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy139);}
#line 2428 "pikchr.c"
        break;
      case 12: /* rvalue ::= PLACENAME */
#line 549 "pikchr.y"
{yylhsminor.yy73 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
#line 2433 "pikchr.c"
  yymsp[0].minor.yy73 = yylhsminor.yy73;
        break;
      case 13: /* pritem ::= FILL */
      case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
      case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
#line 554 "pikchr.y"
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
#line 2441 "pikchr.c"
        break;
      case 16: /* pritem ::= rvalue */
#line 557 "pikchr.y"
{pik_append_num(p,"",yymsp[0].minor.yy73);}
#line 2446 "pikchr.c"
        break;
      case 17: /* pritem ::= STRING */
#line 558 "pikchr.y"
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
#line 2451 "pikchr.c"
        break;
      case 18: /* prsep ::= COMMA */
#line 559 "pikchr.y"
{pik_append(p, " ", 1);}
#line 2456 "pikchr.c"
        break;
      case 19: /* unnamed_element ::= basetype attribute_list */
#line 562 "pikchr.y"
{yylhsminor.yy254 = yymsp[-1].minor.yy254; pik_after_adding_attributes(p,yylhsminor.yy254);}
#line 2461 "pikchr.c"
  yymsp[-1].minor.yy254 = yylhsminor.yy254;
        break;
      case 20: /* basetype ::= CLASSNAME */
#line 564 "pikchr.y"
{yylhsminor.yy254 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
#line 2467 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 21: /* basetype ::= STRING textposition */
#line 566 "pikchr.y"
{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy74; yylhsminor.yy254 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
#line 2473 "pikchr.c"
  yymsp[-1].minor.yy254 = yylhsminor.yy254;
        break;
      case 22: /* basetype ::= LB savelist element_list RB */
#line 568 "pikchr.y"
{ p->list = yymsp[-2].minor.yy72; yymsp[-3].minor.yy254 = pik_elem_new(p,0,0,yymsp[-1].minor.yy72); if(yymsp[-3].minor.yy254) yymsp[-3].minor.yy254->errTok = yymsp[0].minor.yy0; }
#line 2479 "pikchr.c"
        break;
      case 23: /* savelist ::= */
#line 573 "pikchr.y"
{yymsp[1].minor.yy72 = p->list; p->list = 0;}
#line 2484 "pikchr.c"
        break;
      case 24: /* relexpr ::= expr */
#line 580 "pikchr.y"
{yylhsminor.yy60.rAbs = yymsp[0].minor.yy73; yylhsminor.yy60.rRel = 0;}
#line 2489 "pikchr.c"
  yymsp[0].minor.yy60 = yylhsminor.yy60;
        break;
      case 25: /* relexpr ::= expr PERCENT */
#line 581 "pikchr.y"
{yylhsminor.yy60.rAbs = 0; yylhsminor.yy60.rRel = yymsp[-1].minor.yy73/100;}
#line 2495 "pikchr.c"
  yymsp[-1].minor.yy60 = yylhsminor.yy60;
        break;
      case 26: /* optrelexpr ::= */
#line 583 "pikchr.y"
{yymsp[1].minor.yy60.rAbs = 0; yymsp[1].minor.yy60.rRel = 1.0;}
#line 2501 "pikchr.c"
        break;
      case 27: /* attribute_list ::= relexpr alist */
#line 585 "pikchr.y"
{pik_add_direction(p,0,&yymsp[-1].minor.yy60);}
#line 2506 "pikchr.c"
        break;
      case 28: /* attribute ::= numproperty relexpr */
#line 589 "pikchr.y"
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60); }
#line 2511 "pikchr.c"
        break;
      case 29: /* attribute ::= dashproperty expr */
#line 590 "pikchr.y"
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy73); }
#line 2516 "pikchr.c"
        break;
      case 30: /* attribute ::= dashproperty */
#line 591 "pikchr.y"
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0);  }
#line 2521 "pikchr.c"
        break;
      case 31: /* attribute ::= colorproperty rvalue */
#line 592 "pikchr.y"
{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73); }
#line 2526 "pikchr.c"
        break;
      case 32: /* attribute ::= go direction optrelexpr */
#line 593 "pikchr.y"
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy60);}
#line 2531 "pikchr.c"
        break;
      case 33: /* attribute ::= go direction even position */
#line 594 "pikchr.y"
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139);}
#line 2536 "pikchr.c"
        break;
      case 34: /* attribute ::= CLOSE */
#line 595 "pikchr.y"
{ pik_close_path(p,&yymsp[0].minor.yy0); }
#line 2541 "pikchr.c"
        break;
      case 35: /* attribute ::= CHOP */
#line 596 "pikchr.y"
{ p->cur->bChop = 1; }
#line 2546 "pikchr.c"
        break;
      case 36: /* attribute ::= FROM position */
#line 597 "pikchr.y"
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
#line 2551 "pikchr.c"
        break;
      case 37: /* attribute ::= TO position */
#line 598 "pikchr.y"
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy139); }
#line 2556 "pikchr.c"
        break;
      case 38: /* attribute ::= THEN */
#line 599 "pikchr.y"
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
#line 2561 "pikchr.c"
        break;
      case 39: /* attribute ::= THEN optrelexpr HEADING expr */
      case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
#line 601 "pikchr.y"
{pik_move_hdg(p,&yymsp[-2].minor.yy60,&yymsp[-1].minor.yy0,yymsp[0].minor.yy73,0,&yymsp[-3].minor.yy0);}
#line 2567 "pikchr.c"
        break;
      case 40: /* attribute ::= THEN optrelexpr EDGEPT */
      case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
#line 602 "pikchr.y"
{pik_move_hdg(p,&yymsp[-1].minor.yy60,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
#line 2573 "pikchr.c"
        break;
      case 43: /* attribute ::= AT position */
#line 607 "pikchr.y"
{ pik_set_at(p,0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
#line 2578 "pikchr.c"
        break;
      case 44: /* attribute ::= SAME */
#line 609 "pikchr.y"
{pik_same(p,0,&yymsp[0].minor.yy0);}
#line 2583 "pikchr.c"
        break;
      case 45: /* attribute ::= SAME AS object */
#line 610 "pikchr.y"
{pik_same(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
#line 2588 "pikchr.c"
        break;
      case 46: /* attribute ::= STRING textposition */
#line 611 "pikchr.y"
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy74);}
#line 2593 "pikchr.c"
        break;
      case 47: /* attribute ::= FIT */
#line 612 "pikchr.y"
{pik_size_to_fit(p,&yymsp[0].minor.yy0); }
#line 2598 "pikchr.c"
        break;
      case 48: /* attribute ::= BEHIND object */
#line 613 "pikchr.y"
{pik_behind(p,yymsp[0].minor.yy254);}
#line 2603 "pikchr.c"
        break;
      case 49: /* withclause ::= DOT_E edge AT position */
      case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
#line 621 "pikchr.y"
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy139,&yymsp[-1].minor.yy0); }
#line 2609 "pikchr.c"
        break;
      case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
#line 625 "pikchr.y"
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
#line 2614 "pikchr.c"
  yymsp[0].minor.yy0 = yylhsminor.yy0;
        break;
      case 52: /* boolproperty ::= CW */
#line 636 "pikchr.y"
{p->cur->cw = 1;}
#line 2620 "pikchr.c"
        break;
      case 53: /* boolproperty ::= CCW */
#line 637 "pikchr.y"
{p->cur->cw = 0;}
#line 2625 "pikchr.c"
        break;
      case 54: /* boolproperty ::= LARROW */
#line 638 "pikchr.y"
{p->cur->larrow=1; p->cur->rarrow=0; }
#line 2630 "pikchr.c"
        break;
      case 55: /* boolproperty ::= RARROW */
#line 639 "pikchr.y"
{p->cur->larrow=0; p->cur->rarrow=1; }
#line 2635 "pikchr.c"
        break;
      case 56: /* boolproperty ::= LRARROW */
#line 640 "pikchr.y"
{p->cur->larrow=1; p->cur->rarrow=1; }
#line 2640 "pikchr.c"
        break;
      case 57: /* boolproperty ::= INVIS */
#line 641 "pikchr.y"
{p->cur->sw = 0.0;}
#line 2645 "pikchr.c"
        break;
      case 58: /* boolproperty ::= THICK */
#line 642 "pikchr.y"
{p->cur->sw *= 1.5;}
#line 2650 "pikchr.c"
        break;
      case 59: /* boolproperty ::= THIN */
#line 643 "pikchr.y"
{p->cur->sw *= 0.67;}
#line 2655 "pikchr.c"
        break;
      case 60: /* textposition ::= */
#line 645 "pikchr.y"
{yymsp[1].minor.yy74 = 0;}
#line 2660 "pikchr.c"
        break;
      case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
#line 648 "pikchr.y"
{yylhsminor.yy74 = pik_text_position(yymsp[-1].minor.yy74,&yymsp[0].minor.yy0);}
#line 2665 "pikchr.c"
  yymsp[-1].minor.yy74 = yylhsminor.yy74;
        break;
      case 62: /* position ::= expr COMMA expr */
#line 651 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[0].minor.yy73;}
#line 2671 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 63: /* position ::= place PLUS expr COMMA expr */
#line 653 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-4].minor.yy139.x+yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y+yymsp[0].minor.yy73;}
#line 2677 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 64: /* position ::= place MINUS expr COMMA expr */
#line 654 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-4].minor.yy139.x-yymsp[-2].minor.yy73; yylhsminor.yy139.y=yymsp[-4].minor.yy139.y-yymsp[0].minor.yy73;}
#line 2683 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 65: /* position ::= place PLUS LP expr COMMA expr RP */
#line 656 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-6].minor.yy139.x+yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y+yymsp[-1].minor.yy73;}
#line 2689 "pikchr.c"
  yymsp[-6].minor.yy139 = yylhsminor.yy139;
        break;
      case 66: /* position ::= place MINUS LP expr COMMA expr RP */
#line 658 "pikchr.y"
{yylhsminor.yy139.x=yymsp[-6].minor.yy139.x-yymsp[-3].minor.yy73; yylhsminor.yy139.y=yymsp[-6].minor.yy139.y-yymsp[-1].minor.yy73;}
#line 2695 "pikchr.c"
  yymsp[-6].minor.yy139 = yylhsminor.yy139;
        break;
      case 67: /* position ::= LP position COMMA position RP */
#line 659 "pikchr.y"
{yymsp[-4].minor.yy139.x=yymsp[-3].minor.yy139.x; yymsp[-4].minor.yy139.y=yymsp[-1].minor.yy139.y;}
#line 2701 "pikchr.c"
        break;
      case 68: /* position ::= LP position RP */
#line 660 "pikchr.y"
{yymsp[-2].minor.yy139=yymsp[-1].minor.yy139;}
#line 2706 "pikchr.c"
        break;
      case 69: /* position ::= expr between position AND position */
#line 662 "pikchr.y"
{yylhsminor.yy139 = pik_position_between(yymsp[-4].minor.yy73,yymsp[-2].minor.yy139,yymsp[0].minor.yy139);}
#line 2711 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 70: /* position ::= expr LT position COMMA position GT */
#line 664 "pikchr.y"
{yylhsminor.yy139 = pik_position_between(yymsp[-5].minor.yy73,yymsp[-3].minor.yy139,yymsp[-1].minor.yy139);}
#line 2717 "pikchr.c"
  yymsp[-5].minor.yy139 = yylhsminor.yy139;
        break;
      case 71: /* position ::= expr ABOVE position */
#line 665 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y += yymsp[-2].minor.yy73;}
#line 2723 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 72: /* position ::= expr BELOW position */
#line 666 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.y -= yymsp[-2].minor.yy73;}
#line 2729 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 73: /* position ::= expr LEFT OF position */
#line 667 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x -= yymsp[-3].minor.yy73;}
#line 2735 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 74: /* position ::= expr RIGHT OF position */
#line 668 "pikchr.y"
{yylhsminor.yy139=yymsp[0].minor.yy139; yylhsminor.yy139.x += yymsp[-3].minor.yy73;}
#line 2741 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 75: /* position ::= expr ON HEADING EDGEPT OF position */
#line 670 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_hdg(yymsp[-5].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
#line 2747 "pikchr.c"
  yymsp[-5].minor.yy139 = yylhsminor.yy139;
        break;
      case 76: /* position ::= expr HEADING EDGEPT OF position */
#line 672 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_hdg(yymsp[-4].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
#line 2753 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 77: /* position ::= expr EDGEPT OF position */
#line 674 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_hdg(yymsp[-3].minor.yy73,&yymsp[-2].minor.yy0,yymsp[0].minor.yy139);}
#line 2759 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 78: /* position ::= expr ON HEADING expr FROM position */
#line 676 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_angle(yymsp[-5].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
#line 2765 "pikchr.c"
  yymsp[-5].minor.yy139 = yylhsminor.yy139;
        break;
      case 79: /* position ::= expr HEADING expr FROM position */
#line 678 "pikchr.y"
{yylhsminor.yy139 = pik_position_at_angle(yymsp[-4].minor.yy73,yymsp[-2].minor.yy73,yymsp[0].minor.yy139);}
#line 2771 "pikchr.c"
  yymsp[-4].minor.yy139 = yylhsminor.yy139;
        break;
      case 80: /* place ::= edge OF object */
#line 690 "pikchr.y"
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
#line 2777 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 81: /* place2 ::= object */
#line 691 "pikchr.y"
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[0].minor.yy254,0);}
#line 2783 "pikchr.c"
  yymsp[0].minor.yy139 = yylhsminor.yy139;
        break;
      case 82: /* place2 ::= object DOT_E edge */
#line 692 "pikchr.y"
{yylhsminor.yy139 = pik_place_of_elem(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
#line 2789 "pikchr.c"
  yymsp[-2].minor.yy139 = yylhsminor.yy139;
        break;
      case 83: /* place2 ::= NTH VERTEX OF object */
#line 693 "pikchr.y"
{yylhsminor.yy139 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy254);}
#line 2795 "pikchr.c"
  yymsp[-3].minor.yy139 = yylhsminor.yy139;
        break;
      case 84: /* object ::= nth */
#line 705 "pikchr.y"
{yylhsminor.yy254 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
#line 2801 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 85: /* object ::= nth OF|IN object */
#line 706 "pikchr.y"
{yylhsminor.yy254 = pik_find_nth(p,yymsp[0].minor.yy254,&yymsp[-2].minor.yy0);}
#line 2807 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 86: /* objectname ::= PLACENAME */
#line 708 "pikchr.y"
{yylhsminor.yy254 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
#line 2813 "pikchr.c"
  yymsp[0].minor.yy254 = yylhsminor.yy254;
        break;
      case 87: /* objectname ::= objectname DOT_U PLACENAME */
#line 710 "pikchr.y"
{yylhsminor.yy254 = pik_find_byname(p,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
#line 2819 "pikchr.c"
  yymsp[-2].minor.yy254 = yylhsminor.yy254;
        break;
      case 88: /* nth ::= NTH CLASSNAME */
#line 712 "pikchr.y"
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
#line 2825 "pikchr.c"
  yymsp[-1].minor.yy0 = yylhsminor.yy0;
        break;
      case 89: /* nth ::= NTH LAST CLASSNAME */
#line 713 "pikchr.y"
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
#line 2831 "pikchr.c"
  yymsp[-2].minor.yy0 = yylhsminor.yy0;
        break;
      case 90: /* nth ::= LAST CLASSNAME */
#line 714 "pikchr.y"
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
#line 2837 "pikchr.c"
        break;
      case 91: /* nth ::= LAST */
#line 715 "pikchr.y"
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
#line 2842 "pikchr.c"
  yymsp[0].minor.yy0 = yylhsminor.yy0;
        break;
      case 92: /* nth ::= NTH LB RB */
#line 716 "pikchr.y"
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
#line 2848 "pikchr.c"
  yymsp[-2].minor.yy0 = yylhsminor.yy0;
        break;
      case 93: /* nth ::= NTH LAST LB RB */
#line 717 "pikchr.y"
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
#line 2854 "pikchr.c"
  yymsp[-3].minor.yy0 = yylhsminor.yy0;
        break;
      case 94: /* nth ::= LAST LB RB */
#line 718 "pikchr.y"
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
#line 2860 "pikchr.c"
        break;
      case 95: /* expr ::= expr PLUS expr */
#line 720 "pikchr.y"
{yylhsminor.yy73=yymsp[-2].minor.yy73+yymsp[0].minor.yy73;}
#line 2865 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 96: /* expr ::= expr MINUS expr */
#line 721 "pikchr.y"
{yylhsminor.yy73=yymsp[-2].minor.yy73-yymsp[0].minor.yy73;}
#line 2871 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 97: /* expr ::= expr STAR expr */
#line 722 "pikchr.y"
{yylhsminor.yy73=yymsp[-2].minor.yy73*yymsp[0].minor.yy73;}
#line 2877 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 98: /* expr ::= expr SLASH expr */
#line 723 "pikchr.y"
{
  if( yymsp[0].minor.yy73==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy73 = 0.0; }
  else{ yylhsminor.yy73 = yymsp[-2].minor.yy73/yymsp[0].minor.yy73; }
}
#line 2886 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 99: /* expr ::= MINUS expr */
#line 727 "pikchr.y"
{yymsp[-1].minor.yy73=-yymsp[0].minor.yy73;}
#line 2892 "pikchr.c"
        break;
      case 100: /* expr ::= PLUS expr */
#line 728 "pikchr.y"
{yymsp[-1].minor.yy73=yymsp[0].minor.yy73;}
#line 2897 "pikchr.c"
        break;
      case 101: /* expr ::= LP expr RP */
#line 729 "pikchr.y"
{yymsp[-2].minor.yy73=yymsp[-1].minor.yy73;}
#line 2902 "pikchr.c"
        break;
      case 102: /* expr ::= NUMBER */
#line 730 "pikchr.y"
{yylhsminor.yy73=pik_atof(&yymsp[0].minor.yy0);}
#line 2907 "pikchr.c"
  yymsp[0].minor.yy73 = yylhsminor.yy73;
        break;
      case 103: /* expr ::= ID */
#line 731 "pikchr.y"
{yylhsminor.yy73=pik_get_var(p,&yymsp[0].minor.yy0);}
#line 2913 "pikchr.c"
  yymsp[0].minor.yy73 = yylhsminor.yy73;
        break;
      case 104: /* expr ::= FUNC1 LP expr RP */
#line 732 "pikchr.y"
{yylhsminor.yy73 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy73,0.0);}
#line 2919 "pikchr.c"
  yymsp[-3].minor.yy73 = yylhsminor.yy73;
        break;
      case 105: /* expr ::= FUNC2 LP expr COMMA expr RP */
#line 733 "pikchr.y"
{yylhsminor.yy73 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy73,yymsp[-1].minor.yy73);}
#line 2925 "pikchr.c"
  yymsp[-5].minor.yy73 = yylhsminor.yy73;
        break;
      case 106: /* expr ::= place2 DOT_XY X */
#line 734 "pikchr.y"
{yylhsminor.yy73 = yymsp[-2].minor.yy139.x;}
#line 2931 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 107: /* expr ::= place2 DOT_XY Y */
#line 735 "pikchr.y"
{yylhsminor.yy73 = yymsp[-2].minor.yy139.y;}
#line 2937 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      case 108: /* expr ::= object DOT_L numproperty */
      case 109: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==109);
      case 110: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==110);
#line 736 "pikchr.y"
{yylhsminor.yy73=pik_property_of(yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
#line 2945 "pikchr.c"
  yymsp[-2].minor.yy73 = yylhsminor.yy73;
        break;
      default:
      /* (111) lvalue ::= ID */ yytestcase(yyruleno==111);
      /* (112) lvalue ::= FILL */ yytestcase(yyruleno==112);
      /* (113) lvalue ::= COLOR */ yytestcase(yyruleno==113);
      /* (114) lvalue ::= THICKNESS */ yytestcase(yyruleno==114);
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025

3026
3027
3028
3029
3030
3031
3032
3033
  int yymajor,                   /* The major type of the error token */
  pik_parserTOKENTYPE yyminor         /* The minor type of the error token */
){
  pik_parserARG_FETCH
  pik_parserCTX_FETCH
#define TOKEN yyminor
/************ Begin %syntax_error code ****************************************/
#line 498 "pikchr.y"

  if( TOKEN.z && TOKEN.z[0] ){
    pik_error(p, &TOKEN, "syntax error");
  }else{
    pik_error(p, 0, "syntax error");
  }

#line 3051 "pikchr.c"
/************ End %syntax_error code ******************************************/
  pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
  pik_parserCTX_STORE
}

/*
** The following is executed when the parser accepts







|






>
|







3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
  int yymajor,                   /* The major type of the error token */
  pik_parserTOKENTYPE yyminor         /* The minor type of the error token */
){
  pik_parserARG_FETCH
  pik_parserCTX_FETCH
#define TOKEN yyminor
/************ Begin %syntax_error code ****************************************/
#line 502 "pikchr.y"

  if( TOKEN.z && TOKEN.z[0] ){
    pik_error(p, &TOKEN, "syntax error");
  }else{
    pik_error(p, 0, "syntax error");
  }
  UNUSED_PARAMETER(yymajor);
#line 3056 "pikchr.c"
/************ End %syntax_error code ******************************************/
  pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
  pik_parserCTX_STORE
}

/*
** The following is executed when the parser accepts
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
  assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) );
  return yyFallback[iToken];
#else
  (void)iToken;
  return 0;
#endif
}
#line 736 "pikchr.y"



/* Chart of the 140 official HTML color names with their
** corresponding RGB value.
**
** Two new names "None" and "Off" are added with a value







|







3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
  assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) );
  return yyFallback[iToken];
#else
  (void)iToken;
  return 0;
#endif
}
#line 741 "pikchr.y"



/* Chart of the 140 official HTML color names with their
** corresponding RGB value.
**
** Two new names "None" and "Off" are added with a value
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588

3589
3590
3591
3592
3593
3594
3595

/* Methods for the "box" class */
static void boxInit(Pik *p, PElem *pElem){
  pElem->w = pik_value(p, "boxwid",6,0);
  pElem->h = pik_value(p, "boxht",5,0);
  pElem->rad = pik_value(p, "boxrad",6,0);
}
/* Translate the CP_START and CP_END reference points into the
** corresponding compass point based on the direction.
*/
static int boxTranslateEndPoint(PElem *pElem, int cp){
#if 0
  if( cp==CP_START ){
    switch( pElem->inDir ){
      case DIR_RIGHT: cp = CP_W;  break;
      case DIR_DOWN:  cp = CP_N;  break;
      case DIR_LEFT:  cp = CP_E;  break;
      case DIR_UP:    cp = CP_S;  break;
    }
  }else if( cp==CP_END ){
    switch( pElem->outDir ){
      case DIR_RIGHT: cp = CP_E;  break;
      case DIR_DOWN:  cp = CP_S;  break;
      case DIR_LEFT:  cp = CP_W;  break;
      case DIR_UP:    cp = CP_N;  break;
    }
  }
#endif
  return cp;
}
/* Return offset from the center of the box to the compass point 
** given by parameter cp */
static PPoint boxOffset(Pik *p, PElem *pElem, int cp){
  PPoint pt;
  PNum w2 = 0.5*pElem->w;
  PNum h2 = 0.5*pElem->h;
  PNum rad = pElem->rad;
  PNum rx;
  if( rad<=0.0 ){
    rx = 0.0;
  }else{
    if( rad>w2 ) rad = w2;
    if( rad>h2 ) rad = h2;
    rx = 0.29289321881345252392*rad;
  }
  pt.x = pt.y = 0.0;
  switch( boxTranslateEndPoint(pElem,cp) ){
    case CP_C:   pt.x = 0.0;      pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;      pt.y = h2;     break;
    case CP_NE:  pt.x = w2-rx;    pt.y = h2-rx;  break;
    case CP_E:   pt.x = w2;       pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2-rx;    pt.y = rx-h2;  break;
    case CP_S:   pt.x = 0.0;      pt.y = -h2;    break;
    case CP_SW:  pt.x = rx-w2;    pt.y = rx-h2;  break;
    case CP_W:   pt.x = -w2;      pt.y = 0.0;    break;
    case CP_NW:  pt.x = rx-w2;    pt.y = h2-rx;  break;
  }

  return pt;
}
static PPoint boxChop(Pik *p, PElem *pElem, PPoint *pPt){
  PNum dx, dy;
  int cp = CP_C;
  PPoint chop = pElem->ptAt;
  if( pElem->w<=0.0 ) return chop;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















|










>







3537
3538
3539
3540
3541
3542
3543























3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578

/* Methods for the "box" class */
static void boxInit(Pik *p, PElem *pElem){
  pElem->w = pik_value(p, "boxwid",6,0);
  pElem->h = pik_value(p, "boxht",5,0);
  pElem->rad = pik_value(p, "boxrad",6,0);
}























/* Return offset from the center of the box to the compass point 
** given by parameter cp */
static PPoint boxOffset(Pik *p, PElem *pElem, int cp){
  PPoint pt;
  PNum w2 = 0.5*pElem->w;
  PNum h2 = 0.5*pElem->h;
  PNum rad = pElem->rad;
  PNum rx;
  if( rad<=0.0 ){
    rx = 0.0;
  }else{
    if( rad>w2 ) rad = w2;
    if( rad>h2 ) rad = h2;
    rx = 0.29289321881345252392*rad;
  }
  pt.x = pt.y = 0.0;
  switch( cp ){
    case CP_C:   pt.x = 0.0;      pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;      pt.y = h2;     break;
    case CP_NE:  pt.x = w2-rx;    pt.y = h2-rx;  break;
    case CP_E:   pt.x = w2;       pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2-rx;    pt.y = rx-h2;  break;
    case CP_S:   pt.x = 0.0;      pt.y = -h2;    break;
    case CP_SW:  pt.x = rx-w2;    pt.y = rx-h2;  break;
    case CP_W:   pt.x = -w2;      pt.y = 0.0;    break;
    case CP_NW:  pt.x = rx-w2;    pt.y = h2-rx;  break;
  }
  UNUSED_PARAMETER(p);
  return pt;
}
static PPoint boxChop(Pik *p, PElem *pElem, PPoint *pPt){
  PNum dx, dy;
  int cp = CP_C;
  PPoint chop = pElem->ptAt;
  if( pElem->w<=0.0 ) return chop;
3625
3626
3627
3628
3629
3630
3631

3632
3633
3634
3635
3636
3637
3638
  chop.x += pElem->ptAt.x;
  chop.y += pElem->ptAt.y;
  return chop;
}
static void boxFit(Pik *p, PElem *pElem, PNum w, PNum h){
  if( w>0 ) pElem->w = w;
  if( h>0 ) pElem->h = h;

}
static void boxRender(Pik *p, PElem *pElem){
  PNum w2 = 0.5*pElem->w;
  PNum h2 = 0.5*pElem->h;
  PNum rad = pElem->rad;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){







>







3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
  chop.x += pElem->ptAt.x;
  chop.y += pElem->ptAt.y;
  return chop;
}
static void boxFit(Pik *p, PElem *pElem, PNum w, PNum h){
  if( w>0 ) pElem->w = w;
  if( h>0 ) pElem->h = h;
  UNUSED_PARAMETER(p);
}
static void boxRender(Pik *p, PElem *pElem){
  PNum w2 = 0.5*pElem->w;
  PNum h2 = 0.5*pElem->h;
  PNum rad = pElem->rad;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){
3702
3703
3704
3705
3706
3707
3708

3709
3710
3711
3712
3713
3714
3715
3716
3717

3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730

3731
3732
3733
3734
3735
3736
3737
      pElem->rad = 0.5*pElem->w;
      break;
    case T_HEIGHT:
      pElem->w = pElem->h;
      pElem->rad = 0.5*pElem->w;
      break;
  }

}
static PPoint circleChop(Pik *p, PElem *pElem, PPoint *pPt){
  PPoint chop;
  PNum dx = pPt->x - pElem->ptAt.x;
  PNum dy = pPt->y - pElem->ptAt.y;
  PNum dist = hypot(dx,dy);
  if( dist<pElem->rad ) return pElem->ptAt;
  chop.x = pElem->ptAt.x + dx*pElem->rad/dist;
  chop.y = pElem->ptAt.y + dy*pElem->rad/dist;

  return chop;
}
static void circleFit(Pik *p, PElem *pElem, PNum w, PNum h){
  PNum mx = 0.0;
  if( w>0 ) mx = w;
  if( h>mx ) mx = h;
  if( (w*w + h*h) > mx*mx ){
    mx = hypot(w,h);
  }
  if( mx>0.0 ){
    pElem->rad = 0.5*mx;
    pElem->w = pElem->h = mx;
  }

}

static void circleRender(Pik *p, PElem *pElem){
  PNum r = pElem->rad;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){
    pik_append_x(p,"<circle cx=\"", pt.x, "\"");







>









>













>







3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
      pElem->rad = 0.5*pElem->w;
      break;
    case T_HEIGHT:
      pElem->w = pElem->h;
      pElem->rad = 0.5*pElem->w;
      break;
  }
  UNUSED_PARAMETER(p);
}
static PPoint circleChop(Pik *p, PElem *pElem, PPoint *pPt){
  PPoint chop;
  PNum dx = pPt->x - pElem->ptAt.x;
  PNum dy = pPt->y - pElem->ptAt.y;
  PNum dist = hypot(dx,dy);
  if( dist<pElem->rad ) return pElem->ptAt;
  chop.x = pElem->ptAt.x + dx*pElem->rad/dist;
  chop.y = pElem->ptAt.y + dy*pElem->rad/dist;
  UNUSED_PARAMETER(p);
  return chop;
}
static void circleFit(Pik *p, PElem *pElem, PNum w, PNum h){
  PNum mx = 0.0;
  if( w>0 ) mx = w;
  if( h>mx ) mx = h;
  if( (w*w + h*h) > mx*mx ){
    mx = hypot(w,h);
  }
  if( mx>0.0 ){
    pElem->rad = 0.5*mx;
    pElem->w = pElem->h = mx;
  }
  UNUSED_PARAMETER(p);
}

static void circleRender(Pik *p, PElem *pElem){
  PNum r = pElem->rad;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){
    pik_append_x(p,"<circle cx=\"", pt.x, "\"");
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785

3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803

3804
3805
3806
3807
3808

3809
3810
3811
3812



3813
3814
3815
3816
3817
3818
3819
  pik_append_txt(p, pElem, 0);
}
static PPoint cylinderOffset(Pik *p, PElem *pElem, int cp){
  PPoint pt;
  PNum w2 = pElem->w*0.5;
  PNum h1 = pElem->h*0.5;
  PNum h2 = h1 - pElem->rad;
  switch( boxTranslateEndPoint(pElem,cp) ){
    case CP_C:   pt.x = 0.0;   pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;   pt.y = h1;     break;
    case CP_NE:  pt.x = w2;    pt.y = h2;     break;
    case CP_E:   pt.x = w2;    pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2;    pt.y = -h2;    break;
    case CP_S:   pt.x = 0.0;   pt.y = -h1;    break;
    case CP_SW:  pt.x = -w2;   pt.y = -h2;    break;
    case CP_W:   pt.x = -w2;   pt.y = 0.0;    break;
    case CP_NW:  pt.x = -w2;   pt.y = h2;     break;
  }

  return pt;
}

/* Methods for the "dot" class */
static void dotInit(Pik *p, PElem *pElem){
  pElem->rad = pik_value(p, "dotrad",6,0);
  pElem->h = pElem->w = pElem->rad*6;
  pElem->fill = pElem->color;
}
static void dotNumProp(Pik *p, PElem *pElem, PToken *pId){
  switch( pId->eType ){
    case T_COLOR:
      pElem->fill = pElem->color;
      break;
    case T_FILL:
      pElem->color = pElem->fill;
      break;
  }

}
static void dotCheck(Pik *p, PElem *pElem){
  pElem->w = pElem->h = 0;
  pik_bbox_addellipse(&pElem->bbox, pElem->ptAt.x, pElem->ptAt.y,
                       pElem->rad, pElem->rad);

}
static PPoint dotOffset(Pik *p, PElem *pElem, int cp){
  PPoint zero;
  zero.x = zero.y = 0;



  return zero;
}
static void dotRender(Pik *p, PElem *pElem){
  PNum r = pElem->rad;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){
    pik_append_x(p,"<circle cx=\"", pt.x, "\"");







|










>


















>





>




>
>
>







3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
  pik_append_txt(p, pElem, 0);
}
static PPoint cylinderOffset(Pik *p, PElem *pElem, int cp){
  PPoint pt;
  PNum w2 = pElem->w*0.5;
  PNum h1 = pElem->h*0.5;
  PNum h2 = h1 - pElem->rad;
  switch( cp ){
    case CP_C:   pt.x = 0.0;   pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;   pt.y = h1;     break;
    case CP_NE:  pt.x = w2;    pt.y = h2;     break;
    case CP_E:   pt.x = w2;    pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2;    pt.y = -h2;    break;
    case CP_S:   pt.x = 0.0;   pt.y = -h1;    break;
    case CP_SW:  pt.x = -w2;   pt.y = -h2;    break;
    case CP_W:   pt.x = -w2;   pt.y = 0.0;    break;
    case CP_NW:  pt.x = -w2;   pt.y = h2;     break;
  }
  UNUSED_PARAMETER(p);
  return pt;
}

/* Methods for the "dot" class */
static void dotInit(Pik *p, PElem *pElem){
  pElem->rad = pik_value(p, "dotrad",6,0);
  pElem->h = pElem->w = pElem->rad*6;
  pElem->fill = pElem->color;
}
static void dotNumProp(Pik *p, PElem *pElem, PToken *pId){
  switch( pId->eType ){
    case T_COLOR:
      pElem->fill = pElem->color;
      break;
    case T_FILL:
      pElem->color = pElem->fill;
      break;
  }
  UNUSED_PARAMETER(p);
}
static void dotCheck(Pik *p, PElem *pElem){
  pElem->w = pElem->h = 0;
  pik_bbox_addellipse(&pElem->bbox, pElem->ptAt.x, pElem->ptAt.y,
                       pElem->rad, pElem->rad);
  UNUSED_PARAMETER(p);
}
static PPoint dotOffset(Pik *p, PElem *pElem, int cp){
  PPoint zero;
  zero.x = zero.y = 0;
  UNUSED_PARAMETER(p);
  UNUSED_PARAMETER(pElem);
  UNUSED_PARAMETER(cp);
  return zero;
}
static void dotRender(Pik *p, PElem *pElem){
  PNum r = pElem->rad;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){
    pik_append_x(p,"<circle cx=\"", pt.x, "\"");
3841
3842
3843
3844
3845
3846
3847

3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866

3867
3868
3869
3870
3871
3872
3873
  if( pElem->h<=0.0 ) return pElem->ptAt;
  s = pElem->h/pElem->w;
  dq = dx*s;
  dist = hypot(dq,dy);
  if( dist<pElem->h ) return pElem->ptAt;
  chop.x = pElem->ptAt.x + 0.5*dq*pElem->h/(dist*s);
  chop.y = pElem->ptAt.y + 0.5*dy*pElem->h/dist;

  return chop;
}
static PPoint ellipseOffset(Pik *p, PElem *pElem, int cp){
  PPoint pt;
  PNum w = pElem->w*0.5;
  PNum w2 = w*0.70710678118654747608;
  PNum h = pElem->h*0.5;
  PNum h2 = h*0.70710678118654747608;
  switch( boxTranslateEndPoint(pElem,cp) ){
    case CP_C:   pt.x = 0.0;   pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;   pt.y = h;      break;
    case CP_NE:  pt.x = w2;    pt.y = h2;     break;
    case CP_E:   pt.x = w;     pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2;    pt.y = -h2;    break;
    case CP_S:   pt.x = 0.0;   pt.y = -h;     break;
    case CP_SW:  pt.x = -w2;   pt.y = -h2;    break;
    case CP_W:   pt.x = -w;    pt.y = 0.0;    break;
    case CP_NW:  pt.x = -w2;   pt.y = h2;     break;
  }

  return pt;
}
static void ellipseRender(Pik *p, PElem *pElem){
  PNum w = pElem->w;
  PNum h = pElem->h;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){







>








|










>







3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
  if( pElem->h<=0.0 ) return pElem->ptAt;
  s = pElem->h/pElem->w;
  dq = dx*s;
  dist = hypot(dq,dy);
  if( dist<pElem->h ) return pElem->ptAt;
  chop.x = pElem->ptAt.x + 0.5*dq*pElem->h/(dist*s);
  chop.y = pElem->ptAt.y + 0.5*dy*pElem->h/dist;
  UNUSED_PARAMETER(p);
  return chop;
}
static PPoint ellipseOffset(Pik *p, PElem *pElem, int cp){
  PPoint pt;
  PNum w = pElem->w*0.5;
  PNum w2 = w*0.70710678118654747608;
  PNum h = pElem->h*0.5;
  PNum h2 = h*0.70710678118654747608;
  switch( cp ){
    case CP_C:   pt.x = 0.0;   pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;   pt.y = h;      break;
    case CP_NE:  pt.x = w2;    pt.y = h2;     break;
    case CP_E:   pt.x = w;     pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2;    pt.y = -h2;    break;
    case CP_S:   pt.x = 0.0;   pt.y = -h;     break;
    case CP_SW:  pt.x = -w2;   pt.y = -h2;    break;
    case CP_W:   pt.x = -w;    pt.y = 0.0;    break;
    case CP_NW:  pt.x = -w2;   pt.y = h2;     break;
  }
  UNUSED_PARAMETER(p);
  return pt;
}
static void ellipseRender(Pik *p, PElem *pElem){
  PNum w = pElem->w;
  PNum h = pElem->h;
  PPoint pt = pElem->ptAt;
  if( pElem->sw>0.0 ){
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912

3913
3914
3915
3916
3917

3918
3919
3920
3921
3922
3923
3924
  PNum h2 = 0.5*pElem->h;
  PNum rx = pElem->rad;
  PNum mn = w2<h2 ? w2 : h2;
  if( rx>mn ) rx = mn;
  if( rx<mn*0.25 ) rx = mn*0.25;
  pt.x = pt.y = 0.0;
  rx *= 0.5;
  switch( boxTranslateEndPoint(pElem,cp) ){
    case CP_C:   pt.x = 0.0;      pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;      pt.y = h2;     break;
    case CP_NE:  pt.x = w2-rx;    pt.y = h2-rx;  break;
    case CP_E:   pt.x = w2;       pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2;       pt.y = -h2;    break;
    case CP_S:   pt.x = 0.0;      pt.y = -h2;    break;
    case CP_SW:  pt.x = -w2;      pt.y = -h2;    break;
    case CP_W:   pt.x = -w2;      pt.y = 0.0;    break;
    case CP_NW:  pt.x = -w2;      pt.y = h2;     break;
  }

  return pt;
}
static void fileFit(Pik *p, PElem *pElem, PNum w, PNum h){
  if( w>0 ) pElem->w = w;
  if( h>0 ) pElem->h = h + 2*pElem->rad;

}
static void fileRender(Pik *p, PElem *pElem){
  PNum w2 = 0.5*pElem->w;
  PNum h2 = 0.5*pElem->h;
  PNum rad = pElem->rad;
  PPoint pt = pElem->ptAt;
  PNum mn = w2<h2 ? w2 : h2;







|










>





>







3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
  PNum h2 = 0.5*pElem->h;
  PNum rx = pElem->rad;
  PNum mn = w2<h2 ? w2 : h2;
  if( rx>mn ) rx = mn;
  if( rx<mn*0.25 ) rx = mn*0.25;
  pt.x = pt.y = 0.0;
  rx *= 0.5;
  switch( cp ){
    case CP_C:   pt.x = 0.0;      pt.y = 0.0;    break;
    case CP_N:   pt.x = 0.0;      pt.y = h2;     break;
    case CP_NE:  pt.x = w2-rx;    pt.y = h2-rx;  break;
    case CP_E:   pt.x = w2;       pt.y = 0.0;    break;
    case CP_SE:  pt.x = w2;       pt.y = -h2;    break;
    case CP_S:   pt.x = 0.0;      pt.y = -h2;    break;
    case CP_SW:  pt.x = -w2;      pt.y = -h2;    break;
    case CP_W:   pt.x = -w2;      pt.y = 0.0;    break;
    case CP_NW:  pt.x = -w2;      pt.y = h2;     break;
  }
  UNUSED_PARAMETER(p);
  return pt;
}
static void fileFit(Pik *p, PElem *pElem, PNum w, PNum h){
  if( w>0 ) pElem->w = w;
  if( h>0 ) pElem->h = h + 2*pElem->rad;
  UNUSED_PARAMETER(p);
}
static void fileRender(Pik *p, PElem *pElem){
  PNum w2 = 0.5*pElem->w;
  PNum h2 = 0.5*pElem->h;
  PNum rad = pElem->rad;
  PPoint pt = pElem->ptAt;
  PNum mn = w2<h2 ? w2 : h2;
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
static void lineInit(Pik *p, PElem *pElem){
  pElem->w = pik_value(p, "linewid",7,0);
  pElem->h = pik_value(p, "lineht",6,0);
  pElem->rad = pik_value(p, "linerad",7,0);
  pElem->fill = -1.0;
}
static PPoint lineOffset(Pik *p, PElem *pElem, int cp){

#if 0
  /* In legacy PIC, the .center of an unclosed line is half way between
  ** its .start and .end. */
  if( cp==CP_C && !pElem->bClose ){
    PPoint out;
    out.x = 0.5*(pElem->ptEnter.x + pElem->ptExit.x) - pElem->ptAt.x;
    out.y = 0.5*(pElem->ptEnter.x + pElem->ptExit.y) - pElem->ptAt.y;
    return out;
  }
#endif

  return boxOffset(p,pElem,cp);
}
static void lineRender(Pik *p, PElem *pElem){
  int i;
  if( pElem->sw>0.0 ){
    const char *z = "<path d=\"M";
    int n = pElem->nPath;







<










<







3945
3946
3947
3948
3949
3950
3951

3952
3953
3954
3955
3956
3957
3958
3959
3960
3961

3962
3963
3964
3965
3966
3967
3968
static void lineInit(Pik *p, PElem *pElem){
  pElem->w = pik_value(p, "linewid",7,0);
  pElem->h = pik_value(p, "lineht",6,0);
  pElem->rad = pik_value(p, "linerad",7,0);
  pElem->fill = -1.0;
}
static PPoint lineOffset(Pik *p, PElem *pElem, int cp){

#if 0
  /* In legacy PIC, the .center of an unclosed line is half way between
  ** its .start and .end. */
  if( cp==CP_C && !pElem->bClose ){
    PPoint out;
    out.x = 0.5*(pElem->ptEnter.x + pElem->ptExit.x) - pElem->ptAt.x;
    out.y = 0.5*(pElem->ptEnter.x + pElem->ptExit.y) - pElem->ptAt.y;
    return out;
  }
#endif

  return boxOffset(p,pElem,cp);
}
static void lineRender(Pik *p, PElem *pElem){
  int i;
  if( pElem->sw>0.0 ){
    const char *z = "<path d=\"M";
    int n = pElem->nPath;
3999
4000
4001
4002
4003
4004
4005


4006
4007
4008
4009
4010
4011
4012
4013
4014


4015
4016
4017
4018
4019

4020
4021
4022
4023
4024
4025
4026
  pElem->h = pElem->w;
  pElem->fill = -1.0;
  pElem->color = -1.0;
  pElem->sw = -1.0;
}
static void moveRender(Pik *p, PElem *pElem){
  /* No-op */


}

/* Methods for the "oval" class */
static void ovalInit(Pik *p, PElem *pElem){
  pElem->h = pik_value(p, "ovalht",6,0);
  pElem->w = pik_value(p, "ovalwid",7,0);
  pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
}
static void ovalNumProp(Pik *p, PElem *pElem, PToken *pId){


  /* Always adjust the radius to be half of the smaller of
  ** the width and height. */
  pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
}
static void ovalFit(Pik *p, PElem *pElem, PNum w, PNum h){

  if( w>0 ) pElem->w = w;
  if( h>0 ) pElem->h = h;
  if( pElem->w<pElem->h ) pElem->w = pElem->h;
}










>
>









>
>





>







3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
  pElem->h = pElem->w;
  pElem->fill = -1.0;
  pElem->color = -1.0;
  pElem->sw = -1.0;
}
static void moveRender(Pik *p, PElem *pElem){
  /* No-op */
  UNUSED_PARAMETER(p);
  UNUSED_PARAMETER(pElem);
}

/* Methods for the "oval" class */
static void ovalInit(Pik *p, PElem *pElem){
  pElem->h = pik_value(p, "ovalht",6,0);
  pElem->w = pik_value(p, "ovalwid",7,0);
  pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
}
static void ovalNumProp(Pik *p, PElem *pElem, PToken *pId){
  UNUSED_PARAMETER(p);
  UNUSED_PARAMETER(pId);
  /* Always adjust the radius to be half of the smaller of
  ** the width and height. */
  pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
}
static void ovalFit(Pik *p, PElem *pElem, PNum w, PNum h){
  UNUSED_PARAMETER(p);
  if( w>0 ) pElem->w = w;
  if( h>0 ) pElem->h = h;
  if( pElem->w<pElem->h ) pElem->w = pElem->h;
}



4112
4113
4114
4115
4116
4117
4118

4119
4120
4121
4122
4123
4124
4125
  return boxOffset(p, pElem, cp);
}

/* Methods for the "sublist" class */
static void sublistInit(Pik *p, PElem *pElem){
  PEList *pList = pElem->pSublist;
  int i;

  pik_bbox_init(&pElem->bbox);
  for(i=0; i<pList->n; i++){
    pik_bbox_addbox(&pElem->bbox, &pList->a[i]->bbox);
  }
  pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
  pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
  pElem->ptAt.x = 0.5*(pElem->bbox.ne.x + pElem->bbox.sw.x);







>







4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
  return boxOffset(p, pElem, cp);
}

/* Methods for the "sublist" class */
static void sublistInit(Pik *p, PElem *pElem){
  PEList *pList = pElem->pSublist;
  int i;
  UNUSED_PARAMETER(p);
  pik_bbox_init(&pElem->bbox);
  for(i=0; i<pList->n; i++){
    pik_bbox_addbox(&pElem->bbox, &pList->a[i]->bbox);
  }
  pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
  pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
  pElem->ptAt.x = 0.5*(pElem->bbox.ne.x + pElem->bbox.sw.x);
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
   };


/*
** Reduce the length of the line segment by amt (if possible) by
** modifying the location of *t.
*/
static void pik_chop(Pik *p, PPoint *f, PPoint *t, PNum amt){
  PNum dx = t->x - f->x;
  PNum dy = t->y - f->y;
  PNum dist = hypot(dx,dy);
  PNum r;
  if( dist<=amt ){
    *t = *f;
    return;







|







4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
   };


/*
** Reduce the length of the line segment by amt (if possible) by
** modifying the location of *t.
*/
static void pik_chop(PPoint *f, PPoint *t, PNum amt){
  PNum dx = t->x - f->x;
  PNum dy = t->y - f->y;
  PNum dist = hypot(dx,dy);
  PNum r;
  if( dist<=amt ){
    *t = *f;
    return;
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
  ddy = w*dx;
  bx = f->x + e1*dx;
  by = f->y + e1*dy;
  pik_append_xy(p,"<polygon points=\"", t->x, t->y);
  pik_append_xy(p," ",bx-ddx, by-ddy);
  pik_append_xy(p," ",bx+ddx, by+ddy);
  pik_append_clr(p,"\" style=\"fill:",pElem->color,"\"/>\n");
  pik_chop(p,f,t,h/2);
}

/*
** Compute the relative offset to an edge location from the reference for a
** an element.
*/
static PPoint pik_elem_offset(Pik *p, PElem *pElem, int cp){







|







4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
  ddy = w*dx;
  bx = f->x + e1*dx;
  by = f->y + e1*dy;
  pik_append_xy(p,"<polygon points=\"", t->x, t->y);
  pik_append_xy(p," ",bx-ddx, by-ddy);
  pik_append_xy(p," ",bx+ddx, by+ddy);
  pik_append_clr(p,"\" style=\"fill:",pElem->color,"\"/>\n");
  pik_chop(f,t,h/2);
}

/*
** Compute the relative offset to an edge location from the reference for a
** an element.
*/
static PPoint pik_elem_offset(Pik *p, PElem *pElem, int cp){
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550

/*
** Compute the vertical locations for all text items in the
** element pElem.  In other words, set every pElem->aTxt[*].eCode
** value to contain exactly one of: TP_ABOVE2, TP_ABOVE, TP_CENTER,
** TP_BELOW, or TP_BELOW2 is set.
*/
static void pik_txt_vertical_layout(Pik *p, PElem *pElem){
  int n, i;
  PToken *aTxt;
  n = pElem->nTxt;
  if( n==0 ) return;
  aTxt = pElem->aTxt;
  if( n==1 ){
    if( (aTxt[0].eCode & TP_VMASK)==0 ){







|







4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551

/*
** Compute the vertical locations for all text items in the
** element pElem.  In other words, set every pElem->aTxt[*].eCode
** value to contain exactly one of: TP_ABOVE2, TP_ABOVE, TP_CENTER,
** TP_BELOW, or TP_BELOW2 is set.
*/
static void pik_txt_vertical_layout(PElem *pElem){
  int n, i;
  PToken *aTxt;
  n = pElem->nTxt;
  if( n==0 ) return;
  aTxt = pElem->aTxt;
  if( n==1 ){
    if( (aTxt[0].eCode & TP_VMASK)==0 ){
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
  int hasCenter = 0;

  if( p->nErr ) return;
  if( pElem->nTxt==0 ) return;
  aTxt = pElem->aTxt;
  dy = 0.5*p->charHeight;
  n = pElem->nTxt;
  pik_txt_vertical_layout(p, pElem);
  x = pElem->ptAt.x;
  for(i=0; i<n; i++){
    if( (pElem->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
  }
  if( hasCenter ){
    dy2 = dy;
  }else if( pElem->type->isLine ){







|







4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
  int hasCenter = 0;

  if( p->nErr ) return;
  if( pElem->nTxt==0 ) return;
  aTxt = pElem->aTxt;
  dy = 0.5*p->charHeight;
  n = pElem->nTxt;
  pik_txt_vertical_layout(pElem);
  x = pElem->ptAt.x;
  for(i=0; i<n; i++){
    if( (pElem->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
  }
  if( hasCenter ){
    dy2 = dy;
  }else if( pElem->type->isLine ){
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
  for(j=i; j>0 && p->zIn[j-1]!='\n'; j--){}
  iCol = i - j;
  for(nExtra=0; (c = p->zIn[i+nExtra])!=0 && c!='\n'; nExtra++){}
  pik_append(p, "<div><pre>\n", -1);
  pik_append_text(p, p->zIn, i+nExtra, 3);
  pik_append(p, "\n", 1);
  for(i=0; i<iCol; i++){ pik_append(p, " ", 1); }
  for(i=0; i<pErr->n; i++) pik_append(p, "^", 1);
  pik_append(p, "\nERROR: ", -1);
  pik_append_text(p, zMsg, -1, 0);
  pik_append(p, "\n", 1);
  pik_append(p, "\n</pre></div>\n", -1);
}

/*







|







4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
  for(j=i; j>0 && p->zIn[j-1]!='\n'; j--){}
  iCol = i - j;
  for(nExtra=0; (c = p->zIn[i+nExtra])!=0 && c!='\n'; nExtra++){}
  pik_append(p, "<div><pre>\n", -1);
  pik_append_text(p, p->zIn, i+nExtra, 3);
  pik_append(p, "\n", 1);
  for(i=0; i<iCol; i++){ pik_append(p, " ", 1); }
  for(i=0; i<(int)pErr->n; i++) pik_append(p, "^", 1);
  pik_append(p, "\nERROR: ", -1);
  pik_append_text(p, zMsg, -1, 0);
  pik_append(p, "\n", 1);
  pik_append(p, "\n</pre></div>\n", -1);
}

/*
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
**   (2)    Same as (1) but followed by a unit: "cm", "mm", "in",
**          "px", "pt", or "pc".
**   (3)    Hex integers: 0x000000
**
** This routine returns the result in inches.  If a different unit
** is specified, the conversion happens automatically.
*/
PNum pik_atof(Pik *p, PToken *num){
  char *endptr;
  PNum ans;
  if( num->n>=3 && num->z[0]=='0' && (num->z[1]=='x'||num->z[1]=='X') ){
    return (PNum)strtol(num->z+2, 0, 16);
  }
  ans = strtod(num->z, &endptr);
  if( (int)(endptr - num->z)==num->n-2 ){
    char c1 = endptr[0];
    char c2 = endptr[1];
    if( c1=='c' && c2=='m' ){
      ans /= 2.54;
    }else if( c1=='m' && c2=='m' ){
      ans /= 25.4;
    }else if( c1=='p' && c2=='x' ){







|






|







4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
**   (2)    Same as (1) but followed by a unit: "cm", "mm", "in",
**          "px", "pt", or "pc".
**   (3)    Hex integers: 0x000000
**
** This routine returns the result in inches.  If a different unit
** is specified, the conversion happens automatically.
*/
PNum pik_atof(PToken *num){
  char *endptr;
  PNum ans;
  if( num->n>=3 && num->z[0]=='0' && (num->z[1]=='x'||num->z[1]=='X') ){
    return (PNum)strtol(num->z+2, 0, 16);
  }
  ans = strtod(num->z, &endptr);
  if( (int)(endptr - num->z)==(int)num->n-2 ){
    char c1 = endptr[0];
    char c2 = endptr[1];
    if( c1=='c' && c2=='m' ){
      ans /= 2.54;
    }else if( c1=='m' && c2=='m' ){
      ans /= 25.4;
    }else if( c1=='p' && c2=='x' ){
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
  pNew->ptExit = pNew->ptEnter = pNew->ptAt;
  return pNew;
}

/*
** Set the output direction and exit point for an element.
*/
static void pik_elem_set_exit(Pik *p, PElem *pElem, int eDir){
  assert( ValidDir(eDir) );
  pElem->outDir = eDir;
  if( !pElem->type->isLine || pElem->bClose ){
    pElem->ptExit = pElem->ptAt;
    switch( pElem->outDir ){
      default:         pElem->ptExit.x += pElem->w*0.5;  break;
      case DIR_LEFT:   pElem->ptExit.x -= pElem->w*0.5;  break;







|







5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
  pNew->ptExit = pNew->ptEnter = pNew->ptAt;
  return pNew;
}

/*
** Set the output direction and exit point for an element.
*/
static void pik_elem_set_exit(PElem *pElem, int eDir){
  assert( ValidDir(eDir) );
  pElem->outDir = eDir;
  if( !pElem->type->isLine || pElem->bClose ){
    pElem->ptExit = pElem->ptAt;
    switch( pElem->outDir ){
      default:         pElem->ptExit.x += pElem->w*0.5;  break;
      case DIR_LEFT:   pElem->ptExit.x -= pElem->w*0.5;  break;
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
  **      arrow; circle; down; arrow
  **
  ** You can make pikchr render the above exactly like PIC
  ** by deleting the following three lines.  But I (drh) think
  ** it works better with those lines in place.
  */
  if( p->list && p->list->n ){
    pik_elem_set_exit(p, p->list->a[p->list->n-1], eDir);
  }
}

/* Move all coordinates contained within an element (and within its
** substructure) by dx, dy
*/
static void pik_elem_move(PElem *pElem, PNum dx, PNum dy){







|







5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
  **      arrow; circle; down; arrow
  **
  ** You can make pikchr render the above exactly like PIC
  ** by deleting the following three lines.  But I (drh) think
  ** it works better with those lines in place.
  */
  if( p->list && p->list->n ){
    pik_elem_set_exit(p->list->a[p->list->n-1], eDir);
  }
}

/* Move all coordinates contained within an element (and within its
** substructure) by dx, dy
*/
static void pik_elem_move(PElem *pElem, PNum dx, PNum dy){
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
  }
}

/*
** If the current path information came from a "same" or "same as"
** reset it.
*/
static void pik_reset_samepath(Pik *p, PElem *pElem){
  if( p->samePath ){
    p->samePath = 0;
    p->nTPath = 1;
  }
}









|







5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
  }
}

/*
** If the current path information came from a "same" or "same as"
** reset it.
*/
static void pik_reset_samepath(Pik *p){
  if( p->samePath ){
    p->samePath = 0;
    p->nTPath = 1;
  }
}


5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
  p->thenFlag = 1;
}

/* Advance to the next entry in p->aTPath.  Return its index.
*/
static int pik_next_rpath(Pik *p, PToken *pErr){
  int n = p->nTPath - 1;
  if( n+1>=count(p->aTPath) ){
    pik_error(0, pErr, "too many path elements");
    return n;
  }
  n++;
  p->nTPath++;
  p->aTPath[n] = p->aTPath[n-1];
  p->mTPath = 0;







|







5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
  p->thenFlag = 1;
}

/* Advance to the next entry in p->aTPath.  Return its index.
*/
static int pik_next_rpath(Pik *p, PToken *pErr){
  int n = p->nTPath - 1;
  if( n+1>=(int)count(p->aTPath) ){
    pik_error(0, pErr, "too many path elements");
    return n;
  }
  n++;
  p->nTPath++;
  p->aTPath[n] = p->aTPath[n-1];
  p->mTPath = 0;
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
  PElem *pElem = p->cur;
  int n;
  int dir;
  if( !pElem->type->isLine ){
    if( pDir ){
      pik_error(p, pDir, "use with line-oriented objects only");
    }else{
      PToken x = pik_next_semantic_token(p, &pElem->errTok);
      pik_error(p, &x, "syntax error");
    }
    return;
  }
  pik_reset_samepath(p, pElem);
  n = p->nTPath - 1;
  if( p->thenFlag || p->mTPath==3 || n==0 ){
    n = pik_next_rpath(p, pDir);
    p->thenFlag = 0;
  }
  dir = pDir ? pDir->eCode : p->eDir;
  switch( dir ){







|




|







5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
  PElem *pElem = p->cur;
  int n;
  int dir;
  if( !pElem->type->isLine ){
    if( pDir ){
      pik_error(p, pDir, "use with line-oriented objects only");
    }else{
      PToken x = pik_next_semantic_token(&pElem->errTok);
      pik_error(p, &x, "syntax error");
    }
    return;
  }
  pik_reset_samepath(p);
  n = p->nTPath - 1;
  if( p->thenFlag || p->mTPath==3 || n==0 ){
    n = pik_next_rpath(p, pDir);
    p->thenFlag = 0;
  }
  dir = pDir ? pDir->eCode : p->eDir;
  switch( dir ){
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
  PElem *pElem = p->cur;
  int n;
  PNum rDist = pDist->rAbs + pik_value(p,"linewid",7,0)*pDist->rRel;
  if( !pElem->type->isLine ){
    pik_error(p, pErr, "use with line-oriented objects only");
    return;
  }
  pik_reset_samepath(p, pElem);
  do{
    n = pik_next_rpath(p, pErr);
  }while( n<1 );
  if( pHeading ){
    if( rHdg<0.0 || rHdg>360.0 ){
      pik_error(p, pHeading, "headings should be between 0 and 360");
      return;







|







5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
  PElem *pElem = p->cur;
  int n;
  PNum rDist = pDist->rAbs + pik_value(p,"linewid",7,0)*pDist->rRel;
  if( !pElem->type->isLine ){
    pik_error(p, pErr, "use with line-oriented objects only");
    return;
  }
  pik_reset_samepath(p);
  do{
    n = pik_next_rpath(p, pErr);
  }while( n<1 );
  if( pHeading ){
    if( rHdg<0.0 || rHdg>360.0 ){
      pik_error(p, pHeading, "headings should be between 0 and 360");
      return;
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
  PElem *pElem = p->cur;
  int n;
  if( !pElem->type->isLine ){
    pik_error(p, pDir, "use with line-oriented objects only");
    return;
  }
  pik_reset_samepath(p, pElem);
  n = p->nTPath - 1;
  if( p->thenFlag || p->mTPath==3 || n==0 ){
    n = pik_next_rpath(p, pDir);
    p->thenFlag = 0;
  }
  switch( pDir->eCode ){
    case DIR_DOWN:







|







5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
  PElem *pElem = p->cur;
  int n;
  if( !pElem->type->isLine ){
    pik_error(p, pDir, "use with line-oriented objects only");
    return;
  }
  pik_reset_samepath(p);
  n = p->nTPath - 1;
  if( p->thenFlag || p->mTPath==3 || n==0 ){
    n = pik_next_rpath(p, pDir);
    p->thenFlag = 0;
  }
  switch( pDir->eCode ){
    case DIR_DOWN:
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
    return;
  }
  if( pElem->mProp & A_AT ){
    pik_error(p, pErrTok, "location fixed by prior \"at\"");
    return;
  }
  pElem->mProp |= A_AT;
  pElem->eWith = pEdge ? boxTranslateEndPoint(pElem,pEdge->eEdge) : CP_C;
  pElem->with = *pAt;
}

/*
** Try to add a text attribute to an element
*/
static void pik_add_txt(Pik *p, PToken *pTxt, int iPos){
  PElem *pElem = p->cur;
  PToken *pT;
  if( pElem->nTxt >= count(pElem->aTxt) ){
    pik_error(p, pTxt, "too many text terms");
    return;
  }
  pT = &pElem->aTxt[pElem->nTxt++];
  *pT = *pTxt;
  pT->eCode = iPos;
}

/* Merge "text-position" flags
*/
static int pik_text_position(Pik *p, int iPrev, PToken *pFlag){
  int iRes = iPrev;
  switch( pFlag->eType ){
    case T_LJUST:    iRes = (iRes&~TP_JMASK) | TP_LJUST;  break;
    case T_RJUST:    iRes = (iRes&~TP_JMASK) | TP_RJUST;  break;
    case T_ABOVE:    iRes = (iRes&~TP_VMASK) | TP_ABOVE;  break;
    case T_CENTER:   iRes = (iRes&~TP_VMASK) | TP_CENTER; break;
    case T_BELOW:    iRes = (iRes&~TP_VMASK) | TP_BELOW;  break;







|




















|







5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
    return;
  }
  if( pElem->mProp & A_AT ){
    pik_error(p, pErrTok, "location fixed by prior \"at\"");
    return;
  }
  pElem->mProp |= A_AT;
  pElem->eWith = pEdge ? pEdge->eEdge : CP_C;
  pElem->with = *pAt;
}

/*
** Try to add a text attribute to an element
*/
static void pik_add_txt(Pik *p, PToken *pTxt, int iPos){
  PElem *pElem = p->cur;
  PToken *pT;
  if( pElem->nTxt >= count(pElem->aTxt) ){
    pik_error(p, pTxt, "too many text terms");
    return;
  }
  pT = &pElem->aTxt[pElem->nTxt++];
  *pT = *pTxt;
  pT->eCode = iPos;
}

/* Merge "text-position" flags
*/
static int pik_text_position(int iPrev, PToken *pFlag){
  int iRes = iPrev;
  switch( pFlag->eType ){
    case T_LJUST:    iRes = (iRes&~TP_JMASK) | TP_LJUST;  break;
    case T_RJUST:    iRes = (iRes&~TP_JMASK) | TP_RJUST;  break;
    case T_ABOVE:    iRes = (iRes&~TP_VMASK) | TP_ABOVE;  break;
    case T_CENTER:   iRes = (iRes&~TP_VMASK) | TP_CENTER; break;
    case T_BELOW:    iRes = (iRes&~TP_VMASK) | TP_BELOW;  break;
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
    return;
  }
  if( pElem->type->xFit==0 ) return;
  if( (pElem->mProp & A_HEIGHT)==0 ){
    int hasCenter = 0;
    int hasSingleStack = 0;
    int hasDoubleStack = 0;
    pik_txt_vertical_layout(p, pElem);
    for(i=0; i<pElem->nTxt; i++){
      if( pElem->aTxt[i].eCode & TP_CENTER ){
        hasCenter = 1;
      }else if( pElem->aTxt[i].eCode & (TP_ABOVE2|TP_BELOW2) ){
        hasDoubleStack = 1;
      }else if( pElem->aTxt[i].eCode & (TP_ABOVE|TP_BELOW) ){
        hasSingleStack = 1;







|







5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
    return;
  }
  if( pElem->type->xFit==0 ) return;
  if( (pElem->mProp & A_HEIGHT)==0 ){
    int hasCenter = 0;
    int hasSingleStack = 0;
    int hasDoubleStack = 0;
    pik_txt_vertical_layout(pElem);
    for(i=0; i<pElem->nTxt; i++){
      if( pElem->aTxt[i].eCode & TP_CENTER ){
        hasCenter = 1;
      }else if( pElem->aTxt[i].eCode & (TP_ABOVE2|TP_BELOW2) ){
        hasDoubleStack = 1;
      }else if( pElem->aTxt[i].eCode & (TP_ABOVE|TP_BELOW) ){
        hasSingleStack = 1;
5734
5735
5736
5737
5738
5739
5740
5741

5742
5743
5744
5745
5746
5747
5748
*/
static PNum pik_lookup_color(Pik *p, PToken *pId){
  int first, last, mid, c = 0;
  first = 0;
  last = count(aColor)-1;
  while( first<=last ){
    const char *zClr;
    int c1, c2, i;

    mid = (first+last)/2;
    zClr = aColor[mid].zName;
    for(i=0; i<pId->n; i++){
      c1 = zClr[i]&0x7f;
      if( isupper(c1) ) c1 = tolower(c1);
      c2 = pId->z[i]&0x7f;
      if( isupper(c2) ) c2 = tolower(c2);







|
>







5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
*/
static PNum pik_lookup_color(Pik *p, PToken *pId){
  int first, last, mid, c = 0;
  first = 0;
  last = count(aColor)-1;
  while( first<=last ){
    const char *zClr;
    int c1, c2;
    unsigned int i;
    mid = (first+last)/2;
    zClr = aColor[mid].zName;
    for(i=0; i<pId->n; i++){
      c1 = zClr[i]&0x7f;
      if( isupper(c1) ) c1 = tolower(c1);
      c2 = pId->z[i]&0x7f;
      if( isupper(c2) ) c2 = tolower(c2);
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
  }else{
    return pElem->ptExit;
  }
}

/* Do a linear interpolation of two positions.
*/
static PPoint pik_position_between(Pik *p, PNum x, PPoint p1, PPoint p2){
  PPoint out;
  if( x<0.0 ) x = 0.0;
  if( x>1.0 ) x = 1.0;
  out.x = p2.x*x + p1.x*(1.0 - x);
  out.y = p2.y*x + p1.y*(1.0 - x);
  return out;
}

/* Compute the position that is dist away from pt at an heading angle of r
**
** The angle is a compass heading in degrees.  North is 0 (or 360).
** East is 90.  South is 180.  West is 270.  And so forth.
*/
static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt){
  r *= 0.017453292519943295769;  /* degrees to radians */
  pt.x += dist*sin(r);
  pt.y += dist*cos(r);
  return pt;
}

/* Compute the position that is dist away at a compass point
*/
static PPoint pik_position_at_hdg(Pik *p, PNum dist, PToken *pD, PPoint pt){
  return pik_position_at_angle(p, dist, pik_hdg_angle[pD->eEdge], pt);
}

/* Return the coordinates for the n-th vertex of a line.
*/
static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pObj){
  static const PPoint zero;
  int n;







|













|








|
|







5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
  }else{
    return pElem->ptExit;
  }
}

/* Do a linear interpolation of two positions.
*/
static PPoint pik_position_between(PNum x, PPoint p1, PPoint p2){
  PPoint out;
  if( x<0.0 ) x = 0.0;
  if( x>1.0 ) x = 1.0;
  out.x = p2.x*x + p1.x*(1.0 - x);
  out.y = p2.y*x + p1.y*(1.0 - x);
  return out;
}

/* Compute the position that is dist away from pt at an heading angle of r
**
** The angle is a compass heading in degrees.  North is 0 (or 360).
** East is 90.  South is 180.  West is 270.  And so forth.
*/
static PPoint pik_position_at_angle(PNum dist, PNum r, PPoint pt){
  r *= 0.017453292519943295769;  /* degrees to radians */
  pt.x += dist*sin(r);
  pt.y += dist*cos(r);
  return pt;
}

/* Compute the position that is dist away at a compass point
*/
static PPoint pik_position_at_hdg(PNum dist, PToken *pD, PPoint pt){
  return pik_position_at_angle(dist, pik_hdg_angle[pD->eEdge], pt);
}

/* Return the coordinates for the n-th vertex of a line.
*/
static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pObj){
  static const PPoint zero;
  int n;
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
    return zero;
  }
  return pObj->aPath[n-1];
}

/* Return the value of a property of an object.
*/
static PNum pik_property_of(Pik *p, PElem *pElem, PToken *pProp){
  PNum v = 0.0;
  switch( pProp->eType ){
    case T_HEIGHT:    v = pElem->h;            break;
    case T_WIDTH:     v = pElem->w;            break;
    case T_RADIUS:    v = pElem->rad;          break;
    case T_DIAMETER:  v = pElem->rad*2.0;      break;
    case T_THICKNESS: v = pElem->sw;           break;







|







6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
    return zero;
  }
  return pObj->aPath[n-1];
}

/* Return the value of a property of an object.
*/
static PNum pik_property_of(PElem *pElem, PToken *pProp){
  PNum v = 0.0;
  switch( pProp->eType ){
    case T_HEIGHT:    v = pElem->h;            break;
    case T_WIDTH:     v = pElem->w;            break;
    case T_RADIUS:    v = pElem->rad;          break;
    case T_DIAMETER:  v = pElem->rad*2.0;      break;
    case T_THICKNESS: v = pElem->sw;           break;
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202



6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
  /* Compute final bounding box, entry and exit points, center
  ** point (ptAt) and path for the element
  */
  if( pElem->type->isLine ){
    pElem->aPath = malloc( sizeof(PPoint)*p->nTPath );
    if( pElem->aPath==0 ){
      pik_error(p, 0, 0);
      pElem->nPath = 0;
    }else{
      pElem->nPath = p->nTPath;
      for(i=0; i<p->nTPath; i++){
        pElem->aPath[i] = p->aTPath[i];
        pik_bbox_add_xy(&pElem->bbox, pElem->aPath[i].x, pElem->aPath[i].y);
      }
    }

    /* "chop" processing:
    ** If the line goes to the center of an object with an
    ** xChop method, then use the xChop method to trim the line.
    */
    if( pElem->bChop && pElem->nPath>=2 ){
      int n = pElem->nPath;
      pik_autochop(p, &pElem->aPath[n-2], &pElem->aPath[n-1]);
      pik_autochop(p, &pElem->aPath[1], &pElem->aPath[0]);
    }

    pElem->ptEnter = p->aTPath[0];
    pElem->ptExit = p->aTPath[p->nTPath-1];

    /* Compute the center of the line based on the bounding box over
    ** the vertexes */



    pElem->ptAt.x = (pElem->bbox.ne.x + pElem->bbox.sw.x)/2.0;
    pElem->ptAt.y = (pElem->bbox.ne.y + pElem->bbox.sw.y)/2.0;

    /* Reset the width and height of the object to be the width and height
    ** of the bounding box over vertexes */
    pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
    pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;

    /* If this is a polygon (if it has the "close" attribute), then
    ** adjust the exit point */
    if( pElem->bClose ){
      /* "closed" lines work like block objects */
      pik_elem_set_exit(p, pElem, pElem->inDir);
    }else{
      /* For an open line, the "center" is half way between
      ** the .start and the .end */
    }
  }else{
    PNum w2 = pElem->w/2.0;
    PNum h2 = pElem->h/2.0;







|




<













|
|



>
>
>












|







6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185

6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
  /* Compute final bounding box, entry and exit points, center
  ** point (ptAt) and path for the element
  */
  if( pElem->type->isLine ){
    pElem->aPath = malloc( sizeof(PPoint)*p->nTPath );
    if( pElem->aPath==0 ){
      pik_error(p, 0, 0);
      return;
    }else{
      pElem->nPath = p->nTPath;
      for(i=0; i<p->nTPath; i++){
        pElem->aPath[i] = p->aTPath[i];

      }
    }

    /* "chop" processing:
    ** If the line goes to the center of an object with an
    ** xChop method, then use the xChop method to trim the line.
    */
    if( pElem->bChop && pElem->nPath>=2 ){
      int n = pElem->nPath;
      pik_autochop(p, &pElem->aPath[n-2], &pElem->aPath[n-1]);
      pik_autochop(p, &pElem->aPath[1], &pElem->aPath[0]);
    }

    pElem->ptEnter = pElem->aPath[0];
    pElem->ptExit = pElem->aPath[pElem->nPath-1];

    /* Compute the center of the line based on the bounding box over
    ** the vertexes */
    for(i=0; i<pElem->nPath; i++){
      pik_bbox_add_xy(&pElem->bbox, pElem->aPath[i].x, pElem->aPath[i].y);
    }
    pElem->ptAt.x = (pElem->bbox.ne.x + pElem->bbox.sw.x)/2.0;
    pElem->ptAt.y = (pElem->bbox.ne.y + pElem->bbox.sw.y)/2.0;

    /* Reset the width and height of the object to be the width and height
    ** of the bounding box over vertexes */
    pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
    pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;

    /* If this is a polygon (if it has the "close" attribute), then
    ** adjust the exit point */
    if( pElem->bClose ){
      /* "closed" lines work like block objects */
      pik_elem_set_exit(pElem, pElem->inDir);
    }else{
      /* For an open line, the "center" is half way between
      ** the .start and the .end */
    }
  }else{
    PNum w2 = pElem->w/2.0;
    PNum h2 = pElem->h/2.0;
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
          }
          if( c2<'0' || c>'9' ){
            /* This is not an exp */
            i -= 2;
          }else{
            i++;
            isInt = 0;
            while( (c = z[i])>=0 && c<='9' ){ i++; }
          }
        }
        c2 = c ? z[i+1] : 0;
        if( isInt ){
          if( (c=='t' && c2=='h')
           || (c=='r' && c2=='d')
           || (c=='n' && c2=='d')







|







6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
          }
          if( c2<'0' || c>'9' ){
            /* This is not an exp */
            i -= 2;
          }else{
            i++;
            isInt = 0;
            while( (c = z[i])>='0' && c<='9' ){ i++; }
          }
        }
        c2 = c ? z[i+1] : 0;
        if( isInt ){
          if( (c=='t' && c2=='h')
           || (c=='r' && c2=='d')
           || (c=='n' && c2=='d')
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
  }
}

/*
** Return a pointer to the next non-whitespace token after pThis.
** This is used to help form error messages.
*/
static PToken pik_next_semantic_token(Pik *p, PToken *pThis){
  PToken x;
  int sz;
  int i = pThis->n;
  memset(&x, 0, sizeof(x));
  x.z = pThis->z;
  while(1){
    x.z = pThis->z + i;







|







6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
  }
}

/*
** Return a pointer to the next non-whitespace token after pThis.
** This is used to help form error messages.
*/
static PToken pik_next_semantic_token(PToken *pThis){
  PToken x;
  int sz;
  int i = pThis->n;
  memset(&x, 0, sizeof(x));
  x.z = pThis->z;
  while(1){
    x.z = pThis->z + i;
7053
7054
7055
7056
7057
7058
7059
7060
    }
  }
  printf("</body></html>\n");
  return 0; 
}
#endif /* PIKCHR_SHELL */

#line 7085 "pikchr.c"







|
7057
7058
7059
7060
7061
7062
7063
7064
    }
  }
  printf("</body></html>\n");
  return 0; 
}
#endif /* PIKCHR_SHELL */

#line 7089 "pikchr.c"