Hello gerbv developers,

I have implemented a feature which sorts the opened files by guessing the layer from the filename/file extension.

We have had a discussion in the past about extracting the layer info from the Gerber X2 attributes, but this patch does not handle it. Once the attribute parsing got implemented it will be pretty straightforward to implement the sorting.

Please review (and merge if meet the expectations) or let me know if I need to do more adjustments!

--
Best regards,
Miklos Marton

diff --git a/src/gerbv.c b/src/gerbv.c
index ce86b38..97735d9 100644
--- a/src/gerbv.c
+++ b/src/gerbv.c
@@ -168,6 +168,205 @@ static gerbv_user_transformation_t defaultTransformations[NUMBER_OF_DEFAULT_TRAN
 	{0,0,1,1,0,FALSE,FALSE,FALSE},
 };
 
+/* ------------------------------------------------------------------
+ * Phisycal layer - filename pattern lookup.
+ * Starts (*) matching any characters
+ * ------------------------------------------------------------------ */
+static const struct gerbv_layer_lookup_item_t layerIndexLookup[] = {
+	{
+		LAYER_TOP_COOPER,
+		(const char * const []){
+			"*.gtl",
+			"*copper_top*",
+			"*.cmp",
+			"*.top",
+			"*F_Cu.*",
+			"gtl.*",
+			"*-a.*",
+			NULL
+		}
+	},
+	{
+		LAYER_BOTTOM_COOPER,
+		(const char * const []){
+			"*.gbl",
+			"*copper_bottom*",
+			"*.sol",
+			"*.bot",
+			"*B_Cu.*",
+			"gbl.*",
+			"*-f.*",
+			NULL
+		}
+	},
+	{
+		LAYER_TOP_SOLDERMASK,
+		(const char * const []){
+			"*.gts",
+			"*soldermask_top*",
+			"*.stc",
+			"*.smt",
+			"*_smc.*",
+			"*.smc",
+			"*F_Mask.*",
+			"gts.*",
+			"SMask_Top.*",
+			"*-am.*",
+			"*.tmk",
+			NULL
+		}
+	},
+	{
+		LAYER_BOTTOM_SOLDERMASK,
+		(const char * const []){
+			"*.gbs",
+			"*soldermask_bottom*",
+			"*.sts",
+			"*.smb",
+			"*_sms.*",
+			"*.sms",
+			"*B_Mask.*",
+			"gbs.*",
+			"SMask_Bot.*",
+			"*-fm.*",
+			"*.bmk",
+			NULL
+		}
+	},
+	{
+		LAYER_TOP_PASTE,
+		(const char * const []){
+			"*.gtp",
+			"*solderpaste_top*",
+			"*_spc.*",
+			"*F_Paste.*",
+			"*-ap.*",
+			"*.tpa",
+			"*.crc",
+			NULL
+		}
+	},
+	{
+		LAYER_BOTTOM_PASTE,
+		(const char * const []){
+			"*solderpaste_bottom*",
+			"*_sps.*",
+			"*B_Paste.*",
+			"*-fp.*",
+			"*.bpa",
+			"*.crs",
+			NULL
+		}
+	},
+	{
+		LAYER_TOP_SILKSCREEN,
+		(const char * const []){
+			"*.gto",
+			"*silkscreen_top*",
+			"*.ptc",
+			"*.sst",
+			"*_tslk.*",
+			"*F_SilkS.*",
+			"gto.*",
+			"Silk_Top.*",
+			"*-as.*",
+			"*.tsk",
+			"*.plc",
+			"*.ssc",
+			NULL
+		}
+	},
+	{
+		LAYER_BOTTOM_SILKSCREEN,
+		(const char * const []){
+			"*.gbo",
+			"*silkscreen_bottom*",
+			"*.pls",
+			"*.ssb",
+			"*_bslk.*",
+			"*B_SilkS.*",
+			"gbo.*",
+			"Silk_Bot.*",
+			"*-fs.*",
+			"*.bsk",
+			NULL
+		}
+	},
+	{
+		LAYER_DRILLS,
+		(const char * const []){
+			"*.drl",
+			"drill.xln",
+			"*.drd",
+			"Throuhole.tap",
+			"*.txt",
+			"*.ncd",
+			"*.hol",
+			NULL
+		}
+	},
+	{
+		LAYER_OUTLINE,
+		(const char * const []){
+			"*.txt",
+			"*.rou",
+			"*.gml",
+			"Profile.gbr",
+			"NC_Drill.drl",
+			"drl.*",
+			"rout.*",
+			"*-mech.*",
+			"*.brd",
+			NULL
+		}
+	},
+	{
+		LAYER_UNKNOWN,
+		(const char * const []){
+			NULL
+		}
+	}
+};
+
+void
+g_string_replace(GString *g_origString, char *stringToReplace, char *replaceWith, GString *g_output)
+{
+	char *found = NULL;
+	char *copy = NULL;
+	char * p = NULL;
+
+	copy = malloc(g_origString->len + 1);
+	copy = strcpy(copy, g_origString->str);
+	p = copy;
+
+	if (strlen(replaceWith) > 0)
+	{
+		found = strstr(copy, stringToReplace);
+		if (found != NULL)
+		{
+			if((found-copy) > 0){
+				g_string_overwrite_len(g_output, 0, copy, found-copy);
+				g_string_truncate(g_output, found-copy);
+				p += (found - copy);
+			}
+			else{
+				g_string_assign(g_output, "");
+			}
+			g_string_append(g_output, replaceWith);
+			g_string_append(g_output, p + strlen(stringToReplace));
+		}
+		else
+		{
+			g_string_assign(g_output, g_origString->str);
+		}
+	}
+	else
+	{
+		g_string_assign(g_output, g_origString->str);
+	}
+	free(copy);
+}
+
 /* ------------------------------------------------------------------ */
 gerbv_project_t *
 gerbv_create_project (void) {
@@ -224,18 +423,15 @@ gerbv_destroy_fileinfo (gerbv_fileinfo_t *fileInfo){
 void 
 gerbv_open_layer_from_filename(gerbv_project_t *gerbvProject, gchar *filename) 
 {
-  gint idx_loaded;
-  dprintf("Opening filename = %s\n", (gchar *) filename);
-  
-  if (gerbv_open_image(gerbvProject, filename, ++gerbvProject->last_loaded, FALSE, NULL, 0, TRUE) == -1) {
-    GERB_COMPILE_WARNING(_("Could not read \"%s\" (loaded %d)"),
-		    (gchar *) filename, gerbvProject->last_loaded);
-    gerbvProject->last_loaded--;
-  } else {
-    idx_loaded = gerbvProject->last_loaded;
-    gerbvProject->file[idx_loaded]->layer_dirty = FALSE;
-    dprintf("     Successfully opened file!\n");	
-  }
+	dprintf("Opening filename = %s\n", (gchar *) filename);
+
+	if (gerbv_open_image(gerbvProject, filename, ++gerbvProject->last_loaded, FALSE, NULL, 0, TRUE, TRUE) == -1) {
+		GERB_COMPILE_WARNING(_("Could not read \"%s\" (loaded %d)"),
+							 (gchar *) filename, gerbvProject->last_loaded);
+		gerbvProject->last_loaded--;
+	} else {
+		dprintf("     Successfully opened file!\n");
+	}
 } /* gerbv_open_layer_from_filename */
 
 /* ------------------------------------------------------------------ */
@@ -246,7 +442,7 @@ gerbv_open_layer_from_filename_with_color(gerbv_project_t *gerbvProject, gchar *
   gint idx_loaded;
   dprintf("Opening filename = %s\n", (gchar *) filename);
   
-  if (gerbv_open_image(gerbvProject, filename, ++gerbvProject->last_loaded, FALSE, NULL, 0, TRUE) == -1) {
+  if (gerbv_open_image(gerbvProject, filename, ++gerbvProject->last_loaded, FALSE, NULL, 0, TRUE, FALSE) == -1) {
     GERB_COMPILE_WARNING(_("Could not read \"%s\" (loaded %d)"),
 		    (gchar *) filename, gerbvProject->last_loaded);
     gerbvProject->last_loaded--;
@@ -317,7 +513,7 @@ int
 gerbv_revert_file(gerbv_project_t *gerbvProject, int idx){
   int rv;
   
-  rv = gerbv_open_image(gerbvProject, gerbvProject->file[idx]->fullPathname, idx, TRUE, NULL, 0, TRUE);
+  rv = gerbv_open_image(gerbvProject, gerbvProject->file[idx]->fullPathname, idx, TRUE, NULL, 0, TRUE, FALSE);
   gerbvProject->file[idx]->layer_dirty = FALSE;
   return rv;
 }
@@ -462,157 +658,172 @@ gerbv_add_parsed_image_to_project (gerbv_project_t *gerbvProject, gerbv_image_t
 /* ------------------------------------------------------------------ */
 int
 gerbv_open_image(gerbv_project_t *gerbvProject, char *filename, int idx, int reload,
-		gerbv_HID_Attribute *fattr, int n_fattr, gboolean forceLoadFile)
+		gerbv_HID_Attribute *fattr, int n_fattr, gboolean forceLoadFile, gboolean orderByFileName)
 {
-    gerb_file_t *fd;
-    gerbv_image_t *parsed_image = NULL, *parsed_image2 = NULL;
-    gint retv = -1;
-    gboolean isPnpFile = FALSE, foundBinary;
-    gerbv_HID_Attribute *attr_list = NULL;
-    int n_attr = 0;
-    /* If we're reloading, we'll pass in our file format attribute list
-     * since this is our hook for letting the user override the fileformat.
-     */
-    if (reload)
+	gerb_file_t *fd;
+	gerbv_image_t *parsed_image = NULL, *parsed_image2 = NULL;
+	gint retv = -1;
+	gboolean isPnpFile = FALSE, foundBinary;
+	gerbv_HID_Attribute *attr_list = NULL;
+	int n_attr = 0;
+	/* If we're reloading, we'll pass in our file format attribute list
+	 * since this is our hook for letting the user override the fileformat.
+	 */
+	if (reload)
 	{
-	    /* We're reloading so use the attribute list in memory */
-	    attr_list =  gerbvProject->file[idx]->image->info->attr_list;
-	    n_attr =  gerbvProject->file[idx]->image->info->n_attr;
+		/* We're reloading so use the attribute list in memory */
+		attr_list =  gerbvProject->file[idx]->image->info->attr_list;
+		n_attr =  gerbvProject->file[idx]->image->info->n_attr;
 	}
-    else
+	else
 	{
-	    /* We're not reloading so use the attribute list read from the 
-	     * project file if given or NULL otherwise.
-	     */
-	    attr_list = fattr;
-	    n_attr = n_fattr;
+		/* We're not reloading so use the attribute list read from the
+		 * project file if given or NULL otherwise.
+		 */
+		attr_list = fattr;
+		n_attr = n_fattr;
+	}
+	/* if we don't have enough spots, then grow the file list by 2 to account for the possible
+	   loading of two images for PNP files */
+	if ((idx+1) >= gerbvProject->max_files) {
+		gerbvProject->file = g_renew (gerbv_fileinfo_t *,
+									  gerbvProject->file, gerbvProject->max_files + 2);
+
+		gerbvProject->file[gerbvProject->max_files] = NULL;
+		gerbvProject->file[gerbvProject->max_files+1] = NULL;
+		gerbvProject->max_files += 2;
 	}
-    /* if we don't have enough spots, then grow the file list by 2 to account for the possible 
-       loading of two images for PNP files */
-    if ((idx+1) >= gerbvProject->max_files) {
-	gerbvProject->file = g_renew (gerbv_fileinfo_t *,
-			gerbvProject->file, gerbvProject->max_files + 2);
-
-	gerbvProject->file[gerbvProject->max_files] = NULL;
-	gerbvProject->file[gerbvProject->max_files+1] = NULL;
-	gerbvProject->max_files += 2;
-    }
-    
-    dprintf("In open_image, about to try opening filename = %s\n", filename);
-    
-    fd = gerb_fopen(filename);
-    if (fd == NULL) {
-	GERB_COMPILE_ERROR(_("Trying to open \"%s\": %s"),
-			filename, strerror(errno));
-	return -1;
-    }
 
-    /* Store filename info fd for further use */
-    fd->filename = g_strdup(filename);
-    
-    dprintf("In open_image, successfully opened file.  Now check its type....\n");
-    /* Here's where we decide what file type we have */
-    /* Note: if the file has some invalid characters in it but still appears to
-       be a valid file, we check with the user if he wants to continue (only
-       if user opens the layer from the menu...if from the command line, we go
-       ahead and try to load it anyways) */
-
-    if (gerber_is_rs274x_p(fd, &foundBinary)) {
-	dprintf("Found RS-274X file\n");
-	if (!foundBinary || forceLoadFile) {
-		/* figure out the directory path in case parse_gerb needs to
-		 * load any include files */
-		gchar *currentLoadDirectory = g_path_get_dirname (filename);
-		parsed_image = parse_gerb(fd, currentLoadDirectory);
-		g_free (currentLoadDirectory);
+	dprintf("In open_image, about to try opening filename = %s\n", filename);
+
+	fd = gerb_fopen(filename);
+	if (fd == NULL) {
+		GERB_COMPILE_ERROR(_("Trying to open \"%s\": %s"),
+						   filename, strerror(errno));
+		return -1;
 	}
-    } else if(drill_file_p(fd, &foundBinary)) {
-	dprintf("Found drill file\n");
-	if (!foundBinary || forceLoadFile)
-	    parsed_image = parse_drillfile(fd, attr_list, n_attr, reload);
-	
-    } else if (pick_and_place_check_file_type(fd, &foundBinary)) {
-	dprintf("Found pick-n-place file\n");
-	if (!foundBinary || forceLoadFile) {
-		if (!reload) {
-			pick_and_place_parse_file_to_images(fd, &parsed_image, &parsed_image2);
-		} else {
-			switch (gerbvProject->file[idx]->image->layertype) {
-			case GERBV_LAYERTYPE_PICKANDPLACE_TOP:
-				/* Non NULL pointer is used as "not to reload" mark */
-				parsed_image2 = (void *)!NULL;
+
+	/* Store filename info fd for further use */
+	fd->filename = g_strdup(filename);
+
+	dprintf("In open_image, successfully opened file.  Now check its type....\n");
+	/* Here's where we decide what file type we have */
+	/* Note: if the file has some invalid characters in it but still appears to
+	   be a valid file, we check with the user if he wants to continue (only
+	   if user opens the layer from the menu...if from the command line, we go
+	   ahead and try to load it anyways) */
+
+	physical_layer_t layer = gerbv_guess_layer_from_filename(filename);
+	printf("Guessed layer = %d %s\n", (int) layer, gerbv_layer_name_from_layer_index(layer));
+
+	if (gerber_is_rs274x_p(fd, &foundBinary)) {
+		dprintf("Found RS-274X file\n");
+		if (!foundBinary || forceLoadFile) {
+			/* figure out the directory path in case parse_gerb needs to
+			 * load any include files */
+			gchar *currentLoadDirectory = g_path_get_dirname (filename);
+			parsed_image = parse_gerb(fd, currentLoadDirectory);
+			g_free (currentLoadDirectory);
+		}
+	} else if(drill_file_p(fd, &foundBinary)) {
+		dprintf("Found drill file\n");
+		if (!foundBinary || forceLoadFile)
+			parsed_image = parse_drillfile(fd, attr_list, n_attr, reload);
+		layer = LAYER_DRILLS;
+	} else if (pick_and_place_check_file_type(fd, &foundBinary)) {
+		dprintf("Found pick-n-place file\n");
+		if (!foundBinary || forceLoadFile) {
+			if (!reload) {
 				pick_and_place_parse_file_to_images(fd, &parsed_image, &parsed_image2);
-				parsed_image2 = NULL;
-				break;
-			case GERBV_LAYERTYPE_PICKANDPLACE_BOT:
-				/* Non NULL pointer is used as "not to reload" mark */
-				parsed_image2 = (void *)!NULL;
-				pick_and_place_parse_file_to_images(fd, &parsed_image2, &parsed_image);
-				parsed_image2 = NULL;
-				break;
-			default:
-				GERB_COMPILE_ERROR(_("%s: unknown pick-and-place board side to reload"), filename);
+			} else {
+				switch (gerbvProject->file[idx]->image->layertype) {
+				case GERBV_LAYERTYPE_PICKANDPLACE_TOP:
+					layer = LAYER_PNP_TOP;
+					/* Non NULL pointer is used as "not to reload" mark */
+					parsed_image2 = (void *)!NULL;
+					pick_and_place_parse_file_to_images(fd, &parsed_image, &parsed_image2);
+					parsed_image2 = NULL;
+					break;
+				case GERBV_LAYERTYPE_PICKANDPLACE_BOT:
+					layer = LAYER_PNP_BOTTOM;
+					/* Non NULL pointer is used as "not to reload" mark */
+					parsed_image2 = (void *)!NULL;
+					pick_and_place_parse_file_to_images(fd, &parsed_image2, &parsed_image);
+					parsed_image2 = NULL;
+					break;
+				default:
+					GERB_COMPILE_ERROR(_("%s: unknown pick-and-place board side to reload"), filename);
+				}
 			}
+
+			isPnpFile = TRUE;
 		}
-			
-		isPnpFile = TRUE;
+	} else if (gerber_is_rs274d_p(fd)) {
+		gchar *str = g_strdup_printf(_("Most likely found a RS-274D file "
+									   "\"%s\" ... trying to open anyways\n"), filename);
+		dprintf(str);
+		g_warning(str);
+		g_free (str);
+
+		if (!foundBinary || forceLoadFile) {
+			/* figure out the directory path in case parse_gerb needs to
+			 * load any include files */
+			gchar *currentLoadDirectory = g_path_get_dirname (filename);
+			parsed_image = parse_gerb(fd, currentLoadDirectory);
+			g_free (currentLoadDirectory);
+		}
+	} else {
+		layer = LAYER_UNKNOWN;
+		/* This is not a known file */
+		dprintf("Unknown filetype");
+		GERB_COMPILE_ERROR(_("%s: Unknown file type."), filename);
+		parsed_image = NULL;
 	}
-    } else if (gerber_is_rs274d_p(fd)) {
-	gchar *str = g_strdup_printf(_("Most likely found a RS-274D file "
-			"\"%s\" ... trying to open anyways\n"), filename);
-	dprintf(str);
-	g_warning(str);
-	g_free (str);
-
-	if (!foundBinary || forceLoadFile) {
-		/* figure out the directory path in case parse_gerb needs to
-		 * load any include files */
-		gchar *currentLoadDirectory = g_path_get_dirname (filename);
-		parsed_image = parse_gerb(fd, currentLoadDirectory);
-		g_free (currentLoadDirectory);
+
+	g_free(fd->filename);
+	gerb_fclose(fd);
+	if (parsed_image == NULL) {
+		return -1;
 	}
-    } else {
-	/* This is not a known file */
-	dprintf("Unknown filetype");
-	GERB_COMPILE_ERROR(_("%s: Unknown file type."), filename);
-	parsed_image = NULL;
-    }
-    
-    g_free(fd->filename);
-    gerb_fclose(fd);
-    if (parsed_image == NULL) {
-	return -1;
-    }
-    
-    if (parsed_image) {
-	/* strip the filename to the base */
-	gchar *baseName = g_path_get_basename (filename);
-	gchar *displayedName;
-	if (isPnpFile)
-		displayedName = g_strconcat (baseName, _(" (top)"), NULL);
-	else
-		displayedName = g_strdup (baseName);
-    	retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image, filename, displayedName, idx, reload);
-    	g_free (baseName);
-    	g_free (displayedName);
-    }
 
-    /* Set layer_dirty flag to FALSE */
-    gerbvProject->file[idx]->layer_dirty = FALSE;
-
-    /* for PNP place files, we may need to add a second image for the other
-       board side */
-    if (parsed_image2) {
-      /* strip the filename to the base */
-	gchar *baseName = g_path_get_basename (filename);
-	gchar *displayedName;
-	displayedName = g_strconcat (baseName, _(" (bottom)"), NULL);
-    	retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image2, filename, displayedName, idx + 1, reload);
-    	g_free (baseName);
-    	g_free (displayedName);
-    }
+	if (parsed_image) {
+		/* strip the filename to the base */
+		gchar *baseName = g_path_get_basename (filename);
+		gchar *displayedName;
+		if (isPnpFile)
+			displayedName = g_strconcat (baseName, _(" (top)"), NULL);
+		else
+			displayedName = g_strdup (baseName);
+		retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image, filename, displayedName, idx, reload);
+		gerbvProject->file[idx]->layer_index = layer;
+		g_free (baseName);
+		g_free (displayedName);
+	}
 
-    return retv;
+	/* Set layer_dirty flag to FALSE */
+	gerbvProject->file[idx]->layer_dirty = FALSE;
+	/* for PNP place files, we may need to add a second image for the other
+	   board side */
+	if (parsed_image2) {
+		/* strip the filename to the base */
+		gchar *baseName = g_path_get_basename (filename);
+		gchar *displayedName;
+		displayedName = g_strconcat (baseName, _(" (bottom)"), NULL);
+		retv = gerbv_add_parsed_image_to_project (gerbvProject, parsed_image2, filename, displayedName, idx + 1, reload);
+		gerbvProject->file[idx + 1]->layer_index = LAYER_PNP_BOTTOM;
+		gerbvProject->file[idx + 1]->layer_dirty = FALSE;
+		g_free (baseName);
+		g_free (displayedName);
+	}
+
+	if (orderByFileName) {
+		qsort(gerbvProject->file,
+			  gerbvProject->max_files,
+			  sizeof(gerbv_fileinfo_t *),
+			  gerbv_compare_image_layer_index);
+	}
+
+	return retv;
 } /* open_image */
 
 gerbv_image_t *
@@ -1114,3 +1325,77 @@ gerbv_transform_coord_for_image(double *x, double *y,
 	return 0;
 }
 
+
+physical_layer_t
+gerbv_guess_layer_from_filename(gchar *filename)
+{
+	physical_layer_t ret = LAYER_UNKNOWN;
+	int lookupIndex = 0;
+	while (layerIndexLookup[lookupIndex].layerIndex != LAYER_UNKNOWN) {
+		int patternIndex = 0;
+		while (layerIndexLookup[lookupIndex].fileNamePatterns[patternIndex] != NULL) {
+			GError *err = NULL;
+			GMatchInfo *matchInfo;
+			GString *origPattern = g_string_new(layerIndexLookup[lookupIndex].fileNamePatterns[patternIndex]);
+			GString *regexpPattern = g_string_new("");
+			g_string_replace(origPattern, ".", "\\.", regexpPattern);
+			g_string_replace(origPattern, "*", ".*", regexpPattern);
+			GRegex *regex = g_regex_new (regexpPattern->str, G_REGEX_CASELESS, 0, &err);
+			// check for compilation errors here!
+			g_regex_match (regex, filename, 0, &matchInfo);
+			if (g_match_info_matches (matchInfo)) {
+				ret = layerIndexLookup[lookupIndex].layerIndex;
+				break;
+			}
+			g_string_free(origPattern, TRUE);
+			g_string_free(regexpPattern, TRUE);
+			patternIndex++;
+		}
+		lookupIndex++;
+		if (ret != LAYER_UNKNOWN)
+			break;
+	}
+	return ret;
+}
+
+const char *gerbv_layer_name_from_layer_index(const physical_layer_t layerIndex)
+{
+	switch (layerIndex) {
+	default:
+	case LAYER_UNKNOWN:
+		return _("LAYER_UNKNOWN");
+	case LAYER_DRILLS:
+		return _("LAYER_DRILLS");
+	case LAYER_OUTLINE:
+		return _("LAYER_OUTLINE");
+	case LAYER_TOP_SILKSCREEN:
+		return _("LAYER_TOP_SILKSCREEN");
+	case LAYER_TOP_PASTE:
+		return _("LAYER_TOP_PASTE");
+	case LAYER_TOP_SOLDERMASK:
+		return _("LAYER_TOP_SOLDERMASK");
+	case LAYER_TOP_COOPER:
+		return _("LAYER_TOP_COOPER");
+	case LAYER_INTERNAL_TOPMOST:
+		return _("LAYER_INTERNAL_TOPMOST");
+	case LAYER_INTERNAL_BOTTOMMOST:
+		return _("LAYER_INTERNAL_BOTTOMMOST");
+	case LAYER_BOTTOM_COOPER:
+		return _("LAYER_BOTTOM_COOPER");
+	case LAYER_BOTTOM_SOLDERMASK:
+		return _("LAYER_BOTTOM_SOLDERMASK");
+	case LAYER_BOTTOM_PASTE:
+		return _("LAYER_BOTTOM_PASTE");
+	case LAYER_BOTTOM_SILKSCREEN:
+		return _("LAYER_BOTTOM_SILKSCREEN");
+	}
+}
+
+int gerbv_compare_image_layer_index(const gerbv_fileinfo_t **image1, const gerbv_fileinfo_t **image2)
+{
+	if ((*image2) == NULL || (*image1) == NULL)
+		return  -1;
+	if ((*image1)->layer_index >  (*image2)->layer_index) return -1;
+	if ((*image1)->layer_index == (*image2)->layer_index) return 0;
+	if ((*image1)->layer_index <  (*image2)->layer_index) return 1;
+}
diff --git a/src/gerbv.h b/src/gerbv.h
index 26d6492..6d9a9db 100644
--- a/src/gerbv.h
+++ b/src/gerbv.h
@@ -348,6 +348,36 @@ enum draw_mode {
 	FIND_SELECTIONS_TOGGLE,
 };
 
+typedef enum {
+	LAYER_UNKNOWN = 101,
+	// the drill/contour layers should be at the top
+	LAYER_DRILLS = 100,
+	LAYER_OUTLINE = 99,
+
+	LAYER_PNP_TOP = 24,
+
+	LAYER_TOP_SILKSCREEN = 23,
+	LAYER_TOP_PASTE = 22,
+	LAYER_TOP_SOLDERMASK = 21,
+	LAYER_TOP_COOPER = 20,
+
+	LAYER_INTERNAL_TOPMOST = 19,
+
+	LAYER_INTERNAL_BOTTOMMOST = -19,
+
+	LAYER_BOTTOM_COOPER = -20,
+	LAYER_BOTTOM_SOLDERMASK = -21,
+	LAYER_BOTTOM_PASTE = -22,
+	LAYER_BOTTOM_SILKSCREEN = -23,
+
+	LAYER_PNP_BOTTOM = -24,
+}  physical_layer_t;
+
+struct gerbv_layer_lookup_item_t {
+	physical_layer_t layerIndex;
+	const char* const* fileNamePatterns;
+};
+
 /*! The different rendering modes available to libgerbv */
 typedef enum {GERBV_RENDER_TYPE_GDK, /*!< render using normal GDK drawing functions */
 		GERBV_RENDER_TYPE_GDK_XOR, /*!< use the GDK_XOR mask to draw a pseudo-transparent scene */
@@ -727,6 +757,7 @@ typedef struct {
   gchar *name; /*!< the name used when referring to this layer (e.g. in a layer selection menu) */
   gerbv_user_transformation_t transform; /*!< user-specified transformation for this layer (mirroring, translating, etc) */
   gboolean layer_dirty;  /*!< True if layer has been modified since last save */
+  physical_layer_t layer_index;
 } gerbv_fileinfo_t;
 
 /*!  The top-level structure used in libgerbv.  A gerbv_project_t groups together
@@ -823,6 +854,12 @@ gerbv_open_layer_from_filename (
 	gchar *filename /*!< the full pathname of the file to be parsed */
 );
 
+const char*
+gerbv_layer_name_from_layer_index(const physical_layer_t layerIndex);
+
+physical_layer_t
+gerbv_guess_layer_from_filename(gchar *filename);
+
 //! Open a file, parse the contents, and add a new layer to an existing project while setting the color of the layer
 void 
 gerbv_open_layer_from_filename_with_color(gerbv_project_t *gerbvProject, /*!< the existing project to add the new layer to */
@@ -833,6 +870,9 @@ gerbv_open_layer_from_filename_with_color(gerbv_project_t *gerbvProject, /*!< th
 	guint16 alpha /*!< the value for the alpha color component */
 );
 
+int
+gerbv_compare_image_layer_index(const gerbv_fileinfo_t **image1,
+								const gerbv_fileinfo_t **image2);
 //! Free a fileinfo structure
 void
 gerbv_destroy_fileinfo (gerbv_fileinfo_t *fileInfo /*!< the fileinfo to free */
@@ -861,7 +901,7 @@ gerbv_add_parsed_image_to_project (gerbv_project_t *gerbvProject, gerbv_image_t
 			gchar *filename, gchar *baseName, int idx, int reload);
 int
 gerbv_open_image(gerbv_project_t *gerbvProject, char *filename, int idx, int reload,
-		gerbv_HID_Attribute *fattr, int n_fattr, gboolean forceLoadFile);
+		gerbv_HID_Attribute *fattr, int n_fattr, gboolean forceLoadFile, gboolean orderByFileName);
 		
 void
 gerbv_render_get_boundingbox(gerbv_project_t *gerbvProject, gerbv_render_size_t *boundingbox);
diff --git a/src/main.c b/src/main.c
index e83a4a3..1ea9d44 100644
--- a/src/main.c
+++ b/src/main.c
@@ -244,7 +244,7 @@ main_open_project_from_filename(gerbv_project_t *gerbvProject, gchar *filename)
 			if (gerbv_open_image(gerbvProject, fullName,
 					fileIndex, FALSE,
 					plist->attr_list,
-					plist->n_attr, TRUE) == -1) {
+					plist->n_attr, TRUE, FALSE) == -1) {
 				GERB_MESSAGE(_("could not read file: %s"),
 						fullName);
 				plist = plist->next;
_______________________________________________
Gerbv-devel mailing list
Gerbv-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gerbv-devel

Reply via email to