[graphic] iscolor() extended 97/21197/4
Samuel GOUGEON [Tue, 31 Dec 2019 04:46:14 +0000 (05:46 +0100)]
  Now iscolor()
   * accepts special color indices -1 and -2.
     This compels
     - to return something else than -1 for wrong color specifications.
       NaN is used.
     - to return a column of colors indices instead of a RGB matrix,
       (when inputs are colors indices), since rows #-1 and #-2
       do no exist in the colormap.
       Macros where iscolor() is used are updated accordingly.

   * accepts abbreviations of standard color names ("ma" for "magenta", etc)

Change-Id: I985e364b50bd8a4b344fad943fa70ea4e29eb217

scilab/modules/cacsd/macros/sgrid.sci
scilab/modules/graphics/macros/bar.sci
scilab/modules/graphics/macros/iscolor.sci
scilab/modules/graphics/macros/setPlotProperty.sci
scilab/modules/graphics/macros/setSurfProperty.sci
scilab/modules/graphics/tests/unit_tests/iscolor.tst

index b8166c9..6e8e991 100644 (file)
@@ -74,20 +74,22 @@ function sgrid(varargin)
     // colors
     // ------
     if length(varargin)>=j
-        rgb = iscolor(varargin(j), "1#a")
+        colors = iscolor(varargin(j), "1#a")
         if new & new<=j, j = j+1, end
-        if size(rgb,1)>2
+        if size(colors,1)>2
             msg = _("%s: Argument #%d: Scalar or vector with %d components expected.\n")
             error(msprintf(msg, "sgrid", j, 2));
         end
-        if or(rgb==-1)
+        if or(isnan(colors))
             msg = _("%s: Argument #%d: Wrong color specification.\n")
             error(msprintf(msg, "sgrid", j));
         end
-        if size(rgb,1)==1 then
-            rgb = [1;1]*rgb
-        end
-        colors = addcolor(rgb)
+        if size(colors,2)==3   // RGB
+            if size(colors,1)==1 then
+                colors = [1;1]*colors
+            end
+            colors = addcolor(colors)
+        end                  // else: Indices => OK
     end
 
     // Graphics initializations
index 656787d..deefa95 100644 (file)
@@ -169,7 +169,7 @@ function  bar(varargin)
                 error(msprintf(msg, fname, kw+1));
             end
             c = iscolor(COLOR, "a#")
-            if or(c(:,1)==-1)
+            if or(isnan(c(:,1)))
                 error(msprintf(msg, fname, kw+1));
             end
             if nColors~=1 & nColors<size(Y,2) then
index 0bb9b36..6c920ad 100644 (file)
@@ -1,7 +1,5 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2018 - Samuel GOUGEON
-//
-// Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2018, 2019 - Samuel GOUGEON
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
 
 // INTERNAL function to be called by plot(), bar(), barh(), nicholschart(),
 // hallchart(), etc..
-function rgb = iscolor(C, acceptedFormats)
+function colors = iscolor(C, acceptedFormats)
     // C: scalar, vector, matrix.. of colors specifications:
-    //    - integers: => % T if > 0 and <= cmapSize
+    //    - integers: => is a color if -2,-1, or > 0 and <= cmapSize
     //                       default colormap used = gcf().color_map
-    //    - strings: can mix predefined colors names and "#RRGGBB" specifications
+    //    - strings: can mix predefined colors names and "#RRGGBB" specifications.
+    //               Shortcuts from the standard list "red" "green" "blue"
+    //               "cyan" "magenta" "yellow" "black" "white" "k" are supported,
+    //               like "ma" for magenta or "b" for blue.
     //    - (Nx3) [r g b] matrix, with 0 =< r,g,b <= 1 as in the color map.
     // acceptedFormats: single string (optional) made of 0 to 4 chars in any
     //      order among
@@ -26,8 +27,16 @@ function rgb = iscolor(C, acceptedFormats)
     //     "a" : colors names accepted
     //   Default = "1.#a"  (all)
     //
-    // rgb: (Nx3) matrix of 0 <= decimal numbers <= 1, with N = size(C, "*")
-    //      If C(i) is not a known color specification, rgb(i,:) = [-1 -1 -1]
+    // colors:
+    //    - if C are indices: column of indices
+    //    - else: (Nx3) matrix of 0 <= decimal numbers <= 1,
+    //        with N = numbers of colors defined through C.
+    //    If C(i) or C(i,:) is not a known color specification,
+    //    colors(i,:) = %nan
+    //    Warning: the output format can't be forced by specifying a
+    //     unique type of input. For instance, iscolor(4,"a") will
+    //     return %nan (because 4 is recognized as an index),
+    //     NOT [%nan %nan %nan] despite only "a" is accepted.
 
     fname = "iscolor"
 
