1/*********************************************************************** 2 * * 3 * $Id: hpgstransform.c 362 2006-10-16 14:13:48Z softadm $ 4 * * 5 * hpgs - HPGl Script, a hpgl/2 interpreter, which uses a Postscript * 6 * API for rendering a scene and thus renders to a variety of * 7 * devices and fileformats. * 8 * * 9 * (C) 2004-2006 ev-i Informationstechnologie GmbH http://www.ev-i.at * 10 * * 11 * Author: Wolfgang Glas * 12 * * 13 * hpgs is free software; you can redistribute it and/or * 14 * modify it under the terms of the GNU Lesser General Public * 15 * License as published by the Free Software Foundation; either * 16 * version 2.1 of the License, or (at your option) any later version. * 17 * * 18 * hpgs is distributed in the hope that it will be useful, * 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 21 * Lesser General Public License for more details. * 22 * * 23 * You should have received a copy of the GNU Lesser General Public * 24 * License along with this library; if not, write to the * 25 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * 26 * Boston, MA 02111-1307 USA * 27 * * 28 *********************************************************************** 29 * * 30 * The implementation of the HPGL reader. * 31 * * 32 ***********************************************************************/ 33 34#include <hpgsreader.h> 35#include <math.h> 36 37//#define HPGS_DEBUG_XFORM 38 39static void apply_scale(hpgs_reader *reader, 40 const hpgs_point *p1, const hpgs_point *p2) 41{ 42 double xf,yf; 43 double dx = 0.0,dy=0.0; 44 hpgs_point p2u; 45 46 if (reader->sc_type < 0) return; 47 48 // get P2 in old user coordinates 49 p2u.x = reader->frame_x + p2->x * HP_TO_PT; 50 p2u.y = reader->frame_y + p2->y * HP_TO_PT; 51 52 hpgs_matrix_ixform(&p2u,&p2u,&reader->world_matrix); 53 54#ifdef HPGS_DEBUG_XFORM 55 { 56 hpgs_point p1u; 57 58 p1u.x = reader->frame_x + p1->x * HP_TO_PT; 59 p1u.y = reader->frame_y + p1->y * HP_TO_PT; 60 61 hpgs_matrix_ixform(&p1u,&reader->world_matrix,&p1u); 62 63 hpgs_log("SC: P1 = %g,%g.\n",p1->x,p1->y); 64 hpgs_log("SC: P2 = %g,%g.\n",p2->x,p2->y); 65 hpgs_log("SC: p1u = %g,%g.\n",p1u.x,p1u.y); 66 hpgs_log("SC: p2u = %g,%g.\n",p2u.x,p2u.y); 67 hpgs_log("SC: xmin,xmax = %g,%g.\n",reader->sc_xmin,reader->sc_xmax); 68 hpgs_log("SC: ymin,ymax = %g,%g.\n",reader->sc_ymin,reader->sc_ymax); 69 } 70#endif 71 72 switch (reader->sc_type) 73 { 74 case 0: 75 xf = p2u.x / (reader->sc_xmax - reader->sc_xmin); 76 yf = p2u.y / (reader->sc_ymax - reader->sc_ymin); 77 break; 78 case 1: 79 xf = p2u.x / (reader->sc_xmax - reader->sc_xmin); 80 yf = p2u.y / (reader->sc_ymax - reader->sc_ymin); 81 82 if (xf < yf) 83 { 84 dy = (yf-xf) * (reader->sc_ymax - reader->sc_ymin) * 0.01 * reader->sc_left; 85 yf = xf; 86 } 87 else 88 { 89 dx = (xf-yf) * (reader->sc_xmax - reader->sc_xmin) * 0.01 * reader->sc_bottom; 90 xf = yf; 91 } 92 break; 93 94 case 2: 95 xf = reader->sc_xmax; 96 yf = reader->sc_ymax; 97 break; 98 99 default: 100 return; 101 } 102 103#ifdef HPGS_DEBUG_XFORM 104 hpgs_log("SC: xf,yf = %g,%g.\n",xf,yf); 105#endif 106 107 dx -= reader->sc_xmin * xf; 108 dy -= reader->sc_ymin * yf; 109 110 // concatenate transofrmation matrices. 111 // 112 // | 1 0 0 | | 1 0 0 | 113 // | x0 mxx mxy |* | dx xf 0 | = 114 // | y0 myx myy | | dy 0 yf | 115 // 116 // | 1 0 0 | 117 // | x0+mxx*dx+mxy*dy mxx*xf mxy*yf | 118 // | y0+myx*dx+myy*dy myx*xf myy*yf | 119 // 120 121 reader->world_matrix.dx += reader->world_matrix.mxx*dx + reader->world_matrix.mxy*dy; 122 reader->world_matrix.dy += reader->world_matrix.myx*dx + reader->world_matrix.myy*dy; 123 124 reader->world_matrix.mxx *= xf; 125 reader->world_matrix.myx *= xf; 126 reader->world_matrix.mxy *= yf; 127 reader->world_matrix.myy *= yf; 128 129#ifdef HPGS_DEBUG_XFORM 130 hpgs_log("SC: %10g %10g %10g\n",reader->world_matrix.dx,reader->world_matrix.mxx,reader->world_matrix.mxy); 131 hpgs_log("SC: %10g %10g %10g\n",reader->world_matrix.dy,reader->world_matrix.myx,reader->world_matrix.myy); 132#endif 133} 134 135void hpgs_reader_set_default_transformation (hpgs_reader *reader) 136{ 137 // transformation matrix for user to PS coordinates. 138 int angle = reader->y_size >= reader->x_size ? 90 : 0; 139 140 hpgs_point p1 = reader->P1; 141 hpgs_point p2 = reader->P2; 142 143 angle += reader->rotation; 144 145 if ((angle % 180) == 90) 146 { 147 p2.y -= p1.y; 148 p1.y = 0.0; 149 } 150 151 152 reader->world_matrix.dx = reader->frame_x + p1.x * HP_TO_PT; 153 reader->world_matrix.dy = reader->frame_y + p1.y * HP_TO_PT; 154 155 switch (angle % 360) 156 { 157 case 90: 158 reader->world_matrix.mxx = 0.0; 159 reader->world_matrix.mxy = -HP_TO_PT; 160 reader->world_matrix.myx = HP_TO_PT; 161 reader->world_matrix.myy = 0.0; 162 break; 163 case 180: 164 reader->world_matrix.mxx = -HP_TO_PT; 165 reader->world_matrix.mxy = 0.0; 166 reader->world_matrix.myx = 0.0; 167 reader->world_matrix.myy = -HP_TO_PT; 168 break; 169 case 270: 170 reader->world_matrix.mxx = 0.0; 171 reader->world_matrix.mxy = HP_TO_PT; 172 reader->world_matrix.myx = -HP_TO_PT; 173 reader->world_matrix.myy = 0.0; 174 break; 175 default: // 0 176 reader->world_matrix.mxx = HP_TO_PT; 177 reader->world_matrix.mxy = 0.0; 178 reader->world_matrix.myx = 0.0; 179 reader->world_matrix.myy = HP_TO_PT; 180 } 181 182#ifdef HPGS_DEBUG_XFORM 183 hpgs_log("xform: %10g %10g %10g\n",reader->world_matrix.dx,reader->world_matrix.mxx,reader->world_matrix.mxy); 184 hpgs_log("xform: %10g %10g %10g\n",reader->world_matrix.dy,reader->world_matrix.myx,reader->world_matrix.myy); 185#endif 186 187 apply_scale(reader,&p1,&p2); 188 189 reader->world_scale = 190 sqrt (fabs(reader->world_matrix.mxx * reader->world_matrix.myy - 191 reader->world_matrix.mxy * reader->world_matrix.myx ) ); 192 193 // finally transform from model space to the page. 194 hpgs_matrix_concat(&reader->total_matrix,&reader->page_matrix,&reader->world_matrix); 195 196 reader->total_scale = reader->page_scale * reader->world_scale; 197} 198 199/* 200 HPGL command PS (Plot Size) 201*/ 202int hpgs_reader_do_PS (hpgs_reader *reader) 203{ 204 double x_size=reader->x_size/HP_TO_PT; 205 double y_size=reader->y_size/HP_TO_PT; 206 207 if (reader->eoc) 208 { 209 // Well it seems, that some oldstyle HPGL files use 210 // PS w/o arguments in order to enforce a coordinate setup 211 // as if a portrait paper size has been selected. 212 // (resulting in a prerotation of 90 degrees). 213 x_size = 33600.0; 214 y_size = 47520.0; 215 } 216 else 217 { 218 if (hpgs_reader_read_double(reader,&x_size)) return -1; 219 220 // set y-size to sqrt(0.5) * x_size in order to prevent 221 // the picture from rotation. This is better then setting 222 // the y-size to the (fictional) hard-clip limit, because 223 // without rotation we definitely can calculate our own plotsize 224 // using -i. 225 if (reader->eoc) 226 y_size = sqrt(0.5) * x_size; 227 } 228 229 if (!reader->eoc && 230 hpgs_reader_read_double(reader,&y_size)) return -1; 231 232 return hpgs_reader_set_plotsize (reader,x_size,y_size); 233} 234 235/* 236 Actually set the plot size. User by PS command above and by PJL parser. 237*/ 238int hpgs_reader_set_plotsize (hpgs_reader *reader, double x_size, double y_size) 239{ 240 hpgs_bbox bb = { 0.0,0.0,x_size*HP_TO_PT,y_size*HP_TO_PT }; 241 242 reader->x_size = x_size; 243 reader->y_size = y_size; 244 245 if (y_size >= x_size) 246 { 247 reader->P1.x = x_size; 248 reader->P1.y = 0.0; 249 reader->P2.x = 0.0; 250 reader->P2.y = y_size; 251 } 252 else 253 { 254 reader->P1.x = 0.0; 255 reader->P1.y = 0.0; 256 reader->P2.x = x_size; 257 reader->P2.y = y_size; 258 } 259 260 reader->delta_P.x = reader->P2.x - reader->P1.x; 261 reader->delta_P.y = reader->P2.y - reader->P1.y; 262 263 // undo any effects from an RO or SC statement. 264 reader->rotation = 0; 265 reader->sc_type = -1; 266 267 // change the page matrix only, if we don't have a plotsize device. 268 if (!reader->plotsize_device) 269 hpgs_reader_set_page_matrix (reader,&bb); 270 271 hpgs_reader_set_default_transformation(reader); 272 273 // report plot size only if 274 // when we don't have a plotsize device at hands. 275 if (reader->plotsize_device) 276 return 0; 277 278 return hpgs_setplotsize(reader->device,&reader->page_bbox); 279} 280 281/* 282 Change the page matrix according to this content bounding box. 283*/ 284void hpgs_reader_set_page_matrix (hpgs_reader *reader, const hpgs_bbox *bb) 285{ 286 hpgs_bbox rbb; 287 double xscale,yscale; 288 hpgs_point rcp; 289 290 hpgs_matrix_ixform(&rcp,&reader->current_point,&reader->page_matrix); 291 292 // save the content bounding box for propagating it to the 293 // page_asset function. 294 reader->content_bbox = *bb; 295 296 if (reader->page_mode == 0) 297 { 298 reader->page_bbox = *bb; 299 hpgs_matrix_set_identity(&reader->page_matrix); 300 reader->page_scale = 1.0; 301 goto restore_cb; 302 } 303 304 reader->page_matrix.mxx = cos(reader->page_angle * M_PI / 180.0); 305 reader->page_matrix.mxy = -sin(reader->page_angle * M_PI / 180.0); 306 307 reader->page_matrix.myx = sin(reader->page_angle * M_PI / 180.0); 308 reader->page_matrix.myy = cos(reader->page_angle * M_PI / 180.0); 309 310 reader->page_matrix.dx = 0.0; 311 reader->page_matrix.dy = 0.0; 312 313 if (reader->page_mode == 2) // dynamic page. 314 { 315 hpgs_matrix_xform_bbox(&rbb,&reader->page_matrix,bb); 316 317 reader->page_bbox.llx = 0.0; 318 reader->page_bbox.lly = 0.0; 319 320 reader->page_bbox.urx = (rbb.urx-rbb.llx) + 2.0 * reader->page_border; 321 reader->page_bbox.ury = (rbb.ury-rbb.lly) + 2.0 * reader->page_border; 322 323 reader->page_matrix.dx = reader->page_border - rbb.llx; 324 reader->page_matrix.dy = reader->page_border - rbb.lly; 325 326 // do we fit on the maximal page size? 327 if ((reader->page_width <= 0.0 || reader->page_bbox.urx <= reader->page_width) && 328 (reader->page_height <= 0.0 || reader->page_bbox.ury <= reader->page_height) ) 329 { 330 reader->page_scale = 1.0; 331 goto restore_cb; 332 } 333 334 if (reader->page_bbox.urx > reader->page_width) 335 xscale = reader->page_width/reader->page_bbox.urx; 336 else 337 xscale = 1.0; 338 339 if (reader->page_bbox.ury> reader->page_height) 340 yscale = reader->page_height/reader->page_bbox.ury; 341 else 342 yscale = 1.0; 343 344 reader->page_scale = HPGS_MIN(xscale,yscale); 345 346 double rscale = 0.0; 347 double xx = 1.0; 348 349 // transform the scale to a human-interceptable scale. 350 do 351 { 352 xx *= 0.1; 353 rscale = floor(reader->page_scale / xx); 354 } 355 while (rscale < 2.0); 356 357 reader->page_scale = rscale * xx; 358 359 reader->page_matrix.mxx *= reader->page_scale; 360 reader->page_matrix.mxy *= reader->page_scale; 361 362 reader->page_matrix.myx *= reader->page_scale; 363 reader->page_matrix.myy *= reader->page_scale; 364 365 reader->page_matrix.dx *= reader->page_scale; 366 reader->page_matrix.dy *= reader->page_scale; 367 368 reader->page_bbox.urx *= reader->page_scale; 369 reader->page_bbox.ury *= reader->page_scale; 370 371 goto restore_cb; 372 } 373 374 // fixed page. 375 reader->page_bbox.llx = 0.0; 376 reader->page_bbox.lly = 0.0; 377 378 reader->page_bbox.urx = reader->page_width; 379 reader->page_bbox.ury = reader->page_height; 380 381 hpgs_matrix_xform_bbox(&rbb,&reader->page_matrix,bb); 382 383 xscale = (reader->page_width - 2.0 * reader->page_border) / (rbb.urx-rbb.llx); 384 yscale = (reader->page_height - 2.0 * reader->page_border) / (rbb.ury-rbb.lly); 385 386 reader->page_scale = HPGS_MIN(xscale,yscale); 387 388 reader->page_matrix.mxx *= reader->page_scale; 389 reader->page_matrix.mxy *= reader->page_scale; 390 391 reader->page_matrix.myx *= reader->page_scale; 392 reader->page_matrix.myy *= reader->page_scale; 393 394 if (reader->page_scale == xscale) 395 { 396 reader->page_matrix.dx = reader->page_border - reader->page_scale * rbb.llx; 397 reader->page_matrix.dy = 398 0.5 * (reader->page_height - reader->page_scale * (rbb.ury-rbb.lly)) - reader->page_scale * rbb.lly; 399 } 400 else 401 { 402 reader->page_matrix.dx = 403 0.5 * (reader->page_width - reader->page_scale * (rbb.urx-rbb.llx)) - reader->page_scale * rbb.llx; 404 reader->page_matrix.dy = reader->page_border - reader->page_scale * rbb.lly; 405 } 406 407 restore_cb: 408 hpgs_matrix_xform(&reader->current_point,&reader->page_matrix,&rcp); 409} 410 411/* 412 HPGL command FR (advance FRame) 413*/ 414int hpgs_reader_do_FR (hpgs_reader *reader) 415{ 416 double advance = reader->x_size; 417 418 if (!reader->eoc) 419 { 420 if (hpgs_reader_read_double(reader,&advance)) return -1; 421 } 422 423 if (hpgs_reader_checkpath(reader)) return -1; 424 425 while (reader->clipsave_depth > 0) 426 { 427 hpgs_cliprestore(reader->device); 428 --reader->clipsave_depth; 429 } 430 431 if (reader->frame_asset_func) 432 { 433 hpgs_bbox frame_bbox; 434 435 frame_bbox.llx = reader->frame_x == 0.0 ? reader->content_bbox.llx : reader->frame_x; 436 frame_bbox.lly = reader->content_bbox.lly; 437 frame_bbox.urx = reader->frame_x + advance * HP_TO_PT; 438 frame_bbox.ury = reader->content_bbox.ury; 439 440 if (frame_bbox.urx > frame_bbox.llx) 441 { 442 int ipage = reader->current_page; 443 444 if (reader->frame_asset_func(reader->frame_asset_ctxt, 445 reader->device, 446 &reader->page_matrix, 447 &reader->total_matrix, 448 &frame_bbox,ipage <= 1 ? 0 : ipage-1) ) 449 return -1; 450 } 451 } 452 453 reader->frame_x += advance * HP_TO_PT; 454 reader->P1.x -= advance; 455 reader->P2.x -= advance; 456 457 return 0; 458} 459 460/* 461 HPGL command RO (ROtate) 462*/ 463int hpgs_reader_do_RO (hpgs_reader *reader) 464{ 465 int rot=0; 466 hpgs_point p1,p2; 467 double dx,dy; 468 469 if (!reader->eoc && 470 hpgs_reader_read_int(reader,&rot)) return -1; 471 472 switch ((rot - reader->rotation) % 360) 473 { 474 case 90: 475 p1.x = -reader->P1.y; 476 p1.y = reader->P1.x; 477 p2.x = -reader->P2.y; 478 p2.y = reader->P2.x; 479 break; 480 case 180: 481 p1.x = -reader->P1.x; 482 p1.y = -reader->P1.y; 483 p2.x = -reader->P2.x; 484 p2.y = -reader->P2.x; 485 break; 486 case 270: 487 p1.x = reader->P1.y; 488 p1.y = -reader->P1.x; 489 p2.x = reader->P2.y; 490 p2.y = -reader->P2.x; 491 break; 492 default: /* 0,360 */ 493 p1.x = reader->P1.x; 494 p1.y = reader->P1.y; 495 p2.x = reader->P2.x; 496 p2.y = reader->P2.x; 497 break; 498 } 499 500 dx = p1.x < p2.x ? p1.x : p2.x; 501 dy = p1.y < p2.y ? p1.y : p2.y; 502 503#ifdef HPGS_DEBUG_XFORM 504 hpgs_log("RO: rot_old,rot = %d,%d.\n",reader->rotation,rot); 505 hpgs_log("RO: P1 = %g,%g.\n",reader->P1.x,reader->P1.y); 506 hpgs_log("RO: P2 = %g,%g.\n",reader->P2.x,reader->P2.y); 507#endif 508 509 reader->P1.x = p1.x-dx; 510 reader->P1.y = p1.y-dy; 511 reader->P2.x = p2.x-dx; 512 reader->P2.y = p2.y-dy; 513 514#ifdef HPGS_DEBUG_XFORM 515 hpgs_log("RO: P1 = %g,%g.\n",reader->P1.x,reader->P1.y); 516 hpgs_log("RO: P2 = %g,%g.\n",reader->P2.x,reader->P2.y); 517#endif 518 519 reader->rotation = rot; 520 521 hpgs_reader_set_default_transformation(reader); 522 523 return 0; 524} 525 526/* 527 HPGL command SC (SCale) 528*/ 529int hpgs_reader_do_SC (hpgs_reader *reader) 530{ 531 double xmin,xmax,ymin,ymax,left=50.0,bottom=50.0; 532 int type=0; 533 534 if (reader->eoc) 535 { 536 reader->sc_type = -1; 537 hpgs_reader_set_default_transformation(reader); 538 return 0; 539 } 540 541 if (hpgs_reader_read_double(reader,&xmin)) return -1; 542 if (reader->eoc) return -1; 543 if (hpgs_reader_read_double(reader,&xmax)) return -1; 544 if (reader->eoc) return -1; 545 if (hpgs_reader_read_double(reader,&ymin)) return -1; 546 if (reader->eoc) return -1; 547 if (hpgs_reader_read_double(reader,&ymax)) return -1; 548 if (!reader->eoc && 549 hpgs_reader_read_int(reader,&type)) return -1; 550 551 if (type == 1 && !reader->eoc) 552 { 553 if (hpgs_reader_read_double(reader,&left)) return -1; 554 if (reader->eoc) return -1; 555 if (hpgs_reader_read_double(reader,&bottom)) return -1; 556 } 557 558 reader->sc_type = type; 559 reader->sc_xmin = xmin; 560 reader->sc_xmax = xmax; 561 reader->sc_ymin = ymin; 562 reader->sc_ymax = ymax; 563 reader->sc_bottom = bottom; 564 reader->sc_left = left; 565 566 hpgs_reader_set_default_transformation(reader); 567 return 0; 568} 569 570/* 571 HPGL command IP (Input Point) 572*/ 573int hpgs_reader_do_IP (hpgs_reader *reader) 574{ 575 // get default input point. 576 int angle = reader->y_size >= reader->x_size ? 90 : 0; 577 578 angle += reader->rotation; 579 580 switch (angle % 360) 581 { 582 case 90: 583 reader->P1.x = reader->x_size; 584 reader->P1.y = 0.0; 585 reader->P2.x = 0.0; 586 reader->P2.y = reader->y_size; 587 break; 588 case 180: 589 break; 590 reader->P1.x = reader->x_size; 591 reader->P1.y = reader->y_size; 592 reader->P2.x = 0.0; 593 reader->P2.y = 0.0; 594 break; 595 case 270: 596 reader->P1.x = 0.0; 597 reader->P1.y = reader->y_size; 598 reader->P2.x = reader->x_size; 599 reader->P2.y = 0.0; 600 break; 601 default: /* 0 */ 602 reader->P1.x = 0.0; 603 reader->P1.y = 0.0; 604 reader->P2.x = reader->x_size; 605 reader->P2.y = reader->y_size; 606 } 607 608 609 // read input point 610 if (!reader->eoc) 611 { 612 if (hpgs_reader_read_double(reader, 613 angle%180 ? 614 &reader->P1.y : 615 &reader->P1.x )) return -1; 616 if (reader->eoc) return -1; 617 if (hpgs_reader_read_double(reader,angle%180 ? 618 &reader->P2.x : 619 &reader->P1.y )) return -1; 620 } 621 622 if (!reader->eoc) 623 { 624 if (hpgs_reader_read_double(reader, 625 angle%180 ? 626 &reader->P2.y : 627 &reader->P2.x )) return -1; 628 if (reader->eoc) return -1; 629 if (hpgs_reader_read_double(reader, 630 angle%180 ? 631 &reader->P1.x : 632 &reader->P2.y )) return -1; 633 } 634 635 reader->delta_P.x = reader->P2.x - reader->P1.x; 636 reader->delta_P.y = reader->P2.y - reader->P1.y; 637 638#ifdef HPGS_DEBUG_XFORM 639 hpgs_log("IP: angle = %d.\n",angle); 640 hpgs_log("IP: P1 = %g,%g.\n",reader->P1.x,reader->P1.y); 641 hpgs_log("IP: P2 = %g,%g.\n",reader->P2.x,reader->P2.y); 642#endif 643 644 reader->sc_type = -1; 645 hpgs_reader_set_default_transformation(reader); 646 647 return 0; 648} 649 650/* 651 HPGL command IR (Input point Relative) 652*/ 653int hpgs_reader_do_IR (hpgs_reader *reader) 654{ 655 // get default input point. 656 double p1x=0.0,p1y=0.0,p2x,p2y; 657 658 int angle = reader->y_size >= reader->x_size ? 90 : 0; 659 660 angle += reader->rotation; 661 662 switch (angle % 360) 663 { 664 case 90: 665 p1x = reader->x_size; 666 p1y = 0.0; 667 p2x = 0.0; 668 p2y = reader->y_size; 669 break; 670 case 180: 671 break; 672 p1x = reader->x_size; 673 p1y = reader->y_size; 674 p2x = 0.0; 675 p2y = 0.0; 676 break; 677 case 270: 678 p1x = 0.0; 679 p1y = reader->y_size; 680 p2x = reader->x_size; 681 p2y = 0.0; 682 break; 683 default: 684 p1x = 0.0; 685 p1y = 0.0; 686 p2x = reader->x_size; 687 p2y = reader->y_size; 688 } 689 690 // read input point 691 if (!reader->eoc) 692 { 693 double x,y; 694 695 if (hpgs_reader_read_double(reader,&x)) return -1; 696 if (hpgs_reader_read_double(reader,&y)) return -1; 697 698 p1x = reader->x_size * x * 0.01; 699 p2x = p1x + reader->delta_P.x; 700 p1y = reader->y_size * y * 0.01; 701 p2y = p1y + reader->delta_P.y; 702 } 703 704 if (!reader->eoc) 705 { 706 if (hpgs_reader_read_double(reader,&p2x)) return -1; 707 if (hpgs_reader_read_double(reader,&p2y)) return -1; 708 709 p2x = reader->x_size * p2x * 0.01; 710 p2y = reader->y_size * p2y * 0.01; 711 712 reader->delta_P.x = p2x - p1x; 713 reader->delta_P.y = p2y - p1y; 714 } 715 716 reader->P1.x = p1x; 717 reader->P1.y = p1y; 718 reader->P2.x = p2x; 719 reader->P2.y = p2y; 720 721#ifdef HPGS_DEBUG_XFORM 722 hpgs_log("IR: P1 = %g,%g.\n",reader->P1.x,reader->P1.y); 723 hpgs_log("IR: P2 = %g,%g.\n",reader->P2.x,reader->P2.y); 724#endif 725 726 hpgs_reader_set_default_transformation(reader); 727 728 return 0; 729} 730 731/* 732 HPGL command IW (Input Window) 733*/ 734int hpgs_reader_do_IW (hpgs_reader *reader) 735{ 736 // get default input point. 737 hpgs_point ll; 738 hpgs_point ur; 739 hpgs_point p; 740 741 if (hpgs_reader_checkpath(reader)) return -1; 742 743 while (reader->clipsave_depth > 0) 744 { 745 hpgs_cliprestore(reader->device); 746 --reader->clipsave_depth; 747 } 748 749 if (reader->eoc) return 0; 750 751 // read input point 752 if (hpgs_reader_read_point(reader,&ll,1)) return -1; 753 if (hpgs_reader_read_point(reader,&ur,1)) return -1; 754 755 if (hpgs_clipsave(reader->device)) return -1; 756 ++reader->clipsave_depth; 757 758 if (hpgs_newpath(reader->device)) return -1; 759 if (hpgs_moveto(reader->device,&ll)) return -1; 760 p.x = ll.x; 761 p.y = ur.y; 762 if (hpgs_lineto(reader->device,&p)) return -1; 763 if (hpgs_lineto(reader->device,&ur)) return -1; 764 p.x = ur.x; 765 p.y = ll.y; 766 if (hpgs_lineto(reader->device,&p)) return -1; 767 if (hpgs_closepath(reader->device)) return -1; 768 if (hpgs_clip(reader->device,HPGS_TRUE)) return -1; 769 770 reader->have_current_point = 0; 771 772 return hpgs_newpath(reader->device); 773} 774