// Create and return a new layer instance. simplet_layer_t* simplet_layer_new(const char *datastring){ simplet_layer_t *layer; if(!(layer = malloc(sizeof(*layer)))) return NULL; memset(layer, 0, sizeof(*layer)); layer->source = simplet_copy_string(datastring); layer->error.status = SIMPLET_OK; if(!(layer->filters = simplet_list_new())){ free(layer); return NULL; } return layer; }
// Create and return a new layer instance. simplet_layer_t* simplet_layer_new(const char *datastring){ simplet_layer_t *layer; if(!(layer = malloc(sizeof(*layer)))) return NULL; memset(layer, 0, sizeof(*layer)); layer->source = simplet_copy_string(datastring); layer->status = SIMPLET_OK; if(!(layer->queries = simplet_list_new())){ free(layer); return NULL; } simplet_retain((simplet_retainable_t *)layer); return layer; }
// Create and add a placement to the current lithograph if it doesn't overlap // with current labels. void simplet_lithograph_add_placement(simplet_lithograph_t *litho, OGRFeatureH feature, simplet_list_t *styles, cairo_t *proj_ctx) { simplet_style_t *field = simplet_lookup_style(styles, "text-field"); if(!field) return; OGRFeatureDefnH defn; if(!(defn = OGR_F_GetDefnRef(feature))) return; int idx = OGR_FD_GetFieldIndex(defn, (const char*) field->arg); if(idx < 0) return; // Find the largest sub geometry of a particular multi-geometry. OGRGeometryH super = OGR_F_GetGeometryRef(feature); OGRGeometryH geom = super; double area = 0.0; switch(wkbFlatten(OGR_G_GetGeometryType(super))) { case wkbMultiPolygon: case wkbGeometryCollection: for(int i = 0; i < OGR_G_GetGeometryCount(super); i++) { OGRGeometryH subgeom = OGR_G_GetGeometryRef(super, i); if(subgeom == NULL) continue; double ar = OGR_G_Area(subgeom); if(ar > area) { geom = subgeom; area = ar; } } break; default: ; } // Find the center of our geometry. This sometimes throws an invalid geometry // error, so there is a slight bug here somehow. OGRGeometryH center; if(!(center = OGR_G_CreateGeometry(wkbPoint))) return; if(OGR_G_Centroid(geom, center) == OGRERR_FAILURE) { OGR_G_DestroyGeometry(center); return; } // Turn font hinting off cairo_font_options_t *opts; if(!(opts = cairo_font_options_create())){ OGR_G_DestroyGeometry(center); return; } cairo_font_options_set_hint_style(opts, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics(opts, CAIRO_HINT_METRICS_OFF); pango_cairo_context_set_font_options(litho->pango_ctx, opts); cairo_font_options_destroy(opts); // Get the field containing the text for the label. char *txt = simplet_copy_string(OGR_F_GetFieldAsString(feature, idx)); PangoLayout *layout = pango_layout_new(litho->pango_ctx); pango_layout_set_text(layout, txt, -1); free(txt); // Grab the font to use and apply tracking. simplet_style_t *font = simplet_lookup_style(styles, "font"); simplet_apply_styles(layout, styles, "letter-spacing", NULL); const char *font_family; if(!font) font_family = "helvetica 12px"; else font_family = font->arg; PangoFontDescription *desc = pango_font_description_from_string(font_family); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); double x = OGR_G_GetX(center, 0), y = OGR_G_GetY(center, 0); cairo_user_to_device(proj_ctx, &x, &y); // Finally try the placement and test for overlaps. try_and_insert_placement(litho, layout, x, y); OGR_G_DestroyGeometry(center); }
// Set a copy of this source as this layers datasource string. void simplet_layer_set_source(simplet_layer_t *layer, char *source){ char *src = simplet_copy_string(source); if(!src) set_error(layer, SIMPLET_OOM, "out of memory setting source"); layer->source = src; }
// Get the datasource string for this layer. void simplet_layer_get_source(simplet_layer_t *layer, char **source){ *source = simplet_copy_string(layer->source); }