@@ -55,55 +64,72 @@ function rgb = iscolor(C, acceptedFormats)
             msg = _("%s: Argument #%d: Text(s) expected.\n")
             error(msprintf(msg, fname, 2))
         end
-        acceptedFormats = acceptedFormats(1)
+        acceptedFormats = convstr(acceptedFormats(1))
+        if grep(acceptedFormats,"/^[a.#1]+$/","r")==[]
+            msg = _("%s: Argument #%d: Characters in {a.#1} expected.\n")
+            error(msprintf(msg, fname, 2))
+        end
     else
         acceptedFormats = "1.#a";
     end
 
     // PROCESSING
     // ----------
-    if type(C)==10 then
-        rgb = -ones(size(C,"*"), 3);
-        C = stripblanks(C);
+    //tmp = strsubst(strsubst(acceptedFormats, "a",""),"#","");
+    if type(C)==10 // | tmp=="" then
+        colors = %nan * ones(size(C,"*"), 3);
+        C = stripblanks(convstr(C));
 
         // "#RRGGBB" cases
         if grep(acceptedFormats, "#")~=[]
-            k = grep(C, "/^#[0-9a-f]{6}$/i", "r");
+            k = grep(C, "/^#[0-9a-f]{6}$/", "r");
             if k~=[]
                 s = strcat(part(C(k), 2:7));
                 s = matrix(strsplit(s, 2:2:length(s)-1), -1,3);
-                rgb(k,:) = hex2dec(s)/255;
+                colors(k,:) = hex2dec(s)/255;
             end
         end
+
         // Predefined named colors
         if grep(acceptedFormats, "a")~=[]
+            shortList = ["red" "green" "blue" "cyan" "magenta" "yellow" "black" "white"]
             k = grep(C, "/^[a-z0-9 ]+$/i", "r");
             for i = k
                 r = name2rgb(C(i));
                 if r~=[]
-                    rgb(i,:) = r / 255;
+                    colors(i,:) = r / 255;
+                else
+                    // shortcuts in the standard short list
+                    tmp = grep(shortList,"/^"+C(i)+"/","r")
+                    if tmp <> []
+                        colors(i,:) = name2rgb(shortList(tmp(1))) / 255
+                    elseif C(i)=="k"
+                        colors(i,:) = [0 0 0]
+                    end
                 end
             end
         end
     else
         C = real(C)
 
-        // [r g b] case
-        if size(C,"c")==3 & grep(acceptedFormats, ".")~=[]
-            rgb = -ones(C);
-            k = find(and(C>=0 & C<=1, "c"));
-            rgb(k,:) = C(k,:);
-        else
+        if size(C,"c") <> 3 | (or(C<0 | C>1) & and(C==int(C))) then
             // Colors indices
-            rgb = -ones(size(C, "*"), 3);
+            colors = %nan * ones(size(C, "*"), 1);
             if grep(acceptedFormats, "1")~=[]
                 if winsid()==[]
                     cmap = gdf().color_map;
                 else
                     cmap = gcf().color_map;
                 end
-                k = find(C==int(C) & C>0 & C<=size(cmap,"r"))
-                rgb(k,:) = cmap(C(k),:);
+                k = find(C==int(C) & C>-3 & C<>0 & C<=size(cmap,"r"))
+                colors(k) = C(k)
+            end
+        else
+            // [r g b] case
+            colors = %nan * ones(C);
+            if grep(acceptedFormats, ".")~=[]
+                k = find(and(C>=0 & C<=1, "c"));
+                colors(k,:) = C(k,:);
             end
         end
     end
