1-- Demonstrate most Create_Legend capability including unicode symbols.
2--
3-- Copyright (C) 2011-2013 Jerry Bauck
4--
5-- This file is part of PLplot.
6--
7-- PLplot is free software; you can redistribute it and/or modify
8-- it under the terms of the GNU Library General Public License as published
9-- by the Free Software Foundation; either version 2 of the License, or
10-- (at your option) any later version.
11--
12-- PLplot is distributed in the hope that it will be useful,
13-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15-- GNU Library General Public License for more details.
16--
17-- You should have received a copy of the GNU Library General Public License
18-- along with PLplot; if not, write to the Free Software
19-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20--
21
22-- This example designed just for devices (e.g., the cairo-related and
23-- qt-related devices) where the best choice of glyph is automatically
24-- selected by the related libraries (pango/cairo or Qt4) for each
25-- unicode character depending on what system fonts are installed.  Of
26-- course, you must have the appropriate TrueType fonts installed to
27-- have access to all the required glyphs.
28
29-- Ada note: The function TUB is Ada.Strings.Unbounded.To_Unbounded_String
30-- renamed. See PLplot.ads or PLplot.ads.
31
32with
33    Ada.Strings.Unbounded,
34    Ada.Strings,
35    Ada.Strings.Fixed,
36    PLplot_Auxiliary,
37    PLplot_Standard;
38use
39    Ada.Strings.Unbounded,
40    Ada.Strings,
41    Ada.Strings.Fixed,
42    PLplot_Auxiliary,
43    PLplot_Standard;
44
45----------------------------------------------------------------------------
46-- Demonstrate most Create_Legend capability including unicode symbols.
47----------------------------------------------------------------------------
48
49procedure xstandard33a is
50    position_options : Integer_Array_1D(0 .. 15) :=
51       (Pl_Position_Left + Pl_Position_Top + Pl_Position_Outside,
52        Pl_Position_Top + Pl_Position_Outside,
53        Pl_Position_Right + Pl_Position_Top + Pl_Position_Outside,
54        Pl_Position_Right + Pl_Position_Outside,
55        Pl_Position_Right + Pl_Position_Bottom + Pl_Position_Outside,
56        Pl_Position_Bottom + Pl_Position_Outside,
57        Pl_Position_Left + Pl_Position_Bottom + Pl_Position_Outside,
58        Pl_Position_Left + Pl_Position_Outside,
59        Pl_Position_Left + Pl_Position_Top + Pl_Position_Inside,
60        Pl_Position_Top + Pl_Position_Inside,
61        Pl_Position_Right + Pl_Position_Top + Pl_Position_Inside,
62        Pl_Position_Right + Pl_Position_Inside,
63        Pl_Position_Right + Pl_Position_Bottom + Pl_Position_Inside,
64        Pl_Position_Bottom + Pl_Position_Inside,
65        Pl_Position_Left + Pl_Position_Bottom + Pl_Position_Inside,
66        Pl_Position_Left + Pl_Position_Inside);
67
68    -- Pick 5 arbitrary UTF-8 symbols useful for plotting points (✠✚✱✪✽✺✰✴✦).
69    special_symbols : Legend_String_Array_Type(0 .. 4) :=
70       (TUB("✰"), TUB("✴"), TUB("✱"), TUB("✽"), TUB("✦")); -- TUB is renamed To_Unbounded_String.
71
72    -- Create_Colorbar options
73
74    -- Colorbar type options
75    Colorbar_Kinds : constant Integer := 4;
76    colorbar_option_kinds : Integer_Array_1D(0 .. Colorbar_Kinds - 1) := (
77        Pl_Colorbar_Shade,
78        Pl_Colorbar_Shade + Pl_Colorbar_Shade_Label,
79        Pl_Colorbar_Image,
80        Pl_Colorbar_Gradient);
81    colorbar_option_kind_labels : Legend_String_Array_Type(0 .. Colorbar_Kinds - 1) :=
82       (TUB("Shade colorbars"),
83        TUB("Shade colorbars with custom labels"),
84        TUB("Image colorbars"),
85        TUB("Gradient colorbars"));
86
87    -- Which side of the page are we positioned relative to?
88    Colorbar_Positions :constant Integer := 4;
89    colorbar_position_options : Integer_Array_1D(0 .. Colorbar_Positions - 1) :=
90       (Pl_Position_Left,
91        Pl_Position_Right,
92        Pl_Position_Top,
93        Pl_Position_Bottom);
94
95    colorbar_position_option_labels : Legend_String_Array_Type(0 .. Colorbar_Positions - 1) :=
96       (TUB("Left"),
97        TUB("Right"),
98        TUB("Top"),
99        TUB("Bottom"));
100
101    -- Colorbar label positioning options
102    Colorbar_Labels : constant Integer := 4;
103    colorbar_label_options : Integer_Array_1D(0 .. Colorbar_Labels - 1) :=
104       (Pl_Colorbar_Label_Left,
105        Pl_Colorbar_Label_Right,
106        Pl_Colorbar_Label_Top,
107        Pl_Colorbar_Label_Bottom);
108
109    colorbar_label_option_labels : Legend_String_Array_Type(0 .. Colorbar_Labels - 1) :=
110       (TUB("Label left"),
111        TUB("Label right"),
112        TUB("Label top"),
113        TUB("Label bottom"));
114
115    -- Colorbar cap options
116    Colorbar_Caps : constant Integer := 4;
117    colorbar_cap_options : Integer_Array_1D(0 .. Colorbar_Caps - 1) :=
118       (Pl_Colorbar_Cap_None,
119        Pl_Colorbar_Cap_Low,
120        Pl_Colorbar_Cap_High,
121        Pl_Colorbar_Cap_Low + Pl_Colorbar_Cap_High);
122    colorbar_cap_option_labels : Legend_String_Array_Type(0 .. Colorbar_Caps - 1) :=
123       (TUB("No caps"),
124        TUB("Low cap"),
125        TUB("High cap"),
126        TUB("Low and high caps"));
127
128
129    procedure Create_Colorbar_example_page(kind_i : Integer; label_i : Integer; cap_i : Integer;
130        cont_color : Integer; cont_width : Long_Float; n_values : Integer; values : Real_Vector)
131    is
132        -- Parameters for the colorbars on this page
133        position, opt : Integer;
134        x, y, x_length, y_length : Long_Float;
135        ticks : Real_Vector(0 .. 0) := (others => 0.0);
136        sub_ticks : Integer_Array_1D(0 .. 0) := (others => 0);
137        low_cap_color, high_cap_color : Long_Float;
138        vertical, ifn : Boolean;
139        n_axes : Integer := 1;
140        axis_opts : Legend_String_Array_Type(0 .. 0);
141        n_labels : Integer := 1;
142        label_opts : Integer_Array_1D(0 .. 0) := (others => 0);
143        label : Legend_String_Array_Type(0 .. 0);
144        title : Unbounded_String;
145        colorbar_width, colorbar_height : Long_Float;
146        n_values_array : Integer_Array_1D(0 .. 0);
147        values_array : Real_Matrix(0 .. 0, values'first .. values'last);
148        type Stupid is mod 2**7; -- To cover Legend_Colorbar_Position_Type in plplot_thin.ads.
149    begin
150        n_values_array(0) := n_values;
151        for i in values'range loop
152           values_array(0, i) := values(i);
153        end loop;
154
155        low_cap_color := 0.0;
156        high_cap_color := 1.0;
157
158        -- Start a new page.
159        Advance_To_Subpage(Next_Subpage);
160
161        -- Draw one colorbar relative to each side of the page.
162        for position_i in 0 .. Colorbar_Positions - 1 loop
163            position := colorbar_position_options(position_i);
164            opt := colorbar_option_kinds(kind_i) +
165                colorbar_label_options(label_i) + colorbar_cap_options(cap_i);
166
167            -- We have to convert these integers to modular type Stupid before and-ing the bits.
168            -- That's because manipulating bits of non-modular types is nonsense but other
169            -- languages seem to not care about stuff like this.
170            vertical := ((Stupid(position) and Stupid(Pl_Position_Left)) > 0) or
171                        ((Stupid(position) and Stupid(Pl_Position_Right)) > 0);
172
173            ifn := ((Stupid(position) and Stupid(Pl_Position_Left)) > 0) or
174                ((Stupid(position) and Stupid(Pl_Position_Bottom)) > 0);
175
176            -- Set the offset position on the page.
177            if vertical then
178                x        := 0.0;
179                y        := 0.0;
180                x_length := 0.05;
181                y_length := 0.5;
182            else
183                x        := 0.0;
184                y        := 0.0;
185                x_length := 0.5;
186                y_length := 0.05;
187            end if;
188
189            -- Set appropriate labelling options.
190            if ifn then
191                if cont_color = 0 or cont_width = 0.0 then
192                    axis_opts(0) := TUB("uwtivn"); -- TUB is renamed To_Unbounded_String.
193                else
194                    axis_opts(0) := TUB("uwxvn");
195                end if;
196            else
197                if cont_color = 0 or cont_width = 0.0 then
198                    axis_opts(0) := TUB("uwtivm");
199                else
200                    axis_opts(0) := TUB("uwxvm");
201                end if;
202            end if;
203
204            label(0) := colorbar_position_option_labels(position_i) & ", "
205                & colorbar_label_option_labels(label_i);
206
207            -- Smaller text
208            Set_Character_Height(0.0, 0.75);
209            -- Small ticks on the vertical axis
210            Set_Major_Tick_Length(0.0, 0.5);
211            Set_Minor_Tick_Length(0.0, 0.5);
212
213            Set_Viewport_Normalized(0.20, 0.80, 0.20, 0.80);
214            Set_Viewport_World(0.0, 1.0, 0.0, 1.0);
215            -- Set interesting background colour.
216            Set_One_Color_Map_0_And_Alpha(White, 0, 0, 0, 0.20);
217            Create_Colorbar(colorbar_width, colorbar_height,
218                opt + Pl_Colorbar_Bounding_Box + Pl_Colorbar_Background, position,
219                x, y, x_length, y_length,
220                White, Red, 1,
221                low_cap_color, high_cap_color,
222                cont_color, cont_width,
223                label_opts, label,
224                axis_opts,
225                ticks, sub_ticks,
226                n_values_array, values_array);
227
228            -- Reset text and tick sizes
229            Set_Character_Height(0.0, 1.0);
230            Set_Major_Tick_Length(0.0, 1.0);
231            Set_Minor_Tick_Length(0.0, 1.0);
232        end loop;
233
234        -- Draw a page title
235        title := colorbar_option_kind_labels(kind_i) & " - "
236            & colorbar_cap_option_labels(cap_i);
237        Set_Viewport_Normalized(0.0, 1.0, 0.0, 1.0);
238        Set_Viewport_World(0.0, 1.0, 0.0, 1.0);
239        Write_Text_World(0.5, 0.5, 0.0, 0.0, 0.5, To_String(title));
240    end Create_Colorbar_example_page;
241
242
243    procedure Create_Colorbar_example(palette : String; kind_i : Integer; cont_color : Integer;
244        cont_width : Long_Float; n_values : Integer; values : Real_Vector) is
245    begin
246        -- Load the color palette
247        Set_Color_Map_1_From_File(palette, True);
248
249        for label_i in 0 .. Colorbar_Labels - 1 loop
250            for cap_i in 0 .. Colorbar_Caps - 1 loop
251                Create_Colorbar_example_page(kind_i, label_i, cap_i, cont_color, cont_width,
252                    n_values, values );
253            end loop;
254        end loop;
255    end Create_Colorbar_example;
256
257
258    colorbar : Boolean := True; -- By default do not plot Create_Colorbar pages
259                                -- for now while we are working out the API.
260    opt : Integer;
261    nlegend : Integer;
262    nturn : Integer;
263    legend_width, legend_height, x, y, xstart, ystart : Long_Float;
264    max_height, text_scale : Long_Float;
265    position, opt_base, nrow, ncolumn : Integer;
266
267begin -- main
268    Parse_Command_Line_Arguments(Pl_Parse_Full);
269
270    -- Initialize plplot
271    Initialize_PLplot;
272
273    -- First page illustrating the 16 standard positions.
274    declare
275        nlegend : constant Integer := 1;
276        opt_array       :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
277        text_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
278        box_colors      :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
279        box_patterns    :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
280        box_scales      :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
281        box_line_widths :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
282        line_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
283        line_styles     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
284        line_widths     :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
285        symbol_numbers  :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
286        symbol_colors   :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
287        symbol_scales   :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
288        text            : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
289        symbols         : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
290    begin
291        Advance_To_Subpage(Next_Subpage);
292        Set_Viewport_Normalized(0.25, 0.75, 0.25, 0.75);
293        Set_Viewport_World(0.0, 1.0, 0.0, 1.0);
294        Box_Around_Viewport("bc", 0.0, 0, "bc", 0.0, 0);
295        Set_Font(PL_FCI_SANS, -1, -1);
296        Write_Text_Viewport("t", 8.0, 0.5, 0.5, "The 16 standard legend positions with");
297        Write_Text_Viewport("t", 6.0, 0.5, 0.5, "the same (0.05) offset in x and y");
298
299        -- Only specify legend data that are required according to the
300        -- value of opt_array for that entry.
301        opt_base          := Pl_Legend_Background + Pl_Legend_Bounding_Box;
302        opt_array(0)      := Pl_Legend_Line + Pl_Legend_Symbol;
303        line_styles(0)    := 1;
304        line_widths(0)    := 1.0;
305        symbol_scales(0)  := 1.0;
306        symbol_numbers(0) := 4;
307        symbols(0)        := TUB("#(728)");
308
309        -- Use monotype fonts so that all legends are the same size.
310        Set_Font(PL_FCI_MONO, -1, -1);
311        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
312
313        for k in 0 .. 15 loop
314            position := position_options(k);
315            opt      := opt_base;
316            -- Make a 2-digit string with leading 0 for 0 .. 9.
317            if k >= 10 then
318                text(0) := To_Unbounded_String(Trim(Integer'image(k), Left));
319            else
320                text(0) := To_Unbounded_String("0" & Trim(Integer'image(k), Left));
321            end if;
322            text_colors(0)   := 1 + (k mod 8);
323            line_colors(0)   := 1 + (k mod 8);
324            symbol_colors(0) := 1 + (k mod 8);
325
326            Create_Legend(legend_width, legend_height, opt, position, 0.05, 0.05,
327                0.1, White, Red, 1, 0, 0,
328                opt_array, 1.0, 1.0, 2.0,
329                1.0, text_colors, text,
330                Box_Colors, Box_Patterns,
331                Box_Scales, Box_Line_Widths,
332                line_colors, line_styles, line_widths,
333                symbol_colors, symbol_scales, symbol_numbers, symbols);
334        end loop;
335    end; -- declare
336
337    -- Second page illustrating effect of nrow, ncolumn for the same legend data.
338    declare
339        nlegend : constant Integer := 7;
340        opt_array       :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
341        text_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
342        box_colors      :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
343        box_patterns    :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
344        box_scales      :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
345        box_line_widths :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
346        line_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
347        line_styles     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
348        line_widths     :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
349        symbol_numbers  :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
350        symbol_colors   :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
351        symbol_scales   :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
352        text            : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
353        symbols         : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
354    begin
355        Advance_To_Subpage(Next_Subpage);
356        Set_Viewport_Normalized(0.25, 0.75, 0.25, 0.75);
357        Set_Viewport_World(0.0, 1.0, 0.0, 1.0);
358        Box_Around_Viewport("bc", 0.0, 0, "bc", 0.0, 0);
359        Set_Font(PL_FCI_SANS, -1, -1);
360        Write_Text_Viewport("t", 8.0, 0.5, 0.5, "The effect of nrow, ncolumn, PL_LEGEND_ROW_MAJOR,");
361        Write_Text_Viewport("t", 6.0, 0.5, 0.5, "and position for the same legend data");
362
363        -- Only specify legend data that are required according to the
364        -- value of opt_array for that entry.
365        opt_base := Pl_Legend_Background + Pl_Legend_Bounding_Box;
366        for k in 0 .. nlegend - 1 loop
367            opt_array(k)      := Pl_Legend_Line + Pl_Legend_Symbol;
368            line_styles(k)    := 1;
369            line_widths(k)    := 1.0;
370            symbol_scales(k)  := 1.0;
371            symbol_numbers(k) := 2;
372            symbols(k)        := TUB("#(728)");
373            -- Make 2-digit strings with leading 0 for 0 .. 9.
374            if k >= 10 then
375                text(k) := To_Unbounded_String(Trim(Integer'image(k), Left));
376            else
377                text(k) := To_Unbounded_String("0" & Trim(Integer'image(k), Left));
378            end if;
379            text_colors(k)   := 1 + (k mod 8);
380            line_colors(k)   := 1 + (k mod 8);
381            symbol_colors(k) := 1 + (k mod 8);
382        end loop;
383
384        -- Use monotype fonts so that all legends are the same size.
385        Set_Font(PL_FCI_MONO, -1, -1);
386        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
387
388        position := Pl_Position_Top + Pl_Position_Outside;
389        opt      := opt_base;
390        x        := 0.0;
391        y        := 0.1;
392        nrow     := 1;
393        ncolumn  := nlegend;
394        Create_Legend(legend_width, legend_height, opt, position, x, y,
395            0.05, White, Red, 1, nrow, ncolumn,
396            opt_array, 1.0, 1.0, 2.0,
397            1.0, text_colors, text,
398            Box_Colors, Box_Patterns,
399            Box_Scales, Box_Line_Widths,
400            line_colors, line_styles, line_widths,
401            symbol_colors, symbol_scales, symbol_numbers, symbols);
402
403        position := Pl_Position_Bottom + Pl_Position_Outside;
404        opt      := opt_base;
405        x        := 0.0;
406        y        := 0.1;
407        nrow     := 1;
408        ncolumn  := nlegend;
409        Create_Legend(legend_width, legend_height, opt, position, x, y,
410            0.05, White, Red, 1, nrow, ncolumn,
411            opt_array, 1.0, 1.0, 2.0,
412            1.0, text_colors, text,
413            Box_Colors, Box_Patterns,
414            Box_Scales, Box_Line_Widths,
415            line_colors, line_styles, line_widths,
416            symbol_colors, symbol_scales, symbol_numbers, symbols);
417
418        position := Pl_Position_Left + Pl_Position_Outside;
419        opt      := opt_base;
420        x        := 0.1;
421        y        := 0.0;
422        nrow     := nlegend;
423        ncolumn  := 1;
424        Create_Legend(legend_width, legend_height, opt, position, x, y,
425            0.05, White, Red, 1, nrow, ncolumn,
426            opt_array, 1.0, 1.0, 2.0,
427            1.0, text_colors, text,
428            Box_Colors, Box_Patterns,
429            Box_Scales, Box_Line_Widths,
430            line_colors, line_styles, line_widths,
431            symbol_colors, symbol_scales, symbol_numbers, symbols);
432
433        position := Pl_Position_Right + Pl_Position_Outside;
434        opt      := opt_base;
435        x        := 0.1;
436        y        := 0.0;
437        nrow     := nlegend;
438        ncolumn  := 1;
439        Create_Legend(legend_width, legend_height, opt, position, x, y,
440            0.05, White, Red, 1, nrow, ncolumn,
441            opt_array, 1.0, 1.0, 2.0,
442            1.0, text_colors, text,
443            Box_Colors, Box_Patterns,
444            Box_Scales, Box_Line_Widths,
445            line_colors, line_styles, line_widths,
446            symbol_colors, symbol_scales, symbol_numbers, symbols);
447
448        position := Pl_Position_Left + Pl_Position_Top + Pl_Position_Inside;
449        opt      := opt_base;
450        x        := 0.0;
451        y        := 0.0;
452        nrow     := 6;
453        ncolumn  := 2;
454        Create_Legend(legend_width, legend_height, opt, position, x, y,
455            0.05, White, Red, 1, nrow, ncolumn,
456            opt_array, 1.0, 1.0, 2.0,
457            1.0, text_colors, text,
458            Box_Colors, Box_Patterns,
459            Box_Scales, Box_Line_Widths,
460            line_colors, line_styles, line_widths,
461            symbol_colors, symbol_scales, symbol_numbers, symbols);
462
463        position := Pl_Position_Right + Pl_Position_Top + Pl_Position_Inside;
464        opt      := opt_base + Pl_Legend_Row_Major;
465        x        := 0.0;
466        y        := 0.0;
467        nrow     := 6;
468        ncolumn  := 2;
469        Create_Legend(legend_width, legend_height, opt, position, x, y,
470            0.05, White, Red, 1, nrow, ncolumn,
471            opt_array, 1.0, 1.0, 2.0,
472            1.0, text_colors, text,
473            Box_Colors, Box_Patterns,
474            Box_Scales, Box_Line_Widths,
475            line_colors, line_styles, line_widths,
476            symbol_colors, symbol_scales, symbol_numbers, symbols);
477
478        position := Pl_Position_Bottom + Pl_Position_Inside;
479        opt      := opt_base + Pl_Legend_Row_Major;
480        x        := 0.0;
481        y        := 0.0;
482        nrow     := 3;
483        ncolumn  := 3;
484        Create_Legend(legend_width, legend_height, opt, position, x, y,
485            0.05, White, Red, 1, nrow, ncolumn,
486            opt_array, 1.0, 1.0, 2.0,
487            1.0, text_colors, text,
488            Box_Colors, Box_Patterns,
489            Box_Scales, Box_Line_Widths,
490            line_colors, line_styles, line_widths,
491            symbol_colors, symbol_scales, symbol_numbers, symbols);
492    end; -- declare
493
494    -- Third page demonstrating legend alignment
495    Advance_To_Subpage(Next_Subpage);
496    Set_Viewport_Normalized(0.0, 1.0, 0.0, 0.9);
497    Set_Viewport_World(0.0, 1.0, 0.0, 1.0);
498    Set_Font(Pl_Fci_Sans, -1, -1);
499    Write_Text_Viewport("t", 2.0, 0.5, 0.5, "Demonstrate legend alignment");
500
501    x        := 0.1;
502    y        := 0.1;
503    nturn    := 4;
504    nlegend  := 0;
505    position := Pl_Position_Top + Pl_Position_Left + Pl_Position_Subpage;
506    opt_base := Pl_Legend_Background + Pl_Legend_Bounding_Box;
507    opt      := opt_base;
508    for i in 0 .. 8 loop
509
510        -- Set up legend arrays with the correct size, type.
511        if i <= nturn then
512            nlegend := nlegend + 1;
513        else
514            nlegend := nlegend - 1;
515        end if;
516        nlegend := Integer'max(1, nlegend);
517        declare
518            opt_array       :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
519            text_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
520            box_colors      :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
521            box_patterns    :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
522            box_scales      :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
523            box_line_widths :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
524            line_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
525            line_styles     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
526            line_widths     :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
527            symbol_numbers  :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
528            symbol_colors   :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
529            symbol_scales   :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
530            text            : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
531            symbols         : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
532        begin
533            -- Only specify legend data that are required according to the
534            -- value of opt_array for that entry.
535            for k in 0 .. nlegend - 1 loop
536                opt_array(k)      := Pl_Legend_Line + Pl_Legend_Symbol;
537                line_styles(k)    := 1;
538                line_widths(k)    := 1.0;
539                symbol_scales(k)  := 1.0;
540                symbol_numbers(k) := 2;
541                symbols(k)        := TUB("#(728)");
542                -- Make 2-digit strings with leading 0 for 0 .. 9.
543                if k >= 10 then
544                    text(k) := To_Unbounded_String(Trim(Integer'image(k), Left));
545                else
546                    text(k) := To_Unbounded_String("0" & Trim(Integer'image(k), Left));
547                end if;
548                text_colors(k)   := 1 + (k mod 8);
549                line_colors(k)   := 1 + (k mod 8);
550                symbol_colors(k) := 1 + (k mod 8);
551            end loop; -- k
552
553            -- Use monotype fonts so that all legends are the same size.
554            Set_Font(Pl_Fci_Mono, -1, -1);
555            Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
556
557            nrow    := Integer'min(3, nlegend);
558            ncolumn := 0;
559
560            Create_Legend(legend_width, legend_height, opt, position, x, y,
561                0.025, White, Red, 1, nrow, ncolumn,
562                opt_array, 1.0, 1.0, 1.5,
563                1.0, text_colors, text,
564                Box_Colors, Box_Patterns,
565                Box_Scales, Box_Line_Widths,
566                line_colors, line_styles, line_widths,
567                symbol_colors, symbol_scales, symbol_numbers, symbols);
568
569            if i = nturn then
570                position := Pl_Position_Top + Pl_Position_Right + Pl_Position_Subpage;
571                opt      := opt_base;
572                x        := 1.0 - x;
573                y        := y + legend_height;
574            else
575                x := x + legend_width;
576                y := y + legend_height;
577            end if;
578        end; -- declare
579    end loop; -- i
580
581    -- Fourth page illustrating various kinds of legends
582    declare
583        nlegend : constant Integer := 5;
584        opt_array       :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
585        text_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
586        box_colors      :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
587        box_patterns    :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
588        box_scales      :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
589        box_line_widths :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
590        line_colors     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
591        line_styles     :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
592        line_widths     :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
593        symbol_numbers  :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
594        symbol_colors   :         Integer_Array_1D(0 .. nlegend - 1) := (others => 0);
595        symbol_scales   :         Real_Vector     (0 .. nlegend - 1) := (others => 0.0);
596        text            : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
597        symbols         : Legend_String_Array_Type(0 .. nlegend - 1) := (others => TUB(" "));
598    begin
599        max_height := 0.0;
600        xstart     := 0.0;
601        ystart     := 0.1;
602        x          := xstart;
603        y          := ystart;
604        text_scale := 0.90;
605        Advance_To_Subpage(Next_Subpage);
606        Set_Viewport_Normalized(0.0, 1.0, 0.0, 0.90);
607        Set_Viewport_World(0.0, 1.0, 0.0, 1.0);
608        Set_Font(Pl_Fci_Sans, -1, -1);
609        Write_Text_Viewport("t", 2.0, 0.5, 0.5, "Demonstrate Various Kinds of Legends");
610
611        -- Only specify legend data that are required according to the
612        -- value of opt_array for that entry.
613        position := Pl_Position_Left + Pl_Position_Top;
614        opt_base := Pl_Legend_Background + Pl_Legend_Bounding_Box + Pl_Legend_Text_Left;
615
616        -- Set up None, Box, Line, Symbol, and Line & Symbol legend entries.
617        opt_array(0) := Pl_Legend_None;
618        text(0) := TUB("None");
619        text_colors(0) := 1;
620
621        opt_array(1) := Pl_Legend_Color_Box;
622        text(1) := TUB("Box");
623        text_colors(1)     := 2;
624        box_colors(1)      := 2;
625        box_patterns(1)    := 0;
626        box_scales(1)      := 0.8;
627        box_line_widths(1) := 1.0;
628
629        opt_array(2) := Pl_Legend_Line;
630        text(2) := TUB("Line");
631        text_colors(2) := 3;
632        line_colors(2) := 3;
633        line_styles(2) := 1;
634        line_widths(2) := 1.0;
635
636        opt_array(3) := Pl_Legend_Symbol;
637        text(3) := TUB("Symbol");
638        text_colors(3)    := 4;
639        symbol_colors(3)  := 4;
640        symbol_scales(3)  := text_scale;
641        symbol_numbers(3) := 4;
642        symbols(3)        := special_symbols(2);
643
644        opt_array(4) := Pl_Legend_Symbol + Pl_Legend_Line;
645        text(4) := TUB("L & S");
646        text_colors(4)    := 5;
647        line_colors(4)    := 5;
648        line_styles(4)    := 1;
649        line_widths(4)    := 1.0;
650        symbol_colors(4)  := 5;
651        symbol_scales(4)  := text_scale;
652        symbol_numbers(4) := 4;
653        symbols(4)        := special_symbols(2);
654
655        opt := opt_base;
656        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
657
658        Create_Legend(legend_width, legend_height, opt, position, x, y,
659            0.1, White, Red, 1, 0, 0,
660            opt_array, 1.0, text_scale, 2.0,
661            0.0, text_colors, text,
662            box_colors, box_patterns, box_scales, box_line_widths,
663            line_colors, line_styles, line_widths,
664            symbol_colors, symbol_scales, symbol_numbers, symbols);
665        max_height := Long_Float'max(max_height, legend_height);
666
667        -- Set up symbol legend entries with various symbols.
668        for i in 0 .. nlegend - 1 loop
669            opt_array(i) := Pl_Legend_Symbol;
670            text(i) := TUB("Symbol ") & special_symbols(i);
671            text_colors(i)    := i + 1;
672            symbol_colors(i)  := i + 1;
673            symbol_scales(i)  := text_scale;
674            symbol_numbers(i) := 4;
675            symbols(i)        := special_symbols(i);
676        end loop;
677
678        opt := opt_base;
679        x  := x + legend_width;
680        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
681
682        Create_Legend(legend_width, legend_height, opt, position, x, y,
683            0.1, White, Red, 1, 0, 0,
684            opt_array, 1.0, text_scale, 2.0,
685            0.0, text_colors, text,
686            Box_Colors, Box_Patterns,
687            Box_Scales, Box_Line_Widths,
688            line_colors, line_styles, line_widths,
689            symbol_colors, symbol_scales, symbol_numbers, symbols);
690        max_height := Long_Float'max(max_height, legend_height);
691
692        -- Set up symbol legend entries with various numbers of symbols.
693        for i in 0 .. nlegend - 1 loop
694            opt_array(i) := Pl_Legend_Symbol;
695            text(i) := TUB("Symbol Number" & Integer'image(i + 2));
696            text_colors(i)    := i + 1;
697            symbol_colors(i)  := i + 1;
698            symbol_scales(i)  := text_scale;
699            symbol_numbers(i) := i + 2;
700            symbols(i)        := special_symbols(2);
701        end loop;
702
703        opt := opt_base;
704        x  := x + legend_width;
705        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
706
707        Create_Legend(legend_width, legend_height, opt, position, x, y,
708            0.1, White, Red, 1, 0, 0,
709            opt_array, 1.0, text_scale, 2.0,
710            0.0, text_colors, text,
711            Box_Colors, Box_Patterns,
712            Box_Scales, Box_Line_Widths,
713            line_colors, line_styles, line_widths,
714            symbol_colors, symbol_scales, symbol_numbers, symbols);
715        max_height := Long_Float'max(max_height, legend_height);
716
717        -- Set up box legend entries with various colours.
718        for i in 0 .. nlegend - 1 loop
719            opt_array(i) := Pl_Legend_Color_Box;
720            text(i) := TUB("Box Color" & Integer'image(i + 1));
721            text_colors(i)     := i + 1;
722            box_colors(i)      := i + 1;
723            box_patterns(i)    := 0;
724            box_scales(i)      := 0.8;
725            box_line_widths(i) := 1.0;
726        end loop;
727
728        opt := opt_base;
729        -- Use new origin
730        x          := xstart;
731        y         := y + max_height;
732        max_height := 0.0;
733        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
734
735        Create_Legend(legend_width, legend_height, opt, position, x, y,
736            0.1, White, Red, 1, 0, 0,
737            opt_array, 1.0, text_scale, 2.0,
738            0.0, text_colors, text,
739            box_colors, box_patterns, box_scales, box_line_widths,
740            line_colors, line_styles, line_widths,
741            symbol_colors, symbol_scales, symbol_numbers, symbols);
742        max_height := Long_Float'max(max_height, legend_height);
743
744        -- Set up box legend entries with various patterns.
745        for i in 0 .. nlegend - 1 loop
746            opt_array(i) := Pl_Legend_Color_Box;
747            text(i) := TUB("Box Pattern" & Integer'image(i));
748            text_colors(i)     := 2;
749            box_colors(i)      := 2;
750            box_patterns(i)    := i;
751            box_scales(i)      := 0.8;
752            box_line_widths(i) := 1.0;
753        end loop;
754
755        opt := opt_base;
756        x  := x + legend_width;
757        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
758
759        Create_Legend(legend_width, legend_height, opt, position, x, y,
760            0.1, White, Red, 1, 0, 0,
761            opt_array, 1.0, text_scale, 2.0,
762            0.0, text_colors, text,
763            box_colors, box_patterns, box_scales, box_line_widths,
764            line_colors, line_styles, line_widths,
765            symbol_colors, symbol_scales, symbol_numbers, symbols);
766        max_height := Long_Float'max(max_height, legend_height);
767
768        -- Set up box legend entries with various box pattern line widths.
769        for i in 0 .. nlegend - 1 loop
770            opt_array(i) := Pl_Legend_Color_Box;
771            text(i) := TUB("Box Line Width" & Integer'image(i + 1));
772            text_colors(i)     := 2;
773            box_colors(i)      := 2;
774            box_patterns(i)    := 3;
775            box_scales(i)      := 0.8;
776            box_line_widths(i) := Long_Float(i) + 1.0;
777        end loop;
778
779        opt := opt_base;
780        x  := x + legend_width;
781        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
782
783        Create_Legend(legend_width, legend_height, opt, position, x, y,
784            0.1,White, Red, 1, 0, 0,
785            opt_array, 1.0, text_scale, 2.0,
786            0.0, text_colors, text,
787            box_colors, box_patterns, box_scales, box_line_widths,
788            line_colors, line_styles, line_widths,
789            symbol_colors, symbol_scales, symbol_numbers, symbols);
790        max_height := Long_Float'max(max_height, legend_height);
791
792        -- Set up line legend entries with various colours.
793        for i in 0 .. nlegend - 1 loop
794            opt_array(i) := Pl_Legend_Line;
795            text(i) := TUB("Line Color" & Integer'image(i + 1));
796            text_colors(i) := i + 1;
797            line_colors(i) := i + 1;
798            line_styles(i) := 1;
799            line_widths(i) := 1.0;
800        end loop;
801
802        opt := opt_base;
803        -- Use new origin
804        x := xstart;
805        y := y + max_height;
806        max_height := 0.0;
807        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
808
809        Create_Legend(legend_width, legend_height, opt, position, x, y,
810            0.1, White, Red, 1, 0, 0,
811            opt_array, 1.0, text_scale, 2.0,
812            0.0, text_colors, text,
813            box_colors, box_patterns, box_scales, box_line_widths,
814            line_colors, line_styles, line_widths,
815            symbol_colors, symbol_scales, symbol_numbers, symbols);
816        max_height := Long_Float'max(max_height, legend_height);
817
818        -- Set up line legend entries with various styles.
819        for i in 0 .. nlegend - 1 loop
820            opt_array(i) := Pl_Legend_Line;
821            text(i) := TUB("Line Style" & Integer'image(i + 1));
822            text_colors(i) := 2;
823            line_colors(i) := 2;
824            line_styles(i) := i + 1;
825            line_widths(i) := 1.0;
826        end loop;
827
828        opt := opt_base;
829        x  := x + legend_width;
830        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
831
832        Create_Legend(legend_width, legend_height, opt, position, x, y,
833            0.1, White, Red, 1, 0, 0,
834            opt_array, 1.0, text_scale, 2.0,
835            0.0, text_colors, text,
836            box_colors, box_patterns, box_scales, box_line_widths,
837            line_colors, line_styles, line_widths,
838            symbol_colors, symbol_scales, symbol_numbers, symbols);
839        max_height := Long_Float'max(max_height, legend_height);
840
841        -- Set up line legend entries with various widths.
842        for i in 0 .. nlegend - 1 loop
843            opt_array(i) := Pl_Legend_Line;
844            text(i) := TUB("Line Width" & Integer'image(i + 1));
845            text_colors(i) := 2;
846            line_colors(i) := 2;
847            line_styles(i) := 1;
848            line_widths(i) := Long_Float(i) + 1.0;
849        end loop;
850
851        opt := opt_base;
852        x  := x + legend_width;
853        Set_One_Color_Map_0_And_Alpha(White, 32, 32, 32, 0.70);
854
855        Create_Legend(legend_width, legend_height, opt, position, x, y,
856            0.1, White, Red, 1, 0, 0,
857            opt_array, 1.0, text_scale, 2.0,
858            0.0, text_colors, text,
859            box_colors, box_patterns, box_scales, box_line_widths,
860            line_colors, line_styles, line_widths,
861            symbol_colors, symbol_scales, symbol_numbers, symbols);
862        max_height := Long_Float'max(max_height, legend_height);
863    end; -- declare
864
865    if colorbar then
866        -- Color bar examples
867        declare
868            values_small : Real_Vector(0 .. 1)  := (-1.0e-20, 1.0e-20);
869            values_uneven : Real_Vector(0 .. 8) := (-1.0e-20, 2.0e-20, 2.6e-20, 3.4e-20,
870                6.0e-20, 7.0e-20, 8.0e-20, 9.0e-20, 10.0e-20);
871            values_even : Real_Vector(0 .. 8)   := (-2.0e-20, -1.0e-20, 0.0e-20, 1.0e-20,
872                2.0e-20, 3.0e-20, 4.0e-20, 5.0e-20, 6.0e-20);
873        begin
874            -- Use unsaturated green background colour to contrast with black caps.
875            Set_Background_Color_RGB(70, 185, 70);
876            -- Cut out the greatest and smallest bits of the color spectrum to
877            -- leave colors for the end caps.
878            Set_Color_Map_1_Range(0.01, 0.99);
879
880            -- We can only test image and gradient colorbars with two element arrays
881            for i in 2 .. COLORBAR_KINDS - 1 loop
882                Create_Colorbar_example("cmap1_blue_yellow.pal", i, 0, 0.0, 2, values_small);
883            end loop;
884            -- Test shade colorbars with larger arrays
885            for i in 0 .. 1 loop
886                Create_Colorbar_example("cmap1_blue_yellow.pal", i, 4, 2.0, 9, values_even);
887            end loop;
888            for i in 0 .. 1 loop
889                Create_Colorbar_example("cmap1_blue_yellow.pal", i, 0, 0.0, 9, values_uneven);
890            end loop;
891        end;
892    end if;
893    End_PLplot;
894end xstandard33a;
895
896