summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/process_desc.h
blob: 9343eb32da8b1a894138e400bfe4beef6ec22ef6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
 * @file
 * @brief Templates used in describe.cc and in some tiles-only sources
 */

#ifndef DESCRIBE_TEMPLATES_H
#define DESCRIBE_TEMPLATES_H

#include "describe.h"
#include "strings.h"
#include "lang-fake.h"

template<class T> void process_description(T &proc, const describe_info &inf);
template<class T> void process_quote(T &proc, const describe_info &inf);

/* ***********************************************************************
 * template implementations
 * *********************************************************************** */
// My kingdom for a closure.
template<class T>
void process_description(T &proc, const describe_info &inf)
{
    const unsigned int line_width = proc.width();
    const          int height     = proc.height();

    string desc;
    // most stuff goes through translate() twice unnecessarily, yadda yadda yadda

    // How many lines is the title; we also seem to be adding 1 to
    // start with.
    int num_lines = count_desc_lines(filtered_lang(inf.title), line_width) + 1;

    int body_lines   = count_desc_lines(filtered_lang(inf.body.str()), line_width);
    const int suffix_lines = count_desc_lines(filtered_lang(inf.suffix), line_width);
    const int prefix_lines = count_desc_lines(filtered_lang(inf.prefix), line_width);
    const int footer_lines = count_desc_lines(filtered_lang(inf.footer), line_width)
                             + (inf.footer.empty() ? 0 : 1);

    if (inf.title.empty())
    {
        desc = filtered_lang(inf.body.str());
        // There is a default 1 line addition for some reason.
        num_lines = body_lines + 1;
    }
    else
    {
        desc = filtered_lang(inf.title) + "\n\n";
        desc += filtered_lang(inf.body.str());
        // Got 2 lines from the two \ns that weren't counted yet.
        num_lines += body_lines + 2;
    }

    // Prefer the footer over the suffix.
    if (num_lines + suffix_lines + footer_lines <= height)
    {
        desc = desc + filtered_lang(inf.suffix);
        num_lines += suffix_lines;
    }

    // Prefer the footer over the prefix.
    if (num_lines + prefix_lines + footer_lines <= height)
    {
        desc = filtered_lang(inf.prefix) + desc;
        num_lines += prefix_lines;
    }

    if (!inf.footer.empty() && num_lines + footer_lines <= height)
    {
        const int bottom_line = min(max(24, num_lines + 2),
                                    height - footer_lines + 1);
        const int newlines = bottom_line - num_lines;

        if (newlines >= 0)
        {
            desc.append(newlines, '\n');
            desc = desc + filtered_lang(inf.footer);
        }
    }

    // Display as many lines as will fit.
    int lineno = 0;
    while (!desc.empty())
    {
        const string line = wordwrap_line(desc, line_width, false, true);

        // If this is the bottom line of the display but not
        // the last line of text, print an ellipsis instead.
        if (++lineno < height || desc.empty())
        {
            proc.print(line);
            if (!desc.empty())
                proc.nextline();
        }
        else
        {
            proc.print("...");
            break;
        }
    }
}

template<class T>
void process_quote(T &proc, const describe_info &inf)
{
    const unsigned int line_width = proc.width();
    const          int height     = proc.height();

    string desc;

    // How many lines is the title; we also seem to be adding 1 to
    // start with.
    int num_lines = count_desc_lines(inf.title, line_width) + 1;

    int body_lines   = count_desc_lines(inf.quote, line_width);

    // Maybe skip the body if body + title would be too many lines.
    if (inf.title.empty())
    {
        desc = inf.quote;
        // There is a default 1 line addition for some reason.
        num_lines = body_lines + 1;
    }
    else if (body_lines + num_lines + 2 <= height)
    {
        desc = inf.title + "\n\n";
        desc += inf.quote;
        // Got 2 lines from the two \ns that weren't counted yet.
        num_lines += body_lines + 2;
    }
    else
        desc = inf.title + "\n";

    if (num_lines <= height)
    {
        const int bottom_line = min(max(24, num_lines + 2), height);
        const int newlines = bottom_line - num_lines;

        if (newlines >= 0)
            desc.append(newlines, '\n');
    }

    while (!desc.empty())
    {
        proc.print(wordwrap_line(desc, line_width, false, true));
        if (!desc.empty())
            proc.nextline();
    }
}

#endif