Rev 17587 | Rev 17608 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 17587 | Rev 17599 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* |
1 | /* CopyrOAight (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis |
2 | * |
2 | * |
3 | * This program is free software; you can redistribute it and/or modify |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
6 | * (at your option) any later version. |
Line 17... | Line 17... | ||
17 | 17 | ||
18 | #include <errno.h> |
18 | #include <errno.h> |
19 | #include "flydraw.h" |
19 | #include "flydraw.h" |
20 | 20 | ||
21 | /* Tikz things */ |
21 | /* Tikz things */ |
22 | /* the_tiled,gdTiled , int the_tiled*/ |
- | |
- | 22 | ||
23 | static char *tikz_options (int the_color, int the_fill) |
23 | static char *tikz_options (int the_color, int the_fill) |
24 | { |
24 | { |
25 | static char buf[100]; |
25 | static char buf[100]; |
26 | if (the_color == gdBrushed) |
26 | if (the_color == gdBrushed) |
27 | the_color = tikz_brushColor; |
27 | the_color = tikz_brushColor; |
Line 296... | Line 296... | ||
296 | myDashedLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3], pm->color[0]); |
296 | myDashedLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3], pm->color[0]); |
297 | if (tikz_file) |
297 | if (tikz_file) |
298 | fprintf(tikz_file, "\\draw\[%s] (%i, %i) -- (%i, %i);\n", |
298 | fprintf(tikz_file, "\\draw\[%s] (%i, %i) -- (%i, %i);\n", |
299 | tikz_options(pm->color[0],-1), |
299 | tikz_options(pm->color[0],-1), |
300 | pm->p[0],flip(pm->p[1]),pm->p[2],flip(pm->p[3])); |
300 | pm->p[0],flip(pm->p[1]),pm->p[2],flip(pm->p[3])); |
301 | } |
301 | } |
302 | 302 | ||
303 | /* parallel lines. |
303 | /* parallel lines. |
304 | * x1,y1,x2,y2,xv,yv,n,color */ |
304 | * x1,y1,x2,y2,xv,yv,n,color */ |
305 | void obj_parallel(objparm *pm) |
305 | void obj_parallel(objparm *pm) |
306 | { |
306 | { |
307 | int i, n, xi,yi; |
307 | int i, n, xi,yi; |
Line 483... | Line 483... | ||
483 | for(i=2;i<2*n;i+=2) |
483 | for(i=2;i<2*n;i+=2) |
484 | myDashedLine(image,pm->p[i-2],pm->p[i-1],pm->p[i],pm->p[i+1],pm->color[0]); |
484 | myDashedLine(image,pm->p[i-2],pm->p[i-1],pm->p[i],pm->p[i+1],pm->color[0]); |
485 | if (tikz_file){ |
485 | if (tikz_file){ |
486 | fprintf(tikz_file, "\\draw\[%s] (%i, %i) -- (%i, %i);\n", |
486 | fprintf(tikz_file, "\\draw\[%s] (%i, %i) -- (%i, %i);\n", |
487 | tikz_options(pm->color[0],pm->fill),pm->p[i-2],flip(pm->p[i-1]),pm->p[i],flip(pm->p[i+1])); |
487 | tikz_options(pm->color[0],pm->fill),pm->p[i-2],flip(pm->p[i-1]),pm->p[i],flip(pm->p[i+1])); |
488 | } |
488 | } |
489 | if(vimg_enable) vimg_polyline(scale_buf,n,0); |
489 | if(vimg_enable) vimg_polyline(scale_buf,n,0); |
490 | } |
490 | } |
491 | 491 | ||
492 | /* points */ |
492 | /* points */ |
493 | void obj_points(objparm *pm) |
493 | void obj_points(objparm *pm) |
Line 572... | Line 572... | ||
572 | color_bounder,pm->color[0]); |
572 | color_bounder,pm->color[0]); |
573 | } |
573 | } |
574 | gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,pm->color[0]); |
574 | gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,pm->color[0]); |
575 | if(tikz_file) fprintf(tikz_file, "\\draw\[%s] (%i, %i) circle (%f);\n", |
575 | if(tikz_file) fprintf(tikz_file, "\\draw\[%s] (%i, %i) circle (%f);\n", |
576 | tikz_options(pm->color[0],pm->fill),pm->p[0],flip(pm->p[1]),pm->p[2]/2.); |
576 | tikz_options(pm->color[0],pm->fill),pm->p[0],flip(pm->p[1]),pm->p[2]/2.); |
- | 577 | } |
|
- | 578 | ||
- | 579 | typedef enum tikz_fill_options {grille, points, hatch, dhatch} tfo; |
|
- | 580 | int compar(const void *a, const void *b) {return *(int *)b - *(int *)a;} |
|
- | 581 | ||
- | 582 | void tikz_fill(int x, int y, int nx, int ny, int the_color, tfo opt) |
|
- | 583 | { |
|
- | 584 | char *to = tikz_options(the_color,1); |
|
- | 585 | int numpix=sizex*sizey, top = 0, a, cy, lx, rx, seed, nt,ct=0, ct2=0; |
|
- | 586 | printf("Pixels:%d\n",numpix); |
|
- | 587 | int *stack = xmalloc(numpix*sizeof(int)); |
|
- | 588 | int *stack2 = xmalloc(numpix*sizeof(int)); |
|
- | 589 | if (nx==0) nx=1; if (ny==0) ny=1; nt = abs(nx*ny); |
|
- | 590 | seed = gdImageGetPixel(image,x,y); |
|
- | 591 | char *check = xmalloc(numpix); |
|
- | 592 | while (numpix--) check[numpix]=0; |
|
- | 593 | a=x+y*sizex; |
|
- | 594 | check[a]=1; |
|
- | 595 | stack[top++]=a; |
|
- | 596 | while(top) |
|
- | 597 | { |
|
- | 598 | a = stack[--top]; |
|
- | 599 | x = a%sizex; y = a/sizex; |
|
- | 600 | if (gdImageGetPixel(image,x,y) != seed) continue; |
|
- | 601 | if (x>0 && !check[a-1]) {check[a-1]=1; stack[top++]=a-1;} |
|
- | 602 | if (x+1<sizex && !check[a+1]) {check[a+1]=1; stack[top++]=a+1;} |
|
- | 603 | if (y>0 && !check[a-sizex]) {check[a-sizex]=1; stack[top++]=a-sizex;} |
|
- | 604 | if (y+1<sizey && !check[a+sizex]) {check[a+sizex]=1; stack[top++]=a+sizex;} |
|
- | 605 | switch(opt) |
|
- | 606 | { |
|
- | 607 | case grille: if(((x%nx)!=(nx/2))&&((y%ny)!=(ny/2))) continue; break; |
|
- | 608 | case points: if(x%nx!=nx/2||y%ny!=ny/2) continue; break; |
|
- | 609 | case hatch: if(abs((ny*x-nx*y)%nt)!=nt/2) continue; break; |
|
- | 610 | case dhatch: if((ny*x+nx*y)%nt!=nt/2 && abs((ny*x-nx*y)%nt)!=nt/2) continue; break; |
|
- | 611 | default: break; |
|
- | 612 | } |
|
- | 613 | stack2[ct++]=a; |
|
- | 614 | } |
|
- | 615 | free(stack); |
|
- | 616 | free(check); |
|
- | 617 | if (ct==0) return; |
|
- | 618 | qsort(stack2, ct, sizeof(int), compar); |
|
- | 619 | cy=-1; |
|
- | 620 | while (ct--) |
|
- | 621 | { |
|
- | 622 | a = stack2[ct]; |
|
- | 623 | x = a%sizex; y = a/sizex; |
|
- | 624 | if (y != cy || x != rx+1) |
|
- | 625 | { |
|
- | 626 | if (cy >= 0) |
|
- | 627 | fprintf(tikz_file, |
|
- | 628 | "\\draw\[%s] (%.2f,%.2f) rectangle (%.2f,%.2f);\n", |
|
- | 629 | to, lx-0.0,flip(cy-0.0),rx+0.0,flip(cy+0.0)); |
|
- | 630 | cy = y; |
|
- | 631 | lx = rx = x; |
|
- | 632 | ct2++; |
|
- | 633 | } |
|
- | 634 | else |
|
- | 635 | rx++; |
|
- | 636 | } |
|
- | 637 | fprintf(tikz_file, |
|
- | 638 | "\\draw\[%s] (%.2f,%.2f) rectangle (%.2f,%.2f);\n", |
|
- | 639 | to, lx-0.0,flip(cy-0.0),rx+0.0,flip(cy+0.0)); |
|
- | 640 | free(stack2); |
|
577 | } |
641 | } |
578 | 642 | ||
579 | /* flood fill */ |
643 | /* flood fill */ |
580 | void obj_fill(objparm *pm) |
644 | void obj_fill(objparm *pm) |
581 | { |
645 | { |
582 | scale(pm->pd,pm->p,1); |
646 | scale(pm->pd,pm->p,1); |
- | 647 | if (tikz_file) tikz_fill(pm->p[0],pm->p[1],1,1,pm->color[0],grille); |
|
583 | patchgdImageFill(image,pm->p[0],pm->p[1],pm->color[0]); |
648 | patchgdImageFill(image,pm->p[0],pm->p[1],pm->color[0]); |
584 | } |
649 | } |
585 | 650 | ||
586 | /* flood fill to border*/ |
651 | /* flood fill to border*/ |
587 | void obj_fillb(objparm *pm) |
652 | void obj_fillb(objparm *pm) |
588 | { |
653 | { |
589 | scale(pm->pd,pm->p,1); |
654 | scale(pm->pd,pm->p,1); |
- | 655 | if (tikz_file) tikz_fill(pm->p[0],pm->p[1],1,1,pm->color[0],grille); |
|
590 | patchgdImageFillToBorder(image,pm->p[0],pm->p[1],pm->color[0],pm->color[1]); |
656 | patchgdImageFillToBorder(image,pm->p[0],pm->p[1],pm->color[0],pm->color[1]); |
591 | } |
657 | } |
592 | 658 | ||
593 | gdImagePtr himg; |
659 | gdImagePtr himg; |
594 | 660 | ||
595 | int makehatchimage(int x, int y, int px, int py, int col) |
661 | int makehatchimage(int x, int y, int px, int py, int col) |
596 | { |
662 | { |
597 | int c1,c2,r,g,b; |
663 | int c1,c2,r,g,b; |
Line 644... | Line 710... | ||
644 | break; |
710 | break; |
645 | } |
711 | } |
646 | case 2: gdImageLine(himg,0,ay/2,ax-1,ay/2,c); break; |
712 | case 2: gdImageLine(himg,0,ay/2,ax-1,ay/2,c); break; |
647 | case 3: gdImageLine(himg,ax/2,0,ax/2,ay-1,c); break; |
713 | case 3: gdImageLine(himg,ax/2,0,ax/2,ay-1,c); break; |
648 | } |
714 | } |
- | 715 | if (tikz_file) tikz_fill(pm->p[0],pm->p[1],nx,ny,pm->color[0],hatch); |
|
649 | gdImageSetTile(image,himg); |
716 | gdImageSetTile(image,himg); |
650 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
717 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
651 | gdImageDestroy(himg); |
718 | gdImageDestroy(himg); |
652 | if(tiled) gdImageSetTile(image,tileimg); |
719 | if(tiled) gdImageSetTile(image,tileimg); |
653 | } |
720 | } |
654 | 721 | ||
Line 658... | Line 725... | ||
658 | int nx,ny, c; |
725 | int nx,ny, c; |
659 | scale(pm->pd,pm->p,1); |
726 | scale(pm->pd,pm->p,1); |
660 | nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny); |
727 | nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny); |
661 | if(nx==0 && ny==0) {fly_error("bad grid size"); return;} |
728 | if(nx==0 && ny==0) {fly_error("bad grid size"); return;} |
662 | c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]); |
729 | c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]); |
- | 730 | if (tikz_file) tikz_fill(pm->p[0],pm->p[1],nx,ny,pm->color[0],grille); |
|
663 | gdImageLine(himg,0,ny/2,nx-1,ny/2,c); gdImageLine(himg,nx/2,0,nx/2,ny-1,c); |
731 | gdImageLine(himg,0,ny/2,nx-1,ny/2,c); gdImageLine(himg,nx/2,0,nx/2,ny-1,c); |
664 | gdImageSetTile(image,himg); |
732 | gdImageSetTile(image,himg); |
665 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
733 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
666 | gdImageDestroy(himg); |
734 | gdImageDestroy(himg); |
667 | if(tiled) gdImageSetTile(image,tileimg); |
735 | if(tiled) gdImageSetTile(image,tileimg); |
668 | } |
736 | } |
669 | 737 | ||
670 | /* flood fill with double hatching */ |
738 | /* flood fill with double hatching */ |
671 | void obj_diafill(objparm *pm) |
739 | void obj_diafill(objparm *pm) |
672 | { |
740 | { |
673 | int nx,ny, c; |
741 | int nx,ny, c; |
674 | scale(pm->pd,pm->p,1); |
742 | scale(pm->pd,pm->p,1); |
675 | nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny); |
743 | nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny); |
676 | if(nx==0 && ny==0) {fly_error("bad grid size"); return;} |
744 | if(nx==0 && ny==0) {fly_error("bad grid size"); return;} |
677 | c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]); |
745 | c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]); |
- | 746 | if (tikz_file) tikz_fill(pm->p[0],pm->p[1],nx,ny,pm->color[0],dhatch); |
|
678 | gdImageLine(himg,0,0,nx-1,ny-1,c); gdImageLine(himg,0,ny-1,nx-1,0,c); |
747 | gdImageLine(himg,0,0,nx-1,ny-1,c); gdImageLine(himg,0,ny-1,nx-1,0,c); |
679 | gdImageSetTile(image,himg); |
748 | gdImageSetTile(image,himg); |
680 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
749 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
681 | gdImageDestroy(himg); |
750 | gdImageDestroy(himg); |
682 | if(tiled) gdImageSetTile(image,tileimg); |
751 | if(tiled) gdImageSetTile(image,tileimg); |
683 | } |
752 | } |
684 | 753 | ||
685 | /* flood fill with |
754 | /* flood fill with dots */ |
686 | void obj_dotfill(objparm *pm) |
755 | void obj_dotfill(objparm *pm) |
687 | { |
756 | { |
688 | int nx,ny, c; |
757 | int nx,ny, c; |
689 | scale(pm->pd,pm->p,1); |
758 | scale(pm->pd,pm->p,1); |
690 | nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny); |
759 | nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny); |
691 | if(nx==0 && ny==0) {fly_error("bad grid size"); return;} |
760 | if(nx==0 && ny==0) {fly_error("bad grid size"); return;} |
692 | c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]); |
761 | c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]); |
- | 762 | if (tikz_file) tikz_fill(pm->p[0],pm->p[1],nx,ny,pm->color[0],points); |
|
693 | gdImageSetPixel(himg,nx/2,ny/2,c); |
763 | gdImageSetPixel(himg,nx/2,ny/2,c); |
694 | gdImageSetTile(image,himg); |
764 | gdImageSetTile(image,himg); |
695 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
765 | patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled); |
696 | gdImageDestroy(himg); |
766 | gdImageDestroy(himg); |
697 | if(tiled) gdImageSetTile(image,tileimg); |
767 | if(tiled) gdImageSetTile(image,tileimg); |
698 | } |
768 | } |
699 | 769 | ||
700 | struct { |
770 | struct { |
701 | char *name; |
771 | char *name; |
702 | gdFontPtr *fpt; |
772 | gdFontPtr *fpt; |
703 | } fonttab[]={ |
773 | } fonttab[]={ |
Line 716... | Line 786... | ||
716 | { |
786 | { |
717 | char *pp, *pe, *p2; |
787 | char *pp, *pe, *p2; |
718 | int i; |
788 | int i; |
719 | pp=pm->str; pe=strchr(pp,','); if(pe==NULL) { |
789 | pp=pm->str; pe=strchr(pp,','); if(pe==NULL) { |
720 | fly_error("too_few_parms"); return; |
790 | fly_error("too_few_parms"); return; |
721 | } |
791 | } |
722 | *pe++=0; pp=find_word_start(pp); *find_word_end(pp)=0; |
792 | *pe++=0; pp=find_word_start(pp); *find_word_end(pp)=0; |
723 | pe=find_word_start(pe); strip_trailing_spaces(pe); |
793 | pe=find_word_start(pe); strip_trailing_spaces(pe); |
724 | if(*pp) { |
794 | if(*pp) { |
725 | for(i=0;i<fonttab_no && strcmp(pp,fonttab[i].name)!=0; i++); |
795 | for(i=0;i<fonttab_no && strcmp(pp,fonttab[i].name)!=0; i++); |
726 | if(i>=fonttab_no) i=1; |
796 | if(i>=fonttab_no) i=1; |
Line 728... | Line 798... | ||
728 | else i=1; |
798 | else i=1; |
729 | scale(pm->pd,pm->p,1); |
799 | scale(pm->pd,pm->p,1); |
730 | if(*pe=='"') { |
800 | if(*pe=='"') { |
731 | p2=strchr(pe+1,'"'); |
801 | p2=strchr(pe+1,'"'); |
732 | if(p2 && *(p2+1)==0) {*p2=0; pe++;} |
802 | if(p2 && *(p2+1)==0) {*p2=0; pe++;} |
733 | } |
803 | } |
734 | if(pm->fill){ |
804 | if(pm->fill){ |
735 | gdImageStringUp(image,*(fonttab[i].fpt),pm->p[0],pm->p[1], (unsigned char*) pe, |
805 | gdImageStringUp(image,*(fonttab[i].fpt),pm->p[0],pm->p[1], (unsigned char*) pe, |
736 | pm->color[0]); |
806 | pm->color[0]); |
737 | if(tikz_file) fprintf(tikz_file,"\\draw[%s] (%i,%i) node[font=\\%s,rotate=90] {%s};\n", |
807 | if(tikz_file) fprintf(tikz_file,"\\draw[%s] (%i,%i) node[font=\\%s,rotate=90] {%s};\n", |
738 | tikz_options(pm->color[0],pm->fill),pm->p[0],flip(pm->p[1]),fonttab[i].name,(unsigned char*) pe); |
808 | tikz_options(pm->color[0],pm->fill),pm->p[0],flip(pm->p[1]),fonttab[i].name,(unsigned char*) pe); |
Line 751... | Line 821... | ||
751 | scale(pm->pd,pm->p,1); |
821 | scale(pm->pd,pm->p,1); |
752 | gdImageSetPixel(image,pm->p[0],pm->p[1],pm->color[0]); |
822 | gdImageSetPixel(image,pm->p[0],pm->p[1],pm->color[0]); |
753 | if(tikz_file) fprintf(tikz_file,"\\draw[%s] (%i,%i) circle (0pt);\n", |
823 | if(tikz_file) fprintf(tikz_file,"\\draw[%s] (%i,%i) circle (0pt);\n", |
754 | tikz_options(pm->color[0],0),pm->p[0],flip(pm->p[1])); |
824 | tikz_options(pm->color[0],0),pm->p[0],flip(pm->p[1])); |
755 | } |
825 | } |
756 | 826 | ||
757 | /* copy an image file */ |
827 | /* copy an image file */ |
758 | void obj_copy(objparm *pm) |
828 | void obj_copy(objparm *pm) |
759 | { |
829 | { |
760 | char *pp; |
830 | char *pp; |
761 | FILE *inf; |
831 | FILE *inf; |
762 | gdImagePtr insimg; |
832 | gdImagePtr insimg; |
763 | 833 | ||
764 | pp=find_word_start(pm->str);*find_word_end(pp)=0; |
834 | pp=find_word_start(pm->str);*find_word_end(pp)=0; |
765 | inf=open4read(pp); |
835 | inf=open4read(pp); |
766 | if(inf==NULL) { |
836 | if(inf==NULL) { |
767 | fly_error(" |
837 | fly_error("file_does_not_exist"); return; |
768 | } |
838 | } |
769 | insimg=gdImageCreateFromGif(inf); fclose(inf); |
839 | insimg=gdImageCreateFromGif(inf); fclose(inf); |
770 | if(insimg==NULL) { |
840 | if(insimg==NULL) { |
771 | fly_error("bad_gif"); return; |
841 | fly_error("bad_gif"); return; |
772 | } |
842 | } |