Fossil SCM

Update Pikchr to the latest code from the Pikchr website.

drh 2020-09-10 22:56 trunk
Commit a5c685fa0d681d4a4844b6638fd7af52db9b35c68fad2d27c3acfe2b61c2b178
1 file changed +285 -265
+285 -265
--- src/pikchr.c
+++ src/pikchr.c
@@ -315,19 +315,23 @@
315315
const char *zIn; /* Input PIKCHR-language text. zero-terminated */
316316
unsigned int nIn; /* Number of bytes in zIn */
317317
char *zOut; /* Result accumulates here */
318318
unsigned int nOut; /* Bytes written to zOut[] so far */
319319
unsigned int nOutAlloc; /* Space allocated to zOut[] */
320
- PNum wArrow; /* Width of arrowhead at the fat end */
321
- PNum hArrow; /* Height of arrowhead - dist from tip to fat end */
322320
unsigned char eDir; /* Current direction */
323321
PElem *cur; /* Element under construction */
324322
PEList *list; /* Element list under construction */
325323
PVar *pVar; /* Application-defined variables */
326324
PBox bbox; /* Bounding box around all elements */
327
- PNum rScale; /* Multiply to convert inches to pixels */
328
- PNum fontScale; /* Scale fonts by this percent */
325
+ /* Cache of layout values. <=0.0 for unknown... */
326
+ PNum rScale; /* Multiply to convert inches to pixels */
327
+ PNum fontScale; /* Scale fonts by this percent */
328
+ PNum charWidth; /* Character width */
329
+ PNum charHeight; /* Character height */
330
+ PNum wArrow; /* Width of arrowhead at the fat end */
331
+ PNum hArrow; /* Ht of arrowhead - dist from tip to fat end */
332
+ int bLayoutVars; /* True if cache is valid */
329333
char thenFlag; /* True if "then" seen */
330334
const char *zClass; /* Class name for the <svg> */
331335
int wSVG, hSVG; /* Width and height of the <svg> */
332336
/* Paths for lines are constructed here first, then transferred into
333337
** the PElem object at the end: */
@@ -345,12 +349,12 @@
345349
char isLine; /* True if a line class */
346350
void (*xInit)(Pik*,PElem*); /* Initializer */
347351
void (*xNumProp)(Pik*,PElem*,PToken*); /* Value change notification */
348352
PPoint (*xChop)(PElem*,PPoint*); /* Chopper */
349353
PPoint (*xOffset)(Pik*,PElem*,int); /* Offset from center to edge point */
350
- void (*xFit)(Pik*,PElem*,int w,int h); /* Size to fit text */
351
- void (*xRender)(Pik*,PElem*); /* Render */
354
+ void (*xFit)(Pik*,PElem*,PNum w,PNum h); /* Size to fit text */
355
+ void (*xRender)(Pik*,PElem*); /* Render */
352356
};
353357
354358
355359
/* Forward declarations */
356360
static void pik_append(Pik*, const char*,int);
@@ -400,10 +404,11 @@
400404
static void pik_bbox_init(PBox*);
401405
static void pik_bbox_addbox(PBox*,PBox*);
402406
static void pik_bbox_addpt(PBox*,PPoint*);
403407
static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
404408
static void pik_add_txt(Pik*,PToken*,int);
409
+static int pik_text_length(const PToken *pToken);
405410
static void pik_size_to_fit(Pik*,PToken*);
406411
static int pik_text_position(Pik*,int,PToken*);
407412
static PNum pik_property_of(Pik*,PElem*,PToken*);
408413
static PNum pik_func(Pik*,PToken*,PNum,PNum);
409414
static PPoint pik_position_between(Pik *p, PNum x, PPoint p1, PPoint p2);
@@ -410,13 +415,14 @@
410415
static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt);
411416
static PPoint pik_position_at_hdg(Pik *p, PNum dist, PToken *pD, PPoint pt);
412417
static void pik_same(Pik *p, PElem*, PToken*);
413418
static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pElem);
414419
static PToken pik_next_semantic_token(Pik *p, PToken *pThis);
420
+static void pik_compute_layout_settings(Pik*);
415421
416422
417
-#line 443 "pikchr.c"
423
+#line 449 "pikchr.c"
418424
/**************** End of %include directives **********************************/
419425
/* These constants specify the various numeric values for terminal symbols.
420426
***************** Begin token definitions *************************************/
421427
#ifndef T_ID
422428
#define T_ID 1
@@ -1483,22 +1489,22 @@
14831489
** inside the C code.
14841490
*/
14851491
/********* Begin destructor definitions ***************************************/
14861492
case 82: /* element_list */
14871493
{
1488
-#line 432 "pikchr.y"
1494
+#line 438 "pikchr.y"
14891495
pik_elist_free(p,(yypminor->yy42));
1490
-#line 1515 "pikchr.c"
1496
+#line 1521 "pikchr.c"
14911497
}
14921498
break;
14931499
case 83: /* element */
14941500
case 84: /* unnamed_element */
14951501
case 85: /* basetype */
14961502
{
1497
-#line 434 "pikchr.y"
1503
+#line 440 "pikchr.y"
14981504
pik_elem_free(p,(yypminor->yy24));
1499
-#line 1524 "pikchr.c"
1505
+#line 1530 "pikchr.c"
15001506
}
15011507
break;
15021508
/********* End destructor definitions *****************************************/
15031509
default: break; /* If no destructor action specified: do nothing */
15041510
}
@@ -1712,14 +1718,14 @@
17121718
#endif
17131719
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
17141720
/* Here code is inserted which will execute if the parser
17151721
** stack every overflows */
17161722
/******** Begin %stack_overflow code ******************************************/
1717
-#line 463 "pikchr.y"
1723
+#line 469 "pikchr.y"
17181724
17191725
pik_error(p, 0, "parser stack overflow");
1720
-#line 1745 "pikchr.c"
1726
+#line 1751 "pikchr.c"
17211727
/******** End %stack_overflow code ********************************************/
17221728
pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
17231729
pik_parserCTX_STORE
17241730
}
17251731
@@ -2174,556 +2180,556 @@
21742180
** break;
21752181
*/
21762182
/********** Begin reduce actions **********************************************/
21772183
YYMINORTYPE yylhsminor;
21782184
case 0: /* document ::= element_list */
2179
-#line 467 "pikchr.y"
2185
+#line 473 "pikchr.y"
21802186
{pik_render(p,yymsp[0].minor.yy42);}
2181
-#line 2206 "pikchr.c"
2187
+#line 2212 "pikchr.c"
21822188
break;
21832189
case 1: /* element_list ::= element */
2184
-#line 470 "pikchr.y"
2190
+#line 476 "pikchr.y"
21852191
{ yylhsminor.yy42 = pik_elist_append(p,0,yymsp[0].minor.yy24); }
2186
-#line 2211 "pikchr.c"
2192
+#line 2217 "pikchr.c"
21872193
yymsp[0].minor.yy42 = yylhsminor.yy42;
21882194
break;
21892195
case 2: /* element_list ::= element_list EOL element */
2190
-#line 472 "pikchr.y"
2196
+#line 478 "pikchr.y"
21912197
{ yylhsminor.yy42 = pik_elist_append(p,yymsp[-2].minor.yy42,yymsp[0].minor.yy24); }
2192
-#line 2217 "pikchr.c"
2198
+#line 2223 "pikchr.c"
21932199
yymsp[-2].minor.yy42 = yylhsminor.yy42;
21942200
break;
21952201
case 3: /* element ::= */
2196
-#line 475 "pikchr.y"
2202
+#line 481 "pikchr.y"
21972203
{ yymsp[1].minor.yy24 = 0; }
2198
-#line 2223 "pikchr.c"
2204
+#line 2229 "pikchr.c"
21992205
break;
22002206
case 4: /* element ::= direction */
2201
-#line 476 "pikchr.y"
2207
+#line 482 "pikchr.y"
22022208
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy24=0; }
2203
-#line 2228 "pikchr.c"
2209
+#line 2234 "pikchr.c"
22042210
yymsp[0].minor.yy24 = yylhsminor.yy24;
22052211
break;
22062212
case 5: /* element ::= lvalue ASSIGN rvalue */
2207
-#line 477 "pikchr.y"
2213
+#line 483 "pikchr.y"
22082214
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy83,&yymsp[-1].minor.yy0); yylhsminor.yy24=0;}
2209
-#line 2234 "pikchr.c"
2215
+#line 2240 "pikchr.c"
22102216
yymsp[-2].minor.yy24 = yylhsminor.yy24;
22112217
break;
22122218
case 6: /* element ::= PLACENAME COLON unnamed_element */
2213
-#line 479 "pikchr.y"
2219
+#line 485 "pikchr.y"
22142220
{ yylhsminor.yy24 = yymsp[0].minor.yy24; pik_elem_setname(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0); }
2215
-#line 2240 "pikchr.c"
2221
+#line 2246 "pikchr.c"
22162222
yymsp[-2].minor.yy24 = yylhsminor.yy24;
22172223
break;
22182224
case 7: /* element ::= PLACENAME COLON position */
2219
-#line 481 "pikchr.y"
2225
+#line 487 "pikchr.y"
22202226
{ yylhsminor.yy24 = pik_elem_new(p,0,0,0);
22212227
if(yylhsminor.yy24){ yylhsminor.yy24->ptAt = yymsp[0].minor.yy49; pik_elem_setname(p,yylhsminor.yy24,&yymsp[-2].minor.yy0); }}
2222
-#line 2247 "pikchr.c"
2228
+#line 2253 "pikchr.c"
22232229
yymsp[-2].minor.yy24 = yylhsminor.yy24;
22242230
break;
22252231
case 8: /* element ::= unnamed_element */
2226
-#line 483 "pikchr.y"
2232
+#line 489 "pikchr.y"
22272233
{yylhsminor.yy24 = yymsp[0].minor.yy24;}
2228
-#line 2253 "pikchr.c"
2234
+#line 2259 "pikchr.c"
22292235
yymsp[0].minor.yy24 = yylhsminor.yy24;
22302236
break;
22312237
case 9: /* element ::= print prlist */
2232
-#line 484 "pikchr.y"
2238
+#line 490 "pikchr.y"
22332239
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy24=0;}
2234
-#line 2259 "pikchr.c"
2240
+#line 2265 "pikchr.c"
22352241
break;
22362242
case 10: /* rvalue ::= PLACENAME */
2237
-#line 495 "pikchr.y"
2243
+#line 501 "pikchr.y"
22382244
{yylhsminor.yy83 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2239
-#line 2264 "pikchr.c"
2245
+#line 2270 "pikchr.c"
22402246
yymsp[0].minor.yy83 = yylhsminor.yy83;
22412247
break;
22422248
case 11: /* pritem ::= FILL */
22432249
case 12: /* pritem ::= COLOR */ yytestcase(yyruleno==12);
22442250
case 13: /* pritem ::= THICKNESS */ yytestcase(yyruleno==13);
2245
-#line 500 "pikchr.y"
2251
+#line 506 "pikchr.y"
22462252
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2247
-#line 2272 "pikchr.c"
2253
+#line 2278 "pikchr.c"
22482254
break;
22492255
case 14: /* pritem ::= rvalue */
2250
-#line 503 "pikchr.y"
2256
+#line 509 "pikchr.y"
22512257
{pik_append_num(p,"",yymsp[0].minor.yy83);}
2252
-#line 2277 "pikchr.c"
2258
+#line 2283 "pikchr.c"
22532259
break;
22542260
case 15: /* pritem ::= STRING */
2255
-#line 504 "pikchr.y"
2261
+#line 510 "pikchr.y"
22562262
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2257
-#line 2282 "pikchr.c"
2263
+#line 2288 "pikchr.c"
22582264
break;
22592265
case 16: /* prsep ::= COMMA */
2260
-#line 505 "pikchr.y"
2266
+#line 511 "pikchr.y"
22612267
{pik_append(p, " ", 1);}
2262
-#line 2287 "pikchr.c"
2268
+#line 2293 "pikchr.c"
22632269
break;
22642270
case 17: /* unnamed_element ::= basetype attribute_list */
2265
-#line 508 "pikchr.y"
2271
+#line 514 "pikchr.y"
22662272
{yylhsminor.yy24 = yymsp[-1].minor.yy24; pik_after_adding_attributes(p,yylhsminor.yy24);}
2267
-#line 2292 "pikchr.c"
2273
+#line 2298 "pikchr.c"
22682274
yymsp[-1].minor.yy24 = yylhsminor.yy24;
22692275
break;
22702276
case 18: /* basetype ::= CLASSNAME */
2271
-#line 510 "pikchr.y"
2277
+#line 516 "pikchr.y"
22722278
{yylhsminor.yy24 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2273
-#line 2298 "pikchr.c"
2279
+#line 2304 "pikchr.c"
22742280
yymsp[0].minor.yy24 = yylhsminor.yy24;
22752281
break;
22762282
case 19: /* basetype ::= STRING textposition */
2277
-#line 512 "pikchr.y"
2283
+#line 518 "pikchr.y"
22782284
{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy52; yylhsminor.yy24 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2279
-#line 2304 "pikchr.c"
2285
+#line 2310 "pikchr.c"
22802286
yymsp[-1].minor.yy24 = yylhsminor.yy24;
22812287
break;
22822288
case 20: /* basetype ::= LB savelist element_list RB */
2283
-#line 514 "pikchr.y"
2289
+#line 520 "pikchr.y"
22842290
{ p->list = yymsp[-2].minor.yy42; yymsp[-3].minor.yy24 = pik_elem_new(p,0,0,yymsp[-1].minor.yy42); if(yymsp[-3].minor.yy24) yymsp[-3].minor.yy24->errTok = yymsp[0].minor.yy0; }
2285
-#line 2310 "pikchr.c"
2291
+#line 2316 "pikchr.c"
22862292
break;
22872293
case 21: /* savelist ::= */
2288
-#line 519 "pikchr.y"
2294
+#line 525 "pikchr.y"
22892295
{yymsp[1].minor.yy42 = p->list; p->list = 0;}
2290
-#line 2315 "pikchr.c"
2296
+#line 2321 "pikchr.c"
22912297
break;
22922298
case 22: /* attribute_list ::= expr */
2293
-#line 526 "pikchr.y"
2299
+#line 532 "pikchr.y"
22942300
{ pik_add_direction(p,0,&yymsp[0].minor.yy83,0);}
2295
-#line 2320 "pikchr.c"
2301
+#line 2326 "pikchr.c"
22962302
break;
22972303
case 23: /* attribute_list ::= expr PERCENT */
2298
-#line 527 "pikchr.y"
2304
+#line 533 "pikchr.y"
22992305
{ pik_add_direction(p,0,&yymsp[-1].minor.yy83,1);}
2300
-#line 2325 "pikchr.c"
2306
+#line 2331 "pikchr.c"
23012307
break;
23022308
case 24: /* attribute ::= numproperty expr PERCENT */
2303
-#line 532 "pikchr.y"
2309
+#line 538 "pikchr.y"
23042310
{ pik_set_numprop(p,&yymsp[-2].minor.yy0,0.0,yymsp[-1].minor.yy83/100.0); }
2305
-#line 2330 "pikchr.c"
2311
+#line 2336 "pikchr.c"
23062312
break;
23072313
case 25: /* attribute ::= numproperty expr */
23082314
case 28: /* attribute ::= colorproperty rvalue */ yytestcase(yyruleno==28);
2309
-#line 533 "pikchr.y"
2315
+#line 539 "pikchr.y"
23102316
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy83,0.0); }
2311
-#line 2336 "pikchr.c"
2317
+#line 2342 "pikchr.c"
23122318
break;
23132319
case 26: /* attribute ::= dashproperty expr */
2314
-#line 534 "pikchr.y"
2320
+#line 540 "pikchr.y"
23152321
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy83); }
2316
-#line 2341 "pikchr.c"
2322
+#line 2347 "pikchr.c"
23172323
break;
23182324
case 27: /* attribute ::= dashproperty */
2319
-#line 535 "pikchr.y"
2325
+#line 541 "pikchr.y"
23202326
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2321
-#line 2346 "pikchr.c"
2327
+#line 2352 "pikchr.c"
23222328
break;
23232329
case 29: /* attribute ::= direction expr PERCENT */
2324
-#line 538 "pikchr.y"
2330
+#line 544 "pikchr.y"
23252331
{ pik_add_direction(p,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy83,1);}
2326
-#line 2351 "pikchr.c"
2332
+#line 2357 "pikchr.c"
23272333
break;
23282334
case 30: /* attribute ::= direction expr */
2329
-#line 539 "pikchr.y"
2335
+#line 545 "pikchr.y"
23302336
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy83,0);}
2331
-#line 2356 "pikchr.c"
2337
+#line 2362 "pikchr.c"
23322338
break;
23332339
case 31: /* attribute ::= direction */
2334
-#line 540 "pikchr.y"
2340
+#line 546 "pikchr.y"
23352341
{ pik_add_direction(p,&yymsp[0].minor.yy0,0,0); }
2336
-#line 2361 "pikchr.c"
2342
+#line 2367 "pikchr.c"
23372343
break;
23382344
case 32: /* attribute ::= direction even position */
2339
-#line 541 "pikchr.y"
2345
+#line 547 "pikchr.y"
23402346
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy49);}
2341
-#line 2366 "pikchr.c"
2347
+#line 2372 "pikchr.c"
23422348
break;
23432349
case 33: /* attribute ::= CLOSE */
2344
-#line 542 "pikchr.y"
2350
+#line 548 "pikchr.y"
23452351
{ pik_close_path(p,&yymsp[0].minor.yy0); }
2346
-#line 2371 "pikchr.c"
2352
+#line 2377 "pikchr.c"
23472353
break;
23482354
case 34: /* attribute ::= CHOP */
2349
-#line 543 "pikchr.y"
2355
+#line 549 "pikchr.y"
23502356
{ p->cur->bChop = 1; }
2351
-#line 2376 "pikchr.c"
2357
+#line 2382 "pikchr.c"
23522358
break;
23532359
case 35: /* attribute ::= FROM position */
2354
-#line 544 "pikchr.y"
2360
+#line 550 "pikchr.y"
23552361
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy49); }
2356
-#line 2381 "pikchr.c"
2362
+#line 2387 "pikchr.c"
23572363
break;
23582364
case 36: /* attribute ::= TO position */
2359
-#line 545 "pikchr.y"
2365
+#line 551 "pikchr.y"
23602366
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy49); }
2361
-#line 2386 "pikchr.c"
2367
+#line 2392 "pikchr.c"
23622368
break;
23632369
case 37: /* attribute ::= THEN */
2364
-#line 546 "pikchr.y"
2370
+#line 552 "pikchr.y"
23652371
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2366
-#line 2391 "pikchr.c"
2372
+#line 2397 "pikchr.c"
23672373
break;
23682374
case 38: /* attribute ::= AT position */
2369
-#line 548 "pikchr.y"
2375
+#line 554 "pikchr.y"
23702376
{ pik_set_at(p,0,&yymsp[0].minor.yy49,&yymsp[-1].minor.yy0); }
2371
-#line 2396 "pikchr.c"
2377
+#line 2402 "pikchr.c"
23722378
break;
23732379
case 39: /* attribute ::= SAME */
2374
-#line 550 "pikchr.y"
2380
+#line 556 "pikchr.y"
23752381
{pik_same(p,0,&yymsp[0].minor.yy0);}
2376
-#line 2401 "pikchr.c"
2382
+#line 2407 "pikchr.c"
23772383
break;
23782384
case 40: /* attribute ::= SAME AS object */
2379
-#line 551 "pikchr.y"
2385
+#line 557 "pikchr.y"
23802386
{pik_same(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2381
-#line 2406 "pikchr.c"
2387
+#line 2412 "pikchr.c"
23822388
break;
23832389
case 41: /* attribute ::= STRING textposition */
2384
-#line 552 "pikchr.y"
2390
+#line 558 "pikchr.y"
23852391
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy52);}
2386
-#line 2411 "pikchr.c"
2392
+#line 2417 "pikchr.c"
23872393
break;
23882394
case 42: /* attribute ::= FIT */
2389
-#line 553 "pikchr.y"
2395
+#line 559 "pikchr.y"
23902396
{pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2391
-#line 2416 "pikchr.c"
2397
+#line 2422 "pikchr.c"
23922398
break;
23932399
case 43: /* with ::= DOT_E edge AT position */
23942400
case 44: /* with ::= edge AT position */ yytestcase(yyruleno==44);
2395
-#line 560 "pikchr.y"
2401
+#line 566 "pikchr.y"
23962402
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy49,&yymsp[-1].minor.yy0); }
2397
-#line 2422 "pikchr.c"
2403
+#line 2428 "pikchr.c"
23982404
break;
23992405
case 45: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2400
-#line 564 "pikchr.y"
2406
+#line 570 "pikchr.y"
24012407
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
2402
-#line 2427 "pikchr.c"
2408
+#line 2433 "pikchr.c"
24032409
yymsp[0].minor.yy0 = yylhsminor.yy0;
24042410
break;
24052411
case 46: /* boolproperty ::= CW */
2406
-#line 575 "pikchr.y"
2412
+#line 581 "pikchr.y"
24072413
{p->cur->cw = 1;}
2408
-#line 2433 "pikchr.c"
2414
+#line 2439 "pikchr.c"
24092415
break;
24102416
case 47: /* boolproperty ::= CCW */
2411
-#line 576 "pikchr.y"
2417
+#line 582 "pikchr.y"
24122418
{p->cur->cw = 0;}
2413
-#line 2438 "pikchr.c"
2419
+#line 2444 "pikchr.c"
24142420
break;
24152421
case 48: /* boolproperty ::= LARROW */
2416
-#line 577 "pikchr.y"
2422
+#line 583 "pikchr.y"
24172423
{p->cur->larrow=1; p->cur->rarrow=0; }
2418
-#line 2443 "pikchr.c"
2424
+#line 2449 "pikchr.c"
24192425
break;
24202426
case 49: /* boolproperty ::= RARROW */
2421
-#line 578 "pikchr.y"
2427
+#line 584 "pikchr.y"
24222428
{p->cur->larrow=0; p->cur->rarrow=1; }
2423
-#line 2448 "pikchr.c"
2429
+#line 2454 "pikchr.c"
24242430
break;
24252431
case 50: /* boolproperty ::= LRARROW */
2426
-#line 579 "pikchr.y"
2432
+#line 585 "pikchr.y"
24272433
{p->cur->larrow=1; p->cur->rarrow=1; }
2428
-#line 2453 "pikchr.c"
2434
+#line 2459 "pikchr.c"
24292435
break;
24302436
case 51: /* boolproperty ::= INVIS */
2431
-#line 580 "pikchr.y"
2437
+#line 586 "pikchr.y"
24322438
{p->cur->sw = 0.0;}
2433
-#line 2458 "pikchr.c"
2439
+#line 2464 "pikchr.c"
24342440
break;
24352441
case 52: /* textposition ::= */
2436
-#line 582 "pikchr.y"
2442
+#line 588 "pikchr.y"
24372443
{yymsp[1].minor.yy52 = 0;}
2438
-#line 2463 "pikchr.c"
2444
+#line 2469 "pikchr.c"
24392445
break;
24402446
case 53: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED */
2441
-#line 585 "pikchr.y"
2447
+#line 591 "pikchr.y"
24422448
{yylhsminor.yy52 = pik_text_position(p,yymsp[-1].minor.yy52,&yymsp[0].minor.yy0);}
2443
-#line 2468 "pikchr.c"
2449
+#line 2474 "pikchr.c"
24442450
yymsp[-1].minor.yy52 = yylhsminor.yy52;
24452451
break;
24462452
case 54: /* position ::= expr COMMA expr */
2447
-#line 588 "pikchr.y"
2453
+#line 594 "pikchr.y"
24482454
{yylhsminor.yy49.x=yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[0].minor.yy83;}
2449
-#line 2474 "pikchr.c"
2455
+#line 2480 "pikchr.c"
24502456
yymsp[-2].minor.yy49 = yylhsminor.yy49;
24512457
break;
24522458
case 55: /* position ::= place PLUS expr COMMA expr */
2453
-#line 590 "pikchr.y"
2459
+#line 596 "pikchr.y"
24542460
{yylhsminor.yy49.x=yymsp[-4].minor.yy49.x+yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[-4].minor.yy49.y+yymsp[0].minor.yy83;}
2455
-#line 2480 "pikchr.c"
2461
+#line 2486 "pikchr.c"
24562462
yymsp[-4].minor.yy49 = yylhsminor.yy49;
24572463
break;
24582464
case 56: /* position ::= place MINUS expr COMMA expr */
2459
-#line 591 "pikchr.y"
2465
+#line 597 "pikchr.y"
24602466
{yylhsminor.yy49.x=yymsp[-4].minor.yy49.x-yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[-4].minor.yy49.y-yymsp[0].minor.yy83;}
2461
-#line 2486 "pikchr.c"
2467
+#line 2492 "pikchr.c"
24622468
yymsp[-4].minor.yy49 = yylhsminor.yy49;
24632469
break;
24642470
case 57: /* position ::= place PLUS LP expr COMMA expr RP */
2465
-#line 593 "pikchr.y"
2471
+#line 599 "pikchr.y"
24662472
{yylhsminor.yy49.x=yymsp[-6].minor.yy49.x+yymsp[-3].minor.yy83; yylhsminor.yy49.y=yymsp[-6].minor.yy49.y+yymsp[-1].minor.yy83;}
2467
-#line 2492 "pikchr.c"
2473
+#line 2498 "pikchr.c"
24682474
yymsp[-6].minor.yy49 = yylhsminor.yy49;
24692475
break;
24702476
case 58: /* position ::= place MINUS LP expr COMMA expr RP */
2471
-#line 595 "pikchr.y"
2477
+#line 601 "pikchr.y"
24722478
{yylhsminor.yy49.x=yymsp[-6].minor.yy49.x-yymsp[-3].minor.yy83; yylhsminor.yy49.y=yymsp[-6].minor.yy49.y-yymsp[-1].minor.yy83;}
2473
-#line 2498 "pikchr.c"
2479
+#line 2504 "pikchr.c"
24742480
yymsp[-6].minor.yy49 = yylhsminor.yy49;
24752481
break;
24762482
case 59: /* position ::= LP position COMMA position RP */
2477
-#line 596 "pikchr.y"
2483
+#line 602 "pikchr.y"
24782484
{yymsp[-4].minor.yy49.x=yymsp[-3].minor.yy49.x; yymsp[-4].minor.yy49.y=yymsp[-1].minor.yy49.y;}
2479
-#line 2504 "pikchr.c"
2485
+#line 2510 "pikchr.c"
24802486
break;
24812487
case 60: /* position ::= LP position RP */
2482
-#line 597 "pikchr.y"
2488
+#line 603 "pikchr.y"
24832489
{yymsp[-2].minor.yy49=yymsp[-1].minor.yy49;}
2484
-#line 2509 "pikchr.c"
2490
+#line 2515 "pikchr.c"
24852491
break;
24862492
case 61: /* position ::= expr between position AND position */
2487
-#line 599 "pikchr.y"
2493
+#line 605 "pikchr.y"
24882494
{yylhsminor.yy49 = pik_position_between(p,yymsp[-4].minor.yy83,yymsp[-2].minor.yy49,yymsp[0].minor.yy49);}
2489
-#line 2514 "pikchr.c"
2495
+#line 2520 "pikchr.c"
24902496
yymsp[-4].minor.yy49 = yylhsminor.yy49;
24912497
break;
24922498
case 62: /* position ::= expr ABOVE position */
2493
-#line 600 "pikchr.y"
2499
+#line 606 "pikchr.y"
24942500
{yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.y += yymsp[-2].minor.yy83;}
2495
-#line 2520 "pikchr.c"
2501
+#line 2526 "pikchr.c"
24962502
yymsp[-2].minor.yy49 = yylhsminor.yy49;
24972503
break;
24982504
case 63: /* position ::= expr BELOW position */
2499
-#line 601 "pikchr.y"
2505
+#line 607 "pikchr.y"
25002506
{yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.y -= yymsp[-2].minor.yy83;}
2501
-#line 2526 "pikchr.c"
2507
+#line 2532 "pikchr.c"
25022508
yymsp[-2].minor.yy49 = yylhsminor.yy49;
25032509
break;
25042510
case 64: /* position ::= expr LEFT OF position */
2505
-#line 602 "pikchr.y"
2511
+#line 608 "pikchr.y"
25062512
{yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.x -= yymsp[-3].minor.yy83;}
2507
-#line 2532 "pikchr.c"
2513
+#line 2538 "pikchr.c"
25082514
yymsp[-3].minor.yy49 = yylhsminor.yy49;
25092515
break;
25102516
case 65: /* position ::= expr RIGHT OF position */
2511
-#line 603 "pikchr.y"
2517
+#line 609 "pikchr.y"
25122518
{yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.x += yymsp[-3].minor.yy83;}
2513
-#line 2538 "pikchr.c"
2519
+#line 2544 "pikchr.c"
25142520
yymsp[-3].minor.yy49 = yylhsminor.yy49;
25152521
break;
25162522
case 66: /* position ::= expr EDGEPT OF position */
2517
-#line 605 "pikchr.y"
2523
+#line 611 "pikchr.y"
25182524
{yylhsminor.yy49 = pik_position_at_hdg(p,yymsp[-3].minor.yy83,&yymsp[-2].minor.yy0,yymsp[0].minor.yy49);}
2519
-#line 2544 "pikchr.c"
2525
+#line 2550 "pikchr.c"
25202526
yymsp[-3].minor.yy49 = yylhsminor.yy49;
25212527
break;
25222528
case 67: /* position ::= expr HEADING expr FROM position */
2523
-#line 607 "pikchr.y"
2529
+#line 613 "pikchr.y"
25242530
{yylhsminor.yy49 = pik_position_at_angle(p,yymsp[-4].minor.yy83,yymsp[-2].minor.yy83,yymsp[0].minor.yy49);}
2525
-#line 2550 "pikchr.c"
2531
+#line 2556 "pikchr.c"
25262532
yymsp[-4].minor.yy49 = yylhsminor.yy49;
25272533
break;
25282534
case 68: /* place ::= object */
2529
-#line 613 "pikchr.y"
2535
+#line 619 "pikchr.y"
25302536
{yylhsminor.yy49 = pik_place_of_elem(p,yymsp[0].minor.yy24,0);}
2531
-#line 2556 "pikchr.c"
2537
+#line 2562 "pikchr.c"
25322538
yymsp[0].minor.yy49 = yylhsminor.yy49;
25332539
break;
25342540
case 69: /* place ::= object DOT_E edge */
25352541
case 70: /* place ::= object DOT_L START */ yytestcase(yyruleno==70);
25362542
case 71: /* place ::= object DOT_L END */ yytestcase(yyruleno==71);
2537
-#line 614 "pikchr.y"
2543
+#line 620 "pikchr.y"
25382544
{yylhsminor.yy49 = pik_place_of_elem(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2539
-#line 2564 "pikchr.c"
2545
+#line 2570 "pikchr.c"
25402546
yymsp[-2].minor.yy49 = yylhsminor.yy49;
25412547
break;
25422548
case 72: /* place ::= START OF object */
25432549
case 73: /* place ::= END OF object */ yytestcase(yyruleno==73);
25442550
case 74: /* place ::= edge OF object */ yytestcase(yyruleno==74);
2545
-#line 617 "pikchr.y"
2551
+#line 623 "pikchr.y"
25462552
{yylhsminor.yy49 = pik_place_of_elem(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2547
-#line 2572 "pikchr.c"
2553
+#line 2578 "pikchr.c"
25482554
yymsp[-2].minor.yy49 = yylhsminor.yy49;
25492555
break;
25502556
case 75: /* place ::= NTH VERTEX OF object */
2551
-#line 620 "pikchr.y"
2557
+#line 626 "pikchr.y"
25522558
{yylhsminor.yy49 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy24);}
2553
-#line 2578 "pikchr.c"
2559
+#line 2584 "pikchr.c"
25542560
yymsp[-3].minor.yy49 = yylhsminor.yy49;
25552561
break;
25562562
case 76: /* object ::= nth */
2557
-#line 623 "pikchr.y"
2563
+#line 629 "pikchr.y"
25582564
{yylhsminor.yy24 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2559
-#line 2584 "pikchr.c"
2565
+#line 2590 "pikchr.c"
25602566
yymsp[0].minor.yy24 = yylhsminor.yy24;
25612567
break;
25622568
case 77: /* object ::= nth OF|IN object */
2563
-#line 624 "pikchr.y"
2569
+#line 630 "pikchr.y"
25642570
{yylhsminor.yy24 = pik_find_nth(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2565
-#line 2590 "pikchr.c"
2571
+#line 2596 "pikchr.c"
25662572
yymsp[-2].minor.yy24 = yylhsminor.yy24;
25672573
break;
25682574
case 78: /* objectname ::= PLACENAME */
2569
-#line 626 "pikchr.y"
2575
+#line 632 "pikchr.y"
25702576
{yylhsminor.yy24 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2571
-#line 2596 "pikchr.c"
2577
+#line 2602 "pikchr.c"
25722578
yymsp[0].minor.yy24 = yylhsminor.yy24;
25732579
break;
25742580
case 79: /* objectname ::= objectname DOT_U PLACENAME */
2575
-#line 628 "pikchr.y"
2581
+#line 634 "pikchr.y"
25762582
{yylhsminor.yy24 = pik_find_byname(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2577
-#line 2602 "pikchr.c"
2583
+#line 2608 "pikchr.c"
25782584
yymsp[-2].minor.yy24 = yylhsminor.yy24;
25792585
break;
25802586
case 80: /* nth ::= NTH CLASSNAME */
2581
-#line 630 "pikchr.y"
2587
+#line 636 "pikchr.y"
25822588
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2583
-#line 2608 "pikchr.c"
2589
+#line 2614 "pikchr.c"
25842590
yymsp[-1].minor.yy0 = yylhsminor.yy0;
25852591
break;
25862592
case 81: /* nth ::= NTH LAST CLASSNAME */
2587
-#line 631 "pikchr.y"
2593
+#line 637 "pikchr.y"
25882594
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2589
-#line 2614 "pikchr.c"
2595
+#line 2620 "pikchr.c"
25902596
yymsp[-2].minor.yy0 = yylhsminor.yy0;
25912597
break;
25922598
case 82: /* nth ::= LAST CLASSNAME */
2593
-#line 632 "pikchr.y"
2599
+#line 638 "pikchr.y"
25942600
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2595
-#line 2620 "pikchr.c"
2601
+#line 2626 "pikchr.c"
25962602
break;
25972603
case 83: /* nth ::= LAST */
2598
-#line 633 "pikchr.y"
2604
+#line 639 "pikchr.y"
25992605
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2600
-#line 2625 "pikchr.c"
2606
+#line 2631 "pikchr.c"
26012607
yymsp[0].minor.yy0 = yylhsminor.yy0;
26022608
break;
26032609
case 84: /* nth ::= NTH LB RB */
2604
-#line 634 "pikchr.y"
2610
+#line 640 "pikchr.y"
26052611
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2606
-#line 2631 "pikchr.c"
2612
+#line 2637 "pikchr.c"
26072613
yymsp[-2].minor.yy0 = yylhsminor.yy0;
26082614
break;
26092615
case 85: /* nth ::= NTH LAST LB RB */
2610
-#line 635 "pikchr.y"
2616
+#line 641 "pikchr.y"
26112617
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2612
-#line 2637 "pikchr.c"
2618
+#line 2643 "pikchr.c"
26132619
yymsp[-3].minor.yy0 = yylhsminor.yy0;
26142620
break;
26152621
case 86: /* nth ::= LAST LB RB */
2616
-#line 636 "pikchr.y"
2622
+#line 642 "pikchr.y"
26172623
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2618
-#line 2643 "pikchr.c"
2624
+#line 2649 "pikchr.c"
26192625
break;
26202626
case 87: /* expr ::= expr PLUS expr */
2621
-#line 638 "pikchr.y"
2627
+#line 644 "pikchr.y"
26222628
{yylhsminor.yy83=yymsp[-2].minor.yy83+yymsp[0].minor.yy83;}
2623
-#line 2648 "pikchr.c"
2629
+#line 2654 "pikchr.c"
26242630
yymsp[-2].minor.yy83 = yylhsminor.yy83;
26252631
break;
26262632
case 88: /* expr ::= expr MINUS expr */
2627
-#line 639 "pikchr.y"
2633
+#line 645 "pikchr.y"
26282634
{yylhsminor.yy83=yymsp[-2].minor.yy83-yymsp[0].minor.yy83;}
2629
-#line 2654 "pikchr.c"
2635
+#line 2660 "pikchr.c"
26302636
yymsp[-2].minor.yy83 = yylhsminor.yy83;
26312637
break;
26322638
case 89: /* expr ::= expr STAR expr */
2633
-#line 640 "pikchr.y"
2639
+#line 646 "pikchr.y"
26342640
{yylhsminor.yy83=yymsp[-2].minor.yy83*yymsp[0].minor.yy83;}
2635
-#line 2660 "pikchr.c"
2641
+#line 2666 "pikchr.c"
26362642
yymsp[-2].minor.yy83 = yylhsminor.yy83;
26372643
break;
26382644
case 90: /* expr ::= expr SLASH expr */
2639
-#line 641 "pikchr.y"
2645
+#line 647 "pikchr.y"
26402646
{
26412647
if( yymsp[0].minor.yy83==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy83 = 0.0; }
26422648
else{ yylhsminor.yy83 = yymsp[-2].minor.yy83/yymsp[0].minor.yy83; }
26432649
}
2644
-#line 2669 "pikchr.c"
2650
+#line 2675 "pikchr.c"
26452651
yymsp[-2].minor.yy83 = yylhsminor.yy83;
26462652
break;
26472653
case 91: /* expr ::= MINUS expr */
2648
-#line 645 "pikchr.y"
2654
+#line 651 "pikchr.y"
26492655
{yymsp[-1].minor.yy83=-yymsp[0].minor.yy83;}
2650
-#line 2675 "pikchr.c"
2656
+#line 2681 "pikchr.c"
26512657
break;
26522658
case 92: /* expr ::= PLUS expr */
2653
-#line 646 "pikchr.y"
2659
+#line 652 "pikchr.y"
26542660
{yymsp[-1].minor.yy83=yymsp[0].minor.yy83;}
2655
-#line 2680 "pikchr.c"
2661
+#line 2686 "pikchr.c"
26562662
break;
26572663
case 93: /* expr ::= LP expr RP */
2658
-#line 647 "pikchr.y"
2664
+#line 653 "pikchr.y"
26592665
{yymsp[-2].minor.yy83=yymsp[-1].minor.yy83;}
2660
-#line 2685 "pikchr.c"
2666
+#line 2691 "pikchr.c"
26612667
break;
26622668
case 94: /* expr ::= NUMBER */
2663
-#line 648 "pikchr.y"
2669
+#line 654 "pikchr.y"
26642670
{yylhsminor.yy83=pik_atof(p,&yymsp[0].minor.yy0);}
2665
-#line 2690 "pikchr.c"
2671
+#line 2696 "pikchr.c"
26662672
yymsp[0].minor.yy83 = yylhsminor.yy83;
26672673
break;
26682674
case 95: /* expr ::= ID */
2669
-#line 649 "pikchr.y"
2675
+#line 655 "pikchr.y"
26702676
{yylhsminor.yy83=pik_get_var(p,&yymsp[0].minor.yy0);}
2671
-#line 2696 "pikchr.c"
2677
+#line 2702 "pikchr.c"
26722678
yymsp[0].minor.yy83 = yylhsminor.yy83;
26732679
break;
26742680
case 96: /* expr ::= FUNC1 LP expr RP */
2675
-#line 650 "pikchr.y"
2681
+#line 656 "pikchr.y"
26762682
{yylhsminor.yy83 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy83,0.0);}
2677
-#line 2702 "pikchr.c"
2683
+#line 2708 "pikchr.c"
26782684
yymsp[-3].minor.yy83 = yylhsminor.yy83;
26792685
break;
26802686
case 97: /* expr ::= FUNC2 LP expr COMMA expr RP */
2681
-#line 651 "pikchr.y"
2687
+#line 657 "pikchr.y"
26822688
{yylhsminor.yy83 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy83,yymsp[-1].minor.yy83);}
2683
-#line 2708 "pikchr.c"
2689
+#line 2714 "pikchr.c"
26842690
yymsp[-5].minor.yy83 = yylhsminor.yy83;
26852691
break;
26862692
case 98: /* expr ::= object DOT_L locproperty */
26872693
case 99: /* expr ::= object DOT_L numproperty */ yytestcase(yyruleno==99);
26882694
case 100: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==100);
26892695
case 101: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==101);
2690
-#line 653 "pikchr.y"
2696
+#line 659 "pikchr.y"
26912697
{yylhsminor.yy83=pik_property_of(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2692
-#line 2717 "pikchr.c"
2698
+#line 2723 "pikchr.c"
26932699
yymsp[-2].minor.yy83 = yylhsminor.yy83;
26942700
break;
26952701
case 102: /* expr ::= object DOT_E edge DOT_L X */
2696
-#line 657 "pikchr.y"
2702
+#line 663 "pikchr.y"
26972703
{yylhsminor.yy83=pik_place_of_elem(p,yymsp[-4].minor.yy24,&yymsp[-2].minor.yy0).x;}
2698
-#line 2723 "pikchr.c"
2704
+#line 2729 "pikchr.c"
26992705
yymsp[-4].minor.yy83 = yylhsminor.yy83;
27002706
break;
27012707
case 103: /* expr ::= object DOT_E edge DOT_L Y */
2702
-#line 658 "pikchr.y"
2708
+#line 664 "pikchr.y"
27032709
{yylhsminor.yy83=pik_place_of_elem(p,yymsp[-4].minor.yy24,&yymsp[-2].minor.yy0).y;}
2704
-#line 2729 "pikchr.c"
2710
+#line 2735 "pikchr.c"
27052711
yymsp[-4].minor.yy83 = yylhsminor.yy83;
27062712
break;
27072713
case 104: /* expr ::= LP locproperty OF object RP */
27082714
case 105: /* expr ::= LP dashproperty OF object RP */ yytestcase(yyruleno==105);
27092715
case 106: /* expr ::= LP numproperty OF object RP */ yytestcase(yyruleno==106);
27102716
case 107: /* expr ::= LP colorproperty OF object RP */ yytestcase(yyruleno==107);
2711
-#line 659 "pikchr.y"
2717
+#line 665 "pikchr.y"
27122718
{yymsp[-4].minor.yy83=pik_property_of(p,yymsp[-1].minor.yy24,&yymsp[-3].minor.yy0);}
2713
-#line 2738 "pikchr.c"
2719
+#line 2744 "pikchr.c"
27142720
break;
27152721
case 108: /* expr ::= NTH VERTEX OF object DOT_L X */
2716
-#line 665 "pikchr.y"
2722
+#line 671 "pikchr.y"
27172723
{yylhsminor.yy83 = pik_nth_vertex(p,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,yymsp[-2].minor.yy24).x;}
2718
-#line 2743 "pikchr.c"
2724
+#line 2749 "pikchr.c"
27192725
yymsp[-5].minor.yy83 = yylhsminor.yy83;
27202726
break;
27212727
case 109: /* expr ::= NTH VERTEX OF object DOT_L Y */
2722
-#line 667 "pikchr.y"
2728
+#line 673 "pikchr.y"
27232729
{yylhsminor.yy83 = pik_nth_vertex(p,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,yymsp[-2].minor.yy24).y;}
2724
-#line 2749 "pikchr.c"
2730
+#line 2755 "pikchr.c"
27252731
yymsp[-5].minor.yy83 = yylhsminor.yy83;
27262732
break;
27272733
default:
27282734
/* (110) lvalue ::= ID */ yytestcase(yyruleno==110);
27292735
/* (111) lvalue ::= FILL */ yytestcase(yyruleno==111);
@@ -2818,18 +2824,18 @@
28182824
){
28192825
pik_parserARG_FETCH
28202826
pik_parserCTX_FETCH
28212827
#define TOKEN yyminor
28222828
/************ Begin %syntax_error code ****************************************/
2823
-#line 456 "pikchr.y"
2829
+#line 462 "pikchr.y"
28242830
28252831
if( TOKEN.z && TOKEN.z[0] ){
28262832
pik_error(p, &TOKEN, "syntax error");
28272833
}else{
28282834
pik_error(p, 0, "syntax error");
28292835
}
2830
-#line 2855 "pikchr.c"
2836
+#line 2861 "pikchr.c"
28312837
/************ End %syntax_error code ******************************************/
28322838
pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
28332839
pik_parserCTX_STORE
28342840
}
28352841
@@ -3058,11 +3064,11 @@
30583064
#else
30593065
(void)iToken;
30603066
return 0;
30613067
#endif
30623068
}
3063
-#line 677 "pikchr.y"
3069
+#line 683 "pikchr.y"
30643070
30653071
30663072
30673073
/* Chart of the 140 official HTML color names with their
30683074
** corresponding RGB value.
@@ -3231,12 +3237,12 @@
32313237
** Binary search used. Must be kept in sorted order.
32323238
*/
32333239
static const struct { const char *zName; PNum val; } aBuiltin[] = {
32343240
{ "arcrad", 0.25 },
32353241
{ "arrowhead", 2.0 },
3236
- { "arrowht", 0.1 },
3237
- { "arrowwid", 0.05 },
3242
+ { "arrowht", 0.08 },
3243
+ { "arrowwid", 0.06 },
32383244
{ "boxht", 0.5 },
32393245
{ "boxrad", 0.0 },
32403246
{ "boxwid", 0.75 },
32413247
{ "charht", 0.14 },
32423248
{ "charwid", 0.08 },
@@ -3265,11 +3271,11 @@
32653271
/* Methods for the "arc" class */
32663272
static void arcInit(Pik *p, PElem *pElem){
32673273
pElem->w = pik_value(p, "arcrad",6,0);
32683274
pElem->h = pElem->w;
32693275
}
3270
-/* Hck: Arcs are here rendered as quadratic Bezier curves rather
3276
+/* Hack: Arcs are here rendered as quadratic Bezier curves rather
32713277
** than true arcs. Multiple reasons: (1) the legacy-PIC parameters
32723278
** that control arcs are obscure and I could not figure out what they
32733279
** mean based on available documentation. (2) Arcs are rarely used,
32743280
** and so do not seem that important.
32753281
*/
@@ -3388,19 +3394,13 @@
33883394
chop = pElem->type->xOffset(0,pElem,cp);
33893395
chop.x += pElem->ptAt.x;
33903396
chop.y += pElem->ptAt.y;
33913397
return chop;
33923398
}
3393
-static void boxFit(Pik *p, PElem *pElem, int w, int h){
3394
- if( w>0 ){
3395
- PNum ww = pik_value(p, "charwid", 7, 0);
3396
- if( ww>0.0 ) pElem->w = w * ww;
3397
- }
3398
- if( h>0 ){
3399
- PNum hh = pik_value(p, "charht", 6, 0);
3400
- if( hh>0.0 ) pElem->h = h * hh;
3401
- }
3399
+static void boxFit(Pik *p, PElem *pElem, PNum w, PNum h){
3400
+ if( w>0 ) pElem->w = w;
3401
+ if( h>0 ) pElem->h = h;
34023402
}
34033403
static void boxRender(Pik *p, PElem *pElem){
34043404
PNum w2 = 0.5*pElem->w;
34053405
PNum h2 = 0.5*pElem->h;
34063406
PNum rad = pElem->rad;
@@ -3485,18 +3485,16 @@
34853485
if( dist<pElem->rad ) return pElem->ptAt;
34863486
chop.x = pElem->ptAt.x + dx*pElem->rad/dist;
34873487
chop.y = pElem->ptAt.y + dy*pElem->rad/dist;
34883488
return chop;
34893489
}
3490
-static void circleFit(Pik *p, PElem *pElem, int w, int h){
3490
+static void circleFit(Pik *p, PElem *pElem, PNum w, PNum h){
34913491
PNum mx = 0.0;
3492
- PNum ww = pik_value(p, "charwid", 7, 0)*w;
3493
- PNum hh = pik_value(p, "charht", 6, 0)*h;
3494
- if( ww>0 ) mx = ww;
3495
- if( hh>mx ) mx = hh;
3496
- if( (ww*ww + hh*hh) > mx*mx ){
3497
- mx = sqrt(ww*ww + hh*hh);
3492
+ if( w>0 ) mx = w;
3493
+ if( h>mx ) mx = h;
3494
+ if( (w*w + h*h) > mx*mx ){
3495
+ mx = sqrt(w*w + h*h);
34983496
}
34993497
if( mx>0.0 ){
35003498
pElem->rad = 0.5*mx;
35013499
pElem->w = pElem->h = mx;
35023500
}
@@ -3698,19 +3696,13 @@
36983696
static void ovalNumProp(Pik *p, PElem *pElem, PToken *pId){
36993697
/* Always adjust the radius to be half of the smaller of
37003698
** the width and height. */
37013699
pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
37023700
}
3703
-static void ovalFit(Pik *p, PElem *pElem, int w, int h){
3704
- if( w>0 ){
3705
- PNum ww = pik_value(p, "charwid", 7, 0);
3706
- if( ww>0.0 ) pElem->w = w * ww;
3707
- }
3708
- if( h>0 ){
3709
- PNum hh = pik_value(p, "charht", 6, 0);
3710
- if( hh>0.0 ) pElem->h = h * hh;
3711
- }
3701
+static void ovalFit(Pik *p, PElem *pElem, PNum w, PNum h){
3702
+ if( w>0 ) pElem->w = w;
3703
+ if( h>0 ) pElem->h = h;
37123704
if( pElem->w<pElem->h ) pElem->w = pElem->h;
37133705
}
37143706
37153707
37163708
@@ -4251,11 +4243,11 @@
42514243
int hasCenter = 0;
42524244
42534245
if( p->nErr ) return;
42544246
if( pElem->nTxt==0 ) return;
42554247
aTxt = pElem->aTxt;
4256
- dy = 0.5*pik_value(p,"charht",6,0);
4248
+ dy = 0.5*p->charHeight;
42574249
n = pElem->nTxt;
42584250
pik_txt_vertical_layout(p, pElem);
42594251
x = pElem->ptAt.x;
42604252
for(i=0; i<n; i++){
42614253
if( (pElem->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
@@ -4291,12 +4283,12 @@
42914283
pik_append(p, " font-weight=\"bold\"", -1);
42924284
}
42934285
if( pElem->color>=0.0 ){
42944286
pik_append_clr(p, " fill=\"", pElem->color, "\"");
42954287
}
4296
- if( p->fontScale<=99.0 || p->fontScale>=101.0 ){
4297
- pik_append_num(p, " font-size=\"", p->fontScale);
4288
+ if( p->fontScale<=0.99 || p->fontScale>=1.01 ){
4289
+ pik_append_num(p, " font-size=\"", p->fontScale*100.0);
42984290
pik_append(p, "%\"", 2);
42994291
}
43004292
if( (t->eCode & TP_ALIGN)!=0 && pElem->nPath>=2 ){
43014293
int n = pElem->nPath;
43024294
PNum dx = pElem->aPath[n-1].x - pElem->aPath[0].x;
@@ -5053,10 +5045,33 @@
50535045
case T_BOLD: iRes |= TP_BOLD; break;
50545046
case T_ALIGNED: iRes |= TP_ALIGN; break;
50555047
}
50565048
return iRes;
50575049
}
5050
+
5051
+/* Return an estimate of the actually number of displayed characters
5052
+** in a character string.
5053
+**
5054
+** Omit "\" used to escape characters. And count entities like
5055
+** "&lt;" as a single character.
5056
+*/
5057
+static int pik_text_length(const PToken *pToken){
5058
+ int n = pToken->n;
5059
+ const char *z = pToken->z;
5060
+ int cnt, j;
5061
+ for(j=1, cnt=0; j<n-1; j++){
5062
+ cnt++;
5063
+ if( z[j]=='\\' && z[j+1]!='&' ){
5064
+ j++;
5065
+ }else if( z[j]=='&' ){
5066
+ int k;
5067
+ for(k=j+1; k<j+7 && z[k]!=';'; k++){}
5068
+ if( z[k]==';' ) j = k;
5069
+ }
5070
+ }
5071
+ return cnt;
5072
+}
50585073
50595074
/* Adjust the width, height, and or radius of the object so that
50605075
** it fits around the text that has been added so far.
50615076
**
50625077
** (1) Only text specified prior to this attribute is considered.
@@ -5098,32 +5113,18 @@
50985113
}
50995114
h = hasCenter + hasSingleStack*2 + hasDoubleStack*2;
51005115
}
51015116
if( (pElem->mProp & A_WIDTH)==0 ){
51025117
for(i=0; i<pElem->nTxt; i++){
5103
- int j, cnt;
5104
- const char *z = pElem->aTxt[i].z;
5105
- int n = pElem->aTxt[i].n;
5106
- /* cnt will be an estimate of the text width. Do not count
5107
- ** "\" uses as an escape. Count entities like &lt; as a single
5108
- ** character. */
5109
- for(j=1, cnt=0; j<n-1; j++){
5110
- cnt++;
5111
- if( z[j]=='\\' && z[j+1]!='&' ){
5112
- j++;
5113
- }else if( z[j]=='&' ){
5114
- int k;
5115
- for(k=j+1; k<j+7 && z[k]!=';'; k++){}
5116
- if( z[k]==';' ) j = k;
5117
- }
5118
- }
5118
+ int cnt = pik_text_length(&pElem->aTxt[i]);
51195119
if( (pElem->aTxt[i].eCode & TP_JMASK)!=0 ) cnt *= 2;
51205120
if( cnt>w ) w = cnt;
51215121
}
51225122
}
51235123
if( h>0 || w>0 ){
5124
- pElem->type->xFit(p, pElem, w, h);
5124
+ pik_compute_layout_settings(p);
5125
+ pElem->type->xFit(p, pElem, w*p->charWidth, h*p->charHeight);
51255126
}
51265127
}
51275128
51285129
/* Set a local variable name to "val".
51295130
**
@@ -5162,10 +5163,11 @@
51625163
pVar->val /= val;
51635164
}
51645165
break;
51655166
default: pVar->val = val; break;
51665167
}
5168
+ p->bLayoutVars = 0; /* Clear the layout setting cache */
51675169
}
51685170
51695171
/*
51705172
** Search for the variable named z[0..n-1] in:
51715173
**
@@ -5785,36 +5787,54 @@
57855787
pik_elist_render(p, pElem->pSublist);
57865788
}
57875789
}
57885790
}while( bMoreToDo );
57895791
}
5792
+
5793
+/* Recompute key layout parameters from variables. */
5794
+static void pik_compute_layout_settings(Pik *p){
5795
+ PNum thickness; /* Line thickness */
5796
+ PNum wArrow; /* Width of arrowheads */
5797
+
5798
+ /* Set up rendering parameters */
5799
+ if( p->bLayoutVars ) return;
5800
+ thickness = pik_value(p,"thickness",9,0);
5801
+ if( thickness<=0.01 ) thickness = 0.01;
5802
+ wArrow = 0.5*pik_value(p,"arrowwid",8,0);
5803
+ p->wArrow = wArrow/thickness;
5804
+ p->hArrow = pik_value(p,"arrowht",7,0)/thickness;
5805
+ p->rScale = 144.0*pik_value(p,"scale",5,0);
5806
+ if( p->rScale<5.0 ) p->rScale = 5.0;
5807
+ p->fontScale = pik_value(p,"fontscale",9,0);
5808
+ if( p->fontScale<=0.0 ) p->fontScale = 1.0;
5809
+ p->fontScale *= p->rScale/144.0;
5810
+ p->charWidth = pik_value(p,"charwid",7,0)*p->fontScale;
5811
+ p->charHeight = pik_value(p,"charht",6,0)*p->fontScale;
5812
+ p->bLayoutVars = 1;
5813
+}
57905814
57915815
/* Render a list of elements. Write the SVG into p->zOut.
57925816
** Delete the input element_list before returnning.
57935817
*/
57945818
static void pik_render(Pik *p, PEList *pEList){
57955819
int i, j;
57965820
if( pEList==0 ) return;
57975821
if( p->nErr==0 ){
5798
- PNum thickness; /* Line thickness */
5799
- PNum wArrow; /* Width of arrowheads */
5822
+ PNum thickness; /* Stroke width */
58005823
PNum margin; /* Extra bounding box margin */
58015824
PNum leftmargin; /* Extra bounding box area on the left */
58025825
PNum w, h; /* Drawing width and height */
5826
+ PNum wArrow;
58035827
58045828
/* Set up rendering parameters */
5829
+ pik_compute_layout_settings(p);
58055830
thickness = pik_value(p,"thickness",9,0);
58065831
if( thickness<=0.01 ) thickness = 0.01;
58075832
margin = pik_value(p,"margin",6,0);
58085833
margin += thickness;
58095834
leftmargin = pik_value(p,"leftmargin",10,0);
5810
- wArrow = 0.5*pik_value(p,"arrowwid",8,0);
5811
- p->wArrow = wArrow/thickness;
5812
- p->hArrow = pik_value(p,"arrowht",7,0)/thickness;
5813
- p->rScale = 144.0*pik_value(p,"scale",5,0);
5814
- if( p->rScale<5.0 ) p->rScale = 5.0;
5815
- p->fontScale = p->rScale/1.44;
5835
+ wArrow = p->wArrow*thickness;
58165836
58175837
/* Compute a bounding box over all objects so that we can know
58185838
** how big to declare the SVG canvas */
58195839
pik_bbox_init(&p->bbox);
58205840
for(i=0; i<pEList->n; i++){
@@ -6431,6 +6451,6 @@
64316451
printf("</body></html>\n");
64326452
return 0;
64336453
}
64346454
#endif /* PIKCHR_SHELL */
64356455
6436
-#line 6461 "pikchr.c"
6456
+#line 6481 "pikchr.c"
64376457
--- src/pikchr.c
+++ src/pikchr.c
@@ -315,19 +315,23 @@
315 const char *zIn; /* Input PIKCHR-language text. zero-terminated */
316 unsigned int nIn; /* Number of bytes in zIn */
317 char *zOut; /* Result accumulates here */
318 unsigned int nOut; /* Bytes written to zOut[] so far */
319 unsigned int nOutAlloc; /* Space allocated to zOut[] */
320 PNum wArrow; /* Width of arrowhead at the fat end */
321 PNum hArrow; /* Height of arrowhead - dist from tip to fat end */
322 unsigned char eDir; /* Current direction */
323 PElem *cur; /* Element under construction */
324 PEList *list; /* Element list under construction */
325 PVar *pVar; /* Application-defined variables */
326 PBox bbox; /* Bounding box around all elements */
327 PNum rScale; /* Multiply to convert inches to pixels */
328 PNum fontScale; /* Scale fonts by this percent */
 
 
 
 
 
 
329 char thenFlag; /* True if "then" seen */
330 const char *zClass; /* Class name for the <svg> */
331 int wSVG, hSVG; /* Width and height of the <svg> */
332 /* Paths for lines are constructed here first, then transferred into
333 ** the PElem object at the end: */
@@ -345,12 +349,12 @@
345 char isLine; /* True if a line class */
346 void (*xInit)(Pik*,PElem*); /* Initializer */
347 void (*xNumProp)(Pik*,PElem*,PToken*); /* Value change notification */
348 PPoint (*xChop)(PElem*,PPoint*); /* Chopper */
349 PPoint (*xOffset)(Pik*,PElem*,int); /* Offset from center to edge point */
350 void (*xFit)(Pik*,PElem*,int w,int h); /* Size to fit text */
351 void (*xRender)(Pik*,PElem*); /* Render */
352 };
353
354
355 /* Forward declarations */
356 static void pik_append(Pik*, const char*,int);
@@ -400,10 +404,11 @@
400 static void pik_bbox_init(PBox*);
401 static void pik_bbox_addbox(PBox*,PBox*);
402 static void pik_bbox_addpt(PBox*,PPoint*);
403 static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
404 static void pik_add_txt(Pik*,PToken*,int);
 
405 static void pik_size_to_fit(Pik*,PToken*);
406 static int pik_text_position(Pik*,int,PToken*);
407 static PNum pik_property_of(Pik*,PElem*,PToken*);
408 static PNum pik_func(Pik*,PToken*,PNum,PNum);
409 static PPoint pik_position_between(Pik *p, PNum x, PPoint p1, PPoint p2);
@@ -410,13 +415,14 @@
410 static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt);
411 static PPoint pik_position_at_hdg(Pik *p, PNum dist, PToken *pD, PPoint pt);
412 static void pik_same(Pik *p, PElem*, PToken*);
413 static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pElem);
414 static PToken pik_next_semantic_token(Pik *p, PToken *pThis);
 
415
416
417 #line 443 "pikchr.c"
418 /**************** End of %include directives **********************************/
419 /* These constants specify the various numeric values for terminal symbols.
420 ***************** Begin token definitions *************************************/
421 #ifndef T_ID
422 #define T_ID 1
@@ -1483,22 +1489,22 @@
1483 ** inside the C code.
1484 */
1485 /********* Begin destructor definitions ***************************************/
1486 case 82: /* element_list */
1487 {
1488 #line 432 "pikchr.y"
1489 pik_elist_free(p,(yypminor->yy42));
1490 #line 1515 "pikchr.c"
1491 }
1492 break;
1493 case 83: /* element */
1494 case 84: /* unnamed_element */
1495 case 85: /* basetype */
1496 {
1497 #line 434 "pikchr.y"
1498 pik_elem_free(p,(yypminor->yy24));
1499 #line 1524 "pikchr.c"
1500 }
1501 break;
1502 /********* End destructor definitions *****************************************/
1503 default: break; /* If no destructor action specified: do nothing */
1504 }
@@ -1712,14 +1718,14 @@
1712 #endif
1713 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1714 /* Here code is inserted which will execute if the parser
1715 ** stack every overflows */
1716 /******** Begin %stack_overflow code ******************************************/
1717 #line 463 "pikchr.y"
1718
1719 pik_error(p, 0, "parser stack overflow");
1720 #line 1745 "pikchr.c"
1721 /******** End %stack_overflow code ********************************************/
1722 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1723 pik_parserCTX_STORE
1724 }
1725
@@ -2174,556 +2180,556 @@
2174 ** break;
2175 */
2176 /********** Begin reduce actions **********************************************/
2177 YYMINORTYPE yylhsminor;
2178 case 0: /* document ::= element_list */
2179 #line 467 "pikchr.y"
2180 {pik_render(p,yymsp[0].minor.yy42);}
2181 #line 2206 "pikchr.c"
2182 break;
2183 case 1: /* element_list ::= element */
2184 #line 470 "pikchr.y"
2185 { yylhsminor.yy42 = pik_elist_append(p,0,yymsp[0].minor.yy24); }
2186 #line 2211 "pikchr.c"
2187 yymsp[0].minor.yy42 = yylhsminor.yy42;
2188 break;
2189 case 2: /* element_list ::= element_list EOL element */
2190 #line 472 "pikchr.y"
2191 { yylhsminor.yy42 = pik_elist_append(p,yymsp[-2].minor.yy42,yymsp[0].minor.yy24); }
2192 #line 2217 "pikchr.c"
2193 yymsp[-2].minor.yy42 = yylhsminor.yy42;
2194 break;
2195 case 3: /* element ::= */
2196 #line 475 "pikchr.y"
2197 { yymsp[1].minor.yy24 = 0; }
2198 #line 2223 "pikchr.c"
2199 break;
2200 case 4: /* element ::= direction */
2201 #line 476 "pikchr.y"
2202 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy24=0; }
2203 #line 2228 "pikchr.c"
2204 yymsp[0].minor.yy24 = yylhsminor.yy24;
2205 break;
2206 case 5: /* element ::= lvalue ASSIGN rvalue */
2207 #line 477 "pikchr.y"
2208 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy83,&yymsp[-1].minor.yy0); yylhsminor.yy24=0;}
2209 #line 2234 "pikchr.c"
2210 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2211 break;
2212 case 6: /* element ::= PLACENAME COLON unnamed_element */
2213 #line 479 "pikchr.y"
2214 { yylhsminor.yy24 = yymsp[0].minor.yy24; pik_elem_setname(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0); }
2215 #line 2240 "pikchr.c"
2216 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2217 break;
2218 case 7: /* element ::= PLACENAME COLON position */
2219 #line 481 "pikchr.y"
2220 { yylhsminor.yy24 = pik_elem_new(p,0,0,0);
2221 if(yylhsminor.yy24){ yylhsminor.yy24->ptAt = yymsp[0].minor.yy49; pik_elem_setname(p,yylhsminor.yy24,&yymsp[-2].minor.yy0); }}
2222 #line 2247 "pikchr.c"
2223 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2224 break;
2225 case 8: /* element ::= unnamed_element */
2226 #line 483 "pikchr.y"
2227 {yylhsminor.yy24 = yymsp[0].minor.yy24;}
2228 #line 2253 "pikchr.c"
2229 yymsp[0].minor.yy24 = yylhsminor.yy24;
2230 break;
2231 case 9: /* element ::= print prlist */
2232 #line 484 "pikchr.y"
2233 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy24=0;}
2234 #line 2259 "pikchr.c"
2235 break;
2236 case 10: /* rvalue ::= PLACENAME */
2237 #line 495 "pikchr.y"
2238 {yylhsminor.yy83 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2239 #line 2264 "pikchr.c"
2240 yymsp[0].minor.yy83 = yylhsminor.yy83;
2241 break;
2242 case 11: /* pritem ::= FILL */
2243 case 12: /* pritem ::= COLOR */ yytestcase(yyruleno==12);
2244 case 13: /* pritem ::= THICKNESS */ yytestcase(yyruleno==13);
2245 #line 500 "pikchr.y"
2246 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2247 #line 2272 "pikchr.c"
2248 break;
2249 case 14: /* pritem ::= rvalue */
2250 #line 503 "pikchr.y"
2251 {pik_append_num(p,"",yymsp[0].minor.yy83);}
2252 #line 2277 "pikchr.c"
2253 break;
2254 case 15: /* pritem ::= STRING */
2255 #line 504 "pikchr.y"
2256 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2257 #line 2282 "pikchr.c"
2258 break;
2259 case 16: /* prsep ::= COMMA */
2260 #line 505 "pikchr.y"
2261 {pik_append(p, " ", 1);}
2262 #line 2287 "pikchr.c"
2263 break;
2264 case 17: /* unnamed_element ::= basetype attribute_list */
2265 #line 508 "pikchr.y"
2266 {yylhsminor.yy24 = yymsp[-1].minor.yy24; pik_after_adding_attributes(p,yylhsminor.yy24);}
2267 #line 2292 "pikchr.c"
2268 yymsp[-1].minor.yy24 = yylhsminor.yy24;
2269 break;
2270 case 18: /* basetype ::= CLASSNAME */
2271 #line 510 "pikchr.y"
2272 {yylhsminor.yy24 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2273 #line 2298 "pikchr.c"
2274 yymsp[0].minor.yy24 = yylhsminor.yy24;
2275 break;
2276 case 19: /* basetype ::= STRING textposition */
2277 #line 512 "pikchr.y"
2278 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy52; yylhsminor.yy24 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2279 #line 2304 "pikchr.c"
2280 yymsp[-1].minor.yy24 = yylhsminor.yy24;
2281 break;
2282 case 20: /* basetype ::= LB savelist element_list RB */
2283 #line 514 "pikchr.y"
2284 { p->list = yymsp[-2].minor.yy42; yymsp[-3].minor.yy24 = pik_elem_new(p,0,0,yymsp[-1].minor.yy42); if(yymsp[-3].minor.yy24) yymsp[-3].minor.yy24->errTok = yymsp[0].minor.yy0; }
2285 #line 2310 "pikchr.c"
2286 break;
2287 case 21: /* savelist ::= */
2288 #line 519 "pikchr.y"
2289 {yymsp[1].minor.yy42 = p->list; p->list = 0;}
2290 #line 2315 "pikchr.c"
2291 break;
2292 case 22: /* attribute_list ::= expr */
2293 #line 526 "pikchr.y"
2294 { pik_add_direction(p,0,&yymsp[0].minor.yy83,0);}
2295 #line 2320 "pikchr.c"
2296 break;
2297 case 23: /* attribute_list ::= expr PERCENT */
2298 #line 527 "pikchr.y"
2299 { pik_add_direction(p,0,&yymsp[-1].minor.yy83,1);}
2300 #line 2325 "pikchr.c"
2301 break;
2302 case 24: /* attribute ::= numproperty expr PERCENT */
2303 #line 532 "pikchr.y"
2304 { pik_set_numprop(p,&yymsp[-2].minor.yy0,0.0,yymsp[-1].minor.yy83/100.0); }
2305 #line 2330 "pikchr.c"
2306 break;
2307 case 25: /* attribute ::= numproperty expr */
2308 case 28: /* attribute ::= colorproperty rvalue */ yytestcase(yyruleno==28);
2309 #line 533 "pikchr.y"
2310 { pik_set_numprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy83,0.0); }
2311 #line 2336 "pikchr.c"
2312 break;
2313 case 26: /* attribute ::= dashproperty expr */
2314 #line 534 "pikchr.y"
2315 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy83); }
2316 #line 2341 "pikchr.c"
2317 break;
2318 case 27: /* attribute ::= dashproperty */
2319 #line 535 "pikchr.y"
2320 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2321 #line 2346 "pikchr.c"
2322 break;
2323 case 29: /* attribute ::= direction expr PERCENT */
2324 #line 538 "pikchr.y"
2325 { pik_add_direction(p,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy83,1);}
2326 #line 2351 "pikchr.c"
2327 break;
2328 case 30: /* attribute ::= direction expr */
2329 #line 539 "pikchr.y"
2330 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy83,0);}
2331 #line 2356 "pikchr.c"
2332 break;
2333 case 31: /* attribute ::= direction */
2334 #line 540 "pikchr.y"
2335 { pik_add_direction(p,&yymsp[0].minor.yy0,0,0); }
2336 #line 2361 "pikchr.c"
2337 break;
2338 case 32: /* attribute ::= direction even position */
2339 #line 541 "pikchr.y"
2340 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy49);}
2341 #line 2366 "pikchr.c"
2342 break;
2343 case 33: /* attribute ::= CLOSE */
2344 #line 542 "pikchr.y"
2345 { pik_close_path(p,&yymsp[0].minor.yy0); }
2346 #line 2371 "pikchr.c"
2347 break;
2348 case 34: /* attribute ::= CHOP */
2349 #line 543 "pikchr.y"
2350 { p->cur->bChop = 1; }
2351 #line 2376 "pikchr.c"
2352 break;
2353 case 35: /* attribute ::= FROM position */
2354 #line 544 "pikchr.y"
2355 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy49); }
2356 #line 2381 "pikchr.c"
2357 break;
2358 case 36: /* attribute ::= TO position */
2359 #line 545 "pikchr.y"
2360 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy49); }
2361 #line 2386 "pikchr.c"
2362 break;
2363 case 37: /* attribute ::= THEN */
2364 #line 546 "pikchr.y"
2365 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2366 #line 2391 "pikchr.c"
2367 break;
2368 case 38: /* attribute ::= AT position */
2369 #line 548 "pikchr.y"
2370 { pik_set_at(p,0,&yymsp[0].minor.yy49,&yymsp[-1].minor.yy0); }
2371 #line 2396 "pikchr.c"
2372 break;
2373 case 39: /* attribute ::= SAME */
2374 #line 550 "pikchr.y"
2375 {pik_same(p,0,&yymsp[0].minor.yy0);}
2376 #line 2401 "pikchr.c"
2377 break;
2378 case 40: /* attribute ::= SAME AS object */
2379 #line 551 "pikchr.y"
2380 {pik_same(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2381 #line 2406 "pikchr.c"
2382 break;
2383 case 41: /* attribute ::= STRING textposition */
2384 #line 552 "pikchr.y"
2385 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy52);}
2386 #line 2411 "pikchr.c"
2387 break;
2388 case 42: /* attribute ::= FIT */
2389 #line 553 "pikchr.y"
2390 {pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2391 #line 2416 "pikchr.c"
2392 break;
2393 case 43: /* with ::= DOT_E edge AT position */
2394 case 44: /* with ::= edge AT position */ yytestcase(yyruleno==44);
2395 #line 560 "pikchr.y"
2396 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy49,&yymsp[-1].minor.yy0); }
2397 #line 2422 "pikchr.c"
2398 break;
2399 case 45: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2400 #line 564 "pikchr.y"
2401 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2402 #line 2427 "pikchr.c"
2403 yymsp[0].minor.yy0 = yylhsminor.yy0;
2404 break;
2405 case 46: /* boolproperty ::= CW */
2406 #line 575 "pikchr.y"
2407 {p->cur->cw = 1;}
2408 #line 2433 "pikchr.c"
2409 break;
2410 case 47: /* boolproperty ::= CCW */
2411 #line 576 "pikchr.y"
2412 {p->cur->cw = 0;}
2413 #line 2438 "pikchr.c"
2414 break;
2415 case 48: /* boolproperty ::= LARROW */
2416 #line 577 "pikchr.y"
2417 {p->cur->larrow=1; p->cur->rarrow=0; }
2418 #line 2443 "pikchr.c"
2419 break;
2420 case 49: /* boolproperty ::= RARROW */
2421 #line 578 "pikchr.y"
2422 {p->cur->larrow=0; p->cur->rarrow=1; }
2423 #line 2448 "pikchr.c"
2424 break;
2425 case 50: /* boolproperty ::= LRARROW */
2426 #line 579 "pikchr.y"
2427 {p->cur->larrow=1; p->cur->rarrow=1; }
2428 #line 2453 "pikchr.c"
2429 break;
2430 case 51: /* boolproperty ::= INVIS */
2431 #line 580 "pikchr.y"
2432 {p->cur->sw = 0.0;}
2433 #line 2458 "pikchr.c"
2434 break;
2435 case 52: /* textposition ::= */
2436 #line 582 "pikchr.y"
2437 {yymsp[1].minor.yy52 = 0;}
2438 #line 2463 "pikchr.c"
2439 break;
2440 case 53: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED */
2441 #line 585 "pikchr.y"
2442 {yylhsminor.yy52 = pik_text_position(p,yymsp[-1].minor.yy52,&yymsp[0].minor.yy0);}
2443 #line 2468 "pikchr.c"
2444 yymsp[-1].minor.yy52 = yylhsminor.yy52;
2445 break;
2446 case 54: /* position ::= expr COMMA expr */
2447 #line 588 "pikchr.y"
2448 {yylhsminor.yy49.x=yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[0].minor.yy83;}
2449 #line 2474 "pikchr.c"
2450 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2451 break;
2452 case 55: /* position ::= place PLUS expr COMMA expr */
2453 #line 590 "pikchr.y"
2454 {yylhsminor.yy49.x=yymsp[-4].minor.yy49.x+yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[-4].minor.yy49.y+yymsp[0].minor.yy83;}
2455 #line 2480 "pikchr.c"
2456 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2457 break;
2458 case 56: /* position ::= place MINUS expr COMMA expr */
2459 #line 591 "pikchr.y"
2460 {yylhsminor.yy49.x=yymsp[-4].minor.yy49.x-yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[-4].minor.yy49.y-yymsp[0].minor.yy83;}
2461 #line 2486 "pikchr.c"
2462 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2463 break;
2464 case 57: /* position ::= place PLUS LP expr COMMA expr RP */
2465 #line 593 "pikchr.y"
2466 {yylhsminor.yy49.x=yymsp[-6].minor.yy49.x+yymsp[-3].minor.yy83; yylhsminor.yy49.y=yymsp[-6].minor.yy49.y+yymsp[-1].minor.yy83;}
2467 #line 2492 "pikchr.c"
2468 yymsp[-6].minor.yy49 = yylhsminor.yy49;
2469 break;
2470 case 58: /* position ::= place MINUS LP expr COMMA expr RP */
2471 #line 595 "pikchr.y"
2472 {yylhsminor.yy49.x=yymsp[-6].minor.yy49.x-yymsp[-3].minor.yy83; yylhsminor.yy49.y=yymsp[-6].minor.yy49.y-yymsp[-1].minor.yy83;}
2473 #line 2498 "pikchr.c"
2474 yymsp[-6].minor.yy49 = yylhsminor.yy49;
2475 break;
2476 case 59: /* position ::= LP position COMMA position RP */
2477 #line 596 "pikchr.y"
2478 {yymsp[-4].minor.yy49.x=yymsp[-3].minor.yy49.x; yymsp[-4].minor.yy49.y=yymsp[-1].minor.yy49.y;}
2479 #line 2504 "pikchr.c"
2480 break;
2481 case 60: /* position ::= LP position RP */
2482 #line 597 "pikchr.y"
2483 {yymsp[-2].minor.yy49=yymsp[-1].minor.yy49;}
2484 #line 2509 "pikchr.c"
2485 break;
2486 case 61: /* position ::= expr between position AND position */
2487 #line 599 "pikchr.y"
2488 {yylhsminor.yy49 = pik_position_between(p,yymsp[-4].minor.yy83,yymsp[-2].minor.yy49,yymsp[0].minor.yy49);}
2489 #line 2514 "pikchr.c"
2490 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2491 break;
2492 case 62: /* position ::= expr ABOVE position */
2493 #line 600 "pikchr.y"
2494 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.y += yymsp[-2].minor.yy83;}
2495 #line 2520 "pikchr.c"
2496 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2497 break;
2498 case 63: /* position ::= expr BELOW position */
2499 #line 601 "pikchr.y"
2500 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.y -= yymsp[-2].minor.yy83;}
2501 #line 2526 "pikchr.c"
2502 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2503 break;
2504 case 64: /* position ::= expr LEFT OF position */
2505 #line 602 "pikchr.y"
2506 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.x -= yymsp[-3].minor.yy83;}
2507 #line 2532 "pikchr.c"
2508 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2509 break;
2510 case 65: /* position ::= expr RIGHT OF position */
2511 #line 603 "pikchr.y"
2512 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.x += yymsp[-3].minor.yy83;}
2513 #line 2538 "pikchr.c"
2514 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2515 break;
2516 case 66: /* position ::= expr EDGEPT OF position */
2517 #line 605 "pikchr.y"
2518 {yylhsminor.yy49 = pik_position_at_hdg(p,yymsp[-3].minor.yy83,&yymsp[-2].minor.yy0,yymsp[0].minor.yy49);}
2519 #line 2544 "pikchr.c"
2520 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2521 break;
2522 case 67: /* position ::= expr HEADING expr FROM position */
2523 #line 607 "pikchr.y"
2524 {yylhsminor.yy49 = pik_position_at_angle(p,yymsp[-4].minor.yy83,yymsp[-2].minor.yy83,yymsp[0].minor.yy49);}
2525 #line 2550 "pikchr.c"
2526 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2527 break;
2528 case 68: /* place ::= object */
2529 #line 613 "pikchr.y"
2530 {yylhsminor.yy49 = pik_place_of_elem(p,yymsp[0].minor.yy24,0);}
2531 #line 2556 "pikchr.c"
2532 yymsp[0].minor.yy49 = yylhsminor.yy49;
2533 break;
2534 case 69: /* place ::= object DOT_E edge */
2535 case 70: /* place ::= object DOT_L START */ yytestcase(yyruleno==70);
2536 case 71: /* place ::= object DOT_L END */ yytestcase(yyruleno==71);
2537 #line 614 "pikchr.y"
2538 {yylhsminor.yy49 = pik_place_of_elem(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2539 #line 2564 "pikchr.c"
2540 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2541 break;
2542 case 72: /* place ::= START OF object */
2543 case 73: /* place ::= END OF object */ yytestcase(yyruleno==73);
2544 case 74: /* place ::= edge OF object */ yytestcase(yyruleno==74);
2545 #line 617 "pikchr.y"
2546 {yylhsminor.yy49 = pik_place_of_elem(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2547 #line 2572 "pikchr.c"
2548 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2549 break;
2550 case 75: /* place ::= NTH VERTEX OF object */
2551 #line 620 "pikchr.y"
2552 {yylhsminor.yy49 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy24);}
2553 #line 2578 "pikchr.c"
2554 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2555 break;
2556 case 76: /* object ::= nth */
2557 #line 623 "pikchr.y"
2558 {yylhsminor.yy24 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2559 #line 2584 "pikchr.c"
2560 yymsp[0].minor.yy24 = yylhsminor.yy24;
2561 break;
2562 case 77: /* object ::= nth OF|IN object */
2563 #line 624 "pikchr.y"
2564 {yylhsminor.yy24 = pik_find_nth(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2565 #line 2590 "pikchr.c"
2566 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2567 break;
2568 case 78: /* objectname ::= PLACENAME */
2569 #line 626 "pikchr.y"
2570 {yylhsminor.yy24 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2571 #line 2596 "pikchr.c"
2572 yymsp[0].minor.yy24 = yylhsminor.yy24;
2573 break;
2574 case 79: /* objectname ::= objectname DOT_U PLACENAME */
2575 #line 628 "pikchr.y"
2576 {yylhsminor.yy24 = pik_find_byname(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2577 #line 2602 "pikchr.c"
2578 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2579 break;
2580 case 80: /* nth ::= NTH CLASSNAME */
2581 #line 630 "pikchr.y"
2582 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2583 #line 2608 "pikchr.c"
2584 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2585 break;
2586 case 81: /* nth ::= NTH LAST CLASSNAME */
2587 #line 631 "pikchr.y"
2588 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2589 #line 2614 "pikchr.c"
2590 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2591 break;
2592 case 82: /* nth ::= LAST CLASSNAME */
2593 #line 632 "pikchr.y"
2594 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2595 #line 2620 "pikchr.c"
2596 break;
2597 case 83: /* nth ::= LAST */
2598 #line 633 "pikchr.y"
2599 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2600 #line 2625 "pikchr.c"
2601 yymsp[0].minor.yy0 = yylhsminor.yy0;
2602 break;
2603 case 84: /* nth ::= NTH LB RB */
2604 #line 634 "pikchr.y"
2605 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2606 #line 2631 "pikchr.c"
2607 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2608 break;
2609 case 85: /* nth ::= NTH LAST LB RB */
2610 #line 635 "pikchr.y"
2611 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2612 #line 2637 "pikchr.c"
2613 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2614 break;
2615 case 86: /* nth ::= LAST LB RB */
2616 #line 636 "pikchr.y"
2617 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2618 #line 2643 "pikchr.c"
2619 break;
2620 case 87: /* expr ::= expr PLUS expr */
2621 #line 638 "pikchr.y"
2622 {yylhsminor.yy83=yymsp[-2].minor.yy83+yymsp[0].minor.yy83;}
2623 #line 2648 "pikchr.c"
2624 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2625 break;
2626 case 88: /* expr ::= expr MINUS expr */
2627 #line 639 "pikchr.y"
2628 {yylhsminor.yy83=yymsp[-2].minor.yy83-yymsp[0].minor.yy83;}
2629 #line 2654 "pikchr.c"
2630 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2631 break;
2632 case 89: /* expr ::= expr STAR expr */
2633 #line 640 "pikchr.y"
2634 {yylhsminor.yy83=yymsp[-2].minor.yy83*yymsp[0].minor.yy83;}
2635 #line 2660 "pikchr.c"
2636 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2637 break;
2638 case 90: /* expr ::= expr SLASH expr */
2639 #line 641 "pikchr.y"
2640 {
2641 if( yymsp[0].minor.yy83==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy83 = 0.0; }
2642 else{ yylhsminor.yy83 = yymsp[-2].minor.yy83/yymsp[0].minor.yy83; }
2643 }
2644 #line 2669 "pikchr.c"
2645 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2646 break;
2647 case 91: /* expr ::= MINUS expr */
2648 #line 645 "pikchr.y"
2649 {yymsp[-1].minor.yy83=-yymsp[0].minor.yy83;}
2650 #line 2675 "pikchr.c"
2651 break;
2652 case 92: /* expr ::= PLUS expr */
2653 #line 646 "pikchr.y"
2654 {yymsp[-1].minor.yy83=yymsp[0].minor.yy83;}
2655 #line 2680 "pikchr.c"
2656 break;
2657 case 93: /* expr ::= LP expr RP */
2658 #line 647 "pikchr.y"
2659 {yymsp[-2].minor.yy83=yymsp[-1].minor.yy83;}
2660 #line 2685 "pikchr.c"
2661 break;
2662 case 94: /* expr ::= NUMBER */
2663 #line 648 "pikchr.y"
2664 {yylhsminor.yy83=pik_atof(p,&yymsp[0].minor.yy0);}
2665 #line 2690 "pikchr.c"
2666 yymsp[0].minor.yy83 = yylhsminor.yy83;
2667 break;
2668 case 95: /* expr ::= ID */
2669 #line 649 "pikchr.y"
2670 {yylhsminor.yy83=pik_get_var(p,&yymsp[0].minor.yy0);}
2671 #line 2696 "pikchr.c"
2672 yymsp[0].minor.yy83 = yylhsminor.yy83;
2673 break;
2674 case 96: /* expr ::= FUNC1 LP expr RP */
2675 #line 650 "pikchr.y"
2676 {yylhsminor.yy83 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy83,0.0);}
2677 #line 2702 "pikchr.c"
2678 yymsp[-3].minor.yy83 = yylhsminor.yy83;
2679 break;
2680 case 97: /* expr ::= FUNC2 LP expr COMMA expr RP */
2681 #line 651 "pikchr.y"
2682 {yylhsminor.yy83 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy83,yymsp[-1].minor.yy83);}
2683 #line 2708 "pikchr.c"
2684 yymsp[-5].minor.yy83 = yylhsminor.yy83;
2685 break;
2686 case 98: /* expr ::= object DOT_L locproperty */
2687 case 99: /* expr ::= object DOT_L numproperty */ yytestcase(yyruleno==99);
2688 case 100: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==100);
2689 case 101: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==101);
2690 #line 653 "pikchr.y"
2691 {yylhsminor.yy83=pik_property_of(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2692 #line 2717 "pikchr.c"
2693 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2694 break;
2695 case 102: /* expr ::= object DOT_E edge DOT_L X */
2696 #line 657 "pikchr.y"
2697 {yylhsminor.yy83=pik_place_of_elem(p,yymsp[-4].minor.yy24,&yymsp[-2].minor.yy0).x;}
2698 #line 2723 "pikchr.c"
2699 yymsp[-4].minor.yy83 = yylhsminor.yy83;
2700 break;
2701 case 103: /* expr ::= object DOT_E edge DOT_L Y */
2702 #line 658 "pikchr.y"
2703 {yylhsminor.yy83=pik_place_of_elem(p,yymsp[-4].minor.yy24,&yymsp[-2].minor.yy0).y;}
2704 #line 2729 "pikchr.c"
2705 yymsp[-4].minor.yy83 = yylhsminor.yy83;
2706 break;
2707 case 104: /* expr ::= LP locproperty OF object RP */
2708 case 105: /* expr ::= LP dashproperty OF object RP */ yytestcase(yyruleno==105);
2709 case 106: /* expr ::= LP numproperty OF object RP */ yytestcase(yyruleno==106);
2710 case 107: /* expr ::= LP colorproperty OF object RP */ yytestcase(yyruleno==107);
2711 #line 659 "pikchr.y"
2712 {yymsp[-4].minor.yy83=pik_property_of(p,yymsp[-1].minor.yy24,&yymsp[-3].minor.yy0);}
2713 #line 2738 "pikchr.c"
2714 break;
2715 case 108: /* expr ::= NTH VERTEX OF object DOT_L X */
2716 #line 665 "pikchr.y"
2717 {yylhsminor.yy83 = pik_nth_vertex(p,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,yymsp[-2].minor.yy24).x;}
2718 #line 2743 "pikchr.c"
2719 yymsp[-5].minor.yy83 = yylhsminor.yy83;
2720 break;
2721 case 109: /* expr ::= NTH VERTEX OF object DOT_L Y */
2722 #line 667 "pikchr.y"
2723 {yylhsminor.yy83 = pik_nth_vertex(p,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,yymsp[-2].minor.yy24).y;}
2724 #line 2749 "pikchr.c"
2725 yymsp[-5].minor.yy83 = yylhsminor.yy83;
2726 break;
2727 default:
2728 /* (110) lvalue ::= ID */ yytestcase(yyruleno==110);
2729 /* (111) lvalue ::= FILL */ yytestcase(yyruleno==111);
@@ -2818,18 +2824,18 @@
2818 ){
2819 pik_parserARG_FETCH
2820 pik_parserCTX_FETCH
2821 #define TOKEN yyminor
2822 /************ Begin %syntax_error code ****************************************/
2823 #line 456 "pikchr.y"
2824
2825 if( TOKEN.z && TOKEN.z[0] ){
2826 pik_error(p, &TOKEN, "syntax error");
2827 }else{
2828 pik_error(p, 0, "syntax error");
2829 }
2830 #line 2855 "pikchr.c"
2831 /************ End %syntax_error code ******************************************/
2832 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
2833 pik_parserCTX_STORE
2834 }
2835
@@ -3058,11 +3064,11 @@
3058 #else
3059 (void)iToken;
3060 return 0;
3061 #endif
3062 }
3063 #line 677 "pikchr.y"
3064
3065
3066
3067 /* Chart of the 140 official HTML color names with their
3068 ** corresponding RGB value.
@@ -3231,12 +3237,12 @@
3231 ** Binary search used. Must be kept in sorted order.
3232 */
3233 static const struct { const char *zName; PNum val; } aBuiltin[] = {
3234 { "arcrad", 0.25 },
3235 { "arrowhead", 2.0 },
3236 { "arrowht", 0.1 },
3237 { "arrowwid", 0.05 },
3238 { "boxht", 0.5 },
3239 { "boxrad", 0.0 },
3240 { "boxwid", 0.75 },
3241 { "charht", 0.14 },
3242 { "charwid", 0.08 },
@@ -3265,11 +3271,11 @@
3265 /* Methods for the "arc" class */
3266 static void arcInit(Pik *p, PElem *pElem){
3267 pElem->w = pik_value(p, "arcrad",6,0);
3268 pElem->h = pElem->w;
3269 }
3270 /* Hck: Arcs are here rendered as quadratic Bezier curves rather
3271 ** than true arcs. Multiple reasons: (1) the legacy-PIC parameters
3272 ** that control arcs are obscure and I could not figure out what they
3273 ** mean based on available documentation. (2) Arcs are rarely used,
3274 ** and so do not seem that important.
3275 */
@@ -3388,19 +3394,13 @@
3388 chop = pElem->type->xOffset(0,pElem,cp);
3389 chop.x += pElem->ptAt.x;
3390 chop.y += pElem->ptAt.y;
3391 return chop;
3392 }
3393 static void boxFit(Pik *p, PElem *pElem, int w, int h){
3394 if( w>0 ){
3395 PNum ww = pik_value(p, "charwid", 7, 0);
3396 if( ww>0.0 ) pElem->w = w * ww;
3397 }
3398 if( h>0 ){
3399 PNum hh = pik_value(p, "charht", 6, 0);
3400 if( hh>0.0 ) pElem->h = h * hh;
3401 }
3402 }
3403 static void boxRender(Pik *p, PElem *pElem){
3404 PNum w2 = 0.5*pElem->w;
3405 PNum h2 = 0.5*pElem->h;
3406 PNum rad = pElem->rad;
@@ -3485,18 +3485,16 @@
3485 if( dist<pElem->rad ) return pElem->ptAt;
3486 chop.x = pElem->ptAt.x + dx*pElem->rad/dist;
3487 chop.y = pElem->ptAt.y + dy*pElem->rad/dist;
3488 return chop;
3489 }
3490 static void circleFit(Pik *p, PElem *pElem, int w, int h){
3491 PNum mx = 0.0;
3492 PNum ww = pik_value(p, "charwid", 7, 0)*w;
3493 PNum hh = pik_value(p, "charht", 6, 0)*h;
3494 if( ww>0 ) mx = ww;
3495 if( hh>mx ) mx = hh;
3496 if( (ww*ww + hh*hh) > mx*mx ){
3497 mx = sqrt(ww*ww + hh*hh);
3498 }
3499 if( mx>0.0 ){
3500 pElem->rad = 0.5*mx;
3501 pElem->w = pElem->h = mx;
3502 }
@@ -3698,19 +3696,13 @@
3698 static void ovalNumProp(Pik *p, PElem *pElem, PToken *pId){
3699 /* Always adjust the radius to be half of the smaller of
3700 ** the width and height. */
3701 pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
3702 }
3703 static void ovalFit(Pik *p, PElem *pElem, int w, int h){
3704 if( w>0 ){
3705 PNum ww = pik_value(p, "charwid", 7, 0);
3706 if( ww>0.0 ) pElem->w = w * ww;
3707 }
3708 if( h>0 ){
3709 PNum hh = pik_value(p, "charht", 6, 0);
3710 if( hh>0.0 ) pElem->h = h * hh;
3711 }
3712 if( pElem->w<pElem->h ) pElem->w = pElem->h;
3713 }
3714
3715
3716
@@ -4251,11 +4243,11 @@
4251 int hasCenter = 0;
4252
4253 if( p->nErr ) return;
4254 if( pElem->nTxt==0 ) return;
4255 aTxt = pElem->aTxt;
4256 dy = 0.5*pik_value(p,"charht",6,0);
4257 n = pElem->nTxt;
4258 pik_txt_vertical_layout(p, pElem);
4259 x = pElem->ptAt.x;
4260 for(i=0; i<n; i++){
4261 if( (pElem->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
@@ -4291,12 +4283,12 @@
4291 pik_append(p, " font-weight=\"bold\"", -1);
4292 }
4293 if( pElem->color>=0.0 ){
4294 pik_append_clr(p, " fill=\"", pElem->color, "\"");
4295 }
4296 if( p->fontScale<=99.0 || p->fontScale>=101.0 ){
4297 pik_append_num(p, " font-size=\"", p->fontScale);
4298 pik_append(p, "%\"", 2);
4299 }
4300 if( (t->eCode & TP_ALIGN)!=0 && pElem->nPath>=2 ){
4301 int n = pElem->nPath;
4302 PNum dx = pElem->aPath[n-1].x - pElem->aPath[0].x;
@@ -5053,10 +5045,33 @@
5053 case T_BOLD: iRes |= TP_BOLD; break;
5054 case T_ALIGNED: iRes |= TP_ALIGN; break;
5055 }
5056 return iRes;
5057 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5058
5059 /* Adjust the width, height, and or radius of the object so that
5060 ** it fits around the text that has been added so far.
5061 **
5062 ** (1) Only text specified prior to this attribute is considered.
@@ -5098,32 +5113,18 @@
5098 }
5099 h = hasCenter + hasSingleStack*2 + hasDoubleStack*2;
5100 }
5101 if( (pElem->mProp & A_WIDTH)==0 ){
5102 for(i=0; i<pElem->nTxt; i++){
5103 int j, cnt;
5104 const char *z = pElem->aTxt[i].z;
5105 int n = pElem->aTxt[i].n;
5106 /* cnt will be an estimate of the text width. Do not count
5107 ** "\" uses as an escape. Count entities like &lt; as a single
5108 ** character. */
5109 for(j=1, cnt=0; j<n-1; j++){
5110 cnt++;
5111 if( z[j]=='\\' && z[j+1]!='&' ){
5112 j++;
5113 }else if( z[j]=='&' ){
5114 int k;
5115 for(k=j+1; k<j+7 && z[k]!=';'; k++){}
5116 if( z[k]==';' ) j = k;
5117 }
5118 }
5119 if( (pElem->aTxt[i].eCode & TP_JMASK)!=0 ) cnt *= 2;
5120 if( cnt>w ) w = cnt;
5121 }
5122 }
5123 if( h>0 || w>0 ){
5124 pElem->type->xFit(p, pElem, w, h);
 
5125 }
5126 }
5127
5128 /* Set a local variable name to "val".
5129 **
@@ -5162,10 +5163,11 @@
5162 pVar->val /= val;
5163 }
5164 break;
5165 default: pVar->val = val; break;
5166 }
 
5167 }
5168
5169 /*
5170 ** Search for the variable named z[0..n-1] in:
5171 **
@@ -5785,36 +5787,54 @@
5785 pik_elist_render(p, pElem->pSublist);
5786 }
5787 }
5788 }while( bMoreToDo );
5789 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5790
5791 /* Render a list of elements. Write the SVG into p->zOut.
5792 ** Delete the input element_list before returnning.
5793 */
5794 static void pik_render(Pik *p, PEList *pEList){
5795 int i, j;
5796 if( pEList==0 ) return;
5797 if( p->nErr==0 ){
5798 PNum thickness; /* Line thickness */
5799 PNum wArrow; /* Width of arrowheads */
5800 PNum margin; /* Extra bounding box margin */
5801 PNum leftmargin; /* Extra bounding box area on the left */
5802 PNum w, h; /* Drawing width and height */
 
5803
5804 /* Set up rendering parameters */
 
5805 thickness = pik_value(p,"thickness",9,0);
5806 if( thickness<=0.01 ) thickness = 0.01;
5807 margin = pik_value(p,"margin",6,0);
5808 margin += thickness;
5809 leftmargin = pik_value(p,"leftmargin",10,0);
5810 wArrow = 0.5*pik_value(p,"arrowwid",8,0);
5811 p->wArrow = wArrow/thickness;
5812 p->hArrow = pik_value(p,"arrowht",7,0)/thickness;
5813 p->rScale = 144.0*pik_value(p,"scale",5,0);
5814 if( p->rScale<5.0 ) p->rScale = 5.0;
5815 p->fontScale = p->rScale/1.44;
5816
5817 /* Compute a bounding box over all objects so that we can know
5818 ** how big to declare the SVG canvas */
5819 pik_bbox_init(&p->bbox);
5820 for(i=0; i<pEList->n; i++){
@@ -6431,6 +6451,6 @@
6431 printf("</body></html>\n");
6432 return 0;
6433 }
6434 #endif /* PIKCHR_SHELL */
6435
6436 #line 6461 "pikchr.c"
6437
--- src/pikchr.c
+++ src/pikchr.c
@@ -315,19 +315,23 @@
315 const char *zIn; /* Input PIKCHR-language text. zero-terminated */
316 unsigned int nIn; /* Number of bytes in zIn */
317 char *zOut; /* Result accumulates here */
318 unsigned int nOut; /* Bytes written to zOut[] so far */
319 unsigned int nOutAlloc; /* Space allocated to zOut[] */
 
 
320 unsigned char eDir; /* Current direction */
321 PElem *cur; /* Element under construction */
322 PEList *list; /* Element list under construction */
323 PVar *pVar; /* Application-defined variables */
324 PBox bbox; /* Bounding box around all elements */
325 /* Cache of layout values. <=0.0 for unknown... */
326 PNum rScale; /* Multiply to convert inches to pixels */
327 PNum fontScale; /* Scale fonts by this percent */
328 PNum charWidth; /* Character width */
329 PNum charHeight; /* Character height */
330 PNum wArrow; /* Width of arrowhead at the fat end */
331 PNum hArrow; /* Ht of arrowhead - dist from tip to fat end */
332 int bLayoutVars; /* True if cache is valid */
333 char thenFlag; /* True if "then" seen */
334 const char *zClass; /* Class name for the <svg> */
335 int wSVG, hSVG; /* Width and height of the <svg> */
336 /* Paths for lines are constructed here first, then transferred into
337 ** the PElem object at the end: */
@@ -345,12 +349,12 @@
349 char isLine; /* True if a line class */
350 void (*xInit)(Pik*,PElem*); /* Initializer */
351 void (*xNumProp)(Pik*,PElem*,PToken*); /* Value change notification */
352 PPoint (*xChop)(PElem*,PPoint*); /* Chopper */
353 PPoint (*xOffset)(Pik*,PElem*,int); /* Offset from center to edge point */
354 void (*xFit)(Pik*,PElem*,PNum w,PNum h); /* Size to fit text */
355 void (*xRender)(Pik*,PElem*); /* Render */
356 };
357
358
359 /* Forward declarations */
360 static void pik_append(Pik*, const char*,int);
@@ -400,10 +404,11 @@
404 static void pik_bbox_init(PBox*);
405 static void pik_bbox_addbox(PBox*,PBox*);
406 static void pik_bbox_addpt(PBox*,PPoint*);
407 static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
408 static void pik_add_txt(Pik*,PToken*,int);
409 static int pik_text_length(const PToken *pToken);
410 static void pik_size_to_fit(Pik*,PToken*);
411 static int pik_text_position(Pik*,int,PToken*);
412 static PNum pik_property_of(Pik*,PElem*,PToken*);
413 static PNum pik_func(Pik*,PToken*,PNum,PNum);
414 static PPoint pik_position_between(Pik *p, PNum x, PPoint p1, PPoint p2);
@@ -410,13 +415,14 @@
415 static PPoint pik_position_at_angle(Pik *p, PNum dist, PNum r, PPoint pt);
416 static PPoint pik_position_at_hdg(Pik *p, PNum dist, PToken *pD, PPoint pt);
417 static void pik_same(Pik *p, PElem*, PToken*);
418 static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pElem);
419 static PToken pik_next_semantic_token(Pik *p, PToken *pThis);
420 static void pik_compute_layout_settings(Pik*);
421
422
423 #line 449 "pikchr.c"
424 /**************** End of %include directives **********************************/
425 /* These constants specify the various numeric values for terminal symbols.
426 ***************** Begin token definitions *************************************/
427 #ifndef T_ID
428 #define T_ID 1
@@ -1483,22 +1489,22 @@
1489 ** inside the C code.
1490 */
1491 /********* Begin destructor definitions ***************************************/
1492 case 82: /* element_list */
1493 {
1494 #line 438 "pikchr.y"
1495 pik_elist_free(p,(yypminor->yy42));
1496 #line 1521 "pikchr.c"
1497 }
1498 break;
1499 case 83: /* element */
1500 case 84: /* unnamed_element */
1501 case 85: /* basetype */
1502 {
1503 #line 440 "pikchr.y"
1504 pik_elem_free(p,(yypminor->yy24));
1505 #line 1530 "pikchr.c"
1506 }
1507 break;
1508 /********* End destructor definitions *****************************************/
1509 default: break; /* If no destructor action specified: do nothing */
1510 }
@@ -1712,14 +1718,14 @@
1718 #endif
1719 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1720 /* Here code is inserted which will execute if the parser
1721 ** stack every overflows */
1722 /******** Begin %stack_overflow code ******************************************/
1723 #line 469 "pikchr.y"
1724
1725 pik_error(p, 0, "parser stack overflow");
1726 #line 1751 "pikchr.c"
1727 /******** End %stack_overflow code ********************************************/
1728 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1729 pik_parserCTX_STORE
1730 }
1731
@@ -2174,556 +2180,556 @@
2180 ** break;
2181 */
2182 /********** Begin reduce actions **********************************************/
2183 YYMINORTYPE yylhsminor;
2184 case 0: /* document ::= element_list */
2185 #line 473 "pikchr.y"
2186 {pik_render(p,yymsp[0].minor.yy42);}
2187 #line 2212 "pikchr.c"
2188 break;
2189 case 1: /* element_list ::= element */
2190 #line 476 "pikchr.y"
2191 { yylhsminor.yy42 = pik_elist_append(p,0,yymsp[0].minor.yy24); }
2192 #line 2217 "pikchr.c"
2193 yymsp[0].minor.yy42 = yylhsminor.yy42;
2194 break;
2195 case 2: /* element_list ::= element_list EOL element */
2196 #line 478 "pikchr.y"
2197 { yylhsminor.yy42 = pik_elist_append(p,yymsp[-2].minor.yy42,yymsp[0].minor.yy24); }
2198 #line 2223 "pikchr.c"
2199 yymsp[-2].minor.yy42 = yylhsminor.yy42;
2200 break;
2201 case 3: /* element ::= */
2202 #line 481 "pikchr.y"
2203 { yymsp[1].minor.yy24 = 0; }
2204 #line 2229 "pikchr.c"
2205 break;
2206 case 4: /* element ::= direction */
2207 #line 482 "pikchr.y"
2208 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy24=0; }
2209 #line 2234 "pikchr.c"
2210 yymsp[0].minor.yy24 = yylhsminor.yy24;
2211 break;
2212 case 5: /* element ::= lvalue ASSIGN rvalue */
2213 #line 483 "pikchr.y"
2214 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy83,&yymsp[-1].minor.yy0); yylhsminor.yy24=0;}
2215 #line 2240 "pikchr.c"
2216 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2217 break;
2218 case 6: /* element ::= PLACENAME COLON unnamed_element */
2219 #line 485 "pikchr.y"
2220 { yylhsminor.yy24 = yymsp[0].minor.yy24; pik_elem_setname(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0); }
2221 #line 2246 "pikchr.c"
2222 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2223 break;
2224 case 7: /* element ::= PLACENAME COLON position */
2225 #line 487 "pikchr.y"
2226 { yylhsminor.yy24 = pik_elem_new(p,0,0,0);
2227 if(yylhsminor.yy24){ yylhsminor.yy24->ptAt = yymsp[0].minor.yy49; pik_elem_setname(p,yylhsminor.yy24,&yymsp[-2].minor.yy0); }}
2228 #line 2253 "pikchr.c"
2229 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2230 break;
2231 case 8: /* element ::= unnamed_element */
2232 #line 489 "pikchr.y"
2233 {yylhsminor.yy24 = yymsp[0].minor.yy24;}
2234 #line 2259 "pikchr.c"
2235 yymsp[0].minor.yy24 = yylhsminor.yy24;
2236 break;
2237 case 9: /* element ::= print prlist */
2238 #line 490 "pikchr.y"
2239 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy24=0;}
2240 #line 2265 "pikchr.c"
2241 break;
2242 case 10: /* rvalue ::= PLACENAME */
2243 #line 501 "pikchr.y"
2244 {yylhsminor.yy83 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2245 #line 2270 "pikchr.c"
2246 yymsp[0].minor.yy83 = yylhsminor.yy83;
2247 break;
2248 case 11: /* pritem ::= FILL */
2249 case 12: /* pritem ::= COLOR */ yytestcase(yyruleno==12);
2250 case 13: /* pritem ::= THICKNESS */ yytestcase(yyruleno==13);
2251 #line 506 "pikchr.y"
2252 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2253 #line 2278 "pikchr.c"
2254 break;
2255 case 14: /* pritem ::= rvalue */
2256 #line 509 "pikchr.y"
2257 {pik_append_num(p,"",yymsp[0].minor.yy83);}
2258 #line 2283 "pikchr.c"
2259 break;
2260 case 15: /* pritem ::= STRING */
2261 #line 510 "pikchr.y"
2262 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2263 #line 2288 "pikchr.c"
2264 break;
2265 case 16: /* prsep ::= COMMA */
2266 #line 511 "pikchr.y"
2267 {pik_append(p, " ", 1);}
2268 #line 2293 "pikchr.c"
2269 break;
2270 case 17: /* unnamed_element ::= basetype attribute_list */
2271 #line 514 "pikchr.y"
2272 {yylhsminor.yy24 = yymsp[-1].minor.yy24; pik_after_adding_attributes(p,yylhsminor.yy24);}
2273 #line 2298 "pikchr.c"
2274 yymsp[-1].minor.yy24 = yylhsminor.yy24;
2275 break;
2276 case 18: /* basetype ::= CLASSNAME */
2277 #line 516 "pikchr.y"
2278 {yylhsminor.yy24 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2279 #line 2304 "pikchr.c"
2280 yymsp[0].minor.yy24 = yylhsminor.yy24;
2281 break;
2282 case 19: /* basetype ::= STRING textposition */
2283 #line 518 "pikchr.y"
2284 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy52; yylhsminor.yy24 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2285 #line 2310 "pikchr.c"
2286 yymsp[-1].minor.yy24 = yylhsminor.yy24;
2287 break;
2288 case 20: /* basetype ::= LB savelist element_list RB */
2289 #line 520 "pikchr.y"
2290 { p->list = yymsp[-2].minor.yy42; yymsp[-3].minor.yy24 = pik_elem_new(p,0,0,yymsp[-1].minor.yy42); if(yymsp[-3].minor.yy24) yymsp[-3].minor.yy24->errTok = yymsp[0].minor.yy0; }
2291 #line 2316 "pikchr.c"
2292 break;
2293 case 21: /* savelist ::= */
2294 #line 525 "pikchr.y"
2295 {yymsp[1].minor.yy42 = p->list; p->list = 0;}
2296 #line 2321 "pikchr.c"
2297 break;
2298 case 22: /* attribute_list ::= expr */
2299 #line 532 "pikchr.y"
2300 { pik_add_direction(p,0,&yymsp[0].minor.yy83,0);}
2301 #line 2326 "pikchr.c"
2302 break;
2303 case 23: /* attribute_list ::= expr PERCENT */
2304 #line 533 "pikchr.y"
2305 { pik_add_direction(p,0,&yymsp[-1].minor.yy83,1);}
2306 #line 2331 "pikchr.c"
2307 break;
2308 case 24: /* attribute ::= numproperty expr PERCENT */
2309 #line 538 "pikchr.y"
2310 { pik_set_numprop(p,&yymsp[-2].minor.yy0,0.0,yymsp[-1].minor.yy83/100.0); }
2311 #line 2336 "pikchr.c"
2312 break;
2313 case 25: /* attribute ::= numproperty expr */
2314 case 28: /* attribute ::= colorproperty rvalue */ yytestcase(yyruleno==28);
2315 #line 539 "pikchr.y"
2316 { pik_set_numprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy83,0.0); }
2317 #line 2342 "pikchr.c"
2318 break;
2319 case 26: /* attribute ::= dashproperty expr */
2320 #line 540 "pikchr.y"
2321 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy83); }
2322 #line 2347 "pikchr.c"
2323 break;
2324 case 27: /* attribute ::= dashproperty */
2325 #line 541 "pikchr.y"
2326 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2327 #line 2352 "pikchr.c"
2328 break;
2329 case 29: /* attribute ::= direction expr PERCENT */
2330 #line 544 "pikchr.y"
2331 { pik_add_direction(p,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy83,1);}
2332 #line 2357 "pikchr.c"
2333 break;
2334 case 30: /* attribute ::= direction expr */
2335 #line 545 "pikchr.y"
2336 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy83,0);}
2337 #line 2362 "pikchr.c"
2338 break;
2339 case 31: /* attribute ::= direction */
2340 #line 546 "pikchr.y"
2341 { pik_add_direction(p,&yymsp[0].minor.yy0,0,0); }
2342 #line 2367 "pikchr.c"
2343 break;
2344 case 32: /* attribute ::= direction even position */
2345 #line 547 "pikchr.y"
2346 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy49);}
2347 #line 2372 "pikchr.c"
2348 break;
2349 case 33: /* attribute ::= CLOSE */
2350 #line 548 "pikchr.y"
2351 { pik_close_path(p,&yymsp[0].minor.yy0); }
2352 #line 2377 "pikchr.c"
2353 break;
2354 case 34: /* attribute ::= CHOP */
2355 #line 549 "pikchr.y"
2356 { p->cur->bChop = 1; }
2357 #line 2382 "pikchr.c"
2358 break;
2359 case 35: /* attribute ::= FROM position */
2360 #line 550 "pikchr.y"
2361 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy49); }
2362 #line 2387 "pikchr.c"
2363 break;
2364 case 36: /* attribute ::= TO position */
2365 #line 551 "pikchr.y"
2366 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy49); }
2367 #line 2392 "pikchr.c"
2368 break;
2369 case 37: /* attribute ::= THEN */
2370 #line 552 "pikchr.y"
2371 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2372 #line 2397 "pikchr.c"
2373 break;
2374 case 38: /* attribute ::= AT position */
2375 #line 554 "pikchr.y"
2376 { pik_set_at(p,0,&yymsp[0].minor.yy49,&yymsp[-1].minor.yy0); }
2377 #line 2402 "pikchr.c"
2378 break;
2379 case 39: /* attribute ::= SAME */
2380 #line 556 "pikchr.y"
2381 {pik_same(p,0,&yymsp[0].minor.yy0);}
2382 #line 2407 "pikchr.c"
2383 break;
2384 case 40: /* attribute ::= SAME AS object */
2385 #line 557 "pikchr.y"
2386 {pik_same(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2387 #line 2412 "pikchr.c"
2388 break;
2389 case 41: /* attribute ::= STRING textposition */
2390 #line 558 "pikchr.y"
2391 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy52);}
2392 #line 2417 "pikchr.c"
2393 break;
2394 case 42: /* attribute ::= FIT */
2395 #line 559 "pikchr.y"
2396 {pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2397 #line 2422 "pikchr.c"
2398 break;
2399 case 43: /* with ::= DOT_E edge AT position */
2400 case 44: /* with ::= edge AT position */ yytestcase(yyruleno==44);
2401 #line 566 "pikchr.y"
2402 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy49,&yymsp[-1].minor.yy0); }
2403 #line 2428 "pikchr.c"
2404 break;
2405 case 45: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2406 #line 570 "pikchr.y"
2407 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2408 #line 2433 "pikchr.c"
2409 yymsp[0].minor.yy0 = yylhsminor.yy0;
2410 break;
2411 case 46: /* boolproperty ::= CW */
2412 #line 581 "pikchr.y"
2413 {p->cur->cw = 1;}
2414 #line 2439 "pikchr.c"
2415 break;
2416 case 47: /* boolproperty ::= CCW */
2417 #line 582 "pikchr.y"
2418 {p->cur->cw = 0;}
2419 #line 2444 "pikchr.c"
2420 break;
2421 case 48: /* boolproperty ::= LARROW */
2422 #line 583 "pikchr.y"
2423 {p->cur->larrow=1; p->cur->rarrow=0; }
2424 #line 2449 "pikchr.c"
2425 break;
2426 case 49: /* boolproperty ::= RARROW */
2427 #line 584 "pikchr.y"
2428 {p->cur->larrow=0; p->cur->rarrow=1; }
2429 #line 2454 "pikchr.c"
2430 break;
2431 case 50: /* boolproperty ::= LRARROW */
2432 #line 585 "pikchr.y"
2433 {p->cur->larrow=1; p->cur->rarrow=1; }
2434 #line 2459 "pikchr.c"
2435 break;
2436 case 51: /* boolproperty ::= INVIS */
2437 #line 586 "pikchr.y"
2438 {p->cur->sw = 0.0;}
2439 #line 2464 "pikchr.c"
2440 break;
2441 case 52: /* textposition ::= */
2442 #line 588 "pikchr.y"
2443 {yymsp[1].minor.yy52 = 0;}
2444 #line 2469 "pikchr.c"
2445 break;
2446 case 53: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED */
2447 #line 591 "pikchr.y"
2448 {yylhsminor.yy52 = pik_text_position(p,yymsp[-1].minor.yy52,&yymsp[0].minor.yy0);}
2449 #line 2474 "pikchr.c"
2450 yymsp[-1].minor.yy52 = yylhsminor.yy52;
2451 break;
2452 case 54: /* position ::= expr COMMA expr */
2453 #line 594 "pikchr.y"
2454 {yylhsminor.yy49.x=yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[0].minor.yy83;}
2455 #line 2480 "pikchr.c"
2456 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2457 break;
2458 case 55: /* position ::= place PLUS expr COMMA expr */
2459 #line 596 "pikchr.y"
2460 {yylhsminor.yy49.x=yymsp[-4].minor.yy49.x+yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[-4].minor.yy49.y+yymsp[0].minor.yy83;}
2461 #line 2486 "pikchr.c"
2462 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2463 break;
2464 case 56: /* position ::= place MINUS expr COMMA expr */
2465 #line 597 "pikchr.y"
2466 {yylhsminor.yy49.x=yymsp[-4].minor.yy49.x-yymsp[-2].minor.yy83; yylhsminor.yy49.y=yymsp[-4].minor.yy49.y-yymsp[0].minor.yy83;}
2467 #line 2492 "pikchr.c"
2468 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2469 break;
2470 case 57: /* position ::= place PLUS LP expr COMMA expr RP */
2471 #line 599 "pikchr.y"
2472 {yylhsminor.yy49.x=yymsp[-6].minor.yy49.x+yymsp[-3].minor.yy83; yylhsminor.yy49.y=yymsp[-6].minor.yy49.y+yymsp[-1].minor.yy83;}
2473 #line 2498 "pikchr.c"
2474 yymsp[-6].minor.yy49 = yylhsminor.yy49;
2475 break;
2476 case 58: /* position ::= place MINUS LP expr COMMA expr RP */
2477 #line 601 "pikchr.y"
2478 {yylhsminor.yy49.x=yymsp[-6].minor.yy49.x-yymsp[-3].minor.yy83; yylhsminor.yy49.y=yymsp[-6].minor.yy49.y-yymsp[-1].minor.yy83;}
2479 #line 2504 "pikchr.c"
2480 yymsp[-6].minor.yy49 = yylhsminor.yy49;
2481 break;
2482 case 59: /* position ::= LP position COMMA position RP */
2483 #line 602 "pikchr.y"
2484 {yymsp[-4].minor.yy49.x=yymsp[-3].minor.yy49.x; yymsp[-4].minor.yy49.y=yymsp[-1].minor.yy49.y;}
2485 #line 2510 "pikchr.c"
2486 break;
2487 case 60: /* position ::= LP position RP */
2488 #line 603 "pikchr.y"
2489 {yymsp[-2].minor.yy49=yymsp[-1].minor.yy49;}
2490 #line 2515 "pikchr.c"
2491 break;
2492 case 61: /* position ::= expr between position AND position */
2493 #line 605 "pikchr.y"
2494 {yylhsminor.yy49 = pik_position_between(p,yymsp[-4].minor.yy83,yymsp[-2].minor.yy49,yymsp[0].minor.yy49);}
2495 #line 2520 "pikchr.c"
2496 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2497 break;
2498 case 62: /* position ::= expr ABOVE position */
2499 #line 606 "pikchr.y"
2500 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.y += yymsp[-2].minor.yy83;}
2501 #line 2526 "pikchr.c"
2502 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2503 break;
2504 case 63: /* position ::= expr BELOW position */
2505 #line 607 "pikchr.y"
2506 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.y -= yymsp[-2].minor.yy83;}
2507 #line 2532 "pikchr.c"
2508 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2509 break;
2510 case 64: /* position ::= expr LEFT OF position */
2511 #line 608 "pikchr.y"
2512 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.x -= yymsp[-3].minor.yy83;}
2513 #line 2538 "pikchr.c"
2514 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2515 break;
2516 case 65: /* position ::= expr RIGHT OF position */
2517 #line 609 "pikchr.y"
2518 {yylhsminor.yy49=yymsp[0].minor.yy49; yylhsminor.yy49.x += yymsp[-3].minor.yy83;}
2519 #line 2544 "pikchr.c"
2520 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2521 break;
2522 case 66: /* position ::= expr EDGEPT OF position */
2523 #line 611 "pikchr.y"
2524 {yylhsminor.yy49 = pik_position_at_hdg(p,yymsp[-3].minor.yy83,&yymsp[-2].minor.yy0,yymsp[0].minor.yy49);}
2525 #line 2550 "pikchr.c"
2526 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2527 break;
2528 case 67: /* position ::= expr HEADING expr FROM position */
2529 #line 613 "pikchr.y"
2530 {yylhsminor.yy49 = pik_position_at_angle(p,yymsp[-4].minor.yy83,yymsp[-2].minor.yy83,yymsp[0].minor.yy49);}
2531 #line 2556 "pikchr.c"
2532 yymsp[-4].minor.yy49 = yylhsminor.yy49;
2533 break;
2534 case 68: /* place ::= object */
2535 #line 619 "pikchr.y"
2536 {yylhsminor.yy49 = pik_place_of_elem(p,yymsp[0].minor.yy24,0);}
2537 #line 2562 "pikchr.c"
2538 yymsp[0].minor.yy49 = yylhsminor.yy49;
2539 break;
2540 case 69: /* place ::= object DOT_E edge */
2541 case 70: /* place ::= object DOT_L START */ yytestcase(yyruleno==70);
2542 case 71: /* place ::= object DOT_L END */ yytestcase(yyruleno==71);
2543 #line 620 "pikchr.y"
2544 {yylhsminor.yy49 = pik_place_of_elem(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2545 #line 2570 "pikchr.c"
2546 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2547 break;
2548 case 72: /* place ::= START OF object */
2549 case 73: /* place ::= END OF object */ yytestcase(yyruleno==73);
2550 case 74: /* place ::= edge OF object */ yytestcase(yyruleno==74);
2551 #line 623 "pikchr.y"
2552 {yylhsminor.yy49 = pik_place_of_elem(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2553 #line 2578 "pikchr.c"
2554 yymsp[-2].minor.yy49 = yylhsminor.yy49;
2555 break;
2556 case 75: /* place ::= NTH VERTEX OF object */
2557 #line 626 "pikchr.y"
2558 {yylhsminor.yy49 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy24);}
2559 #line 2584 "pikchr.c"
2560 yymsp[-3].minor.yy49 = yylhsminor.yy49;
2561 break;
2562 case 76: /* object ::= nth */
2563 #line 629 "pikchr.y"
2564 {yylhsminor.yy24 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2565 #line 2590 "pikchr.c"
2566 yymsp[0].minor.yy24 = yylhsminor.yy24;
2567 break;
2568 case 77: /* object ::= nth OF|IN object */
2569 #line 630 "pikchr.y"
2570 {yylhsminor.yy24 = pik_find_nth(p,yymsp[0].minor.yy24,&yymsp[-2].minor.yy0);}
2571 #line 2596 "pikchr.c"
2572 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2573 break;
2574 case 78: /* objectname ::= PLACENAME */
2575 #line 632 "pikchr.y"
2576 {yylhsminor.yy24 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2577 #line 2602 "pikchr.c"
2578 yymsp[0].minor.yy24 = yylhsminor.yy24;
2579 break;
2580 case 79: /* objectname ::= objectname DOT_U PLACENAME */
2581 #line 634 "pikchr.y"
2582 {yylhsminor.yy24 = pik_find_byname(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2583 #line 2608 "pikchr.c"
2584 yymsp[-2].minor.yy24 = yylhsminor.yy24;
2585 break;
2586 case 80: /* nth ::= NTH CLASSNAME */
2587 #line 636 "pikchr.y"
2588 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2589 #line 2614 "pikchr.c"
2590 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2591 break;
2592 case 81: /* nth ::= NTH LAST CLASSNAME */
2593 #line 637 "pikchr.y"
2594 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2595 #line 2620 "pikchr.c"
2596 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2597 break;
2598 case 82: /* nth ::= LAST CLASSNAME */
2599 #line 638 "pikchr.y"
2600 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2601 #line 2626 "pikchr.c"
2602 break;
2603 case 83: /* nth ::= LAST */
2604 #line 639 "pikchr.y"
2605 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2606 #line 2631 "pikchr.c"
2607 yymsp[0].minor.yy0 = yylhsminor.yy0;
2608 break;
2609 case 84: /* nth ::= NTH LB RB */
2610 #line 640 "pikchr.y"
2611 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2612 #line 2637 "pikchr.c"
2613 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2614 break;
2615 case 85: /* nth ::= NTH LAST LB RB */
2616 #line 641 "pikchr.y"
2617 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2618 #line 2643 "pikchr.c"
2619 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2620 break;
2621 case 86: /* nth ::= LAST LB RB */
2622 #line 642 "pikchr.y"
2623 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2624 #line 2649 "pikchr.c"
2625 break;
2626 case 87: /* expr ::= expr PLUS expr */
2627 #line 644 "pikchr.y"
2628 {yylhsminor.yy83=yymsp[-2].minor.yy83+yymsp[0].minor.yy83;}
2629 #line 2654 "pikchr.c"
2630 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2631 break;
2632 case 88: /* expr ::= expr MINUS expr */
2633 #line 645 "pikchr.y"
2634 {yylhsminor.yy83=yymsp[-2].minor.yy83-yymsp[0].minor.yy83;}
2635 #line 2660 "pikchr.c"
2636 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2637 break;
2638 case 89: /* expr ::= expr STAR expr */
2639 #line 646 "pikchr.y"
2640 {yylhsminor.yy83=yymsp[-2].minor.yy83*yymsp[0].minor.yy83;}
2641 #line 2666 "pikchr.c"
2642 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2643 break;
2644 case 90: /* expr ::= expr SLASH expr */
2645 #line 647 "pikchr.y"
2646 {
2647 if( yymsp[0].minor.yy83==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy83 = 0.0; }
2648 else{ yylhsminor.yy83 = yymsp[-2].minor.yy83/yymsp[0].minor.yy83; }
2649 }
2650 #line 2675 "pikchr.c"
2651 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2652 break;
2653 case 91: /* expr ::= MINUS expr */
2654 #line 651 "pikchr.y"
2655 {yymsp[-1].minor.yy83=-yymsp[0].minor.yy83;}
2656 #line 2681 "pikchr.c"
2657 break;
2658 case 92: /* expr ::= PLUS expr */
2659 #line 652 "pikchr.y"
2660 {yymsp[-1].minor.yy83=yymsp[0].minor.yy83;}
2661 #line 2686 "pikchr.c"
2662 break;
2663 case 93: /* expr ::= LP expr RP */
2664 #line 653 "pikchr.y"
2665 {yymsp[-2].minor.yy83=yymsp[-1].minor.yy83;}
2666 #line 2691 "pikchr.c"
2667 break;
2668 case 94: /* expr ::= NUMBER */
2669 #line 654 "pikchr.y"
2670 {yylhsminor.yy83=pik_atof(p,&yymsp[0].minor.yy0);}
2671 #line 2696 "pikchr.c"
2672 yymsp[0].minor.yy83 = yylhsminor.yy83;
2673 break;
2674 case 95: /* expr ::= ID */
2675 #line 655 "pikchr.y"
2676 {yylhsminor.yy83=pik_get_var(p,&yymsp[0].minor.yy0);}
2677 #line 2702 "pikchr.c"
2678 yymsp[0].minor.yy83 = yylhsminor.yy83;
2679 break;
2680 case 96: /* expr ::= FUNC1 LP expr RP */
2681 #line 656 "pikchr.y"
2682 {yylhsminor.yy83 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy83,0.0);}
2683 #line 2708 "pikchr.c"
2684 yymsp[-3].minor.yy83 = yylhsminor.yy83;
2685 break;
2686 case 97: /* expr ::= FUNC2 LP expr COMMA expr RP */
2687 #line 657 "pikchr.y"
2688 {yylhsminor.yy83 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy83,yymsp[-1].minor.yy83);}
2689 #line 2714 "pikchr.c"
2690 yymsp[-5].minor.yy83 = yylhsminor.yy83;
2691 break;
2692 case 98: /* expr ::= object DOT_L locproperty */
2693 case 99: /* expr ::= object DOT_L numproperty */ yytestcase(yyruleno==99);
2694 case 100: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==100);
2695 case 101: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==101);
2696 #line 659 "pikchr.y"
2697 {yylhsminor.yy83=pik_property_of(p,yymsp[-2].minor.yy24,&yymsp[0].minor.yy0);}
2698 #line 2723 "pikchr.c"
2699 yymsp[-2].minor.yy83 = yylhsminor.yy83;
2700 break;
2701 case 102: /* expr ::= object DOT_E edge DOT_L X */
2702 #line 663 "pikchr.y"
2703 {yylhsminor.yy83=pik_place_of_elem(p,yymsp[-4].minor.yy24,&yymsp[-2].minor.yy0).x;}
2704 #line 2729 "pikchr.c"
2705 yymsp[-4].minor.yy83 = yylhsminor.yy83;
2706 break;
2707 case 103: /* expr ::= object DOT_E edge DOT_L Y */
2708 #line 664 "pikchr.y"
2709 {yylhsminor.yy83=pik_place_of_elem(p,yymsp[-4].minor.yy24,&yymsp[-2].minor.yy0).y;}
2710 #line 2735 "pikchr.c"
2711 yymsp[-4].minor.yy83 = yylhsminor.yy83;
2712 break;
2713 case 104: /* expr ::= LP locproperty OF object RP */
2714 case 105: /* expr ::= LP dashproperty OF object RP */ yytestcase(yyruleno==105);
2715 case 106: /* expr ::= LP numproperty OF object RP */ yytestcase(yyruleno==106);
2716 case 107: /* expr ::= LP colorproperty OF object RP */ yytestcase(yyruleno==107);
2717 #line 665 "pikchr.y"
2718 {yymsp[-4].minor.yy83=pik_property_of(p,yymsp[-1].minor.yy24,&yymsp[-3].minor.yy0);}
2719 #line 2744 "pikchr.c"
2720 break;
2721 case 108: /* expr ::= NTH VERTEX OF object DOT_L X */
2722 #line 671 "pikchr.y"
2723 {yylhsminor.yy83 = pik_nth_vertex(p,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,yymsp[-2].minor.yy24).x;}
2724 #line 2749 "pikchr.c"
2725 yymsp[-5].minor.yy83 = yylhsminor.yy83;
2726 break;
2727 case 109: /* expr ::= NTH VERTEX OF object DOT_L Y */
2728 #line 673 "pikchr.y"
2729 {yylhsminor.yy83 = pik_nth_vertex(p,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,yymsp[-2].minor.yy24).y;}
2730 #line 2755 "pikchr.c"
2731 yymsp[-5].minor.yy83 = yylhsminor.yy83;
2732 break;
2733 default:
2734 /* (110) lvalue ::= ID */ yytestcase(yyruleno==110);
2735 /* (111) lvalue ::= FILL */ yytestcase(yyruleno==111);
@@ -2818,18 +2824,18 @@
2824 ){
2825 pik_parserARG_FETCH
2826 pik_parserCTX_FETCH
2827 #define TOKEN yyminor
2828 /************ Begin %syntax_error code ****************************************/
2829 #line 462 "pikchr.y"
2830
2831 if( TOKEN.z && TOKEN.z[0] ){
2832 pik_error(p, &TOKEN, "syntax error");
2833 }else{
2834 pik_error(p, 0, "syntax error");
2835 }
2836 #line 2861 "pikchr.c"
2837 /************ End %syntax_error code ******************************************/
2838 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
2839 pik_parserCTX_STORE
2840 }
2841
@@ -3058,11 +3064,11 @@
3064 #else
3065 (void)iToken;
3066 return 0;
3067 #endif
3068 }
3069 #line 683 "pikchr.y"
3070
3071
3072
3073 /* Chart of the 140 official HTML color names with their
3074 ** corresponding RGB value.
@@ -3231,12 +3237,12 @@
3237 ** Binary search used. Must be kept in sorted order.
3238 */
3239 static const struct { const char *zName; PNum val; } aBuiltin[] = {
3240 { "arcrad", 0.25 },
3241 { "arrowhead", 2.0 },
3242 { "arrowht", 0.08 },
3243 { "arrowwid", 0.06 },
3244 { "boxht", 0.5 },
3245 { "boxrad", 0.0 },
3246 { "boxwid", 0.75 },
3247 { "charht", 0.14 },
3248 { "charwid", 0.08 },
@@ -3265,11 +3271,11 @@
3271 /* Methods for the "arc" class */
3272 static void arcInit(Pik *p, PElem *pElem){
3273 pElem->w = pik_value(p, "arcrad",6,0);
3274 pElem->h = pElem->w;
3275 }
3276 /* Hack: Arcs are here rendered as quadratic Bezier curves rather
3277 ** than true arcs. Multiple reasons: (1) the legacy-PIC parameters
3278 ** that control arcs are obscure and I could not figure out what they
3279 ** mean based on available documentation. (2) Arcs are rarely used,
3280 ** and so do not seem that important.
3281 */
@@ -3388,19 +3394,13 @@
3394 chop = pElem->type->xOffset(0,pElem,cp);
3395 chop.x += pElem->ptAt.x;
3396 chop.y += pElem->ptAt.y;
3397 return chop;
3398 }
3399 static void boxFit(Pik *p, PElem *pElem, PNum w, PNum h){
3400 if( w>0 ) pElem->w = w;
3401 if( h>0 ) pElem->h = h;
 
 
 
 
 
 
3402 }
3403 static void boxRender(Pik *p, PElem *pElem){
3404 PNum w2 = 0.5*pElem->w;
3405 PNum h2 = 0.5*pElem->h;
3406 PNum rad = pElem->rad;
@@ -3485,18 +3485,16 @@
3485 if( dist<pElem->rad ) return pElem->ptAt;
3486 chop.x = pElem->ptAt.x + dx*pElem->rad/dist;
3487 chop.y = pElem->ptAt.y + dy*pElem->rad/dist;
3488 return chop;
3489 }
3490 static void circleFit(Pik *p, PElem *pElem, PNum w, PNum h){
3491 PNum mx = 0.0;
3492 if( w>0 ) mx = w;
3493 if( h>mx ) mx = h;
3494 if( (w*w + h*h) > mx*mx ){
3495 mx = sqrt(w*w + h*h);
 
 
3496 }
3497 if( mx>0.0 ){
3498 pElem->rad = 0.5*mx;
3499 pElem->w = pElem->h = mx;
3500 }
@@ -3698,19 +3696,13 @@
3696 static void ovalNumProp(Pik *p, PElem *pElem, PToken *pId){
3697 /* Always adjust the radius to be half of the smaller of
3698 ** the width and height. */
3699 pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
3700 }
3701 static void ovalFit(Pik *p, PElem *pElem, PNum w, PNum h){
3702 if( w>0 ) pElem->w = w;
3703 if( h>0 ) pElem->h = h;
 
 
 
 
 
 
3704 if( pElem->w<pElem->h ) pElem->w = pElem->h;
3705 }
3706
3707
3708
@@ -4251,11 +4243,11 @@
4243 int hasCenter = 0;
4244
4245 if( p->nErr ) return;
4246 if( pElem->nTxt==0 ) return;
4247 aTxt = pElem->aTxt;
4248 dy = 0.5*p->charHeight;
4249 n = pElem->nTxt;
4250 pik_txt_vertical_layout(p, pElem);
4251 x = pElem->ptAt.x;
4252 for(i=0; i<n; i++){
4253 if( (pElem->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
@@ -4291,12 +4283,12 @@
4283 pik_append(p, " font-weight=\"bold\"", -1);
4284 }
4285 if( pElem->color>=0.0 ){
4286 pik_append_clr(p, " fill=\"", pElem->color, "\"");
4287 }
4288 if( p->fontScale<=0.99 || p->fontScale>=1.01 ){
4289 pik_append_num(p, " font-size=\"", p->fontScale*100.0);
4290 pik_append(p, "%\"", 2);
4291 }
4292 if( (t->eCode & TP_ALIGN)!=0 && pElem->nPath>=2 ){
4293 int n = pElem->nPath;
4294 PNum dx = pElem->aPath[n-1].x - pElem->aPath[0].x;
@@ -5053,10 +5045,33 @@
5045 case T_BOLD: iRes |= TP_BOLD; break;
5046 case T_ALIGNED: iRes |= TP_ALIGN; break;
5047 }
5048 return iRes;
5049 }
5050
5051 /* Return an estimate of the actually number of displayed characters
5052 ** in a character string.
5053 **
5054 ** Omit "\" used to escape characters. And count entities like
5055 ** "&lt;" as a single character.
5056 */
5057 static int pik_text_length(const PToken *pToken){
5058 int n = pToken->n;
5059 const char *z = pToken->z;
5060 int cnt, j;
5061 for(j=1, cnt=0; j<n-1; j++){
5062 cnt++;
5063 if( z[j]=='\\' && z[j+1]!='&' ){
5064 j++;
5065 }else if( z[j]=='&' ){
5066 int k;
5067 for(k=j+1; k<j+7 && z[k]!=';'; k++){}
5068 if( z[k]==';' ) j = k;
5069 }
5070 }
5071 return cnt;
5072 }
5073
5074 /* Adjust the width, height, and or radius of the object so that
5075 ** it fits around the text that has been added so far.
5076 **
5077 ** (1) Only text specified prior to this attribute is considered.
@@ -5098,32 +5113,18 @@
5113 }
5114 h = hasCenter + hasSingleStack*2 + hasDoubleStack*2;
5115 }
5116 if( (pElem->mProp & A_WIDTH)==0 ){
5117 for(i=0; i<pElem->nTxt; i++){
5118 int cnt = pik_text_length(&pElem->aTxt[i]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5119 if( (pElem->aTxt[i].eCode & TP_JMASK)!=0 ) cnt *= 2;
5120 if( cnt>w ) w = cnt;
5121 }
5122 }
5123 if( h>0 || w>0 ){
5124 pik_compute_layout_settings(p);
5125 pElem->type->xFit(p, pElem, w*p->charWidth, h*p->charHeight);
5126 }
5127 }
5128
5129 /* Set a local variable name to "val".
5130 **
@@ -5162,10 +5163,11 @@
5163 pVar->val /= val;
5164 }
5165 break;
5166 default: pVar->val = val; break;
5167 }
5168 p->bLayoutVars = 0; /* Clear the layout setting cache */
5169 }
5170
5171 /*
5172 ** Search for the variable named z[0..n-1] in:
5173 **
@@ -5785,36 +5787,54 @@
5787 pik_elist_render(p, pElem->pSublist);
5788 }
5789 }
5790 }while( bMoreToDo );
5791 }
5792
5793 /* Recompute key layout parameters from variables. */
5794 static void pik_compute_layout_settings(Pik *p){
5795 PNum thickness; /* Line thickness */
5796 PNum wArrow; /* Width of arrowheads */
5797
5798 /* Set up rendering parameters */
5799 if( p->bLayoutVars ) return;
5800 thickness = pik_value(p,"thickness",9,0);
5801 if( thickness<=0.01 ) thickness = 0.01;
5802 wArrow = 0.5*pik_value(p,"arrowwid",8,0);
5803 p->wArrow = wArrow/thickness;
5804 p->hArrow = pik_value(p,"arrowht",7,0)/thickness;
5805 p->rScale = 144.0*pik_value(p,"scale",5,0);
5806 if( p->rScale<5.0 ) p->rScale = 5.0;
5807 p->fontScale = pik_value(p,"fontscale",9,0);
5808 if( p->fontScale<=0.0 ) p->fontScale = 1.0;
5809 p->fontScale *= p->rScale/144.0;
5810 p->charWidth = pik_value(p,"charwid",7,0)*p->fontScale;
5811 p->charHeight = pik_value(p,"charht",6,0)*p->fontScale;
5812 p->bLayoutVars = 1;
5813 }
5814
5815 /* Render a list of elements. Write the SVG into p->zOut.
5816 ** Delete the input element_list before returnning.
5817 */
5818 static void pik_render(Pik *p, PEList *pEList){
5819 int i, j;
5820 if( pEList==0 ) return;
5821 if( p->nErr==0 ){
5822 PNum thickness; /* Stroke width */
 
5823 PNum margin; /* Extra bounding box margin */
5824 PNum leftmargin; /* Extra bounding box area on the left */
5825 PNum w, h; /* Drawing width and height */
5826 PNum wArrow;
5827
5828 /* Set up rendering parameters */
5829 pik_compute_layout_settings(p);
5830 thickness = pik_value(p,"thickness",9,0);
5831 if( thickness<=0.01 ) thickness = 0.01;
5832 margin = pik_value(p,"margin",6,0);
5833 margin += thickness;
5834 leftmargin = pik_value(p,"leftmargin",10,0);
5835 wArrow = p->wArrow*thickness;
 
 
 
 
 
5836
5837 /* Compute a bounding box over all objects so that we can know
5838 ** how big to declare the SVG canvas */
5839 pik_bbox_init(&p->bbox);
5840 for(i=0; i<pEList->n; i++){
@@ -6431,6 +6451,6 @@
6451 printf("</body></html>\n");
6452 return 0;
6453 }
6454 #endif /* PIKCHR_SHELL */
6455
6456 #line 6481 "pikchr.c"
6457

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button