/* Copy area (x1,y1)-(x2,y2) from a bitmap (if bm==NULL from the screen) and create a structure ws_bitmap with the area in bitmap. Returns NULL if not successful, the pointer to the structure otherwise. */ struct ws_bitmap *ws_savebitmap(struct ws_bitmap *bm, int x1, int y1, int xsize, int ysize) { GrContext *gc; struct ws_bitmap *bmap; if ( xsize < 0 || ysize < 0 || y1 < 0 || x1 < 0 || x1 + xsize > GrSizeX() || y1 + ysize > GrSizeY() ) { return NULL; } checkmem( bmap = MALLOC( sizeof(struct ws_bitmap) ) ); checkmem( gc = GrCreateContext(xsize, ysize, NULL, NULL) ); GrBitBlt(gc, 0, 0, bm == NULL ? NULL : bm->bitmap, x1, y1, x1 + xsize - 1, y1 + ysize - 1, GrWRITE); bmap->bitmap = (void *)gc; bmap->xpos = x1; bmap->ypos = y1; bmap->xsize = xsize; bmap->ysize = ysize; bmap->w = NULL; return bmap; }
struct w_button *w_addbutton(struct w_button *b, int draw) { struct wi_button *bi; my_assert( b != NULL && b->d.d != NULL && (b->w != NULL || !draw) ); checkmem( bi = MALLOC( sizeof(struct wi_button) ) ); bi->b = *b; copylisthead(&bi->b.inscription, &b->inscription); copylisthead(&bi->b.a_inscription, &b->a_inscription); bi->sys_button = 0; bi->activated = 1; bi->bm = NULL; bi->drawn = draw; bi->tobechanged = 1; if (b->w) { if ( draw && !wi_drawbutton(bi, 0) ) { return NULL; } checkmem( bi->n = addnode(&( (struct wi_window *)bi->b.w )->buttonlist, -1, bi) ); bi->b.no = bi->n->no; } else { bi->b.no = -1; } return &bi->b; }
/* cursor is activated if event.kbstat&bitmask==kbstat. w=width, h=height, xo,yo=hot spot, colortable maps colors from data to normal colors. */ void w_initkbstatcursor(char *data, int w, int h, int xo, int yo, GrColorTableP colortable, enum kbstattypes kbstat, enum kbstattypes bitmask) { int i; struct kbstatcursor *kbsc; my_assert( (kbstat < 2 << MAX_KBSTAT) && data != NULL ); for (i = 0, kbsc = NULL; i < notes.num_kbstatcursors; i++) { if (notes.kbstatcursors[i].kbstat == kbstat && notes.kbstatcursors[i].bitmask == bitmask) { kbsc = ¬es.kbstatcursors[i]; } } if (!kbsc) { checkmem( notes.kbstatcursors = REALLOC( notes.kbstatcursors, ++notes.num_kbstatcursors * sizeof(struct kbstatcursor) ) ); kbsc = ¬es.kbstatcursors[notes.num_kbstatcursors - 1]; kbsc->kbstat = kbstat; kbsc->bitmask = bitmask; } else { ws_killcursor(kbsc->cursor); } checkmem( kbsc->cursor = ws_initcursor(data, w, h, xo, yo, colortable) ); }
/* Draws a button with an image. data is the substructure of the button. bm is the pointer to the normal image. abm the pointer to the image for the activated button. The color 0 in the images is replaced with the correct background color for the button. The button is as large as the image plus the edge of the button if the xsize is set to -1. If the button is a string button ysize may be set to -1 to get the stdsize for stringbuttons. If the buttons is not a string button and xsize!=-1 then ysize must be set as well. Therefore both images must be of equal size. The position is the position of the left upper edge of the button (not the image). Returns pointer to button-structure if successful, 0 otherwise. */ struct w_button *w_addimagebutton(struct w_window *w, enum but_types type, int xpos, int ypos, int xsize, int ysize, struct ws_bitmap *bm, struct ws_bitmap *abm, void *data, int with_bg, int draw) { struct w_button *b, *nb; struct w_description *d1, *d2; if (abm == NULL || bm == NULL || abm->xsize != bm->xsize || abm->ysize != bm->ysize) { return NULL; } checkmem( b = MALLOC( sizeof(struct w_button) ) ); b->xpos = xpos; b->ypos = ypos; b->w = w; if (xsize < 0) { b->xsize = bm->xsize + (type == w_b_switch ? 6 : 2); b->ysize = bm->ysize + (type == w_b_switch ? 6 : 2); } else { b->xsize = xsize; b->ysize = ysize < 0 ? shapes.titlebar_height + 5 : ysize; } b->type = type; b->helptxt = NULL; initlist(&b->inscription); initlist(&b->a_inscription); b->d.d = data; checkmem( d1 = MALLOC( sizeof(struct w_description) ) ); d1->contents.bm = bm; d1->type = w_bdt_image; d1->image_with_bg = with_bg; d1->y = d1->x = type == w_b_switch ? 3 : 1; if (type == w_b_string) { d1->y = (b->ysize - bm->ysize) / 2; b->d.str->d_xsize = bm->xsize + 2; b->d.str->offset = 0; b->d.str->length = (b->xsize - b->d.str->d_xsize - 10) / ws_pixstrlen( "M"); } checkmem( addnode(&b->inscription, -1, d1) ); checkmem( d2 = MALLOC( sizeof(struct w_description) ) ); *d2 = *d1; d2->contents.bm = abm; checkmem( addnode(&b->a_inscription, -1, d2) ); nb = w_addbutton(b, draw); free(b); return nb; }
void changepogfile(char *pogfilename) { char const *pogname; FILE *pf = NULL; if (!pogfilename || ( pf = fopen(pogfilename, "rb") ) == NULL) { pogname = NULL; } else { if ( ( pogname = strrchr(pogfilename, '/') ) != NULL ) { pogname++; } else { pogname = pogfilename; } } if (pig.current_pogname) { FREE(pig.current_pogname); pig.current_pogname = NULL; } if (pogname) { checkmem( pig.current_pogname = MALLOC(strlen(pogname) + 1) ); strcpy(pig.current_pogname, pogname); } if (pogfilename) { FREE(pogfilename); } newpigfile(l ? l->pigname : pig.default_pigname, pf); }
/* * Main entry function for this specific parser type. * We expect a zero terminated string. * * The parser structure is uninitialized upon entry, and should be * cleared with `clear_flatbuffer_parser` subsequently. * * Datastructures point into the token buffer and into the input * buffer, so the parser and input should not be cleared prematurely. * * The input buffer must remain valid until the parser is cleared * because the internal represenation stores pointers into the buffer. * * `own_buffer` indicates that the the buffer should be deallocated when * the parser is cleaned up. */ int fb_parse(fb_parser_t *P, const char *input, int len, int own_buffer) { static const char *id_none = "NONE"; static const char *id_ubyte = "ubyte"; P->line = input; P->linenum = 1; /* Used with union defaults. */ inject_token(&P->t_none, id_none, LEX_TOK_ID); inject_token(&P->t_ubyte, id_ubyte, tok_kw_ubyte); if (own_buffer) { P->managed_input = input; } lex(input, len, 0, P); P->te = P->token; P->token = P->ts; /* Only used while processing table id's. */ checkmem((P->tmp_field_marker = malloc((size_t)P->opts.vt_max_count))); if (P->token->id == tok_kw_doc_comment) { next(P); } parse_schema(P); return P->failed; }
UnitsEdit *UnitsEditPage::addEdit( const QString &labelKey, const char **varList, const char **unitsList, int row, bool showDecimals ) { // Find the variable EqVar *varPtr = m_dialog->m_bp->m_eqTree->m_varDict->find( varList[0] ); if ( ! varPtr ) // This code block should never be executed! { QString text(""); translate( text, "UnitsEditDialog:UnknownVar", varList[0] ); bomb( text ); } // Create the QLabel QString text(""); translate( text, labelKey ); QLabel *label = new QLabel( text, m_frame, QString( "%1:Label" ).arg( labelKey ) ); Q_CHECK_PTR( label ); m_grid->addMultiCellWidget( label, row, row, 0, 0, AlignLeft ); // Create the combo box QComboBox *combo = new QComboBox( false, m_frame, QString( "%1:ComboBox" ).arg( labelKey ) ); Q_CHECK_PTR( combo ); // Insert items into the combo box while searching for the current item int n = 0; for ( int id = 0; unitsList[id]; id++ ) { combo->insertItem( unitsList[id] ); if ( appSiUnits()->equivalent( unitsList[id], varPtr->m_displayUnits.latin1() ) ) { n = id; } } combo->setCurrentItem( n ); m_grid->addMultiCellWidget( combo, row, row, 1, 1 ); // Create the spin box QSpinBox *spin = NULL; if ( showDecimals ) { spin = new QSpinBox( 0, 6, 1, m_frame, QString( "%1:SpinBox" ).arg( labelKey ) ); Q_CHECK_PTR( spin ); spin->setValue( varPtr->m_displayDecimals ); m_grid->addMultiCellWidget( spin, row, row, 2, 2 ); } // All rows share the available space equally m_grid->setRowStretch( row, 10 ); // Create the new UnitsEdit UnitsEdit *edit = new UnitsEdit( varList, varPtr, combo, spin ); checkmem( __FILE__, __LINE__, edit, "UnitsEdit edit", 1 ); // Add the UnitsEdit to the UnitEditPage's m_editList m_editList->append( edit ); return( edit ); }
static FILE *open_file(fb_options_t *opts, fb_schema_t *S) { FILE *fp = 0; char *path; const char *prefix = opts->outpath ? opts->outpath : ""; int prefix_len = strlen(prefix); const char *name; int len; const char *ext; name = S->basename; len = strlen(name); ext = flatbuffers_extension; /* We generally should not use cgen options here, but in this case it makes sense. */ if (opts->gen_stdout) { return stdout; } checkmem((path = fb_create_join_path(prefix, prefix_len, name, len, ext, 1))); fp = fopen(path, "wb"); if (!fp) { fprintf(stderr, "error opening file for writing binary schema: %s\n", path); } free(path); return fp; }
void set_titlebar_text(char const *txt) { if (notes.titlebar_text) { FREE(notes.titlebar_text); } checkmem( notes.titlebar_text = MALLOC(strlen(txt) + 1) ); strcpy(notes.titlebar_text, txt); drawmenubar(); }
char *makepath(const char *path, const char *fname) { char *lp; checkmem( lp = MALLOC(strlen(fname) + strlen(path) + 2) ); strcpy(lp, path); strcat(lp, "/"); strcat(lp, fname); return lp; }
bool PropertyDict::add( const QString &name, Property::PropertyType type, const QString &value, int releaseFrom, int releaseThru ) { // Create the property property Property *property = new Property( type, "", releaseFrom, releaseThru ); checkmem( __FILE__, __LINE__, property, "Property property", 1 ); // Add it to the dictionary insert( name, property ); // Test and store its value update( name, value ) ; return( true ); }
void copytxtnums(enum txttypes dest, enum txttypes source) { int n; n = pig.num_txtlist[dest] + pig.num_txtlist[source]; checkmem( pig.txtlist[dest] = REALLOC( pig.txtlist[dest], n * sizeof(struct ham_txt *) ) ); memmove( &pig.txtlist[dest][pig.num_txtlist[dest]], pig.txtlist[source], pig.num_txtlist[source] * sizeof(struct ham_txt *) ); pig.num_txtlist[dest] = n; }
int main(int argc, char **argv) { char *mapping; int fd, i; /* * Make some random ordering of writing the chunks to the * memory map.. * * Start with fully ordered.. */ for (i = 0; i < NRCHUNKS; i++) chunkorder[i] = i; /* ..and then mix it up randomly */ srandom(time(NULL)); for (i = 0; i < NRCHUNKS; i++) { int index = (unsigned int) random() % NRCHUNKS; int nr = chunkorder[index]; chunkorder[index] = chunkorder[i]; chunkorder[i] = nr; } fd = open("mapfile", O_RDWR | O_TRUNC | O_CREAT, 0666); if (fd < 0) return -1; if (ftruncate(fd, SIZE) < 0) return -1; mapping = remap(fd, NULL); if (-1 == (int)(long)mapping) return -1; for (i = 0; i < NRCHUNKS; i++) { int chunk = chunkorder[i]; printf("Writing chunk %d/%d (%d%%) \r", i, NRCHUNKS, 100*i/NRCHUNKS); fillmem(mapping + chunk * CHUNKSIZE, chunk); } printf("\n"); /* Unmap, drop, and remap.. */ mapping = remap(fd, mapping); /* .. and check */ for (i = 0; i < NRCHUNKS; i++) { int chunk = i; printf("Checking chunk %d/%d (%d%%) \r", i, NRCHUNKS, 100*i/NRCHUNKS); checkmem(mapping + chunk * CHUNKSIZE, chunk); } printf("\n"); return 0; }
bool PropertyDict::readXmlFile( const QString &fileName ) { PropertyParser *handler = new PropertyParser( this, fileName ); checkmem( __FILE__, __LINE__, handler, "PropertyParser handler", 1 ); QFile xmlFile( fileName ); QXmlInputSource source( &xmlFile ); QXmlSimpleReader reader; reader.setContentHandler( handler ); reader.setErrorHandler( handler ); bool result = reader.parse( &source ); delete handler; return( result ); }
void b_changepigfile(struct w_button *b) { if (!l) { printmsg(TXT_NOLEVEL); return; } FREE(l->pigname); checkmem( l->pigname = MALLOC(strlen(b->d.ls->options[b->d.ls->selected]) + 5) ); strcpy(l->pigname, b->d.ls->options[b->d.ls->selected]); strcat(l->pigname, ".256"); newpigfile(l->pigname, pig.pogfile); }
int checkd1version(char *path) { FILE *f; char buffer[100]; unsigned long d; printf("Checking Descent 1 version...\n"); makedospath(path, buffer); strcat(buffer, "/"); strcat(buffer, "descent.pig"); checkmem( f = fopen(buffer, "rb") ); my_assert(fread(&d, sizeof(long), 1, f) == 1); fclose(f); return (d >= 0x10000) ? d1_14_reg : d1_10_reg; }
/* * Removal of duplicate inclusions is only for a cleaner output - it is * not stricly necessary because the preprocessor handles include * guards. The guards are required to deal with concatenated files * regardless unless we generate special code for concatenation. */ void fb_gen_c_includes(output_t *out, const char *ext, const char *extup) { fb_include_t *inc = out->S->includes; char *basename, *basenameup, *s; str_set_t set; fb_clear(set); /* Don't include our own file. */ str_set_insert_item(&set, fb_copy_path(out->S->basenameup, -1), ht_keep); while (inc) { checkmem((basename = fb_create_basename( inc->name.s.s, inc->name.s.len, out->opts->default_schema_ext))); inc = inc->link; checkmem((basenameup = fb_copy_path(basename, -1))); s = basenameup; while (*s) { *s = toupper(*s); ++s; } if (str_set_insert_item(&set, basenameup, ht_keep)) { free(basenameup); free(basename); continue; } /* The include guard is needed when concatening output. */ fprintf(out->fp, "#ifndef %s%s\n" "#include \"%s%s\"\n" "#endif\n", basenameup, extup, basename, ext); free(basename); /* `basenameup` stored in str_set. */ } str_set_destroy(&set, _str_set_destructor, 0); }
/* if a button is created before the window is made, this routine can put it into the window. */ void w_buttoninwin(struct w_window *w, struct w_button *b, int draw) { struct wi_button *bi = (struct wi_button *)b; my_assert(b != NULL && w != NULL && b->w == NULL); b->w = w; bi->drawn = draw; if (draw) { my_assert( wi_drawbutton(bi, 0) ); } checkmem( bi->n = addnode(&( (struct wi_window *)bi->b.w )->buttonlist, -1, bi) ); bi->b.no = bi->n->no; }
/* Creates a bitmap xsize*ysize and draws the lines into it. The lines are an array of n lines which consist of a color (1 int) and 2 coords (4 ints) */ struct ws_bitmap *w_createlinesbm(int xsize, int ysize, int n, int *lines) { struct ws_bitmap *bm; int i; my_assert(lines); checkmem( bm = ws_createbitmap(xsize, ysize, NULL) ); for (i = 0; i < n; i++) { ws_bmdrawline(bm, lines[i * 5 + 1], lines[i * 5 + 2], lines[i * 5 + 3], lines[i * 5 + 4], lines[i * 5], 0); } return bm; }
UnitsEditPage *UnitsEditDialog::addPage( const QString &tabKey, int rows, const QString &pictureFile, const QString &pictureName, const QString &htmlFile ) { // Create the new page UnitsEditPage *page = new UnitsEditPage( this, rows, pictureFile, pictureName, htmlFile, QString( "%1:%2" ).arg( name() ).arg( tabKey ) ); checkmem( __FILE__, __LINE__, page, "UnitsEditPage page", 1 ); // Add it to the dialog's page list m_pageList->append( page ); // Add the tab if ( ! tabKey.isNull() && ! tabKey.isEmpty() ) { QString tabText(""); translate( tabText, tabKey ); addTab( page, tabText ); } return( page ); }
int fb_open_output_file(output_t *out, const char *name, int len, const char *ext) { char *path; int ret; const char *prefix = out->opts->outpath ? out->opts->outpath : ""; int prefix_len = strlen(prefix); if (out->opts->gen_stdout) { out->fp = stdout; return 0; } checkmem((path = fb_create_join_path(prefix, prefix_len, name, len, ext, 1))); out->fp = fopen(path, "wb"); ret = 0; if (!out->fp) { fprintf(stderr, "error opening file for write: %s\n", path); ret = -1; } free(path); return ret; }
static void push_token(fb_parser_t *P, long id, const char *first, const char *last) { size_t offset; fb_token_t *t; P->te = P->ts + P->tcapacity; if (P->token == P->te) { offset = P->token - P->ts; P->tcapacity = P->tcapacity ? 2 * P->tcapacity : 1024; P->ts = realloc(P->ts, P->tcapacity * sizeof(fb_token_t)); checkmem(P->ts); P->te = P->ts + P->tcapacity; P->token = P->ts + offset; } t = P->token; t->id = id; t->text = first; t->len = last - first; t->linenum = P->linenum; t->pos = first - P->line + 1; ++P->token; }
void wi_undrawwin(struct wi_window *wi) { if (!wi->drawn) { return; } my_assert(wi != NULL && wi->bg != NULL); if (wi->w.refresh != wr_routine) { if (wi->in) { ws_freebitmap(wi->in); wi->in = NULL; } checkmem( wi->in = ws_savebitmap( NULL, w_xwinincoord(&wi->w, 0), w_ywinincoord(&wi->w, 0), w_xwininsize(&wi->w), w_ywininsize(&wi->w) ) ); } ws_restorebitmap(wi->bg); wi->bg = NULL; wi->drawn = 0; }
void appSiUnitsCreate( void ) { AppSiUnits = new SIUnits(); checkmem( __FILE__, __LINE__, AppSiUnits, "SIUnits AppSiUnits", 1 ); return; }
/** * Open and read an initialization file, putting the information * therein into a newly-allocated object of type Ini. * * @param[in] ifname Name of input file * * @returns Newly-allocate Ini object containing info from input file. */ Ini *Ini_new(const char *ifname) { FILE *ifp = fopen(ifname, "r"); int inPopHist = 0; if(ifp == NULL) return NULL; Ini *ini = malloc(sizeof(Ini)); checkmem(ini, __FILE__, __LINE__); memset(ini, 0, sizeof(Ini)); ini->a = NULL; ini->epochList = NULL; Tokenizer *tkz = Tokenizer_new(100); char buff[1000]; int lineno = 0, ntokens; while(fgets(buff, sizeof(buff), ifp) != NULL) { ++lineno; if(!strchr(buff, '\n') && !feof(ifp)) eprintf("ERR@%s:%d: Buffer overflow. buff=\"%s\"\n", __FILE__, __LINE__, buff); /* skip blank lines and comments */ stripComment(buff); if(strempty(buff)) continue; if(inPopHist) { Tokenizer_split(tkz, buff, " \t"); /* tokenize */ ntokens = Tokenizer_strip(tkz, " \t\n"); /* strip extraneous */ if(ntokens != 2) break; double t = strtod(Tokenizer_token(tkz, 0), NULL); double twoN = strtod(Tokenizer_token(tkz, 1), NULL); ini->epochList = EpochLink_new(ini->epochList, t, twoN); if(!isfinite(t)) break; } else if(strchr(buff, '=')) { Tokenizer_split(tkz, buff, "="); /* tokenize */ ntokens = Tokenizer_strip(tkz, " \t\n"); /* strip extraneous */ if(ntokens != 2) eprintf("ERR@:%s:%d:" "Broken assignment @ line %u" " of initialization file", __FILE__, __LINE__, lineno); ini->a = Assignment_new(ini->a, Tokenizer_token(tkz, 0), Tokenizer_token(tkz, 1)); } else { Tokenizer_split(tkz, buff, " \t"); /* tokenize */ ntokens = Tokenizer_strip(tkz, " \t\n"); /* strip * extraneous */ if(ntokens == 0) continue; if(ntokens != 1) eprintf("ERR@:%s:%d:" "Broken command @ line %u" " of initialization file." " inPopHist=%d; ntokens=%d\n", __FILE__, __LINE__, lineno, inPopHist, ntokens); if(!strcmp("PopHist", Tokenizer_token(tkz, 0))) inPopHist = 1; else ini->a = Assignment_new(ini->a, Tokenizer_token(tkz, 0), "1"); } } Tokenizer_free(tkz); fclose(ifp); return ini; }
int flatcc_parse_file(flatcc_context_t ctx, const char *filename) { fb_parser_t *P = ctx; int inpath_len, filename_len; char *buf, *path, *include_file; const char *inpath; size_t size; fb_name_t *inc; int i, ret; filename_len = strlen(filename); /* Don't parse the same file twice, or any other file with same basename. */ if (fb_schema_table_insert_item(&P->schema.root_schema->include_index, &P->schema, ht_keep)) { return 0; } buf = 0; path = 0; include_file = 0; ret = -1; /* * For root files, read file relative to working dir first. For * included files (`referer_path` set), first try include paths * in order, then path relative to including file. */ if (!P->referer_path) { if (!(buf = fb_read_file(filename, P->opts.max_schema_size, &size))) { if (size + P->schema.root_schema->total_source_size > P->opts.max_schema_size && P->opts.max_schema_size > 0) { fb_print_error(P, "input exceeds maximum allowed size\n"); return -1; } } else { checkmem((path = fb_copy_path(filename, -1))); } } for (i = 0; !buf && i < P->opts.inpath_count; ++i) { inpath = P->opts.inpaths[i]; inpath_len = strlen(inpath); checkmem((path = fb_create_join_path(inpath, inpath_len, filename, filename_len, "", 1))); if (!(buf = fb_read_file(path, P->opts.max_schema_size, &size))) { free(path); path = 0; if (size > P->opts.max_schema_size && P->opts.max_schema_size > 0) { fb_print_error(P, "input exceeds maximum allowed size\n"); return -1; } } } if (!buf && P->referer_path) { inpath = P->referer_path; inpath_len = fb_find_basename(inpath, strlen(inpath)); checkmem((path = fb_create_join_path(inpath, inpath_len, filename, filename_len, "", 1))); if (!(buf = fb_read_file(path, P->opts.max_schema_size, &size))) { free(path); path = 0; if (size > P->opts.max_schema_size && P->opts.max_schema_size > 0) { fb_print_error(P, "input exceeds maximum allowed size\n"); return -1; } } } if (!buf) { fb_print_error(P, "error reading included schema file: %s\n", filename); return -1; } P->schema.root_schema->total_source_size += size; P->path = path; /* * Even if we do not have the recursive option set, we still * need to parse all include files to make sense of the current * file. */ if (!(ret = fb_parse(P, buf, size, 1))) { inc = P->schema.includes; while (inc) { checkmem((include_file = fb_copy_path(inc->name.s.s, inc->name.s.len))); if (__parse_include_file(P, include_file)) { return -1; } free(include_file); include_file = 0; inc = inc->link; } /* Add self to set of visible schema. */ ptr_set_insert_item(&P->schema.visible_schema, &P->schema, ht_keep); ret = fb_build_schema(P); } return ret; }
void BpDocument::composeLineGraph( int yid, EqVar *xVar, EqVar *yVar, EqVar *zVar, GraphAxleParms *xParms, GraphAxleParms *yParms ) { //-------------------------------------------------------------------------- // 1: Set up fonts, pens, and colors used by this graph //-------------------------------------------------------------------------- // Graph fonts QFont textFont( property()->string( "graphTextFontFamily" ), property()->integer( "graphTextFontSize" ) ); QColor textColor( property()->color( "graphTextFontColor" ) ); QPen textPen( textColor ); // How many colors are requested? QString colorName( property()->color( "graphLineColor" ) ); int colors = 1; if ( colorName == "rainbow" ) { colors = property()->integer( "graphRainbowColors" ); } // Allocate number of requested colors. QColor *color = new QColor [colors]; checkmem( __FILE__, __LINE__, color, "QColor color", colors ); int colorId = 0; // If only 1 color... if ( colors == 1 ) { color[0].setNamedColor( colorName ); } // else if rainbow colors are requested... else { // todo - add some code to check conflicts with graphBackgroundColor // and graphGridColor (if graphGridWidth > 0 ). int hue = 0; for ( colorId = 0; colorId < colors; colorId++ ) { color[colorId].setHsv( hue, 255, 255); hue += 360 / colors; } colorId = 0; } // Set up line width and color int lineWidth = property()->integer( "graphLineWidth" ); QPen pen( color[0], lineWidth, SolidLine ); //-------------------------------------------------------------------------- // 2: Create the graph and add its curves. //-------------------------------------------------------------------------- // Initialize graph and variables Graph g; GraphLine *line[graphMaxLines]; double l_x[graphMaxSteps]; double l_y[graphMaxSteps]; int curves = ( tableCols() < graphMaxLines ) ? ( tableCols() ) : ( graphMaxLines ); int points = tableRows(); int vStep = tableCols() * tableVars(); // Loop for each zVar family curve value in this graph (or at least once!). // Note that zVar count is in tableCols(), e.g. each column stores a curve, // and zVar values are in tableCol( col ). int col, vid; for ( col = 0; col < curves; col++ ) { // tableVal[] offset of first y-value for this curve. vid = yid + col * tableVars(); // Set up the y[point] array for this curve. // Note number of points is in tableRows() and // point x values are in tableRow( point ). for ( int point = 0; point < points; point++ ) { l_x[point] = tableRow( point ); l_y[point] = tableVal( vid ); vid += vStep; } // If we're out of colors, start over. if ( colorId >= colors ) { colorId = 0; } // Create a graph line (with its own copy of the data). pen.setColor( color[colorId++] ); line[col] = g.addGraphLine( points, l_x, l_y, pen ); } // Next z-variable curve. //-------------------------------------------------------------------------- // 3: Add curve labels if there is more than 1 curve. //-------------------------------------------------------------------------- QString label; if ( curves > 1 ) { colorId = 0; #define GRAPH_LABEL_METHOD_1 #ifdef GRAPH_LABEL_METHOD_1 // Label x array index step size between labels int j1 = points / curves; if ( j1 < 1 ) { j1 = 1; } // Label x array index offset int j0 = j1 / 2; #endif double xLabel, yLabel; int idx; // Loop for each z-variable curve. for ( col = 0; col < curves; col++ ) { // Get a new color for the curve. if ( colorId >= colors ) { colorId = 0; } // Set the curve label. if ( zVar->isDiscrete() ) { int iid = (int) tableCol( col ); label = zVar->m_itemList->itemName( iid ); } else if ( zVar->isContinuous() ) { int decimals = zVar->m_displayDecimals; label.sprintf( "%1.*f", zVar->m_displayDecimals, tableCol( col ) ); // Remove all trailing zeros while ( decimals && label.endsWith( "0" ) ) { label = label.left( label.length()-1 ); decimals--; } } #ifdef GRAPH_LABEL_METHOD_1 // Determine an x-axis index for the label position. idx = ( j0 + col * j1 ) % points; xLabel = line[col]->m_x[idx]; yLabel = line[col]->m_y[idx]; #endif #ifdef GRAPH_LABEL_METHOD_2 // NEW LABEL POSITIONING METHOD STARTS HERE // Find the x position where this variable has the maximum y // clearance // Loop for each x value for this curve idx = 0; double dMax = 0; double dir = 1.; double yMin = yParms->m_axleMin; double yMax = yParms->m_axleMax; for ( int row=1; row<tableRows()-1; row++ ) { // Find vertical clearance above and below this x point double y0 = m_eqTree->getResult( row, col, yid ); // Don't consider locations outside the viewport if ( y0 < yMin || y0 > yMax ) { continue; } double below = y0 - yMin; double above = yMax - y0; double dist, y1; // Loop for each family member curve for ( int c=0; c<curves; c++ ) { // Skip self if ( c == col ) { continue; } y1 = m_eqTree->getResult( row, c, yid ); y1 = ( y1 < yMax ) ? y1 : yMax; y1 = ( y1 > yMin ) ? y1 : yMin; // Shrink vertical clearance above and below this x point? if ( y0 <= y1 ) { dist = y1 - y0; above = ( dist < above ) ? dist : above; } else { dist = y0 - y1; below = ( dist < below ) ? dist : below; } } // Is this the maximum vertical clearance so far? if ( above + below > dMax ) { dMax = above + below; idx = row; dir = ( above > below ) ? 1. : -1; } } xLabel = line[col]->m_x[idx]; double offset = dir * 0.02 * ( yMax - yMin ); yLabel = line[col]->m_y[idx] + offset; #endif // Set the label text, font, color, and position. line[col]->setGraphLineLabel( label, xLabel, yLabel, textFont, QColor( color[colorId++] ) ); } // Next curve. // Add a z-variable label to the graph. label = *(zVar->m_label); if ( zVar->isContinuous() ) { label = *(zVar->m_label) + "\n" + zVar->displayUnits(true); } g.setMultipleCurveLabel( label ); } //-------------------------------------------------------------------------- // 4: Compose the graph and add an output page to draw it onto //-------------------------------------------------------------------------- composeGraphBasics( &g, true, xVar, yVar, zVar, curves, xParms, yParms ); // Create a separate output page for this graph. QString text(""); translate( text, "BpDocument:Graphs:By" ); label = *(yVar->m_label) + " " + text + " " + *(xVar->m_label); if ( curves > 1 ) { translate( text, "BpDocument:Graphs:And" ); label += " " + text + " " + *(zVar->m_label); } startNewPage( label, TocLineGraph ); // This is how we save the graph and its composer. m_composer->graph( g, m_pageSize->m_marginLeft + m_pageSize->m_bodyWd * property()->real( "graphXOffset" ), m_pageSize->m_marginTop + m_pageSize->m_bodyHt * property()->real( "graphYOffset" ), m_pageSize->m_bodyWd * property()->real( "graphScaleWidth" ), m_pageSize->m_bodyHt * property()->real( "graphScaleHeight" ) ); // Be polite and stop the composer. m_composer->end(); delete[] color; return; }
bool BpDocument::composeGraphs( bool lineGraphs, bool showDialogs ) { // Bar graph settings int tics = 2; double max = 100.; double min = 0.; // Line graph settings if ( lineGraphs ) { tics = 11; max = tableRow( tableRows()-1 ); min = tableRow(0); } GraphAxleParms *xParms = new GraphAxleParms( min, max, tics ); checkmem( __FILE__, __LINE__, xParms, "GraphAxleParms xParms", 1 ); if ( lineGraphs && min > 0. && property()->boolean( "graphXOriginAtZero" ) ) { xParms->useOrigin(); } // Determine the x-, y-, and z-variables. EqVar *xVar = m_eqTree->m_rangeVar[0]; EqVar *zVar = m_eqTree->m_rangeVar[1]; EqVar *yVar = 0; //-------------------------------------------------------------------------- // 2: Determine nice axis parameters for the x- and all the y-variables. //-------------------------------------------------------------------------- // Initialize the Y axle for each graph to a nice range QPtrList<GraphAxleParms> *yParmsList = new QPtrList<GraphAxleParms>(); yParmsList->setAutoDelete( true ); GraphAxleParms *yParms = 0; int yid; for ( yid = 0; yid < tableVars(); yid++ ) { yVar = tableVar( yid ); yParms = 0; // The yVar must be continuous. if ( yVar->isContinuous() ) { // Get Y range if ( lineGraphs ) { graphYMinMax( yid, min, max ); } else { barYMinMax( yid, min, max ); } // Determine and store nice axis parameters tics = 11; yParms = new GraphAxleParms( min, max, tics ); checkmem( __FILE__, __LINE__, yParms, "GraphAxleParms yParms", 1 ); yParmsList->append( yParms ); // If bar graph, or line graphs must start at origin if ( min > 0. ) { if ( ! lineGraphs || property()->boolean( "graphYOriginAtZero" ) ) { yParms->useOrigin(); } } // If min and max are the same, make them different if ( min == max ) { yParms->setAxle( min-1., max+1., 3 ); } } } //-------------------------------------------------------------------------- // 1: Allow the user to change the axle parameters. //-------------------------------------------------------------------------- if ( showDialogs && property()->boolean( "graphYUserRange" ) ) { GraphLimitsDialog *dialog = new GraphLimitsDialog( this, yParmsList, "graphLimitsDialog" ); checkmem( __FILE__, __LINE__, dialog, "GraphLimitsDialog dialog", 1 ); if ( dialog->exec() == QDialog::Accepted ) { dialog->store(); } delete dialog; dialog = 0; } //-------------------------------------------------------------------------- // 3: Draw each graph. //-------------------------------------------------------------------------- // Set up the progress dialog. int step = 0; int steps = tableVars(); QString text(""), button(""); if ( lineGraphs ) { translate( text, "BpDocument:Graphs:DrawingLineGraphs" ); } else { translate( text, "BpDocument:Graphs:DrawingBarGraphs" ); } translate( button, "BpDocument:Graphs:Abort" ); QProgressDialog *progress = new QProgressDialog( QString( text ).arg( steps ), button, steps ); Q_CHECK_PTR( progress ); progress->setMinimumDuration( 0 ); progress->setProgress( 0 ); // Loop for each output variable: one graph is composed per output variable. bool result = true; for ( yid = 0, yParms = yParmsList->first(); yid < tableVars(); yid++ ) { yVar = tableVar( yid ); // The yVar must be continuous. if ( yVar->isContinuous() ) { // Recompute nice Y axis //min = ( yParms->m_axleMin < yParms->m_dataMin ) // ? yParms->m_axleMin // : yParms->m_dataMin; min = yParms->m_axleMin; //max = ( yParms->m_axleMax > yParms->m_dataMax ) // ? yParms->m_axleMax // : yParms->m_dataMax; max = yParms->m_axleMax; // If min and max are the same, make them different tics = 11; if ( min == max ) { yParms->setAxle( min-1., max+1., 3 ); } // Compose this graph. if ( lineGraphs ) { composeLineGraph( yid, xVar, yVar, zVar, xParms, yParms ); } else { composeBarGraph( yid, xVar, yVar, xParms, yParms ); } // Update progress dialog. progress->setProgress( ++step ); qApp->processEvents(); if ( progress->wasCancelled() ) { result = false; break; } yParms = yParmsList->next(); } } // Cleanup and return. delete progress; progress = 0; delete xParms; xParms = 0; delete yParmsList; yParmsList = 0; return( result ); }
void BpDocument::composeBarGraph( int yid, EqVar *xVar, EqVar *yVar, GraphAxleParms *xParms, GraphAxleParms *yParms ) { //-------------------------------------------------------------------------- // 1: Set up fonts, pens, and colors used by this graph //-------------------------------------------------------------------------- // Graph fonts. QFont textFont( property()->string( "graphTextFontFamily" ), property()->integer( "graphTextFontSize" ) ); QColor textColor( property()->color( "graphTextFontColor" ) ); QPen textPen( textColor ); // How many colors are requested? QString colorName( property()->color( "graphBarColor" ) ); int colors = 1; if ( colorName == "rainbow" ) { colors = property()->integer( "graphRainbowColors" ); } // Allocate number of requested colors. QColor *color = new QColor [colors]; checkmem( __FILE__, __LINE__, color, "QColor color", colors ); int colorId = 0; // If only 1 color... if ( colors == 1 ) { color[0].setNamedColor( colorName ); } // else if rainbow colors are requested. else { // \todo - add some code to check conflicts with graphBackgroundColor // and graphGridColor (if graphGridWidth > 0 ). int hue = 0; for ( colorId = 0; colorId < colors; colorId++ ) { color[colorId].setHsv( hue, 255, 255); hue += 360 / colors; } colorId = 0; } // Setup bar brush and color QBrush barBrush( color[colorId], Qt::SolidPattern ); //-------------------------------------------------------------------------- // 2: Create the graph and its text and axles. //-------------------------------------------------------------------------- // Initialize graph and variables Graph g; int bars = ( tableRows() < graphMaxBars ) ? tableRows() : graphMaxBars ; int vStep = tableVars(); // Draw thew basic graph (axis and text) composeGraphBasics( &g, false, xVar, yVar, 0, bars, xParms, yParms ); //-------------------------------------------------------------------------- // 3: Add the bars. //-------------------------------------------------------------------------- // Each bar occupies 2/3 of its x range, plus a 1/3 padding on right. double xMin = xParms->m_axleMin; double xMax = xParms->m_axleMax; double xMinorStep = ( xMax - xMin ) / (double) ( 3 * bars + 1 ); double xMajorStep = 3. * xMinorStep; // Create each data bar and add it to the graph. double x0, x1, y0, y1, xl; double yl = 0.; double rotation = 0.; QString label; int row, vid; for ( row = 0, vid = yid; row < bars; row++, vid += vStep ) { x0 = xMin + xMinorStep + row * xMajorStep; x1 = xMin + ( row + 1 ) * xMajorStep; y0 = yParms->m_axleMin; y1 = tableVal( vid ); xl = 0.5 * (x0 + x1) ; // If we're out of colors, start over. if ( colorId >= colors ) { colorId = 0; } // Set the bar brush to this color. barBrush.setColor( color[colorId++] ); // Create the graph bar. GraphBar *bar = g.addGraphBar( x0, y0, x1, y1, barBrush, textPen ); // Create the bar label. int iid = (int) tableRow( row ); label = xVar->m_itemList->itemName( iid ); bar->setGraphBarLabel( label, xl, yl, textFont, textColor, rotation ); } //-------------------------------------------------------------------------- // 4: Add an output page on which to draw the graph. //-------------------------------------------------------------------------- // Create a separate page for this graph. QString text(""); translate( text, "BpDocument:Graphs:By" ); label = QString( "%1 %2 %3" ) .arg( *(yVar->m_label) ) .arg( text ) .arg( *(xVar->m_label) ); startNewPage( label, TocBarGraph ); // This is how we save the graph and its composer. m_composer->graph( g, m_pageSize->m_marginLeft + m_pageSize->m_bodyWd * property()->real( "graphXOffset" ), m_pageSize->m_marginTop + m_pageSize->m_bodyHt * property()->real( "graphYOffset" ), m_pageSize->m_bodyWd * property()->real( "graphScaleWidth" ), m_pageSize->m_bodyHt * property()->real( "graphScaleHeight" ) ); // Be polite and stop the composer. m_composer->end(); delete[] color; return; }
/* Draw the window wi in the foreground and save the background. */ void wi_drawwin(struct wi_window *wi) { int titlebar, x; struct node *n; my_assert(wi != NULL); titlebar = ( ( wi->w.buttons & (wb_drag | wb_size | wb_close) ) != 0 || wi->w.title != NULL ); if (wi->w.shrunk && !titlebar) { wi->w.shrunk = 0; } wi->win_contents = ( (!wi->w.shrunk && wi->w.ysize >= shapes.titlebar_height * 2) || !titlebar ); if (wi->bg) { ws_freebitmap(wi->bg); } checkmem( wi->bg = ws_savebitmap(NULL, wi->w.xpos, wi->w.ypos, wi->w.xsize, wi->w.ysize) ); if (wi->win_contents) { ws_drawbox(w_xwinincoord(&wi->w, -1), w_ywinincoord(&wi->w, -1), w_xwininsize(&wi->w) + 2, w_ywininsize(&wi->w) + 2, notes.colindex[wi == notes.cur_win ? cv_curwin : cv_winedge], 0); ws_drawfilledbox(w_xwinincoord(&wi->w, 0), w_ywinincoord(&wi->w, 0), w_xwininsize(&wi->w), w_ywininsize( &wi->w), notes.colindex[cv_winfill], 0); } for (n = wi->buttonlist.head; n->next != NULL && n->d.w_b->sys_button; n = n->next) { wi_drawbutton(n->d.w_b, 0); } if (titlebar) { if ( !( wi->w.buttons & (wb_drag | wb_size) ) ) { if ( !( wi->w.buttons & (wb_close | wb_shrink) ) ) { ws_drawfilledbox( x = wi->w.xpos, wi->w.ypos, wi->w.xsize, shapes.titlebar_height, notes.colindex[notes.cur_win == wi ? cv_curwin : cv_buttonin], 0); } else { ws_drawfilledbox( x = wi->w.xpos + shapes.closebutton_width, wi->w.ypos, wi->w.xsize - shapes.closebutton_width, shapes.titlebar_height, notes.colindex[notes.cur_win == wi ? cv_curwin : cv_buttonin], 0); } ws_drawtext(x + 4, wi->w.ypos + 2, wi->w.xpos + wi->w.xsize - x - 6, wi->w.title, notes.colindex[cv_textbg], -1); ws_drawtext(x + 3, wi->w.ypos + 1, wi->w.xpos + wi->w.xsize - x - 6, wi->w.title, notes.colindex[cv_textfg], -1); } } wi->drawn = 1; if (wi->win_contents) { switch (wi->w.refresh) { case wr_routine: wi->w.refresh_routine(&wi->w, wi->w.data); break; case wr_normal: if (wi->in != NULL) { ws_copybitmap(NULL, w_xwinincoord(&wi->w, 0), w_ywinincoord(&wi->w, 0), wi->in, 0, 0, w_xwininsize( &wi->w) > wi->in->xsize ? wi->in->xsize : w_xwininsize(&wi->w), w_ywininsize( &wi->w) > wi->in->ysize ? wi->in->xsize : w_ywininsize(&wi->w), 1); ws_freebitmap(wi->in); wi->in = NULL; } break; default: fprintf(errf, "Unknown refresh-type in drawwin: %d\n", wi->w.refresh); } } }