/************************************************************************* * *N draw_text_row * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws annotation for a given row in the text * pseudo-primitive table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * row <input>==(row_type) row of the text table. * table <input>==(vpf_table_type) text primitive table. * return <output>==(int) 0 if the user escapes, 1 upon successful * completion. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels August 1991 DOS Turbo C *E *************************************************************************/ int draw_text_row( row_type row, vpf_table_type table ) { int xscr,yscr, shape_pos, text_pos; ossim_int32 n, nshape; coordinate_type *shape_line; char *text; struct viewporttype vp; shape_pos = table_pos("SHAPE_LINE",table); /**** MUST CHECK FOR 'Z', 'B', AND 'Y' TYPES - SEE VPFPRIM.C ****/ shape_line = (coordinate_type *)get_table_element(shape_pos,row,table, NULL,&nshape); text_pos = table_pos("STRING",table); text = (char *)get_table_element(text_pos,row,table,NULL,&n); screenxy(shape_line[0].x,shape_line[0].y,&xscr,&yscr); getviewsettings(&vp); if ((gpgetfont() != DEFAULT_FONT) || (yscr > gptextheight(text))) { hidemousecursor(); gptext(xscr,yscr,text); showmousecursor(); } free(shape_line); free(text); while (kbhit()) { if (getch()==27) { return 0; } } return 1; }
/************************************************************************* * *N printer_ok * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function determines whether the printer is ready and allows * the user to keep retrying or cancel. Must be in graphics mode to call * this function. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * return <output> == (int) TRUE if ready, FALSE if cancel. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels November 1990 Original Version DOS Turbo C *E *************************************************************************/ int printer_ok( void ) { int retry; char *msg[] = {"Printer not ready"}; while (!printer_ready()) { hidemousecursor(); retry = displayerror(msg,1); showmousecursor(); if (!retry) return FALSE; } return TRUE; }
/************************************************************************* * *N info_window * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function displays a temporary window to the screen with a * single string of text. Must be in graphics mode to call this * function. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * text <input> == (char *)message to display. * return <output> == (window_type) window created and displayed. * [Will need to be deleted] *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels July 1990 Original Version DOS Turbo C *E *************************************************************************/ window_type info_window( char *text ) { window_type w; int x,y; settextstyle(SMALL_FONT,HORIZ_DIR,4); settextjustify(LEFT_TEXT,BOTTOM_TEXT); if (textwidth(text) > getmaxx()) x = getmaxx()-20; else x = textwidth(text) + 20; create_window( &w, x, textheight(text)+10, menucolor,menubordercolor ); get_display_position( &x, &y, w ); open_window( &w, x,y ); setcolor(menutextcolor); hidemousecursor(); outtextxy( 10,textheight(text)+5,text ); showmousecursor(); return w; }
/************************************************************************* * *N draw_point_row * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws an entity node for the row in the given * entity node primitive table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * row <input>==(row_type) row of the entity node * primitive table. * table <input>==(vpf_table_type) entity node primitive table. * return <output>==(int) 0 if the user escapes, 1 upon successful * completion. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels August 1991 DOS Turbo C *E *************************************************************************/ int draw_point_row( row_type row, vpf_table_type table ) { int xscr,yscr, coord_pos; ossim_int32 n; coordinate_type pnt; coord_pos = table_pos("COORDINATE",table); get_table_element(coord_pos,row,table,&pnt,&n); screenxy(pnt.x,pnt.y,&xscr,&yscr); hidemousecursor(); gpmarker(xscr,yscr); showmousecursor(); while (kbhit()) { if (getch()==27) { return 0; } } return 1; }
/************************************************************************* * *N outline_face_table * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function outlines the specified face from a previously unopened * face primitive table in the given color. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * face_id <input>==(ossim_int32) id of the face to be outlined. * fname <input>==(char *) file name of the face primitive table. * color <input>==(int) color to outline the face. * inner <input>==(int) if TRUE, draw inner rings; * if FALSE, only draw outer ring. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *************************************************************************/ void outline_face_table( ossim_int32 face_id, char *fname, int color, int inner ) { vpf_table_type facetable, ringtable, edgetable; char *name; name = (char *)vpfmalloc( 255*sizeof(char) ); gpsetlinecolor( color ); facetable = vpf_open_table(fname,disk, "rb", (char *)NULL); strupr(fname); strcpy( name, facetable.path ); strcat( name, "RNG" ); ringtable = vpf_open_table( name, disk, "rb", (char *)NULL ); strcpy( name, facetable.path ); strcat( name, "EDG" ); edgetable = vpf_open_table( name, disk, "rb", (char *)NULL ); free( name ); hidemousecursor(); outline_face( face_id, facetable, ringtable, edgetable, color, inner ); showmousecursor(); vpf_close_table(&facetable); vpf_close_table(&ringtable); vpf_close_table(&edgetable); }
/************************************************************************* * *N displayerror * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function displays an error message when a disk error is detected. * It displays the given lines of text in a popup panel and waits for * the user to click on either retry or cancel. It returns 1 for retry * and 0 for cancel. Must be in graphics mode to call this function. * * text strings may contain embedded newlines, in which case text to the * right of the newline will be displayed on (what else?) a new line. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * text[] <input> == (char *) array of text strings to be displayed. * nlines <input> == (int) number of lines of text (this count ignores * newline characters embedded in the text * strings * return <output> == (VPF_BOOLEAN) 1 => retry, * 0 => cancel. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels July 1990 Prototype 3 DOS Turbo C *E *************************************************************************/ VPF_BOOLEAN displayerror( char *text[], int nlines ) { register int i; int maxw, height, x, y, pad, choice, n_real_lines; panel_type panel; int retry_button = 'r', cancel_button = 'c', msg_ar_sz = 10; char * walker, ** msgs; struct viewporttype view; getviewsettings( &view ); setviewport(0,0,getmaxx(),getmaxy(),1); settextstyle( SMALL_FONT, HORIZ_DIR, 4 ); msgs = (char **) vpfmalloc(msg_ar_sz * sizeof(char *)); maxw = height = 0; for (n_real_lines = i = 0; i < nlines; i++) { walker = text[i]; while (1) { size_t substr_len = strcspn(walker, "\n"); char plug; maxw = max(maxw, textwidth(walker)); height = height + textheight(walker) + 5; plug = walker[substr_len]; walker[substr_len] = '\0'; msgs[n_real_lines++] = strdup(walker); if (n_real_lines == msg_ar_sz) msgs = (char **) realloc(msgs, (msg_ar_sz += 5) * sizeof(char *)); if (plug == 0) break; walker[substr_len] = plug; walker += substr_len + 1; } } if (maxw < (textwidth("Retry") + textwidth("Cancel") + 20)) maxw = textwidth("Retry") + textwidth("Cancel") + 20; pad = (maxw*10)/100; maxw = maxw + (2*pad); height = height + 2*(textheight("Retry") + 5) + 1; maxw = min(getmaxx(), maxw); height = min(getmaxy()-10, height); create_panel( &panel, maxw, height, menucolor, menubordercolor ); for (y = i = 0; i < n_real_lines; i++) { create_label(msgs[i], pad, y, SMALL_FONT, 4, menutextcolor, &panel ); y += textheight(msgs[i]) + 3; } y = height-15; create_button( retry_button, "Retry", 3, y, SMALL_FONT, 4, menutextcolor, menucolor, menubordercolor, RELIEVED, &panel ); create_button( cancel_button, "Cancel", maxw - (textwidth("Cancel") + 13), y, SMALL_FONT, 4, menutextcolor, menucolor, menubordercolor, RELIEVED, &panel ); get_display_position( &x, &y, panel.window ); display_panel( &panel, x,y ); showmousecursor(); arrow_cursor(); choice = process_panel( &panel, 0 ); hidemousecursor(); destroy_panel( &panel ); close_panel( &panel ); setviewport(view.left,view.top,view.right,view.bottom,view.clip); for (i = 0; i < n_real_lines; i++) free(msgs[i]); free(msgs); return (choice == retry_button) ? 1 : 0; }
/************************************************************************* * *N draw_selected_features * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws the selected features from a specified feature * class based upon a query (either an expression or the pre-compiled * results of an expression). *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * view <inout>==(view_type *) view structure. * themenum <input>==(int) theme number. * library <input>==(library_type *) VPF library structure. * mapenv <input>==(map_environment_type *) map environment structure. * return <output>==(int) completion status: * 1 if completed successfully, * 0 if an error occurred. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels August 1991 DOS Turbo C *E *************************************************************************/ int draw_selected_features( view_type *view, int themenum, library_type *library, map_environment_type *mapenv ) { int status, fcnum, finished, cov, tilecover, TILEPATH_, prim; int outline, color1, color2, color3, color4; vpf_table_type rngtable,edgtable,fbrtable, tile_table; row_type row; char *ptable[] = {"","edg","fac","txt","end","cnd"}; register rspf_int32 i, j, p, pclass, tile; int display_order[] = {FACE,EDGE,ENTITY_NODE,CONNECTED_NODE,TEXT}; register rspf_int32 starttile, endtile, startprim, endprim; rspf_int32 count; char path[255], covpath[255], tiledir[255], *buf, str[255]; char *drive, rngpath[255],edgpath[255],edxpath[255],fbrpath[255]; boolean rng_rdisk,edg_rdisk,fbr_rdisk; set_type primitives, feature_rows; fcrel_type fcrel; window_type info; struct viewporttype vp; getviewsettings(&vp); fcnum = view->theme[themenum].fcnum; sprintf(path,"%stileref\\tileref.aft",library->path); if (access(path,0) != 0) { tilecover = FALSE; } else { tile_table = vpf_open_table(path,disk,"rb",NULL); TILEPATH_ = table_pos("TILE_NAME",tile_table); tilecover = TRUE; } feature_rows = get_selected_features( view, themenum, *library ); for (p=0;p<5;p++) { pclass = display_order[p]; if ((pclass != library->fc[fcnum].primclass) && (library->fc[fcnum].primclass != COMPLEX_FEATURE)) continue; if ((library->fc[fcnum].primclass == COMPLEX_FEATURE) && (!library->fc[fcnum].cprim[pclass])) continue; /* Set up the feature class table relate chain. */ /* The feature table is fcrel.table[0]. */ /* The primitive table is the last table in the chain: */ /* fcrel.table[ fcrel.nchain-1 ]. */ j = 0; for (i=0;i<strlen(library->fc[fcnum].table);i++) if (library->fc[fcnum].table[i] == '\\') j = i+1; strcpy( str, &(library->fc[fcnum].table[j])); fcrel = select_feature_class_relate(fcnum, library, str, ptable[pclass]); prim = fcrel.nchain-1; /*** 'Tile' number 1 is the universe polygon for the tileref cover ***/ starttile = set_min(library->tile_set); if (starttile < 2) starttile = 2; endtile = set_max(library->tile_set); if (endtile < 2) endtile = 2; for (tile = starttile; tile <= endtile; tile++ ) { if (!set_member(tile,library->tile_set)) continue; if (tilecover) { row = get_row(tile,tile_table); buf = (char *)get_table_element(TILEPATH_,row,tile_table, NULL,&count); free_row(row,tile_table); strcpy(tiledir,buf); rightjust(tiledir); strcat(tiledir,"\\"); free(buf); } else { strcpy(tiledir,""); } cov = library->fc[fcnum].coverage; strcpy( covpath, library->cover[cov].path ); finished = TRUE; sprintf(path,"%s%s%s",covpath,tiledir,ptable[pclass]); if (access(path,0) != 0) continue; fcrel.table[prim] = vpf_open_table(path,disk,"rb",NULL); info = info_window("Searching..."); primitives = get_selected_tile_primitives( library, fcnum, fcrel, feature_rows, mapenv, tile, tiledir, &status ); delete_window(&info); setviewport(vp.left,vp.top,vp.right,vp.bottom,vp.clip); /* Reset plate-carree parameters (changed in */ /* get_selected_tile_primitives() ) */ if (mapenv->projection == PLATE_CARREE) set_plate_carree_parameters( central_meridian( mapenv->mapextent.x1, mapenv->mapextent.x2), 0.0, 1.0 ); if (primitives.size < 1) { vpf_close_table(&fcrel.table[prim]); continue; } if (!status) { set_nuke(&primitives); vpf_close_table(&fcrel.table[prim]); break; } if (pclass == FACE) { /* Must also open RNG, EDG, and FBR for drawing faces. */ /* If a RAM disk is specified, copy these to it and open */ /* them there. */ rng_rdisk = FALSE; edg_rdisk = FALSE; fbr_rdisk = FALSE; drive = getenv("TMP"); buf = (char *)vpfmalloc(255); sprintf(path,"%s%srng",covpath,tiledir); strcpy(rngpath,path); if (drive && filesize(path) < available_space(drive)) { sprintf(rngpath,"%s\\RNG",drive); sprintf(buf,"COPY %s %s > NUL",path,rngpath); system(buf); rng_rdisk = TRUE; } rngtable = vpf_open_table(rngpath,disk,"rb",NULL); sprintf(path,"%s%sedg",covpath,tiledir); strcpy(edgpath,path); sprintf(edxpath,"%s%sedx",covpath,tiledir); if (drive && (filesize(path)+filesize(edxpath))<available_space(drive)) { sprintf(edgpath,"%s\\EDG",drive); sprintf(buf,"COPY %s %s > NUL",path,edgpath); system(buf); sprintf(edxpath,"%s\\EDX",drive); sprintf(buf,"COPY %s%sedx %s > NUL",covpath,tiledir,edxpath); system(buf); edg_rdisk = TRUE; } edgtable = vpf_open_table(edgpath,disk,"rb",NULL); sprintf(path,"%s%sfbr",covpath,tiledir); strcpy(fbrpath,path); if (drive && filesize(path) < available_space(drive)) { sprintf(fbrpath,"%s\\FBR",drive); sprintf(buf,"COPY %s %s > NUL",path,fbrpath); system(buf); fbr_rdisk = TRUE; } fbrtable = vpf_open_table(fbrpath,disk,"rb",NULL); free(buf); } finished = 1; startprim = set_min(primitives); endprim = set_max(primitives); /* It turns out to be MUCH faster off of a CD-ROM to */ /* read each row and discard unwanted ones than to */ /* forward seek past them. It's about the same off */ /* of a hard disk. */ fseek(fcrel.table[prim].fp, index_pos(startprim,fcrel.table[prim]), SEEK_SET); for (i=startprim;i<=endprim;i++) { row = read_next_row(fcrel.table[prim]); if (set_member( i, primitives )) { /* Draw the primitive */ switch (pclass) { case EDGE: finished = draw_edge_row(row,fcrel.table[prim]); break; case ENTITY_NODE: case CONNECTED_NODE: finished = draw_point_row(row,fcrel.table[prim]); break; case FACE: gpgetlinecolor( &outline ); gpgetpattern( &color1, &color2, &color3, &color4 ); hidemousecursor(); draw_face_row( row,fcrel.table[prim], rngtable, edgtable, fbrtable, outline, color1, color2, color3, color4 ); showmousecursor(); finished = 1; if (kbhit()) { if (getch()==27) finished = 0; } break; case TEXT: finished = draw_text_row(row,fcrel.table[prim]); break; } } free_row(row,fcrel.table[prim]); if (!finished) { status = 0; break; } } if (pclass == FACE) { vpf_close_table(&rngtable); if (rng_rdisk) remove(rngpath); vpf_close_table(&edgtable); if (edg_rdisk) { remove(edgpath); remove(edxpath); } vpf_close_table(&fbrtable); if (fbr_rdisk) remove(fbrpath); } vpf_close_table(&fcrel.table[prim]); set_nuke(&primitives); if (!finished) { status = 0; break; } } if (!finished) { status = 0; deselect_feature_class_relate( &fcrel ); break; } status = 1; if (kbhit()) { if (getch()==27) { status = 0; deselect_feature_class_relate( &fcrel ); break; } } deselect_feature_class_relate(&fcrel); } if (tilecover) { vpf_close_table(&tile_table); } set_nuke(&feature_rows); return status; }
/************************************************************************* * *N draw_edge_coordinates * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws the coordinates of an edge record. * It tries its darndest to detect and get rid of projection * "zingers" - lines that dart across the screen because of * lines projected onto the map that wrap around behind the * globe or change hemispheres. The ability to handle these * projection artifacts is what turns what should be a very * simple function into a very ugly piece of code. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * edge_rec <input>==(edge_rec_type *) pointer to an edge record. * return <output>==(int) 0 if the user escapes, 1 upon successful * completion. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels Feb 1992 DOS Turbo C *E *************************************************************************/ int draw_edge_coordinates( edge_rec_type *edge_rec ) { int xscr,yscr, xprev,yprev, x1,y1,x2,y2, mbrx2, wrap; register ossim_int32 i; extent_type mbr; coordinate_type coord; /* First compute the MBR from the coordinates. */ coord = first_edge_coordinate(edge_rec); mbr.x1 = coord.x; mbr.y1 = coord.y; mbr.x2 = coord.x; mbr.y2 = coord.y; for (i=1;i<edge_rec->npts;i++) { coord = next_edge_coordinate(edge_rec); if (coord.x < mbr.x1) mbr.x1 = coord.x; if (coord.y < mbr.y1) mbr.y1 = coord.y; if (coord.x > mbr.x2) mbr.x2 = coord.x; if (coord.y > mbr.y2) mbr.y2 = coord.y; } screen_bounds(mbr.x1,mbr.y1,mbr.x2,mbr.y2,&x1,&y1,&x2,&y2); if ( (x1 < 0 && x2 < 0) || (x1 > gpgetmaxx() && x2 > gpgetmaxx()) || (y1 < 0 && y2 < 0) || (y1 > gpgetmaxy() && y2 > gpgetmaxy()) ) return 1; if (x1 > gpgetmaxx() && x2 < 0) return 1; wrap = 0; mbrx2 = x2; if (x2 < x1) { /* The box wraps around the screen */ /* (or at least wraps off the edge of the screen) */ wrap = gpgetmaxx(); if (x2 < 0) wrap -= x2; /* Adjust the maximum screen value */ x2 += wrap; } coord = first_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (wrap && xscr < x1) xscr += wrap; gpmoveto(xscr,yscr); xprev = xscr; yprev = yscr; for (i=1;i<edge_rec->npts;i++) { coord = next_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (xscr == MAXINT || yscr == MAXINT) { xprev = xscr; yprev = yscr; continue; } if (wrap && xscr < x1) xscr += wrap; if (xscr==xprev && yscr==yprev) continue; if (xprev == MAXINT || yprev == MAXINT) gpmoveto(xscr,yscr); hidemousecursor(); gplineto( xscr, yscr ); showmousecursor(); xprev = xscr; yprev = yscr; while (kbhit()) { if (getch()==27) { return 0; } } } if (wrap && mbrx2 > 0) { /* The edge wraps around and is displayed on the other */ /* edge of the screen. */ x2 -= wrap; coord = first_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (xscr > x2) xscr -= wrap; gpmoveto(xscr,yscr); xprev = xscr; yprev = yscr; for (i=1;i<edge_rec->npts;i++) { coord = next_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (xscr == MAXINT || yscr == MAXINT) { xprev = xscr; yprev = yscr; continue; } if (xscr > x2) xscr -= wrap; if (xscr==xprev && yscr==yprev) continue; if (xprev == MAXINT || yprev == MAXINT) gpmoveto(xscr,yscr); hidemousecursor(); gplineto( xscr, yscr ); showmousecursor(); xprev = xscr; yprev = yscr; while (kbhit()) { if (getch()==27) { return 0; } } } } return 1; }
/************************************************************************* * *N draw_polygon * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws a polygon for VPF face structure tables. * It is complicated by the fact that it checks to see whether * enough memory is available to draw the entire polygon in a * Shademap structure, or whether the face must be broken up into * smaller chunks so the bit arrays can fit into memory. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * mbrx1 <input> == (int) mbr corner 1 x coordinate. * mbry1 <input> == (int) mbr corner 1 y coordinate. * mbrx2 <input> == (int) mbr corner 2 x coordinate. * mbry2 <input> == (int) mbr corner 2 y coordinate. * face_rec <input> == (face_rec_type) * ringtable <input> == (vpf_table_type) VPF ring table. * edgetable <input> == (vpf_table_type) VPF edge table. * outline <input> == (color_type) polygon outline color. * pattern <input> == (Pattern) polygon fill pattern. * wrap <input> == (int) wrap around if the polygon wraps around * the screen. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *************************************************************************/ void draw_polygon( int mbrx1, int mbry1, int mbrx2, int mbry2, face_rec_type face_rec, vpf_table_type ringtable, vpf_table_type edgetable, color_type outline, Pattern pattern, int wrap ) { int x1,y1,x2,y2, nchunks,chunk,delta, ok, k; Shademap *poly; IBox bounding,wdw,make_ibox(); ring_rec_type ring_rec; x1 = mbrx1-2; y1 = mbry1-2; x2 = mbrx2+2; y2 = mbry2+2; delta = x2-x1; nchunks=1; wdw = make_ibox(0,0,gpgetmaxx()+1,gpgetmaxy()); bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade( bounding, wdw, outline, pattern); if (!poly) return; if (gpgetdevice() == SCREEN) { /* wdw = make_ibox(0,0,getmaxx()+1,getmaxy()); bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade( bounding, wdw, outline, pattern); if (!poly) return; */ ok = TRUE; if (!poly->Bordermap.array || !poly->Maskmap.array) { /* Not enough memory - Split polygon up */ if (poly->Bordermap.array) FreeArrayOfBits(poly->Bordermap); if (poly->Maskmap.array) FreeArrayOfBits(poly->Maskmap); free(poly); poly = (Shademap *)NULL; k = 2; delta = gpgetmaxx()/k; nchunks = (mbrx2-mbrx1)/delta + 1; ok = FALSE; while (!ok) { ok = TRUE; bounding = make_ibox(0,y1,delta,y2); poly = OpenShade( bounding, wdw, outline, pattern); if (!poly) return; if (!poly->Bordermap.array || !poly->Maskmap.array) { ok = FALSE; if (poly->Bordermap.array) FreeArrayOfBits(poly->Bordermap); if (poly->Maskmap.array) FreeArrayOfBits(poly->Maskmap); free(poly); k++; delta = gpgetmaxx()/k; if (delta < 5) return; nchunks = (mbrx2-mbrx1)/delta + 1; } else { FreeArrayOfBits(poly->Bordermap); FreeArrayOfBits(poly->Maskmap); free(poly); poly = (Shademap *)NULL; } } x2 = x1 + delta; bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade(bounding,wdw,outline,pattern); } } for (chunk=0;chunk<nchunks;chunk++) { ring_rec = read_ring( face_rec.ring, ringtable ); draw_polygon_loop( face_rec.id, ring_rec.edge, edgetable, poly, wrap ); gpcloseloop(poly); while (ring_rec.face == face_rec.id ) { ring_rec = read_next_ring( ringtable ); if (feof(ringtable.fp)) { gpcloseloop(poly); break; } if (ring_rec.face == face_rec.id) { draw_polygon_loop( face_rec.id, ring_rec.edge, edgetable, poly, wrap ); gpcloseloop(poly); } } hidemousecursor(); gpfillpoly(poly); showmousecursor(); if (gpgetdevice()==SCREEN) { poly = (Shademap *)NULL; if (x2 < mbrx2 && chunk < (nchunks)) { x1 = x2; x2 += delta; bounding = make_ibox(x1,y1,x2,y2); poly = OpenShade(bounding,wdw,outline,pattern); } } } if (poly) { if (gpgetdevice()==SCREEN) CloseShade(poly); else { FreeArrayOfBits(poly->Bordermap); FreeArrayOfBits(poly->Maskmap); free(poly); } } }