/** * global_range_contained: * @sheet : The calling context #Sheet for references with sheet==NULL * @a: * @b: * * return true if a is contained in b * we do not handle 3d ranges **/ gboolean global_range_contained (Sheet const *sheet, GnmValue const *a, GnmValue const *b) { Sheet const *target; g_return_val_if_fail (a != NULL, FALSE); g_return_val_if_fail (b != NULL, FALSE); if ((a->type != VALUE_CELLRANGE) || (b->type != VALUE_CELLRANGE)) return FALSE; target = eval_sheet (a->v_range.cell.a.sheet, sheet); if (target != eval_sheet (a->v_range.cell.b.sheet, sheet)) return FALSE; if (target != eval_sheet (b->v_range.cell.a.sheet, sheet) || target != eval_sheet (b->v_range.cell.b.sheet, sheet)) return FALSE; if (a->v_range.cell.a.row < b->v_range.cell.a.row) return FALSE; if (a->v_range.cell.b.row > b->v_range.cell.b.row) return FALSE; if (a->v_range.cell.a.col < b->v_range.cell.a.col) return FALSE; if (a->v_range.cell.b.col > b->v_range.cell.b.col) return FALSE; return TRUE; }
static void cb_check_name (G_GNUC_UNUSED gpointer key, GnmNamedExpr *nexpr, CheckName *user) { GnmValue *v; if (nexpr->scope == NULL || nexpr->is_hidden || !nexpr->texpr) return; v = gnm_expr_top_get_range (nexpr->texpr); if (v != NULL) { if (v->type == VALUE_CELLRANGE) { GnmRangeRef const *ref = &v->v_range.cell; if (!ref->a.col_relative && !ref->b.col_relative && !ref->a.row_relative && !ref->b.row_relative && eval_sheet (ref->a.sheet, user->sheet) == user->sheet && eval_sheet (ref->b.sheet, user->sheet) == user->sheet && MIN (ref->a.col, ref->b.col) == user->r->start.col && MAX (ref->a.col, ref->b.col) == user->r->end.col && MIN (ref->a.row, ref->b.row) == user->r->start.row && MAX (ref->a.row, ref->b.row) == user->r->end.row) user->res = nexpr; } value_release (v); } }
/** * gnm_scenario_apply: * @sc: #GnmScenario * * Returns: (transfer full): the newly allocated #GOUndo. **/ GOUndo * gnm_scenario_apply (GnmScenario *sc) { GOUndo *undo = NULL; GSList *l; g_return_val_if_fail (GNM_IS_SCENARIO (sc), NULL); for (l = sc->items; l; l = l->next) { GnmScenarioItem *sci = l->data; GnmValue const *val = sci->value; GnmSheetRange sr; Sheet *sheet; if (!gnm_scenario_item_valid (sci, &sr)) continue; sheet = eval_sheet (sr.sheet, sc->sheet); if (val) { /* FIXME: think about arrays. */ GnmCell *cell = sheet_cell_fetch (sheet, sr.range.start.col, sr.range.start.row); sheet_cell_set_value (cell, value_dup (val)); } else { GOUndo *u = clipboard_copy_range_undo (sheet, &sr.range); /* FIXME: Clear the range. */ undo = go_undo_combine (undo, u); } } return undo; }
/* * Finds a column index of a field. */ int find_column_of_field (GnmEvalPos const *ep, GnmValue const *database, GnmValue const *field) { Sheet *sheet; GnmCell *cell; gchar *field_name; int begin_col, end_col, row, n, column; int offset; // I'm not certain we should demand this, but the code clearly wants // it. if (!VALUE_IS_CELLRANGE (database)) return -1; offset = database->v_range.cell.a.col; if (VALUE_IS_FLOAT (field)) return value_get_as_int (field) + offset - 1; if (!VALUE_IS_STRING (field)) return -1; sheet = eval_sheet (database->v_range.cell.a.sheet, ep->sheet); field_name = value_get_as_string (field); column = -1; /* find the column that is labeled after `field_name' */ begin_col = database->v_range.cell.a.col; end_col = database->v_range.cell.b.col; row = database->v_range.cell.a.row; for (n = begin_col; n <= end_col; n++) { char const *txt; gboolean match; cell = sheet_cell_get (sheet, n, row); if (cell == NULL) continue; gnm_cell_eval (cell); txt = cell->value ? value_peek_string (cell->value) : ""; match = (g_ascii_strcasecmp (field_name, txt) == 0); if (match) { column = n; break; } } g_free (field_name); return column; }
/** * parse_database_criteria: * @ep: #GnmEvalPos * @database: #GnmValue * @criteria: #GnmValue * * Parses the criteria cell range. * Returns: (element-type GnmDBCriteria) (transfer full): */ GSList * parse_database_criteria (GnmEvalPos const *ep, GnmValue const *database, GnmValue const *criteria) { Sheet *sheet; GnmCell *cell; int i; int b_col, b_row, e_col, e_row; int *field_ind; g_return_val_if_fail (VALUE_IS_CELLRANGE (criteria), NULL); sheet = eval_sheet (criteria->v_range.cell.a.sheet, ep->sheet); b_col = criteria->v_range.cell.a.col; b_row = criteria->v_range.cell.a.row; e_col = criteria->v_range.cell.b.col; e_row = criteria->v_range.cell.b.row; if (e_col < b_col) { int tmp = b_col; b_col = e_col; e_col = tmp; } /* Find the index numbers for the columns of criterias */ field_ind = g_alloca (sizeof (int) * (e_col - b_col + 1)); for (i = b_col; i <= e_col; i++) { cell = sheet_cell_get (sheet, i, b_row); if (cell == NULL) continue; gnm_cell_eval (cell); if (gnm_cell_is_empty (cell)) continue; field_ind[i - b_col] = find_column_of_field (ep, database, cell->value); if (field_ind[i - b_col] == -1) return NULL; } return parse_criteria_range (sheet, b_col, b_row + 1, e_col, e_row, field_ind, FALSE); }
void gnm_scenario_add_area (GnmScenario *sc, const GnmSheetRange *sr) { GnmScenarioItem *sci; struct cb_save_cells data; g_return_if_fail (GNM_IS_SCENARIO (sc)); g_return_if_fail (sr != NULL); sci = gnm_scenario_item_new (sc->sheet); gnm_scenario_item_set_range (sci, sr); sc->items = g_slist_prepend (sc->items, sci); data.items = NULL; data.sc = sc; sheet_foreach_cell_in_range (eval_sheet (sr->sheet, sc->sheet), CELL_ITER_IGNORE_NONEXISTENT, sr->range.start.col, sr->range.start.row, sr->range.end.col, sr->range.end.row, cb_save_cells, &data); sc->items = g_slist_concat (sc->items, g_slist_reverse (data.items)); }
/** * value_area_get_x_y: * @v: const #GnmValue * * @x: column * @y: row * @ep: const #GnmEvalPos * * * An internal routine to get a cell from an array or range. * Ensures that elements of CELLRANGE are evaluated * * If any problems occur a NULL is returned. **/ GnmValue const * value_area_get_x_y (GnmValue const *v, int x, int y, GnmEvalPos const *ep) { g_return_val_if_fail (v, NULL); if (VALUE_IS_ARRAY (v)){ g_return_val_if_fail (x < v->v_array.x && y < v->v_array.y, NULL); return v->v_array.vals [x][y]; } else if (VALUE_IS_CELLRANGE (v)) { GnmCellRef const * const a = &v->v_range.cell.a; GnmCellRef const * const b = &v->v_range.cell.b; int a_col = a->col; int a_row = a->row; int b_col = b->col; int b_row = b->row; GnmCell *cell; Sheet *sheet; /* Handle relative references */ if (a->col_relative) a_col += ep->eval.col; if (a->row_relative) a_row += ep->eval.row; if (b->col_relative) b_col += ep->eval.col; if (b->row_relative) b_row += ep->eval.row; /* Handle inverted references */ if (a_row > b_row) { int tmp = a_row; a_row = b_row; b_row = tmp; } if (a_col > b_col) { int tmp = a_col; a_col = b_col; b_col = tmp; } a_col += x; a_row += y; /* * FIXME FIXME FIXME * This should return NA but some of the math functions may * rely on this for now. */ g_return_val_if_fail (a_row<=b_row, NULL); g_return_val_if_fail (a_col<=b_col, NULL); sheet = eval_sheet (a->sheet, ep->sheet); g_return_val_if_fail (IS_SHEET (sheet), NULL); /* Speedup */ if (sheet->cols.max_used < a_col || sheet->rows.max_used < a_row) return value_new_empty (); cell = sheet_cell_get (sheet, a_col, a_row); if (cell != NULL) { gnm_cell_eval (cell); return cell->value; } return value_new_empty (); } else return v; return NULL; }
void Patch::draw(SkCanvas* canvas, const SkPaint& paint, int nu, int nv, bool doTextures, bool doColors) { if (nu < 1 || nv < 1) { return; } int i, npts = (nu + nv) * 2; SkAutoSTMalloc<16, SkPoint> storage(npts + 1); SkPoint* edge0 = storage.get(); SkPoint* edge1 = edge0 + nu; SkPoint* edge2 = edge1 + nv; SkPoint* edge3 = edge2 + nu; // evaluate the edge points eval_patch_edge(fPts + 0, edge0, nu); eval_patch_edge(fPts + 3, edge1, nv); eval_patch_edge(fPts + 6, edge2, nu); eval_patch_edge(fPts + 9, edge3, nv); edge3[nv] = edge0[0]; // the last shall be first for (i = 0; i < npts; i++) { // canvas->drawLine(edge0[i].fX, edge0[i].fY, edge0[i+1].fX, edge0[i+1].fY, paint); } int row, vertCount = (nu + 1) * (nv + 1); SkAutoTMalloc<SkPoint> vertStorage(vertCount); SkPoint* verts = vertStorage.get(); // first row memcpy(verts, edge0, (nu + 1) * sizeof(SkPoint)); // rows SkPoint* r = verts; for (row = 1; row < nv; row++) { r += nu + 1; r[0] = edge3[nv - row]; for (int col = 1; col < nu; col++) { eval_sheet(edge0, nu, nv, col, row, &r[col]); } r[nu] = edge1[row]; } // last row SkPoint* last = verts + nv * (nu + 1); for (i = 0; i <= nu; i++) { last[i] = edge2[nu - i]; } // canvas->drawPoints(verts, vertCount, paint); int stripCount = (nu + 1) * 2; SkAutoTMalloc<SkPoint> stripStorage(stripCount * 2); SkAutoTMalloc<SkColor> colorStorage(stripCount); SkPoint* strip = stripStorage.get(); SkPoint* tex = strip + stripCount; SkColor* colors = colorStorage.get(); SkScalar t = 0; const SkScalar ds = SK_Scalar1 * fW / nu; const SkScalar dt = SK_Scalar1 * fH / nv; r = verts; for (row = 0; row < nv; row++) { SkPoint* upper = r; SkPoint* lower = r + nu + 1; r = lower; SkScalar s = 0; for (i = 0; i <= nu; i++) { strip[i*2 + 0] = *upper++; strip[i*2 + 1] = *lower++; tex[i*2 + 0].set(s, t); tex[i*2 + 1].set(s, t + dt); colors[i*2 + 0] = make_color(s/fW, t/fH); colors[i*2 + 1] = make_color(s/fW, (t + dt)/fH); s += ds; } t += dt; canvas->drawVertices(SkCanvas::kTriangleStrip_VertexMode, stripCount, strip, doTextures ? tex : nullptr, doColors ? colors : nullptr, nullptr, nullptr, 0, paint); } }