68 error (
"set: invalid value for %s property", pname.c_str ());
77 const std::set<std::string>& pnames,
80 size_t len = pname.length ();
81 std::set<std::string> matches;
83 for (std::set<std::string>::const_iterator p = pnames.begin ();
84 p != pnames.end (); p++)
88 if (len == p->length ())
98 size_t num_matches = matches.size ();
100 if (num_matches == 0)
102 error (
"%s: unknown %s property %s",
103 who.c_str (), what.c_str (), pname.c_str ());
105 else if (num_matches > 1)
109 std::ostringstream os;
113 std::string match_list = os.str ();
115 error (
"%s: ambiguous %s property name %s; possible matches:\n\n%s",
116 who.c_str (), what.c_str (), pname.c_str (), match_list.c_str ());
118 else if (num_matches == 1)
122 std::string possible_match = *(matches.begin ());
125 "%s: allowing %s to match %s property %s",
126 who.c_str (), pname.c_str (), what.c_str (),
127 possible_match.c_str ());
129 return possible_match;
142 double delta = 1.0 / 63.0;
155 if (x >= 3.0/8.0 && x < 5.0/8.0)
156 cmap(i,0) = 4.0 * x - 3.0/2.0;
157 else if (x >= 5.0/8.0 && x < 7.0/8.0)
159 else if (x >= 7.0/8.0)
160 cmap(i,0) = -4.0 * x + 9.0/2.0;
162 if (x >= 1.0/8.0 && x < 3.0/8.0)
163 cmap(i,1) = 4.0 * x - 1.0/2.0;
164 else if (x >= 3.0/8.0 && x < 5.0/8.0)
166 else if (x >= 5.0/8.0 && x < 7.0/8.0)
167 cmap(i,1) = -4.0 * x + 7.0/2.0;
170 cmap(i,2) = 4.0 * x + 1.0/2.0;
171 else if (x >= 1.0/8.0 && x < 3.0/8.0)
173 else if (x >= 3.0/8.0 && x < 5.0/8.0)
174 cmap(i,2) = -4.0 * x + 5.0/2.0;
189 Matrix retval (1, 4, 1.0);
206 Matrix retval (7, 3, 0.0);
332 Matrix retval (1, 4, 0.0);
345 Matrix retval (1, 2, 0.0);
356 Matrix retval (1, 4, 0.0);
372 if (from_units.
compare (to_units))
378 double points_size = 0;
381 if (from_units.
compare (
"points"))
382 points_size = font_size;
387 if (from_units.
compare (
"pixels"))
388 points_size = font_size * 72.0 / res;
389 else if (from_units.
compare (
"inches"))
390 points_size = font_size * 72.0;
391 else if (from_units.
compare (
"centimeters"))
392 points_size = font_size * 72.0 / 2.54;
393 else if (from_units.
compare (
"normalized"))
394 points_size = font_size * parent_height * 72.0 / res;
397 double new_font_size = 0;
399 if (to_units.
compare (
"points"))
400 new_font_size = points_size;
406 if (to_units.
compare (
"pixels"))
407 new_font_size = points_size * res / 72.0;
408 else if (to_units.
compare (
"inches"))
409 new_font_size = points_size / 72.0;
410 else if (to_units.
compare (
"centimeters"))
411 new_font_size = points_size * 2.54 / 72.0;
412 else if (to_units.
compare (
"normalized"))
416 if (parent_height > 0)
417 new_font_size = points_size * res / (parent_height * 72.0);
421 return new_font_size;
430 bool is_rectangle = (pos.
numel () == 4);
431 bool is_2d = (pos.
numel () == 2);
433 if (from_units.
compare (
"pixels"))
435 else if (from_units.
compare (
"normalized"))
437 retval(0) = pos(0) * parent_dim(0) + 1;
438 retval(1) = pos(1) * parent_dim(1) + 1;
441 retval(2) = pos(2) * parent_dim(0);
442 retval(3) = pos(3) * parent_dim(1);
447 else if (from_units.
compare (
"characters"))
456 f = 12.0 * res / 74.951;
460 retval(0) = 0.5 * pos(0) *
f;
461 retval(1) = pos(1) *
f;
464 retval(2) = 0.5 * pos(2) *
f;
465 retval(3) = pos(3) *
f;
478 if (from_units.
compare (
"points"))
480 else if (from_units.
compare (
"inches"))
482 else if (from_units.
compare (
"centimeters"))
487 retval(0) = pos(0) * f + 1;
488 retval(1) = pos(1) * f + 1;
491 retval(2) = pos(2) *
f;
492 retval(3) = pos(3) *
f;
499 if (! to_units.
compare (
"pixels"))
501 if (to_units.
compare (
"normalized"))
503 retval(0) = (retval(0) - 1) / parent_dim(0);
504 retval(1) = (retval(1) - 1) / parent_dim(1);
507 retval(2) /= parent_dim(0);
508 retval(3) /= parent_dim(1);
513 else if (to_units.
compare (
"characters"))
520 f = 12.0 * res / 74.951;
524 retval(0) = 2 * retval(0) /
f;
525 retval(1) = retval(1) /
f;
528 retval(2) = 2 * retval(2) /
f;
529 retval(3) = retval(3) /
f;
542 if (to_units.
compare (
"points"))
544 else if (to_units.
compare (
"inches"))
546 else if (to_units.
compare (
"centimeters"))
551 retval(0) = (retval(0) - 1) / f;
552 retval(1) = (retval(1) - 1) / f;
563 else if (! is_rectangle && ! is_2d)
579 if (ax.valid_object ())
584 bool is_rectangle = (pos.
numel () == 4);
586 ax_size = ax_bbox.
extract_n (0, 2, 1, 2);
588 if (from_units.
compare (
"data"))
598 retval(0) =
v1(0) - ax_bbox(0) + 1;
599 retval(1) = ax_bbox(1) + ax_bbox(3) -
v1(1) + 1;
600 retval(2) =
v2(0) -
v1(0);
601 retval(3) =
v1(1) -
v2(1);
609 retval(0) = v(0) - ax_bbox(0) + 1;
610 retval(1) = ax_bbox(1) + ax_bbox(3) - v(1) + 1;
617 if (! to_units.
compare (
"pixels"))
625 retval(0) + ax_bbox(0) - 1,
626 ax_bbox(1) + ax_bbox(3) - retval(1) + 1);
628 retval(0) + retval(2) + ax_bbox(0) - 1,
629 ax_bbox(1) + ax_bbox(3) - (retval(1) + retval(3)) + 1);
635 retval(2) =
v2(0) -
v1(0);
636 retval(3) =
v2(1) -
v1(1);
642 retval(0) + ax_bbox(0) - 1,
643 ax_bbox(1) + ax_bbox(3) - retval(1) + 1);
667 sz.
extract_n (0, 2, 1, 2)).extract_n (0, 2, 1, 2);
676 x =
xround ((nc - 1) * (x - clim_0) / (clim_1 - clim_0));
696 av[i+lda] = cmapv[idx+nc];
697 av[i+2*lda] = cmapv[idx+2*nc];
708 convert_cdata_2 (is_scaled, clim_0, clim_1, cmapv, cv[i], lda, nc, i, av);
713 bool is_scaled,
int cdim)
717 if (dv.length () == cdim && dv(cdim-1) == 3)
726 if (fig.valid_object ())
756 const double *cmapv = cmap.
data ();
758 double clim_0 = clim(0);
759 double clim_1 = clim(1);
761 #define CONVERT_CDATA_1(ARRAY_T, VAL_FN) \
764 ARRAY_T tmp = cdata. VAL_FN ## array_value (); \
766 convert_cdata_1 (is_scaled, clim_0, clim_1, cmapv, \
767 tmp.data (), lda, nc, av); \
778 error (
"unsupported type for cdata (= %s)", cdata.
type_name ().c_str ());
780 #undef CONVERT_CDATA_1
788 double& eminp,
double& emaxp)
790 const T *data = m.
data ();
795 double e =
double (data[i]);
806 if (e > 0 && e < eminp)
809 if (e < 0 && e > emaxp)
819 int len = name.length ();
832 pfx = name.substr (0, 5);
838 pfx = name.substr (0, 6);
844 pfx = name.substr (0, 7);
851 pfx = name.substr (0, 9);
858 pfx = name.substr (0, 10);
860 if (pfx.
compare (
"uipushtool"))
864 pfx = name.substr (0, 12);
866 if (pfx.
compare (
"uitoggletool"))
870 pfx = name.substr (0, 13);
872 if (pfx.
compare (
"uicontextmenu"))
885 rest = name.substr (offset);
902 else if (type.
compare (
"axes"))
903 go =
new axes (h, p);
904 else if (type.
compare (
"line"))
905 go =
new line (h, p);
906 else if (type.
compare (
"text"))
907 go =
new text (h, p);
908 else if (type.
compare (
"image"))
909 go =
new image (h, p);
910 else if (type.
compare (
"patch"))
911 go =
new patch (h, p);
912 else if (type.
compare (
"surface"))
914 else if (type.
compare (
"hggroup"))
916 else if (type.
compare (
"uimenu"))
918 else if (type.
compare (
"uicontrol"))
920 else if (type.
compare (
"uipanel"))
922 else if (type.
compare (
"uicontextmenu"))
924 else if (type.
compare (
"uitoolbar"))
926 else if (type.
compare (
"uipushtool"))
928 else if (type.
compare (
"uitoggletool"))
942 if (
id >= 0 && do_notify_toolkit)
965 for (
int i = 0; i < l.
length (); i++)
975 : default_val (), possible_vals ()
978 size_t len = opt_string.length ();
979 bool done = len == 0;
983 size_t end = opt_string.find (
'|', beg);
985 if (end == std::string::npos)
991 std::string t = opt_string.substr (beg, end-beg);
996 t = t.substr (1, t.length () - 2);
1012 for (std::set<caseless_str>::const_iterator it =
possible_vals.begin ();
1018 retval =
"{" + *it +
"}";
1025 retval +=
" | {" + *it +
"}";
1027 retval +=
" | " + *it;
1031 retval =
"[ " + retval +
" ]";
1040 for (std::set<caseless_str>::const_iterator it =
possible_vals.begin ();
1042 retval(i++) = std::string (*it);
1049 double tmp_rgb[3] = {0, 0, 0};
1051 unsigned int len = str.length ();
1053 std::transform (str.begin (), str.end (), str.begin (), tolower);
1055 if (str.compare (0, len,
"blue", 0, len) == 0)
1057 else if (str.compare (0, len,
"black", 0, len) == 0
1058 || str.compare (0, len,
"k", 0, len) == 0)
1059 tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 0;
1060 else if (str.compare (0, len,
"red", 0, len) == 0)
1062 else if (str.compare (0, len,
"green", 0, len) == 0)
1064 else if (str.compare (0, len,
"yellow", 0, len) == 0)
1065 tmp_rgb[0] = tmp_rgb[1] = 1;
1066 else if (str.compare (0, len,
"magenta", 0, len) == 0)
1067 tmp_rgb[0] = tmp_rgb[2] = 1;
1068 else if (str.compare (0, len,
"cyan", 0, len) == 0)
1069 tmp_rgb[1] = tmp_rgb[2] = 1;
1070 else if (str.compare (0, len,
"white", 0, len) == 0
1071 || str.compare (0, len,
"w", 0, len) == 0)
1072 tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 1;
1078 for (
int i = 0; i < 3; i++)
1079 xrgb(i) = tmp_rgb[i];
1100 if (s.length () != match.length ())
1102 "%s: allowing %s to match %s value %s",
1103 "set", s.c_str (),
get_name ().c_str (),
1123 error (
"invalid value for color property \"%s\" (value = %s)",
1128 error (
"invalid value for color property \"%s\"",
1135 if (m.
numel () == 3)
1149 error (
"invalid value for color property \"%s\"",
1153 error (
"invalid value for color property \"%s\"",
1171 if (s.length () != match.length ())
1173 "%s: allowing %s to match %s value %s",
1174 "set", s.c_str (),
get_name ().c_str (),
1182 error (
"invalid value for double_radio property \"%s\"",
1197 error (
"invalid value for double_radio property \"%s\"",
1229 int vlen = vdims.
length ();
1239 if (itdims.
length () == vlen)
1243 for (
int i = 0; xok && i < vlen; i++)
1247 if (itdims(i) != vdims(i))
1268 #define CHECK_ARRAY_EQUAL(T,F,A) \
1270 if (data.numel () == 1) \
1271 return data.F ## scalar_value () == \
1272 v.F ## scalar_value (); \
1277 const A m1 = data.F ## array_value (); \
1278 const T* d1 = m1.data (); \
1279 const A m2 = v.F ## array_value (); \
1280 const T* d2 = m2.data ();\
1284 for (int i = 0; flag && i < data.numel (); i++) \
1285 if (d1[i] != d2[i]) \
1376 error (
"set: invalid graphics handle (= %g) for property \"%s\"",
1380 error (
"set: invalid graphics handle for property \"%s\"",
1406 if (! return_hidden)
1409 else if (return_hidden)
1413 retval.resize (k, 1);
1488 executing_callback =
true;
1507 std::string val = (args.
length () > 0 ? args(0).string_value () :
"");
1512 else if (type.
compare (
"any"))
1519 else if (type.
compare (
"radio"))
1523 std::string vals = args(0).string_value ();
1530 retval.set (args(1));
1533 error (
"addproperty: invalid argument for radio property, expected a string value");
1536 error (
"addproperty: missing possible values for radio property");
1538 else if (type.
compare (
"double"))
1540 double d = (args.
length () > 0 ? args(0).double_value () : 0);
1545 else if (type.
compare (
"handle"))
1556 else if (type.
compare (
"boolean"))
1561 retval.set (args(0));
1563 else if (type.
compare (
"data"))
1569 retval.set (args(0));
1575 else if (type.
compare (
"color"))
1589 if (args.
length () > 0 && ! args(0).is_empty ())
1590 retval.set (args(0));
1604 std::map<caseless_str, graphics_object>::const_iterator it =
1605 dprop_obj_map.find (go_name);
1607 if (it == dprop_obj_map.end ())
1616 dprop_obj_map[go_name] = go;
1628 retval = prop.
clone ();
1631 retval.set_name (name);
1634 retval.set (args(0));
1638 error (
"addproperty: invalid object type (= %s)",
1642 error (
"addproperty: unsupported type for dynamic property (= %s)",
1658 for (
int k = 0; k < children.
numel (); k++)
1676 for (
int k = 0; k < children.
numel (); k++)
1704 size_t len = name.length ();
1715 pfx = name.substr (0, 5);
1721 pfx = name.substr (0, 6);
1727 pfx = name.substr (0, 7);
1734 pfx = name.substr (0, 9);
1741 pfx = name.substr (0, 10);
1743 if (pfx.
compare (
"uipushtool"))
1747 pfx = name.substr (0, 12);
1749 if (pfx.
compare (
"uitoogletool"))
1753 pfx = name.substr (0, 13);
1755 if (pfx.
compare (
"uicontextmenu"))
1769 std::string pname = name.substr (offset);
1771 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
1775 bool has_property =
false;
1778 else if (pfx ==
"line")
1780 else if (pfx ==
"text")
1782 else if (pfx ==
"image")
1784 else if (pfx ==
"patch")
1786 else if (pfx ==
"figure")
1788 else if (pfx ==
"surface")
1790 else if (pfx ==
"hggroup")
1792 else if (pfx ==
"uimenu")
1794 else if (pfx ==
"uicontrol")
1796 else if (pfx ==
"uipanel")
1798 else if (pfx ==
"uicontextmenu")
1800 else if (pfx ==
"uitoolbar")
1802 else if (pfx ==
"uipushtool")
1807 bool remove =
false;
1812 remove = (tval.compare (
"remove") == 0);
1821 if (p != pval_map.end ())
1825 pval_map[pname] = val;
1828 error (
"invalid %s property '%s'", pfx.c_str (), pname.c_str ());
1833 error (
"invalid default property specification");
1843 size_t len = name.length ();
1854 pfx = name.substr (0, 5);
1860 pfx = name.substr (0, 6);
1866 pfx = name.substr (0, 7);
1873 pfx = name.substr (0, 9);
1880 pfx = name.substr (0, 10);
1882 if (pfx.
compare (
"uipushtool"))
1886 pfx = name.substr (0, 12);
1888 if (pfx.
compare (
"uitoggletool"))
1892 pfx = name.substr (0, 13);
1894 if (pfx.
compare (
"uicontextmenu"))
1906 std::string pname = name.substr (offset);
1908 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
1920 if (q != pval_map.end ())
1936 std::string prefix = prefix_arg + p->first;
1941 q != pval_map.end ();
1943 m.
assign (prefix + q->first, q->second);
1954 int nargin = args.
length ();
1957 error (
"graphics_object::set: Nothing to set");
1958 else if (nargin % 2 == 0)
1960 for (
int i = 0; i < nargin; i += 2)
1968 set_value_or_default (name, val);
1974 error (
"set: expecting argument %d to be a property name", i);
1978 error (
"set: invalid number of arguments");
2001 error (
"set: number of names must match number of value columns (%d != %d)",
2012 set_value_or_default (name, val);
2075 set_value_or_default (name, val);
2175 if (tval.compare (
"default") == 0)
2182 rep->set (name, default_val);
2184 else if (tval.compare (
"factory") == 0)
2191 rep->set (name, default_val);
2196 if (tval.compare (
"\\default") == 0)
2197 rep->set (name,
"default");
2198 else if (tval.compare (
"\\factory") == 0)
2199 rep->set (name,
"factory");
2201 rep->set (name, val);
2205 rep->set (name, val);
2229 static double maxrand = RAND_MAX + 2.0;
2231 return (rand () + 1.0) / maxrand;
2239 if (integer_figure_handle)
2248 while (handle_map.find (retval) != handle_map.end ())
2260 if (p != handle_free_list.end ())
2263 handle_free_list.erase (p);
2281 if (h.
value () != 0)
2285 if (p != handle_map.end ())
2298 p->second.finalize ();
2309 handle_map.erase (p);
2312 handle_free_list.insert
2316 error (
"graphics_handle::free: invalid object %g", h.
value ());
2319 error (
"graphics_handle::free: can't delete root figure");
2327 iterator p = handle_map.find (old_gh);
2329 if (p != handle_map.end ())
2333 handle_map.erase (p);
2335 handle_map[new_gh] = go;
2337 if (old_gh.
value () < 0)
2342 error (
"graphics_handle::free: invalid object %g", old_gh.
value ());
2345 q != figure_list.end (); q++)
2362 obj.
set (name, val);
2379 return obj.
get (name);
2406 obj.
set (
"parent", new_parent.
value ());
2411 error (
"%s: invalid graphics handle (= %g) for %s",
2412 who.c_str (), val,
property.c_str ());
2415 error (
"%s: expecting %s to be a graphics handle",
2416 who.c_str (),
property.c_str ());
2514 Matrix hlist = do_figure_handle_list (
true);
2526 hlist = do_figure_handle_list (
true);
2538 hlist = do_figure_handle_list (
true);
2540 assert (hlist.
numel () == 0);
2544 callback_objects.clear ();
2551 parent_obj.
adopt (h);
2598 return obj && obj.
isa (
"figure");
2649 std::string go_name = graphics_object_name ();
2653 if (p != defaults.
end ())
2658 q != pval_map.end ();
2661 std::string pname = q->first;
2663 obj.
set (pname, q->second);
2667 error (
"error setting default property %s", pname.c_str ());
2679 std::map<caseless_str, property, cmp_caseless_str>::const_iterator it =
2680 all_props.find (name);
2682 if (it != all_props.end ())
2683 retval = it->second.get ();
2685 error (
"get: unknown property \"%s\"", name.c_str ());
2695 for (std::map<caseless_str, property, cmp_caseless_str>::const_iterator
2696 it = all_props.begin (); it != all_props.end (); ++it)
2697 if (all || ! it->second.is_hidden ())
2698 m.
assign (it->second.get_name (), it->second.get ());
2703 std::set<std::string>
2706 return dynamic_properties;
2712 const std::set<std::string>& dynprops = dynamic_property_names ();
2714 if (dynprops.find (pname) != dynprops.end ())
2717 return all_props.find (pname) != all_props.end ();
2724 std::map<caseless_str, property, cmp_caseless_str>::iterator it =
2725 all_props.find (pname);
2727 if (it != all_props.end ())
2728 it->second.set (val);
2730 error (
"set: unknown property \"%s\"", pname.c_str ());
2734 dynamic_properties.insert (pname);
2743 std::map<caseless_str, property, cmp_caseless_str>::const_iterator it =
2744 all_props.find (name);
2746 if (it == all_props.end ())
2748 error (
"get_property: unknown property \"%s\"", name.c_str ());
2764 if (hnp == __myhandle__)
2765 error (
"set: can not set object parent to be object itself");
2770 if (new_parent.
ok ())
2780 if (new_parent_obj.
get_parent () == __myhandle__)
2788 ::adopt (parent.handle_value (), __myhandle__);
2791 error (
"set: invalid graphics handle (= %g) for parent", hnp);
2795 error (
"set: expecting parent to be a graphics handle");
2801 __modified__ =
"on";
2838 return (handlevisibility.is (
"on")
2839 || (executing_callback && ! handlevisibility.is (
"off")));
2856 Matrix kids = get_children ();
2858 for (
int i = 0; i < kids.
numel (); i++)
2880 property p = get_property (nm);
2883 p.add_listener (v, mode);
2890 property p = get_property (nm);
2893 p.delete_listener (v, mode);
2909 error (
"base_graphics_object::update_axis_limits: invalid graphics object");
2924 error (
"base_graphics_object::update_axis_limits: invalid graphics object");
2967 if (pa->first !=
"children")
2971 if (p.ok () && ! p.is_hidden ())
2973 retval +=
"\n\t" + std::string (pa->first) +
": ";
2983 error (
"base_graphics_object::values_as_string: invalid graphics object");
2998 pa != m.
end (); pa++)
3000 if (pa->first !=
"children")
3004 if (p.ok () && ! p.is_hidden ())
3007 retval.
assign (p.get_name (), p.values_as_cell ());
3015 error (
"base_graphics_object::values_as_struct: invalid graphics object");
3050 currentfigure = val;
3069 if (! cbo_stack.empty ())
3071 val = cbo_stack.front ();
3073 cbo_stack.pop_front ();
3076 callbackobject = val;
3080 if (get_callbackobject ().ok ())
3081 cbo_stack.push_front (get_callbackobject ());
3083 callbackobject = val;
3094 if (integerhandle.set (val,
true))
3096 bool int_fig_handle = integerhandle.is_on ();
3112 Matrix kids = get_children ();
3123 if (__myhandle__ == cf)
3124 xset (0,
"currentfigure", __myhandle__.value ());
3126 this_go.
update (integerhandle.get_id ());
3143 double dpi = get_screenpixelsperinch ();
3145 if (xunits.
compare (
"inches"))
3152 else if (xunits.
compare (
"centimeters"))
3156 ss(2) *= 2.54 / dpi;
3157 ss(3) *= 2.54 / dpi;
3159 else if (xunits.
compare (
"normalized"))
3165 else if (xunits.
compare (
"points"))
3173 set_screensize (ss);
3181 pos(2) = screen_size(0);
3182 pos(3) = screen_size(1);
3229 p != default_properties.
end (); p++)
3232 std::string prefix = p->first;
3235 q != pval_map.end ();
3238 std::string s = q->first;
3240 if (prefix ==
"axes" && (s ==
"position" || s ==
"units"))
3241 new_defaults.
set (prefix + s, q->second);
3242 else if (prefix ==
"figure" && (s ==
"position" || s ==
"units"
3243 || s ==
"windowstyle"
3244 || s ==
"paperunits"))
3245 new_defaults.
set (prefix + s, q->second);
3249 default_properties = new_defaults;
3279 if (gh == currentaxes.handle_value ())
3283 Matrix kids = get_children ();
3291 if (go.
isa (
"axes"))
3293 new_currentaxes = kid;
3298 currentaxes = new_currentaxes;
3310 xset (0,
"currentfigure", __myhandle__.value ());
3321 get_position ().matrix_value () :
3322 get_outerposition ().matrix_value ());
3328 pos(1) = screen_size(1) - pos(1) - pos(3);
3335 bool do_notify_toolkit)
3340 pos(1) = screen_size(1) - pos(1) - pos(3);
3346 set_position (pos, do_notify_toolkit);
3348 set_outerposition (pos, do_notify_toolkit);
3354 Matrix bb = get_boundingbox (
true);
3360 pos(1) = bb(3) - pos(1);
3371 Matrix bb = get_boundingbox (
true);
3380 pos(1) = bb(3) - pos(1);
3387 bool do_notify_toolkit)
3392 bool modified =
false;
3394 old_bb = get_boundingbox (
true);
3395 modified = position.set (v,
false, do_notify_toolkit);
3396 new_bb = get_boundingbox (
true);
3398 if (old_bb != new_bb)
3400 if (old_bb(2) != new_bb(2) || old_bb(3) != new_bb(3))
3402 execute_resizefcn ();
3403 update_boundingbox ();
3409 position.run_listeners (
POSTSET);
3417 bool do_notify_toolkit)
3421 if (outerposition.set (v,
true, do_notify_toolkit))
3438 error (
"set: can't set the paperunits to normalized when the papertype is custom");
3442 if (paperunits.set (v,
true))
3444 update_paperunits (old_paperunits);
3462 error (
"set: can't set the paperunits to normalized when the papertype is custom");
3465 if (papertype.set (v,
true))
3467 update_papertype ();
3480 if (! punits.
compare (
"normalized"))
3485 if (punits.
compare (
"inches"))
3488 mm2units = 1 / 25.4 ;
3490 else if (punits.
compare (
"centimeters"))
3493 mm2units = 1 / 10.0;
3498 mm2units = 72.0 / 25.4;
3503 ret (0) = 8.5 * in2units;
3504 ret (1) = 11.0 * in2units;
3506 else if (typ.
compare (
"uslegal"))
3508 ret (0) = 8.5 * in2units;
3509 ret (1) = 14.0 * in2units;
3511 else if (typ.
compare (
"tabloid"))
3513 ret (0) = 11.0 * in2units;
3514 ret (1) = 17.0 * in2units;
3518 ret (0) = 841.0 * mm2units;
3519 ret (1) = 1189.0 * mm2units;
3523 ret (0) = 594.0 * mm2units;
3524 ret (1) = 841.0 * mm2units;
3528 ret (0) = 420.0 * mm2units;
3529 ret (1) = 594.0 * mm2units;
3533 ret (0) = 297.0 * mm2units;
3534 ret (1) = 420.0 * mm2units;
3538 ret (0) = 210.0 * mm2units;
3539 ret (1) = 297.0 * mm2units;
3543 ret (0) = 148.0 * mm2units;
3544 ret (1) = 210.0 * mm2units;
3548 ret (0) = 1029.0 * mm2units;
3549 ret (1) = 1456.0 * mm2units;
3553 ret (0) = 728.0 * mm2units;
3554 ret (1) = 1028.0 * mm2units;
3558 ret (0) = 514.0 * mm2units;
3559 ret (1) = 728.0 * mm2units;
3563 ret (0) = 364.0 * mm2units;
3564 ret (1) = 514.0 * mm2units;
3568 ret (0) = 257.0 * mm2units;
3569 ret (1) = 364.0 * mm2units;
3573 ret (0) = 182.0 * mm2units;
3574 ret (1) = 257.0 * mm2units;
3576 else if (typ.
compare (
"arch-a"))
3578 ret (0) = 9.0 * in2units;
3579 ret (1) = 12.0 * in2units;
3581 else if (typ.
compare (
"arch-b"))
3583 ret (0) = 12.0 * in2units;
3584 ret (1) = 18.0 * in2units;
3586 else if (typ.
compare (
"arch-c"))
3588 ret (0) = 18.0 * in2units;
3589 ret (1) = 24.0 * in2units;
3591 else if (typ.
compare (
"arch-d"))
3593 ret (0) = 24.0 * in2units;
3594 ret (1) = 36.0 * in2units;
3596 else if (typ.
compare (
"arch-e"))
3598 ret (0) = 36.0 * in2units;
3599 ret (1) = 48.0 * in2units;
3603 ret (0) = 8.5 * in2units;
3604 ret (1) = 11.0 * in2units;
3608 ret (0) = 11.0 * in2units;
3609 ret (1) = 17.0 * in2units;
3613 ret (0) = 17.0 * in2units;
3614 ret (1) = 22.0 * in2units;
3618 ret (0) = 22.0 * in2units;
3619 ret (1) = 34.0 * in2units;
3623 ret (0) = 34.0 * in2units;
3624 ret (1) = 43.0 * in2units;
3634 Matrix pos = get_paperposition ().matrix_value ();
3635 Matrix sz = get_papersize ().matrix_value ();
3642 std::string porient = get_paperorientation ();
3648 if (old_paperunits.
compare (
"centimeters"))
3653 else if (old_paperunits.
compare (
"points"))
3659 if (punits.
compare (
"centimeters"))
3664 else if (punits.
compare (
"points"))
3673 if (porient ==
"landscape")
3674 std::swap (sz(0), sz(1));
3690 if (! typ.
compare (
"<custom>"))
3693 if (get_paperorientation () ==
"landscape")
3694 std::swap (sz(0), sz(1));
3704 Matrix sz = get_papersize ().matrix_value ();
3707 std::swap (sz(0), sz(1));
3713 paperorientation.set (
"portrait");
3715 std::string punits = get_paperunits ();
3716 if (punits ==
"centimeters")
3721 else if (punits ==
"points")
3726 if (punits ==
"normalized")
3729 if (get_papertype () ==
"<custom>")
3730 error (
"set: can't set the papertype to <custom> when the paperunits is normalized");
3736 std::string typ =
"<custom>";
3737 const double mm2in = 1.0 / 25.4;
3738 const double tol = 0.01;
3746 else if (
std::abs (sz(0) - 841.0 * mm2in)
3747 +
std::abs (sz(1) - 1198.0 * mm2in) < tol)
3749 else if (
std::abs (sz(0) - 594.0 * mm2in)
3750 +
std::abs (sz(1) - 841.0 * mm2in) < tol)
3752 else if (
std::abs (sz(0) - 420.0 * mm2in)
3753 +
std::abs (sz(1) - 594.0 * mm2in) < tol)
3755 else if (
std::abs (sz(0) - 297.0 * mm2in)
3756 +
std::abs (sz(1) - 420.0 * mm2in) < tol)
3758 else if (
std::abs (sz(0) - 210.0 * mm2in)
3759 +
std::abs (sz(1) - 297.0 * mm2in) < tol)
3761 else if (
std::abs (sz(0) - 148.0 * mm2in)
3762 +
std::abs (sz(1) - 210.0 * mm2in) < tol)
3764 else if (
std::abs (sz(0) - 1029.0 * mm2in)
3765 +
std::abs (sz(1) - 1456.0 * mm2in) < tol)
3767 else if (
std::abs (sz(0) - 728.0 * mm2in)
3768 +
std::abs (sz(1) - 1028.0 * mm2in) < tol)
3770 else if (
std::abs (sz(0) - 514.0 * mm2in)
3771 +
std::abs (sz(1) - 728.0 * mm2in) < tol)
3773 else if (
std::abs (sz(0) - 364.0 * mm2in)
3774 +
std::abs (sz(1) - 514.0 * mm2in) < tol)
3776 else if (
std::abs (sz(0) - 257.0 * mm2in)
3777 +
std::abs (sz(1) - 364.0 * mm2in) < tol)
3779 else if (
std::abs (sz(0) - 182.0 * mm2in)
3780 +
std::abs (sz(1) - 257.0 * mm2in) < tol)
3814 papertype.set (typ);
3816 if (punits ==
"centimeters")
3821 else if (punits ==
"points")
3826 if (get_paperorientation () ==
"landscape")
3828 std::swap (sz(0), sz(1));
3868 std::string porient = get_paperorientation ();
3869 Matrix sz = get_papersize ().matrix_value ();
3870 Matrix pos = get_paperposition ().matrix_value ();
3871 if ((sz(0) > sz(1) && porient ==
"portrait")
3872 || (sz(0) < sz(1) && porient ==
"landscape"))
3874 std::swap (sz(0), sz(1));
3875 std::swap (pos(0), pos(1));
3876 std::swap (pos(2), pos(3));
3917 if (units.set (v,
true))
3919 update_units (old_units);
3928 position.set (
convert_position (get_position ().matrix_value (), old_units,
3953 if (is_numbertitle ())
3955 std::ostringstream os;
3956 std::string nm = get_name ();
3958 os <<
"Figure " << __myhandle__.value ();
3960 os <<
": " << get_name ();
3996 outerposition.add_constraint (
dim_vector (1, 4));
3997 tightinset.add_constraint (
dim_vector (1, 4));
3998 looseinset.add_constraint (
dim_vector (1, 4));
3999 colororder.add_constraint (
dim_vector (-1, 3));
4000 dataaspectratio.add_constraint (
dim_vector (1, 3));
4001 plotboxaspectratio.add_constraint (
dim_vector (1, 3));
4002 alim.add_constraint (2);
4003 clim.add_constraint (2);
4004 xlim.add_constraint (2);
4005 ylim.add_constraint (2);
4006 zlim.add_constraint (2);
4010 ticklength.add_constraint (
dim_vector (1, 2));
4015 cameraposition.add_constraint (
dim_vector (1, 3));
4016 cameratarget.add_constraint (
dim_vector (1, 3));
4019 cameraupvector = upv;
4020 cameraupvector.add_constraint (
dim_vector (1, 3));
4021 currentpoint.add_constraint (
dim_vector (2, 3));
4025 x_zlim.resize (1, 2);
4031 calc_ticklabels (xtick, xticklabel, xscale.is (
"log"));
4032 calc_ticklabels (ytick, yticklabel, yscale.is (
"log"));
4033 calc_ticklabels (ztick, zticklabel, zscale.is (
"log"));
4035 xset (xlabel.handle_value (),
"handlevisibility",
"off");
4036 xset (ylabel.handle_value (),
"handlevisibility",
"off");
4037 xset (zlabel.handle_value (),
"handlevisibility",
"off");
4038 xset (title.handle_value (),
"handlevisibility",
"off");
4040 xset (xlabel.handle_value (),
"horizontalalignment",
"center");
4041 xset (xlabel.handle_value (),
"horizontalalignmentmode",
"auto");
4042 xset (ylabel.handle_value (),
"horizontalalignment",
"center");
4043 xset (ylabel.handle_value (),
"horizontalalignmentmode",
"auto");
4044 xset (zlabel.handle_value (),
"horizontalalignment",
"right");
4045 xset (zlabel.handle_value (),
"horizontalalignmentmode",
"auto");
4046 xset (title.handle_value (),
"horizontalalignment",
"center");
4047 xset (title.handle_value (),
"horizontalalignmentmode",
"auto");
4049 xset (xlabel.handle_value (),
"verticalalignment",
"top");
4050 xset (xlabel.handle_value (),
"verticalalignmentmode",
"auto");
4051 xset (ylabel.handle_value (),
"verticalalignment",
"bottom");
4052 xset (ylabel.handle_value (),
"verticalalignmentmode",
"auto");
4053 xset (title.handle_value (),
"verticalalignment",
"bottom");
4054 xset (title.handle_value (),
"verticalalignmentmode",
"auto");
4056 xset (ylabel.handle_value (),
"rotation", 90.0);
4057 xset (ylabel.handle_value (),
"rotationmode",
"auto");
4059 xset (zlabel.handle_value (),
"visible",
"off");
4061 xset (xlabel.handle_value (),
"clipping",
"off");
4062 xset (ylabel.handle_value (),
"clipping",
"off");
4063 xset (zlabel.handle_value (),
"clipping",
"off");
4064 xset (title.handle_value (),
"clipping",
"off");
4066 xset (xlabel.handle_value (),
"autopos_tag",
"xlabel");
4067 xset (ylabel.handle_value (),
"autopos_tag",
"ylabel");
4068 xset (zlabel.handle_value (),
"autopos_tag",
"zlabel");
4069 xset (title.handle_value (),
"autopos_tag",
"title");
4071 adopt (xlabel.handle_value ());
4072 adopt (ylabel.handle_value ());
4073 adopt (zlabel.handle_value ());
4074 adopt (title.handle_value ());
4077 tlooseinset(2) = 1-tlooseinset(0)-tlooseinset(2);
4078 tlooseinset(3) = 1-tlooseinset(1)-tlooseinset(3);
4079 looseinset = tlooseinset;
4088 Matrix ext = get_extent (
true,
true);
4089 ext(1) = parent_bb(3) - ext(1) - ext(3);
4094 if (ext(0) < pos(0))
4096 pos(2) += pos(0)-ext(0);
4099 if (ext(0)+ext(2) > pos(0)+pos(2))
4100 pos(2) = ext(0)+ext(2)-pos(0);
4102 if (ext(1) < pos(1))
4104 pos(3) += pos(1)-ext(1);
4107 if (ext(1)+ext(3) > pos(1)+pos(3))
4108 pos(3) = ext(1)+ext(3)-pos(1);
4116 if (activepositionproperty.is (
"position"))
4119 update_outerposition ();
4121 set_units (
"normalized");
4122 Matrix pos = position.get ().matrix_value ();
4123 Matrix outpos = outerposition.get ().matrix_value ();
4124 Matrix tightpos = calc_tightbox (pos);
4125 Matrix tinset (1, 4, 1.0);
4126 tinset(0) = pos(0)-tightpos(0);
4127 tinset(1) = pos(1)-tightpos(1);
4128 tinset(2) = tightpos(0)+tightpos(2)-pos(0)-pos(2);
4129 tinset(3) = tightpos(1)+tightpos(3)-pos(1)-pos(3);
4130 tightinset = tinset;
4131 set_units (old_units);
4132 update_transform ();
4133 if (activepositionproperty.is (
"position"))
4136 update_outerposition ();
4202 const std::string& who,
4212 xset (val,
"string", v);
4218 if (go.
isa (
"text"))
4219 val = ::
reparent (v,
"set", who, __myhandle__,
false);
4224 error (
"set: expecting text graphics object or character string for %s property, found %s",
4225 who.c_str (), cname.c_str ());
4231 xset (val,
"handlevisibility",
"off");
4239 adopt (hp.handle_value ());
4246 set_text_child (xlabel,
"xlabel", v);
4247 xset (xlabel.handle_value (),
"positionmode",
"auto");
4248 xset (xlabel.handle_value (),
"rotationmode",
"auto");
4249 xset (xlabel.handle_value (),
"horizontalalignmentmode",
"auto");
4250 xset (xlabel.handle_value (),
"verticalalignmentmode",
"auto");
4251 xset (xlabel.handle_value (),
"clipping",
"off");
4252 xset (xlabel.handle_value (),
"color", get_xcolor ());
4253 xset (xlabel.handle_value (),
"autopos_tag",
"xlabel");
4254 update_xlabel_position ();
4260 set_text_child (ylabel,
"ylabel", v);
4261 xset (ylabel.handle_value (),
"positionmode",
"auto");
4262 xset (ylabel.handle_value (),
"rotationmode",
"auto");
4263 xset (ylabel.handle_value (),
"horizontalalignmentmode",
"auto");
4264 xset (ylabel.handle_value (),
"verticalalignmentmode",
"auto");
4265 xset (ylabel.handle_value (),
"clipping",
"off");
4266 xset (ylabel.handle_value (),
"color", get_ycolor ());
4267 xset (ylabel.handle_value (),
"autopos_tag",
"ylabel");
4268 update_ylabel_position ();
4274 set_text_child (zlabel,
"zlabel", v);
4275 xset (zlabel.handle_value (),
"positionmode",
"auto");
4276 xset (zlabel.handle_value (),
"rotationmode",
"auto");
4277 xset (zlabel.handle_value (),
"horizontalalignmentmode",
"auto");
4278 xset (zlabel.handle_value (),
"verticalalignmentmode",
"auto");
4279 xset (zlabel.handle_value (),
"clipping",
"off");
4280 xset (zlabel.handle_value (),
"color", get_zcolor ());
4281 xset (zlabel.handle_value (),
"autopos_tag",
"zlabel");
4282 update_zlabel_position ();
4288 set_text_child (title,
"title", v);
4289 xset (title.handle_value (),
"positionmode",
"auto");
4290 xset (title.handle_value (),
"horizontalalignment",
"center");
4291 xset (title.handle_value (),
"horizontalalignmentmode",
"auto");
4292 xset (title.handle_value (),
"verticalalignment",
"bottom");
4293 xset (title.handle_value (),
"verticalalignmentmode",
"auto");
4294 xset (title.handle_value (),
"clipping",
"off");
4295 xset (title.handle_value (),
"autopos_tag",
"title");
4296 update_title_position ();
4301 const std::string& mode)
4306 dataaspectratiomode =
"auto";
4345 xticklabelmode =
"auto";
4346 yticklabelmode =
"auto";
4347 zticklabelmode =
"auto";
4349 interpreter =
"none";
4361 yaxislocation =
"left";
4362 xaxislocation =
"bottom";
4364 Matrix tview (1, 2, 0.0);
4368 __hold_all__ =
"off";
4369 nextplot =
"replace";
4371 ambientlightcolor =
Matrix (1, 3, 1.0);
4374 camerapositionmode =
"auto";
4375 cameratargetmode =
"auto";
4376 cameraupvectormode =
"auto";
4377 cameraviewanglemode =
"auto";
4379 drawmode =
"normal";
4381 fontangle =
"normal";
4384 fontunits =
"points";
4385 fontweight =
"normal";
4387 gridlinestyle =
":";
4388 linestyleorder =
"-";
4390 minorgridlinestyle =
":";
4393 plotboxaspectratiomode =
"auto";
4394 projection =
"orthographic";
4397 tickdirmode =
"auto";
4400 tightinset =
Matrix (1, 4, 0.0);
4409 if (mode !=
"replace")
4413 activepositionproperty =
"outerposition";
4416 delete_children (
true);
4430 xset (xlabel.handle_value (),
"handlevisibility",
"off");
4431 xset (ylabel.handle_value (),
"handlevisibility",
"off");
4432 xset (zlabel.handle_value (),
"handlevisibility",
"off");
4433 xset (title.handle_value (),
"handlevisibility",
"off");
4435 xset (xlabel.handle_value (),
"horizontalalignment",
"center");
4436 xset (xlabel.handle_value (),
"horizontalalignmentmode",
"auto");
4437 xset (ylabel.handle_value (),
"horizontalalignment",
"center");
4438 xset (ylabel.handle_value (),
"horizontalalignmentmode",
"auto");
4439 xset (zlabel.handle_value (),
"horizontalalignment",
"right");
4440 xset (zlabel.handle_value (),
"horizontalalignmentmode",
"auto");
4441 xset (title.handle_value (),
"horizontalalignment",
"center");
4442 xset (title.handle_value (),
"horizontalalignmentmode",
"auto");
4444 xset (xlabel.handle_value (),
"verticalalignment",
"top");
4445 xset (xlabel.handle_value (),
"verticalalignmentmode",
"auto");
4446 xset (ylabel.handle_value (),
"verticalalignment",
"bottom");
4447 xset (ylabel.handle_value (),
"verticalalignmentmode",
"auto");
4448 xset (title.handle_value (),
"verticalalignment",
"bottom");
4449 xset (title.handle_value (),
"verticalalignmentmode",
"auto");
4451 xset (ylabel.handle_value (),
"rotation", 90.0);
4452 xset (ylabel.handle_value (),
"rotationmode",
"auto");
4454 xset (zlabel.handle_value (),
"visible",
"off");
4456 xset (xlabel.handle_value (),
"clipping",
"off");
4457 xset (ylabel.handle_value (),
"clipping",
"off");
4458 xset (zlabel.handle_value (),
"clipping",
"off");
4459 xset (title.handle_value (),
"clipping",
"off");
4461 xset (xlabel.handle_value (),
"autopos_tag",
"xlabel");
4462 xset (ylabel.handle_value (),
"autopos_tag",
"ylabel");
4463 xset (zlabel.handle_value (),
"autopos_tag",
"zlabel");
4464 xset (title.handle_value (),
"autopos_tag",
"title");
4466 adopt (xlabel.handle_value ());
4467 adopt (ylabel.handle_value ());
4468 adopt (zlabel.handle_value ());
4469 adopt (title.handle_value ());
4471 update_transform ();
4496 if (! is_beingdeleted ())
4510 if (xlabel.handle_value ().ok () && h == xlabel.handle_value ())
4511 delete_text_child (xlabel);
4512 else if (ylabel.handle_value ().ok () && h == ylabel.handle_value ())
4513 delete_text_child (ylabel);
4514 else if (zlabel.handle_value ().ok () && h == zlabel.handle_value ())
4515 delete_text_child (zlabel);
4516 else if (title.handle_value ().ok () && h == title.handle_value ())
4517 delete_text_child (title);
4526 for (
int i = 0; i < 4; i++)
4543 v(0) =
x; v(1) = y; v(2) = z;
4557 m(0,0) =
x; m(1,1) = y; m(2,2) = z; m(3,3) = 1;
4565 m(0,3) =
x; m(1,3) = y; m(2,3) = z; m(3,3) = 1;
4606 double fact = 1.0 / sqrt (v(0)*v(0)+v(1)*v(1)+v(2)*v(2));
4607 scale (v, fact, fact, fact);
4619 return sqrt (
dot (v, v));
4635 static double data[32] =
4668 double xd = (xdir_is (
"normal") ? 1 : -1);
4669 double yd = (ydir_is (
"normal") ? 1 : -1);
4670 double zd = (zdir_is (
"normal") ? 1 : -1);
4672 Matrix xlimits = sx.scale (get_xlim ().matrix_value ());
4673 Matrix ylimits = sy.scale (get_ylim ().matrix_value ());
4674 Matrix zlimits = sz.scale (get_zlim ().matrix_value ());
4676 double xo = xlimits(xd > 0 ? 0 : 1);
4677 double yo = ylimits(yd > 0 ? 0 : 1);
4678 double zo = zlimits(zd > 0 ? 0 : 1);
4680 Matrix pb = get_plotboxaspectratio ().matrix_value ();
4682 bool autocam = (camerapositionmode_is (
"auto")
4683 && cameratargetmode_is (
"auto")
4684 && cameraupvectormode_is (
"auto")
4685 && cameraviewanglemode_is (
"auto"));
4686 bool dowarp = (autocam && dataaspectratiomode_is (
"auto")
4687 && plotboxaspectratiomode_is (
"auto"));
4693 if (cameratargetmode_is (
"auto"))
4695 c_center(0) = (xlimits(0)+xlimits(1))/2;
4696 c_center(1) = (ylimits(0)+ylimits(1))/2;
4697 c_center(2) = (zlimits(0)+zlimits(1))/2;
4702 c_center =
cam2xform (get_cameratarget ().matrix_value ());
4704 if (camerapositionmode_is (
"auto"))
4706 Matrix tview = get_view ().matrix_value ();
4707 double az = tview(0), el = tview(1);
4708 double d = 5 * sqrt (pb(0)*pb(0)+pb(1)*pb(1)+pb(2)*pb(2));
4710 if (el == 90 || el == -90)
4711 c_eye(2) = d*
signum (el);
4716 c_eye(0) = d * cos (el) * sin (az);
4717 c_eye(1) = -d* cos (el) * cos (az);
4718 c_eye(2) = d * sin (el);
4720 c_eye(0) = c_eye(0)*(xlimits(1)-xlimits(0))/(xd*pb(0))+c_center(0);
4721 c_eye(1) = c_eye(1)*(ylimits(1)-ylimits(0))/(yd*pb(1))+c_center(1);
4722 c_eye(2) = c_eye(2)*(zlimits(1)-zlimits(0))/(zd*pb(2))+c_center(2);
4727 c_eye =
cam2xform (get_cameraposition ().matrix_value ());
4729 if (cameraupvectormode_is (
"auto"))
4731 Matrix tview = get_view ().matrix_value ();
4732 double az = tview(0), el = tview(1);
4734 if (el == 90 || el == -90)
4737 -
signum (el) *sin (az*M_PI/180.0)*(xlimits(1)-xlimits(0))/pb(0);
4739 signum (el) * cos (az*M_PI/180.0)*(ylimits(1)-ylimits(0))/pb(1);
4747 c_upv =
cam2xform (get_cameraupvector ().matrix_value ());
4758 scale (x_pre, pb(0), pb(1), pb(2));
4760 scale (x_pre, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
4761 zd/(zlimits(1)-zlimits(0)));
4764 xform (c_eye, x_pre);
4765 xform (c_center, x_pre);
4766 scale (c_upv, pb(0)/(xlimits(1)-xlimits(0)), pb(1)/(ylimits(1)-ylimits(0)),
4767 pb(2)/(zlimits(1)-zlimits(0)));
4768 translate (c_center, -c_eye(0), -c_eye(1), -c_eye(2));
4776 double fa = 1 / sqrt(1-
f(2)*
f(2));
4777 scale (UP, fa, fa, fa);
4783 scale (x_view, 1, 1, -1);
4785 l(0,0) = s(0); l(0,1) = s(1); l(0,2) = s(2);
4786 l(1,0) = u(0); l(1,1) = u(1); l(1,2) = u(2);
4787 l(2,0) = -
f(0); l(2,1) = -
f(1); l(2,2) = -
f(2);
4788 x_view = x_view * l;
4789 translate (x_view, -c_eye(0), -c_eye(1), -c_eye(2));
4790 scale (x_view, pb(0), pb(1), pb(2));
4795 double xM = cmax(0)-cmin(0);
4796 double yM = cmax(1)-cmin(1);
4798 Matrix bb = get_boundingbox (
true);
4802 if (cameraviewanglemode_is (
"auto"))
4809 if (
false && dowarp)
4810 af = 1.0 / (xM > yM ? xM : yM);
4813 if ((bb(2)/bb(3)) > (xM/yM))
4818 v_angle = 2 * (180.0 / M_PI) *
atan (1 / (2 * af *
norm (
F)));
4820 cameraviewangle = v_angle;
4823 v_angle = get_cameraviewangle ();
4825 double pf = 1 / (2 * tan ((v_angle / 2) * M_PI / 180.0) *
norm (
F));
4826 scale (x_projection, pf, pf, 1);
4832 translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
4833 scale (x_viewport, bb(2)/xM, -bb(3)/yM, 1);
4840 if ((bb(2)/bb(3)) > (xM/yM))
4846 pix = (bb(2) < bb(3) ? bb(2) : bb(3));
4847 translate (x_viewport, bb(0)+bb(2)/2, bb(1)+bb(3)/2, 0);
4848 scale (x_viewport, pix, -pix, 1);
4851 x_normrender = x_viewport * x_projection * x_view;
4857 x_zlim(0) = cmin(2);
4858 x_zlim(1) = cmax(2);
4860 x_render = x_normrender;
4861 scale (x_render, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
4862 zd/(zlimits(1)-zlimits(0)));
4865 x_viewtransform = x_view;
4866 x_projectiontransform = x_projection;
4867 x_viewporttransform = x_viewport;
4868 x_normrendertransform = x_normrender;
4869 x_rendertransform = x_render;
4871 x_render_inv = x_render.
inverse ();
4877 scale (x_gl_mat1, xd/(xlimits(1)-xlimits(0)), yd/(ylimits(1)-ylimits(0)),
4878 zd/(zlimits(1)-zlimits(0)));
4880 x_gl_mat2 = x_viewport * x_projection;
4888 if (updating_axes_layout)
4893 double xd = (xdir_is (
"normal") ? 1 : -1);
4894 double yd = (ydir_is (
"normal") ? 1 : -1);
4895 double zd = (zdir_is (
"normal") ? 1 : -1);
4897 const Matrix xlims = xform.
xscale (get_xlim ().matrix_value ());
4898 const Matrix ylims = xform.
yscale (get_ylim ().matrix_value ());
4899 const Matrix zlims = xform.
zscale (get_zlim ().matrix_value ());
4900 double x_min = xlims(0), x_max = xlims(1);
4901 double y_min = ylims(0), y_max = ylims(1);
4902 double z_min = zlims(0), z_max = zlims(1);
4908 p1 = xform.
transform (x_min, (y_min+y_max)/2, (z_min+z_max)/2,
false);
4909 p2 = xform.
transform (x_max, (y_min+y_max)/2, (z_min+z_max)/2,
false);
4910 dir(0) =
xround (p2(0)-p1(0));
4911 dir(1) =
xround (p2(1)-p1(1));
4912 dir(2) = (p2(2)-p1(2));
4913 if (dir(0) == 0 && dir(1) == 0)
4915 else if (dir(2) == 0)
4919 else if (dir(1) == 0)
4926 xPlane = (dir(0) > 0 ? x_max : x_min);
4928 xPlane = (dir(1) < 0 ? x_max : x_min);
4931 xPlane = (dir(2) < 0 ? x_min : x_max);
4933 xPlaneN = (xPlane == x_min ? x_max : x_min);
4934 fx = (x_max-x_min) / sqrt (dir(0)*dir(0)+dir(1)*dir(1));
4936 p1 = xform.
transform ((x_min+x_max)/2, y_min, (z_min+z_max)/2,
false);
4937 p2 = xform.
transform ((x_min+x_max)/2, y_max, (z_min+z_max)/2,
false);
4938 dir(0) =
xround (p2(0)-p1(0));
4939 dir(1) =
xround (p2(1)-p1(1));
4940 dir(2) = (p2(2)-p1(2));
4941 if (dir(0) == 0 && dir(1) == 0)
4943 else if (dir(2) == 0)
4947 else if (dir(1) == 0)
4954 yPlane = (dir(0) > 0 ? y_max : y_min);
4956 yPlane = (dir(1) < 0 ? y_max : y_min);
4959 yPlane = (dir(2) < 0 ? y_min : y_max);
4961 yPlaneN = (yPlane == y_min ? y_max : y_min);
4962 fy = (y_max-y_min) / sqrt (dir(0)*dir(0)+dir(1)*dir(1));
4964 p1 = xform.
transform ((x_min+x_max)/2, (y_min+y_max)/2, z_min,
false);
4965 p2 = xform.
transform ((x_min+x_max)/2, (y_min+y_max)/2, z_max,
false);
4966 dir(0) =
xround (p2(0)-p1(0));
4967 dir(1) =
xround (p2(1)-p1(1));
4968 dir(2) = (p2(2)-p1(2));
4969 if (dir(0) == 0 && dir(1) == 0)
4971 else if (dir(2) == 0)
4975 else if (dir(1) == 0)
4982 zPlane = (dir(0) > 0 ? z_min : z_max);
4984 zPlane = (dir(1) < 0 ? z_min : z_max);
4987 zPlane = (dir(2) < 0 ? z_min : z_max);
4989 zPlaneN = (zPlane == z_min ? z_max : z_min);
4990 fz = (z_max-z_min) / sqrt (dir(0)*dir(0)+dir(1)*dir(1));
4994 updating_axes_layout =
true;
4996 xySym = (xd*yd*(xPlane-xPlaneN)*(yPlane-yPlaneN) > 0);
4997 zSign = (zd*(zPlane-zPlaneN) <= 0);
4998 xyzSym = zSign ? xySym : !xySym;
4999 xpTick = (zSign ? xPlaneN : xPlane);
5000 ypTick = (zSign ? yPlaneN : yPlane);
5001 zpTick = (zSign ? zPlane : zPlaneN);
5002 xpTickN = (zSign ? xPlane : xPlaneN);
5003 ypTickN = (zSign ? yPlane : yPlaneN);
5004 zpTickN = (zSign ? zPlaneN : zPlane);
5012 if (xaxislocation_is (
"top"))
5014 double tmp = yPlane;
5021 if (yaxislocation_is (
"right"))
5023 double tmp = xPlane;
5030 if (layer_is (
"top"))
5039 Matrix viewmat = get_view ().matrix_value ();
5040 nearhoriz =
std::abs (viewmat(1)) <= 5;
5042 update_ticklength ();
5052 if (tickdirmode_is (
"auto"))
5053 tickdir.set (mode2d ?
"in" :
"out",
true);
5055 double ticksign = (tickdir_is (
"in") ? -1 : 1);
5057 Matrix bbox = get_boundingbox (
true);
5058 Matrix ticklen = get_ticklength ().matrix_value ();
5059 ticklen(0) = ticklen(0) *
std::max (bbox(2), bbox(3));
5060 ticklen(1) = ticklen(1) *
std::max (bbox(2), bbox(3));
5062 xticklen = ticksign * (mode2d ? ticklen(0) : ticklen(1));
5063 yticklen = ticksign * (mode2d ? ticklen(0) : ticklen(1));
5064 zticklen = ticksign * (mode2d ? ticklen(0) : ticklen(1));
5066 xtickoffset = (mode2d ?
std::max (0., xticklen) :
std::abs (xticklen)) + 5;
5067 ytickoffset = (mode2d ?
std::max (0., yticklen) :
std::abs (yticklen)) + 5;
5068 ztickoffset = (mode2d ?
std::max (0., zticklen) :
std::abs (zticklen)) + 5;
5070 update_xlabel_position ();
5071 update_ylabel_position ();
5072 update_zlabel_position ();
5073 update_title_position ();
5099 if (updating_xlabel_position)
5110 updating_xlabel_position =
true;
5118 ?
"center" : (xyzSym ?
"left" :
"right"));
5138 ext = get_ticklabel_extents (get_xtick ().matrix_value (),
5139 get_xticklabel ().all_strings (),
5140 get_xlim ().matrix_value ());
5142 double wmax = ext(0), hmax = ext(1), angle = 0;
5146 bool tick_along_z = nearhoriz ||
xisinf (fy);
5148 p(2) += (
signum (zpTick-zpTickN)*fz*xtickoffset);
5150 p(1) += (
signum (ypTick-ypTickN)*fy*xtickoffset);
5152 p = xform.
transform (p(0), p(1), p(2),
false);
5157 p(0) += (xyzSym ? wmax : -wmax);
5167 p(1) += (x2Dtop ? -hmax : hmax);
5191 if (updating_ylabel_position)
5202 updating_ylabel_position =
true;
5210 ?
"center" : (!xyzSym ?
"left" :
"right"));
5218 (ystate ==
AXE_VERT_DIR && !y2Dright ?
"bottom" :
"top");
5239 ext = get_ticklabel_extents (get_ytick ().matrix_value (),
5240 get_yticklabel ().all_strings (),
5241 get_ylim ().matrix_value ());
5243 double wmax = ext(0)+4, hmax = ext(1), angle = 0;
5247 bool tick_along_z = nearhoriz ||
xisinf (fx);
5249 p(2) += (
signum (zpTick-zpTickN)*fz*ytickoffset);
5251 p(0) += (
signum (xpTick-xpTickN)*fx*ytickoffset);
5253 p = xform.
transform (p(0), p(1), p(2),
false);
5258 p(0) += (!xyzSym ? wmax : -wmax);
5263 p(0) += (y2Dright ? wmax : -wmax);
5292 if (updating_zlabel_position)
5299 bool camAuto = cameraupvectormode_is (
"auto");
5304 updating_zlabel_position =
true;
5320 ?
"bottom" : ((zSign || camAuto) ?
"bottom" :
"top"));
5332 ext = get_ticklabel_extents (get_ztick ().matrix_value (),
5333 get_zticklabel ().all_strings (),
5334 get_zlim ().matrix_value ());
5336 double wmax = ext(0), hmax = ext(1), angle = 0;
5342 (zpTickN+zpTick)/2);
5344 p(0) += (
signum (xPlaneN-xPlane)*fx*ztickoffset);
5346 p(1) += (
signum (yPlane-yPlaneN)*fy*ztickoffset);
5351 (zpTickN+zpTick)/2);
5353 p(1) += (
signum (yPlaneN-yPlane)*fy*ztickoffset);
5355 p(0) += (
signum (xPlane-xPlaneN)*fx*ztickoffset);
5358 p = xform.
transform (p(0), p(1), p(2),
false);
5406 if (updating_title_position)
5415 updating_title_position =
true;
5422 Matrix bbox = get_extent (
false);
5427 (x_zlim(0)+x_zlim(1))/2);
5432 ext = get_ticklabel_extents (get_xtick ().matrix_value (),
5433 get_xticklabel ().all_strings (),
5434 get_xlim ().matrix_value ());
5448 if (elem_type ==
"xlabel")
5449 update_xlabel_position ();
5450 else if (elem_type ==
"ylabel")
5451 update_ylabel_position ();
5452 else if (elem_type ==
"zlabel")
5453 update_zlabel_position ();
5454 else if (elem_type ==
"title")
5455 update_title_position ();
5456 else if (elem_type ==
"sync")
5462 double xlength,
double ylength,
double zlength)
5464 double xval = xlength/scalefactors(0);
5465 double yval = ylength/scalefactors(1);
5466 double zval = zlength/scalefactors(2);
5468 double minval =
xmin (
xmin (xval, yval), zval);
5470 aspectratios(0) = xval/minval;
5471 aspectratios(1) = yval/minval;
5472 aspectratios(2) = zval/minval;
5477 double pbfactor,
double dafactor,
char limit_type,
bool tight)
5490 s =
xmax(s, (maxval - minval) / (pbfactor * dafactor));
5494 s =
xmax(s, (limits(1) - limits(0)) / (pbfactor * dafactor));
5502 if (updating_aspectratios)
5505 Matrix xlimits = get_xlim ().matrix_value ();
5506 Matrix ylimits = get_ylim ().matrix_value ();
5507 Matrix zlimits = get_zlim ().matrix_value ();
5509 double dx = (xlimits(1)-xlimits(0));
5510 double dy = (ylimits(1)-ylimits(0));
5511 double dz = (zlimits(1)-zlimits(0));
5513 Matrix da = get_dataaspectratio ().matrix_value ();
5514 Matrix pba = get_plotboxaspectratio ().matrix_value ();
5516 if (dataaspectratiomode_is (
"auto"))
5518 if (plotboxaspectratiomode_is (
"auto"))
5520 pba =
Matrix (1, 3, 1.0);
5521 plotboxaspectratio.set (pba,
false);
5525 dataaspectratio.set (da,
false);
5527 else if (plotboxaspectratiomode_is (
"auto"))
5530 plotboxaspectratio.set (pba,
false);
5535 bool modified_limits =
false;
5538 if (xlimmode_is (
"auto") && ylimmode_is (
"auto") && zlimmode_is (
"auto"))
5540 modified_limits =
true;
5541 kids = get_children ();
5546 else if (xlimmode_is (
"auto") && ylimmode_is (
"auto"))
5548 modified_limits =
true;
5551 else if (ylimmode_is (
"auto") && zlimmode_is (
"auto"))
5553 modified_limits =
true;
5556 else if (zlimmode_is (
"auto") && xlimmode_is (
"auto"))
5558 modified_limits =
true;
5562 if (modified_limits)
5568 updating_aspectratios =
true;
5576 if (xlimmode_is (
"auto"))
5579 xlimits(0) = 0.5 * (xlimits(0) + xlimits(1) - dx);
5580 xlimits(1) = xlimits(0) + dx;
5582 set_xlimmode (
"auto");
5585 if (ylimmode_is (
"auto"))
5588 ylimits(0) = 0.5 * (ylimits(0) + ylimits(1) - dy);
5589 ylimits(1) = ylimits(0) + dy;
5591 set_ylimmode (
"auto");
5594 if (zlimmode_is (
"auto"))
5597 zlimits(0) = 0.5 * (zlimits(0) + zlimits(1) - dz);
5598 zlimits(1) = zlimits(0) + dz;
5600 set_zlimmode (
"auto");
5606 plotboxaspectratio.set (pba,
false);
5614 #ifdef HAVE_FREETYPE
5615 #ifdef HAVE_FONTCONFIG
5616 text_renderer.set_font (
get (
"fontname").string_value (),
5617 get (
"fontweight").string_value (),
5618 get (
"fontangle").string_value (),
5619 get (
"fontsize").double_value ());
5628 const Matrix& parent_pix_size)
const
5630 Matrix pos =
internal ? get_position ().matrix_value ()
5631 : get_outerposition ().matrix_value ();
5632 Matrix parent_size (parent_pix_size);
5634 if (parent_size.
numel () == 0)
5649 pos(1) = parent_size(1) - pos(1) - pos(3);
5664 for (
int i = 0; i <= 1; i++)
5665 for (
int j = 0; j <= 1; j++)
5666 for (
int k = 0; k <= 1; k++)
5669 j ? yPlaneN : yPlane,
5670 k ? zPlaneN : zPlane,
false);
5679 for (
int i = 0; i < 4; i++)
5683 text_handle = get_title ();
5685 text_handle = get_xlabel ();
5687 text_handle = get_ylabel ();
5689 text_handle = get_zlabel ();
5696 text_pos = xform.
transform (text_pos(0), text_pos(1), text_pos(2));
5699 ext(0) =
std::min (ext(0), text_pos(0));
5700 ext(1) =
std::min (ext(1), text_pos(1));
5701 ext(2) =
std::max (ext(2), text_pos(0));
5702 ext(3) =
std::max (ext(3), text_pos(1));
5708 bool ignore_horizontal =
false;
5709 bool ignore_vertical =
false;
5710 if (only_text_height)
5713 if (text_rotation == 0. || text_rotation == 180.)
5714 ignore_horizontal =
true;
5715 else if (text_rotation == 90. || text_rotation == 270.)
5716 ignore_vertical =
true;
5719 if (! ignore_horizontal)
5721 ext(0) =
std::min (ext(0), text_pos(0)+text_ext(0));
5723 text_pos(0)+text_ext(0)+text_ext(2));
5726 if (! ignore_vertical)
5729 text_pos(1)-text_ext(1)-text_ext(3));
5730 ext(3) =
std::max (ext(3), text_pos(1)-text_ext(1));
5736 ext(2) = ext(2)-ext(0);
5737 ext(3) = ext(3)-ext(1);
5759 std::ostringstream oss;
5771 std::istringstream iss (valstr);
5775 while (std::getline (iss, tmpstr,
'|'))
5779 if (*valstr.rbegin () ==
'|')
5780 sv.
append (std::string (
""));
5800 set_xticklabelmode (
"manual");
5801 xticklabel.run_listeners (
POSTSET);
5805 set_xticklabelmode (
"manual");
5816 set_yticklabelmode (
"manual");
5817 yticklabel.run_listeners (
POSTSET);
5821 set_yticklabelmode (
"manual");
5832 set_zticklabelmode (
"manual");
5833 zticklabel.run_listeners (
POSTSET);
5837 set_zticklabelmode (
"manual");
5860 std::istringstream iss (valstr);
5864 while (std::getline (iss, tmpstr,
'|'))
5868 if (*valstr.rbegin () ==
'|')
5869 sv.
append (std::string (
""));
5897 if (units.set (v,
true))
5899 update_units (old_units);
5913 old_units, new_units,
5917 old_units, new_units,
5921 old_units, new_units,
5925 old_units, new_units,
5936 if (fontunits.set (v,
true))
5938 update_fontunits (old_fontunits);
5948 double parent_height = get_boundingbox (
true).elem (3);
5949 double fsz = get_fontsize ();
5959 double fs = get_fontsize ();
5960 double parent_height = box_pix_height;
5962 if (fontunits_is (
"normalized") && parent_height <= 0)
5963 parent_height = get_boundingbox (
true).elem (3);
5982 bool use_scale)
const
5996 bool use_scale)
const
6002 v(0) = sx.unscale (v(0));
6003 v(1) = sy.unscale (v(1));
6004 v(2) = sz.unscale (v(2));
6051 double& min_pos,
double& max_neg,
6063 if (
xfinite (val) && val < min_val)
6067 if (
xfinite (val) && val > max_val)
6071 if (
xfinite (val) && val > 0 && val < min_pos)
6075 if (
xfinite (val) && val < 0 && val > max_neg)
6116 magform ((hi-lo)/ticint, a, b);
6118 static const double sqrt_2 = sqrt (2.0);
6119 static const double sqrt_10 = sqrt (10.0);
6120 static const double sqrt_50 = sqrt (50.0);
6124 else if (a < sqrt_10)
6126 else if (a < sqrt_50)
6141 double min_pos,
double max_neg,
6146 double min_val =
xmin;
6147 double max_val =
xmax;
6149 if (
xisinf (min_val) && min_val > 0 &&
xisinf (max_val) && max_val < 0)