00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define SELECTED 1
00027 #define DESELECTED 0
00028
00029 static long VP,VF;
00030
00031 static void GetATMholdPoint(long *x, long *y, long cx, long cy, short pt);
00032 static void process_type1_routine(character_program Cp);
00033 static long CurveUpto(long vp, point *p, double d, long n);
00034
00035 static void DeselectVertexSet(long vs, long vf){
00036 vertex *Vs;
00037 while(vs < vf){
00038 Vs=(MainVp+vs);
00039 if(Vs->status == SELECTED){
00040 Vs->status = DESELECTED; NvertSelect--; NvertDeselect++;
00041 }
00042 vs++;
00043 }
00044 }
00045
00046 static void SelectVertexSet(long vs, long vf){
00047 vertex *Vs;
00048 while(vs < vf){
00049 Vs=(MainVp+vs);
00050 if(Vs->status == DESELECTED){
00051 Vs->status = SELECTED; NvertSelect++; NvertDeselect--;
00052 }
00053 vs++;
00054 }
00055 }
00056
00057 static void MakeNewPSletter(HWND hwnd){
00058 long i,j,char_id,Depth,Opx,Opy,Opz;
00059 int ifail,capped=0;
00060 long Vstart,Vstop,BackStart,BackStop,fBevelStart,fBevelStop,Vfirst;
00061 long ep,Estart=-1;
00062 long fp,LastFace;
00063 skel *sp;
00064 Vfirst=Nvert;
00065 char_id=0;
00066 Opx=NpointerX; Opy=NpointerY; Opz=NpointerZ;
00067 DeselectVertexSet(0,Nvert);
00068 while ((j=(long)lpAtm->ATM_Letters[char_id++]) > 0){
00069 n_Subroutines = 0; C_Subs=NULL; Cprogram.n=0; Cprogram.p=NULL;
00070 if((type1_stack=(int *)X__Malloc(512*sizeof(int))) == NULL){
00071 MessageBox(hwnd,"Out of memory","ATM",MB_OK);
00072 return;
00073 }
00074 if((ifail=decode_build_type1((int)j,lpAtm->last_ATM_font)) != OK){
00075 if(ifail == FAIL){
00076 MessageBox(hwnd,"Font corrupt","ATM",MB_OK);
00077 }
00078 else if(ifail == MEMFAIL){
00079 MessageBox(hwnd,"Out of memory","ATM",MB_OK);
00080 }
00081 goto FREEALL;
00082 }
00083 SP=0; XX=NpointerY; YY=NpointerZ;
00084 Cwidthx=0; Cwidthy=0; Vstart=Nvert; Estart=Nedge; VF=VP= -1;
00085 process_type1_routine(Cprogram);
00086 if(lpAtm->ATM_chara_width > 0){
00087 Depth=MaxScale*(double)lpAtm->ATM_chara_width/100.0*Scale;
00088 }
00089 else Depth=0;
00090 if(j == 32){
00091 UpdateVertexHeap(Nvert+2);
00092 CreateVertex();
00093 (MainVp+Nvert-1)->xyz[0]=NpointerX-Depth/2;
00094 (MainVp+Nvert-1)->xyz[1]=NpointerY;
00095 (MainVp+Nvert-1)->xyz[2]=NpointerZ;
00096 CreateVertex();
00097 (MainVp+Nvert-1)->xyz[0]=NpointerX-Depth/2;
00098 (MainVp+Nvert-1)->xyz[1]=NpointerY+Cwidthx*lpAtm->FORB;
00099 (MainVp+Nvert-1)->xyz[2]=NpointerZ+Cwidthy;
00100 UpdateEdgeHeap(Nedge+1);
00101 CreateEdge(Nvert-1,Nvert-2);
00102 }
00103 NpointerY += Cwidthx*lpAtm->FORB; NpointerZ += Cwidthy;
00104 FREEALL:
00105 X__Free(type1_stack);
00106 if(Cprogram.p != NULL)X__Free(Cprogram.p);
00107 if(C_Subs != NULL && n_Subroutines > 0){
00108 for(i=0;i<n_Subroutines;i++){
00109 if(C_Subs[i].p != NULL)X__Free(C_Subs[i].p);
00110 }
00111 X__Free(C_Subs);
00112 }
00113 C_Subs=NULL; Cprogram.p=NULL;
00114 Vstop=Nvert; VP=Vstart; while(VP < Nvert){
00115 (MainVp+VP)->xyz[1] += rand()%4-2;
00116
00117 VP++;
00118 }
00119 if(Vstop == Vstart)ifail=FAIL;
00120 if(ifail == FAIL)break;
00121 CreateSkeleton(FirstSp); sp=MainSp;
00122 if(j == 32){
00123 strcpy(MainSp->name,"Space");
00124 }
00125 else{
00126 if(j > 64 && j < 91)sprintf(MainSp->name,"%c%ld-C",j,char_id);
00127 else sprintf(MainSp->name,"%c%ld",j,char_id);
00128 }
00129 MainSp->xyz[0]=NpointerX-Depth/2;
00130 GetATMholdPoint(&MainSp->xyz[1],&MainSp->xyz[2],Cwidthx,Cwidthy,0);
00131
00132 CreateSkeleton(MainSp);
00133 strcpy(MainSp->name,"F.Pt.");
00134 MainSp->xyz[0]=NpointerX-Depth/2;
00135 GetATMholdPoint(&MainSp->xyz[1],&MainSp->xyz[2],Cwidthx,Cwidthy,1);
00136
00137 DeselectVertexSet(Vstart,Vstop);
00138 Estart=Nedge;
00139 LastFace=Nface;
00140 if(j == 32)goto SPACEBREAK;
00141 if(lpAtm->ATM_cap && !lpAtm->ATM_bevel_front && !lpAtm->ATM_bevel_back){
00142 capped=1;
00143 SelectVertexSet(Vstart,Vstop);
00144 LastFace=Nface;
00145 if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00146 DeselectVertexSet(Vstart,Vstop);
00147 fp=LastFace; while(fp < Nface){
00148 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00149 fp++;
00150 }
00151 LastFace=Nface;
00152 }
00153 if(lpAtm->ATM_chara_width > 0){
00154 SelectVertexSet(Vstart,Vstop);
00155 BackStart=Nvert; LastFace=Nface;
00156 if(!CreateAttachedCopy(1))break;
00157 BackStop=Nvert;
00158 DeselectVertexSet(BackStart,BackStop);
00159 VP=BackStart; while(VP < BackStop){
00160 (MainVp+VP)->xyz[0] -= Depth;
00161 VP++;
00162 }
00163 fp=LastFace; while(fp < Nface){
00164 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_side_colour[i];
00165
00166 fp++;
00167 }
00168 LastFace=Nface;
00169 }
00170 else{BackStart=Vstart; BackStop=Vstop;}
00171 if((lpAtm->FORB > 0 && lpAtm->ATM_bevel_front) ||
00172 (lpAtm->FORB < 0 && lpAtm->ATM_bevel_back)){
00173 SelectVertexSet(Vstart,Vstop);
00174 fBevelStart=Nvert; LastFace=Nface;
00175 if(AutoFacetCurveWithHoles(3,0,1,(double)lpAtm->ATM_bevel_angle,
00176 (double)lpAtm->ATM_bevel_width/2000.0*MaxScale*Scale) == FAIL)break;
00177 fBevelStop=Nvert;
00178 fp=LastFace; while(fp < Nface){
00179 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_beve_colour[i];
00180
00181 fp++;
00182 }
00183 LastFace=Nface;
00184 if(lpAtm->ATM_cap){
00185 if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00186 fp=LastFace; while(fp < Nface){
00187 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00188 fp++;
00189 }
00190 LastFace=Nface;
00191 }
00192 DeselectVertexSet(fBevelStart,fBevelStop);
00193 }
00194 else if(lpAtm->ATM_cap && !capped){
00195 SelectVertexSet(Vstart,Vstop);
00196 LastFace=Nface;
00197 if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00198 DeselectVertexSet(Vstart,Vstop);
00199 fp=LastFace; while(fp < Nface){
00200 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00201 fp++;
00202 }
00203 LastFace=Nface;
00204 }
00205 if((lpAtm->FORB > 0 && lpAtm->ATM_bevel_back) ||
00206 (lpAtm->FORB < 0 && lpAtm->ATM_bevel_front)){
00207 SelectVertexSet(BackStart,BackStop);
00208 fBevelStart=Nvert; LastFace=Nface;
00209 if(AutoFacetCurveWithHoles(3,0,1,(double)(lpAtm->ATM_bevel_angle * -1),
00210 (double)lpAtm->ATM_bevel_width/2000.0*MaxScale*Scale) == FAIL)break;
00211 fBevelStop=Nvert;
00212 fp=LastFace; while(fp < Nface){
00213 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_beve_colour[i];
00214
00215 fp++;
00216 }
00217 LastFace=Nface;
00218 if(lpAtm->ATM_cap){
00219 if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00220 fp=LastFace; while(fp < Nface){
00221 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00222 fp++;
00223 }
00224 LastFace=Nface;
00225 }
00226 DeselectVertexSet(fBevelStart,fBevelStop);
00227 }
00228 else if(lpAtm->ATM_cap && !capped){
00229 SelectVertexSet(BackStart,BackStop);
00230 LastFace=Nface;
00231 if(AutoFacetCurveWithHoles(0,0,1,0.0,0.0) == FAIL)break;
00232 DeselectVertexSet(BackStart,BackStop);
00233 fp=LastFace; while(fp < Nface){
00234 for(i=0;i<3;i++)(MainFp+fp)->color[i]=lpAtm->ATM_face_colour[i];
00235 fp++;
00236 }
00237 LastFace=Nface;
00238 }
00239 SPACEBREAK:
00240 VP=Vstart; while(VP < Nvert){
00241 (MainVp+VP)->sp=sp;
00242 VP++;
00243 }
00244 DrawModel();
00245 }
00246 SelectVertexSet(Vfirst,Nvert);
00247 NpointerX=Opx; NpointerY=Opy; NpointerZ=Opz;
00248
00249 return;
00250 }
00251
00252 static void GetATMholdPoint(long *x, long *y, long cx, long cy, short pt){
00253 long x0,y0;
00254 double offx[]={0.0,0.5,1.0, 0.5, 0.0 ,0.5, 1.0};
00255 double offy[]={0.0,0.0,0.0,300.0,600.0,600.0,600.0};
00256 x0=NpointerY-cx*lpAtm->FORB;
00257 y0=NpointerZ-cy;
00258 if(pt == 0){
00259 *x=x0+(long)(offx[lpAtm->ATM_offset]*(double)cx)*lpAtm->FORB;
00260 *y=y0+(long)(offy[lpAtm->ATM_offset]*Scale);
00261 }
00262 else{
00263 *x=x0+(long)((offx[lpAtm->ATM_offset]+1.0)*(double)cx)*lpAtm->FORB;
00264 *y=y0+(long)(offy[lpAtm->ATM_offset]*Scale+(double)cy);
00265 }
00266 }
00267
00268
00269 static void process_type1_routine(character_program Cp){
00270 int i,com,sid,last_line=0;
00271 long u,v,w,x,y,z;
00272 for(i=0;i<Cp.n;i++){
00273 com=(int)Cp.p[i].i;
00274 if(Cp.p[i].com == 0)type1_stack[SP++] = com;
00275 else{
00276 switch(com){
00277 case 1: SP=0; break;
00278 case 3: SP=0; break;
00279 case 4:
00280 x = 0; y = (long)type1_stack[SP-1];
00281 goto MOVEJUMP;
00282 case 5:
00283 x = (long)type1_stack[SP-2];
00284 y = (long)type1_stack[SP-1];
00285 LINEJUMP:
00286 last_line=1;
00287 if(VP < 0){
00288 UpdateVertexHeap(Nvert+1);
00289 CreateVertex();
00290 (MainVp+Nvert-1)->xyz[1]=XX;
00291 (MainVp+Nvert-1)->xyz[2]=YY;
00292 (MainVp+Nvert-1)->xyz[0]=NpointerX;
00293 VP=VF=Nvert-1;
00294 }
00295 UpdateVertexHeap(Nvert+1);
00296 CreateVertex();
00297 UpdateEdgeHeap(Nedge+1);
00298 CreateEdge(VP,Nvert-1);
00299 (MainVp+Nvert-1)->xyz[1]=XX+x*Scale/2*lpAtm->FORB;
00300 (MainVp+Nvert-1)->xyz[2]=YY+y*Scale/2;
00301 (MainVp+Nvert-1)->xyz[0]=NpointerX;
00302 VP=Nvert-1;
00303 XX += x*Scale*lpAtm->FORB; YY += y*Scale;
00304 if(VF >= 0 && (MainVp+VF)->xyz[1] == XX
00305 && (MainVp+VF)->xyz[2] == YY){
00306 UpdateEdgeHeap(Nedge+1);
00307 CreateEdge(VP,VF);
00308 VP=VF;
00309 }
00310 else{
00311 UpdateVertexHeap(Nvert+1);
00312 CreateVertex();
00313 UpdateEdgeHeap(Nedge+1);
00314 CreateEdge(VP,Nvert-1);
00315 (MainVp+Nvert-1)->xyz[1]=XX;
00316 (MainVp+Nvert-1)->xyz[2]=YY;
00317 (MainVp+Nvert-1)->xyz[0]=NpointerX;
00318 VP=Nvert-1;
00319 }
00320 SP=0; break;
00321 case 6:
00322 y = 0; x = (long)type1_stack[SP-1];
00323 goto LINEJUMP;
00324 case 7:
00325 x = 0; y = (long)type1_stack[SP-1];
00326 goto LINEJUMP;
00327 case 8:
00328 u = (long)type1_stack[SP-6];
00329 v = (long)type1_stack[SP-5];
00330 w = (long)type1_stack[SP-4];
00331 x = (long)type1_stack[SP-3];
00332 y = (long)type1_stack[SP-2];
00333 z = (long)type1_stack[SP-1];
00334 CURVEJUMP:
00335 last_line=0;
00336 if(VP < 0){
00337 UpdateVertexHeap(Nvert+1);
00338 CreateVertex();
00339 (MainVp+Nvert-1)->xyz[1]=XX;
00340 (MainVp+Nvert-1)->xyz[2]=YY;
00341 (MainVp+Nvert-1)->xyz[0]=NpointerX;
00342 VP=VF=Nvert-1;
00343 }
00344 PP[0][0]=XX; PP[0][1]=YY; PP[0][2]=0;
00345 XX += u*Scale*lpAtm->FORB; YY += v*Scale;
00346 PP[1][0]=XX; PP[1][1]=YY; PP[1][2]=0;
00347 XX += w*Scale*lpAtm->FORB; YY += x*Scale;
00348 PP[2][0]=XX; PP[2][1]=YY; PP[2][2]=0;
00349 XX += y*Scale*lpAtm->FORB; YY += z*Scale;
00350 PP[3][0]=XX; PP[3][1]=YY; PP[3][2]=0;
00351 VP=CurveUpto(VP,PP,MaxScale*Scale,Nmax);
00352 SP=0; break;
00353 case 9:
00354 if(VF == VP){
00355 VF=VP=-1;
00356 break;
00357 }
00358 if(VF >= 0 && VP >= 0){
00359 if(last_line){
00360 UpdateVertexHeap(Nvert+1);
00361 CreateVertex();
00362 (MainVp+Nvert-1)->xyz[1]=((MainVp+VP)->xyz[1]+(MainVp+VF)->xyz[1])/2;
00363 (MainVp+Nvert-1)->xyz[2]=((MainVp+VP)->xyz[2]+(MainVp+VF)->xyz[2])/2;
00364 (MainVp+Nvert-1)->xyz[0]=NpointerX;
00365 UpdateEdgeHeap(Nedge+1);
00366 CreateEdge(VP,Nvert-1);
00367 VP=Nvert-1;
00368 }
00369 UpdateEdgeHeap(Nedge+1);
00370 CreateEdge(VP,VF);
00371 }
00372 VF=VP= -1;
00373 SP=0; break;
00374 case 10:
00375
00376 sid=type1_stack[SP-1];
00377 SP=0;
00378 if(sid >= 0 && sid < n_Subroutines)
00379 process_type1_routine(C_Subs[sid]);
00380 break;
00381 case 11:
00382 SP=0; return;
00383 case 13:
00384 XX = NpointerY+(long)type1_stack[SP-2]*Scale*lpAtm->FORB;
00385 Cwidthx=(long)type1_stack[SP-1]*Scale;
00386 SP=0; break;
00387 case 14:
00388 SP=0; break;
00389 case 21:
00390 x = (long)type1_stack[SP-2];
00391 y = (long)type1_stack[SP-1];
00392 MOVEJUMP:
00393 last_line=0;
00394 XX += x*Scale*lpAtm->FORB; YY += y*Scale;
00395 SP=0; break;
00396 case 22:
00397 y = 0; x = (long)type1_stack[SP-1];
00398 goto MOVEJUMP;
00399 case 30:
00400 u = 0;
00401 v = (long)type1_stack[SP-4];
00402 w = (long)type1_stack[SP-3];
00403 x = (long)type1_stack[SP-2];
00404 y = (long)type1_stack[SP-1];
00405 z = 0;
00406 goto CURVEJUMP;
00407 case 31:
00408 u = (long)type1_stack[SP-4];
00409 v = 0;
00410 w = (long)type1_stack[SP-3];
00411 x = (long)type1_stack[SP-2];
00412 y = 0;
00413 z = (long)type1_stack[SP-1];
00414 goto CURVEJUMP;
00415 case 12:
00416 i++; com=Cp.p[i].i;
00417 switch (com) {
00418 case 0: SP=0; break;
00419 case 1: SP=0; break;
00420 case 2: SP=0; break;
00421 case 6:
00422 SP=0; break;
00423 case 7:
00424 XX = NpointerX+(long)type1_stack[SP-4]*Scale*lpAtm->FORB;
00425 YY = NpointerY+(long)type1_stack[SP-3]*Scale;
00426 Cwidthx=(long)type1_stack[SP-2]*Scale;
00427 Cwidthy=(long)type1_stack[SP-1]*Scale;
00428 SP=0; break;
00429 case 12:
00430 x = (long)type1_stack[SP-2];
00431 y = (long)type1_stack[SP-1];
00432 SP -= 1;
00433 type1_stack[SP-1] = (int)((double)x/(double)y);
00434 break;
00435 case 16:
00436 SP=0; break;
00437 case 17:
00438 type1_stack[SP++] = -1;
00439 break;
00440 case 33:
00441 SP=0; break;
00442 default: SP=0; break;
00443 }
00444 break;
00445 default: SP=0; break;
00446 }
00447 }
00448 }
00449 }
00450
00451 static long CurveUpto(long vp, point *p, double d, long n){
00452 long i,j,N;
00453 double l=0,mu;
00454 point po;
00455 for(i=0;i<3;i++)for(j=0;j<2;j++){
00456 l += ((double)(p[i+1][j] - p[i][j]))*(double)((p[i+1][j] - p[i][j]));
00457 }
00458 N=(long)((sqrt(l)/d)*(double)n);
00459 N=max(N,4);
00460 UpdateVertexHeap(Nvert+N+1);
00461 UpdateEdgeHeap(Nedge+N+1);
00462 for(i=1;i<=N;i++){
00463 mu=(double)i/(double)N;
00464 Casteljau2(po,p,0,3,mu);
00465 if(i == N && VF >= 0 && po[0] == (MainVp+VF)->xyz[1]
00466 && po[1] == (MainVp+VF)->xyz[2]){
00467 ;
00468 }
00469 else{
00470 CreateVertex();
00471 CreateEdge(vp,Nvert-1);
00472 vp=Nvert-1;
00473 (MainVp+Nvert-1)->xyz[1]=po[0];
00474 (MainVp+Nvert-1)->xyz[2]=po[1];
00475 (MainVp+Nvert-1)->xyz[0]=NpointerX;
00476 }
00477 }
00478 UpdateVertexHeap(Nvert);
00479 UpdateEdgeHeap(Nedge);
00480 return Nvert-1;
00481 }