Mercurial > octave
view scripts/plot/appearance/whitebg.m @ 30564:796f54d4ddbf stable
update Octave Project Developers copyright for the new year
In files that have the "Octave Project Developers" copyright notice,
update for 2021.
In all .txi and .texi files except gpl.txi and gpl.texi in the
doc/liboctave and doc/interpreter directories, change the copyright
to "Octave Project Developers", the same as used for other source
files. Update copyright notices for 2022 (not done since 2019). For
gpl.txi and gpl.texi, change the copyright notice to be "Free Software
Foundation, Inc." and leave the date at 2007 only because this file
only contains the text of the GPL, not anything created by the Octave
Project Developers.
Add Paul Thomas to contributors.in.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 28 Dec 2021 18:22:40 -0500 |
parents | 0a5b15007766 |
children | 597f3ee61a48 |
line wrap: on
line source
######################################################################## ## ## Copyright (C) 2010-2022 The Octave Project Developers ## ## See the file COPYRIGHT.md in the top-level directory of this ## distribution or <https://octave.org/copyright/>. ## ## This file is part of Octave. ## ## Octave is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <https://www.gnu.org/licenses/>. ## ######################################################################## ## -*- texinfo -*- ## @deftypefn {} {} whitebg () ## @deftypefnx {} {} whitebg (@var{color}) ## @deftypefnx {} {} whitebg ("none") ## @deftypefnx {} {} whitebg (@var{hfig}) ## @deftypefnx {} {} whitebg (@var{hfig}, @var{color}) ## @deftypefnx {} {} whitebg (@var{hfig}, "none") ## Invert the colors in the current color scheme. ## ## The root properties are also inverted such that all subsequent plots will ## use the new color scheme. ## ## If the optional argument @var{color} is present then the background color ## is set to @var{color} rather than inverted. @var{color} may be a string ## representing one of the eight known colors or an RGB triplet. The special ## string argument @qcode{"none"} restores the plot to the factory default ## colors. ## ## If the first argument @var{hfig} is a figure handle or list of figure ## handles, then operate on these figures rather than the current figure ## returned by @code{gcf}. The root properties will not be changed unless 0 ## is in the list of figures. ## ## Programming Note: @code{whitebg} operates by changing the color properties ## of the children of the specified figures. Only objects with a single color ## are affected. For example, a patch with a single @qcode{"FaceColor"} will ## be changed, but a patch with shading (@qcode{"interp"}) will not be ## modified. For inversion, the new color is simply the inversion in RGB ## space: @code{@var{cnew} = [1-@var{R} 1-@var{G} 1-@var{B}]}. When a color ## is specified, the axes and figure are set to the new color, and the color ## of child objects are then adjusted to have some contrast (visibility) ## against the new background. ## @seealso{reset, get, set} ## @end deftypefn ## FIXME: It's not clear whether Matlab also changes color properties ## of the figure object itself, or only the children. However, visually, ## it looks better to change the figure along with the axes background. function whitebg (varargin) if (nargin > 2) print_usage (); endif h = 0; color = NaN; have_fig = false; if (nargin > 0) if (all (ishghandle (varargin{1}))) h = varargin{1}; have_fig = true; if (nargin == 2) color = varargin{2}; endif elseif (nargin == 1) color = varargin{1}; else print_usage (); endif endif if (! have_fig) fig = gcf (); do_root = true; elseif (all (isfigure (h) | h == 0)) fig = h(h != 0); do_root = any (h == 0); else error ("whitebg: HFIG must be a valid figure handle"); endif if (isnan (color)) if (do_root) ## Set the default axes and figure properties on root ## so that subsequent plots have the new color scheme fac = get (0, "factory"); fields = fieldnames (fac); idx = ! cellfun ("isempty", regexp (fields, '^factory(axes|figure).*color$')); ## Use default value in place of factory value if specified. for field = fields(idx)' defaultfield = strrep (field{1}, "factory", "default"); try defaultvalue = 1 - get (0, defaultfield); catch defaultvalue = 1 - fac.(field{1}); end_try_catch set (0, defaultfield, defaultvalue); endfor endif ## The sort is necessary so that child legend objects are acted on ## before the legend axes object. hlist = sort (findobj (fig)); for h = hlist' props = get (h); fields = fieldnames (props); ## Find all fields with the word color in them and invert. idx = find (! cellfun ("isempty", regexp (fields, 'color$'))); for field = fields(idx)' c = props.(field{1}); if (! ischar (c) && columns (c) == 3) set (h, field{1}, 1 - c); endif endfor endfor else # 2nd argument such as a color or "none" if (! strcmp (color, "none")) ## Set the specified color on the figure and all axes objects hlist = [fig; findobj(fig, "type", "axes")]; set (hlist, "color", color); if (do_root) defs = get (0, "default"); if (isfield (defs, "defaultaxescolor") && strcmp (defs.defaultaxescolor, "none")) set (0, "defaultaxescolor", color); endif endif ## Adjust colors of remaining objects to have some contrast bg = rgb2hsv (get (fig, "color")); ## List of children without the figure and axes objects already changed hlist = setdiff (findobj (fig), hlist); for h = hlist' props = get (h); fields = fieldnames (props); ## Find all fields with the word color in them and adjust HSV. idx = find (! cellfun ("isempty", regexp (fields, 'color$'))); for field = fields(idx)' c = props.(field{1}); if (! ischar (c) && columns (c) == 3) set (h, field{1}, calc_contrast_color (bg, c)); endif endfor endfor else ## Reset colors to factory defaults if (do_root) fac = get (0, "factory"); fields = fieldnames (fac); idx = ! cellfun ("isempty", regexp (fields, '^factory(axes|figure).*color$')); for field = fields(idx)' factoryfield = field{1}; factoryvalue = fac.(factoryfield); if (strncmp (factoryfield, "factoryfigure", 13)) ## Strip off "factoryfigure" part of fieldname before applying set (fig, factoryfield(14:end), factoryvalue); endif ## Remove applied default from root defaultfield = strrep (factoryfield, "factory", "default"); set (0, defaultfield, "remove"); endfor endif hlist = sort (findobj (fig)); for h = hlist' props = get (h); fields = fieldnames (props); ## Find all fields with the word color in them and restore to factory. idx = find (! cellfun ("isempty", regexp (fields, 'color$'))); for field = fields(idx)' set (h, field{1}, "factory"); endfor endfor endif endif endfunction ## Calculate a new color which contrasts with the supplied bg color and is ## perceptually related to the original color. ## ## Input color bg must be in HSV space. Input color corig is in RGB space. ## ## FIXME: Calculation is segregated into its own function in case anyone wants ## to try and improve the selection of a "contrasting" color. ## ## This algorithm maintains at least 90 degrees separation between corig and bg ## in Hue rotation space. No modifications are done for saturation or value. function cnew = calc_contrast_color (bg, corig) hsv = rgb2hsv (corig); contrast_hue = mod (bg(1) + 0.5, 1); # Generate a contrasting bg color ## If close to existing contrast color, leave alone delta = abs (hsv(1) - contrast_hue); if (delta < 0.25 || delta > 0.75) cnew(1) = hsv(1); else cnew(1) = mod (hsv(1) + 0.5, 1); endif ## No modifications to saturation or value. cnew(2:3) = hsv(2:3); cnew = hsv2rgb (cnew); endfunction %!test %! dac = get (0, "defaultaxescolor"); %! dfc = get (0, "defaultfigurecolor"); %! hf = figure ("visible", "off"); %! unwind_protect %! hl = line ("Color", "r"); %! assert (get (hf, "color"), dfc); %! assert (get (gca, "color"), dac); %! assert (get (hl, "color"), [1 0 0]); %! whitebg (hf); %! assert (get (hf, "color"), 1 - dfc); %! assert (get (gca, "color"), 1 - dac); %! assert (get (hl, "color"), [0 1 1]); %! c = [0.2 0.2 0.2]; %! whitebg (hf, c); %! assert (get (hf, "color"), c); %! assert (get (gca, "color"), c); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect ## Test input validation %!error whitebg (1,2,3) %!error whitebg ({1}, 2)