index 7a2660e..1af232b 100644 (file)
@@ -1,8 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) 2004-2006 - INRIA - Fabrice Leray
-// Copyright (C) 2018 - Samuel GOUGEON
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2018, 2019 - Samuel GOUGEON
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
@@ -36,7 +35,7 @@ function [fail]=setPlotProperty(PropertyName,PropertyValue,Curves,current_figure
     case "foreground"         // <=> Color
         /////////////////////////
         c = iscolor(PropertyValue);
-        if or(c(:,1)==-1)
+        if or(isnan(c(:,1)))
             msg = _("%s: Argument #%d: Wrong color specification.\n")
             warning(msprintf(msg, "setPlotProperty", 2));
             ResetFigureDDM(current_figure, cur_draw_mode);
@@ -49,7 +48,11 @@ function [fail]=setPlotProperty(PropertyName,PropertyValue,Curves,current_figure
             return
         end
         Curves.line_mode = "on";
-        ind = addcolor(c(1:length(Curves),:));
+        if size(c,2) > 1    // c is RGB
+            ind = addcolor(c(1:length(Curves),:));
+        else
+            ind = c
+        end
         for i = 1:length(ind)
             Curves($-i+1).foreground = ind(i);
             Curves($-i+1).mark_foreground = ind(i);
index 3f1c0f8..113247e 100644 (file)
@@ -1,8 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) 2004-2006 - INRIA - Fabrice Leray
-// Copyright (C) 2018 - Samuel GOUGEON
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2018, 2019 - Samuel GOUGEON
 //
 // This file is hereby licensed under the terms of the GNU GPL v2.0,
 // pursuant to article 5.3.4 of the CeCILL v.2.1.
@@ -248,7 +247,7 @@ function fail = setSurfProperty(PropertyName, PropertyValue, Surface, X, Y, Z, C
             if type(PropertyValue) == 10
                 if PropertyValue=="auto"        // NOT DOCUMENTED
                     Surface(markmodeON).mark_foreground =  Surface.foreground;
-                    // If Surface may really be a vector of Surface handles, 
+                    // If Surface may really be a vector of Surface handles,
                     // this original assignment should not work...
                     return
                 elseif PropertyValue=="none"    // NOT DOCUMENTED
@@ -337,20 +336,14 @@ function k=getIndexInStringTable(pattern,table)
 endfunction
 
 function co = getColorIndFromProp(PropertyValue, current_figure, cur_draw_mode)
-    c = iscolor(PropertyValue); // "colorName" | "#RRGGBB" | [r,g,b] | indCmap accepted
-    co = [];
-    if find(c(:,1)~=-1)~=[]
-        co = addcolor(c(1,:));
-    else    // maybe an abbreviate colorname?
-        index = getColorIndex(PropertyValue);
-        if index > 0 & index < 10
-            Colors = ["red" "green" "blue" "cyan" "magenta" "yellow" "black" "black" "white"]
-            co = color(Colors(index));
-        else
-            msg = gettext("%s: Argument #%d: Wrong color specification.\n")
-            warning(msprintf(msg, "setSurfProperty", 2));
-            ResetFigureDDM(current_figure, cur_draw_mode);
-            return;
-        end
+    co = iscolor(PropertyValue); // "colorName" | "#RRGGBB" | [r,g,b] | indCmap accepted
+    if or(isnan(co(:,1))) then
+        msg = gettext("%s: Argument #%d: Wrong color specification.\n")
+        warning(msprintf(msg, "setSurfProperty", 2));
+        ResetFigureDDM(current_figure, cur_draw_mode);
+        return
+    end
+    if size(co,2)==3 then
+        co = addcolor(co(1,:));
     end
 endfunction
index cae0944..85aafa3 100644 (file)
@@ -1,6 +1,6 @@
 // =============================================================================
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2018 - Samuel GOUGEON
+// Copyright (C) 2018, 2019 - Samuel GOUGEON
 //
 //  This file is distributed under the same license as the Scilab package.
 // =============================================================================
 assert_checkequal(iscolor([]), []);
 assert_checkequal(iscolor("red"), [1 0 0]);
 assert_checkequal(iscolor("red", "a"), [1 0 0]);
-assert_checkequal(iscolor("red", "1"), [-1 -1 -1]);
-assert_checkequal(iscolor("red", "."), [-1 -1 -1]);
-assert_checkequal(iscolor("red", "#"), [-1 -1 -1]);
+assert_checkequal(iscolor("red", "1"), [%nan %nan %nan]);
+assert_checkequal(iscolor("red", "."), [%nan %nan %nan]);
+assert_checkequal(iscolor("red", "#"), [%nan %nan %nan]);
 assert_checkequal(iscolor("orange"), [255 165 0]/255);
 assert_checkequal(iscolor("OrAngE"), [255 165 0]/255);
 assert_checkequal(iscolor("Scilab Blue2"), [0 0 208]/255);
+cnames = ["r" "g" "GRE" "b" "c" "m" "ma" "y" "Yel" "w" "k"];
+ref =     [1.  0.   0.   0.  0.  1.  1.   1.   1.   1.   0.
+           0.  1.   1.   0.  1.  0.  0.   1.   1.   1.   0.
+           0.  0.   0.   1.  1.  1.  1.   0.   0.   1.   0.
+           ]';
+assert_checkequal(iscolor(cnames), ref);
 
 // #RRGGBB
 assert_checkequal(iscolor("#123456"), [18 52 86]/255);
 assert_checkequal(iscolor("#123456"), [18 52 86]/255);
-assert_checkequal(iscolor("#12345G"), [-1 -1 -1]);
 assert_checkequal(iscolor("#abcdef"), [171 205 239]/255);
 assert_checkequal(iscolor("#ABcDeF"), [171 205 239]/255);
+assert_checkequal(iscolor("#12345G"), [%nan %nan %nan]);
+assert_checkequal(iscolor("#1234"),   [%nan %nan %nan]);
 
 // Mixed names + #RRGGBB
 assert_checkequal(iscolor(["#abcdef" "orange"]), [171 205 239 ; 255 165 0]/255);
 
 // Indices
-cmap = gdf().color_map;
-assert_checkequal(iscolor(-1), [-1 -1 -1]);
-assert_checkequal(iscolor(0), [-1 -1 -1]);
-assert_checkequal(iscolor(1.5), [-1 -1 -1]);
-assert_checkequal(iscolor(4), cmap(4,:));
-assert_checkequal(iscolor(4, "a"), [-1 -1 -1]);
-assert_checkequal(iscolor(4, "."), [-1 -1 -1]);
-assert_checkequal(iscolor(4, "#"), [-1 -1 -1]);
-assert_checkequal(iscolor(100), [-1 -1 -1]);
-assert_checkequal(iscolor(1:2), cmap(1:2,:));
-assert_checkequal(iscolor(1:3), [-1 -1 -1]);    // warning
-assert_checkequal(iscolor(1:3, "1"), cmap(1:3,:));
-assert_checkequal(iscolor(1:4), cmap(1:4,:));
+sdf();
+assert_checkequal(iscolor([-1 -2]), [-1 ; -2]); // special indices
+assert_checkequal(iscolor(0), %nan);
+assert_checkequal(iscolor([-1 -2 0]), [-1 -2 %nan]');
+assert_checkequal(iscolor(1.5), %nan);
+assert_checkequal(iscolor(4), 4);
+assert_checkequal(iscolor(4, "a"), %nan);
+assert_checkequal(iscolor(4, "."), %nan);
+assert_checkequal(iscolor(4, "#"), %nan);
+assert_checkequal(iscolor(100), %nan);  // too big for the default CM
+assert_checkequal(iscolor(1:2), (1:2)');
+assert_checkequal(iscolor(1:3), (1:3)');
 
 f = scf(123);
-cmap = jetcolormap(64);
-f.color_map = cmap;
-assert_checkequal(iscolor(4), cmap(4,:));
-assert_checkequal(iscolor(1:2), cmap(1:2,:));
-assert_checkequal(iscolor(1:3, "1"), cmap(1:3,:));
-assert_checkequal(iscolor(1:4), cmap(1:4,:));
-assert_checkequal(iscolor(65), [-1 -1 -1]);
+f.color_map = jetcolormap(64);
+assert_checkequal(iscolor([1 7 4 3]), [1 7 4 3]');
+assert_checkequal(iscolor(65), %nan);
 delete(f)
 
 // [r g b]
-assert_checkequal(iscolor([-0.1 .2 .3]), [-1 -1 -1]);
-assert_checkequal(iscolor([0.1 .2  3]), [-1 -1 -1]);
+assert_checkequal(iscolor([-0.1 .2 .3]), [%nan %nan %nan]);
+assert_checkequal(iscolor([0.1 .2  3]), [%nan %nan %nan]);
 assert_checkequal(iscolor([0.1 .2 .3]), [0.1 0.2 0.3]);
-assert_checkequal(iscolor([0.1 .2 .3], "a"), -ones(3,3));
-assert_checkequal(iscolor([0.1 .2 .3], "#"), -ones(3,3));
-assert_checkequal(iscolor([0.1 .2 .3], "1"), -ones(3,3));
+assert_checkequal(iscolor([0.1 .2 .3], "a"), %nan*ones(1,3));
+assert_checkequal(iscolor([0.1 .2 .3], "#"), %nan*ones(1,3));
+assert_checkequal(iscolor([0.1 .2 .3], "1"), %nan*ones(1,3));
 assert_checkequal(iscolor([0.1 .2 .3], "1."), [.1 .2 .3]);
-assert_checkequal(iscolor([0.1 .2 .3 .4]), -ones(4,3));
+assert_checkequal(iscolor([0.1 .2 .3 .4]), %nan*ones(4,1));
 m = rand(10,3);
 assert_checkequal(iscolor(m), m);