1 // $Id: Banner.cc 5748 2014-10-11 19:38:53Z flaterco $
2
3 /* Banner Graph printed sideways on tractor feed dot matrix printer
4
5 Copyright (C) 1998 David Flater.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program 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 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "libxtide.hh"
22 #include "Graph.hh"
23 #include "PixelatedGraph.hh"
24 #include "TTYGraph.hh"
25 #include "Banner.hh"
26
27 namespace libxtide {
28
29
30 // Fudge factor to correct aspect ratio on line printer
31 // Correct 10x6 of Pica type to be 1:1
32 static const double LPaspectfudge (0.6);
33
34
Banner(unsigned xSize,unsigned ySize)35 Banner::Banner (unsigned xSize, unsigned ySize): TTYGraph (ySize, xSize) {
36 // turn sideways ^^^^^^^^^^^^
37 }
38
39
factory(const Station & station,unsigned xSize,Timestamp startTime,Timestamp endTime)40 Banner * const Banner::factory (const Station &station,
41 unsigned xSize,
42 Timestamp startTime,
43 Timestamp endTime) {
44 // Everything is sideways.
45 Interval increment (std::max (
46 (interval_rep_t)1,
47 Global::intervalround (Global::aspectMagicNumber /
48 (double)xSize /
49 (station.aspect * LPaspectfudge))));
50
51 // I really painted myself into a corner this time. To create a
52 // Banner I need to know the length. The length I want depends on
53 // labelWidth (the amount by which Graph fudges the start position
54 // to avoid clobbering it with depth labels). To get labelWidth I
55 // need an instance of Banner. Catch-22.
56
57 // In the absence of a better idea, I create one Banner just to get
58 // labelWidth and then do it right. Thankfully, banners are not the
59 // sort of objects that get created often.
60 Banner throwawayBanner (xSize, Global::minTTYwidth);
61
62 // Stuff duplicated from Graph::drawTides, but with confusion of X and Y.
63 const double ymin (vertGraphMargin * (double)xSize);
64 const double ymax ((double)xSize - ymin);
65 const double valmin (station.minLevelHeuristic().val());
66 const double valmax (station.maxLevelHeuristic().val());
67 assert (valmin < valmax);
68
69 unsigned lineStep, labelWidth, labelRight;
70 int minDepth, maxDepth;
71 const Dstr unitsDesc (Units::shortName (station.predictUnits()));
72 throwawayBanner.figureLabels (ymax, ymin, valmax, valmin, unitsDesc,
73 lineStep, labelWidth,
74 labelRight, minDepth, maxDepth);
75
76 // At last we have labelWidth and can proceed.
77 unsigned ySize (std::max (Global::iround ((endTime - startTime) / increment +
78 throwawayBanner.startPosition(labelWidth)),
79 (int)Global::minTTYwidth));
80 return new Banner (xSize, ySize);
81 }
82
83
drawHorizontalLineP(int xlo,int xhi,int y,Colors::Colorchoice c unusedParameter)84 void Banner::drawHorizontalLineP (int xlo, int xhi, int y,
85 Colors::Colorchoice c unusedParameter) {
86 const char bar (VT100_mode ? '�' : '|');
87 for (int i=xlo; i<=xhi; ++i)
88 setPixel (i, y, bar);
89 }
90
91
drawHourTick(double x,Colors::Colorchoice c unusedParameter,bool thick)92 void Banner::drawHourTick (double x, Colors::Colorchoice c unusedParameter,
93 bool thick) {
94 int ix = Global::ifloor(x);
95 setPixel (ix, _ySize-1, '-');
96 if (thick) {
97 setPixel (ix-1, _ySize-1, '-');
98 setPixel (ix+1, _ySize-1, '-');
99 }
100 }
101
102
print(Dstr & text_out)103 void Banner::print (Dstr &text_out) {
104 // Everything is sideways.
105 text_out = (char *)NULL;
106 SafeVector<char> buf (_ySize+2);
107 buf[_ySize] = '\n';
108 buf[_ySize+1] = '\0';
109 for (unsigned x=0; x<_xSize; ++x) {
110 for (unsigned y=0; y<_ySize; ++y)
111 buf[y] = tty[(_ySize-1-y)*_xSize+x];
112 text_out += &(buf[0]);
113 }
114 if (VT100_mode)
115 VT100_postproc (text_out);
116 }
117
118
aspectFudgeFactor() const119 const double Banner::aspectFudgeFactor() const {
120 return LPaspectfudge;
121 }
122
123
drawStringSideways(int x,int y,const Dstr & s)124 void Banner::drawStringSideways (int x, int y, const Dstr &s) {
125 for (unsigned a=0; a<s.length(); ++a)
126 setPixel (x, y-a, s[a]);
127 }
128
129
labelHourTick(double x,const Dstr & label)130 void Banner::labelHourTick (double x, const Dstr &label) {
131 drawStringSideways (Global::ifloor(x),
132 _ySize - hourTickLen() - 1,
133 label);
134 }
135
136
labelEvent(int topLine,const EventBlurb & blurb)137 void Banner::labelEvent (int topLine, const EventBlurb &blurb) {
138 int x = Global::ifloor (blurb.x);
139 if (topLine >= 0) {
140 drawStringSideways (x-1, blurb.line1.length()-1, blurb.line1);
141 drawStringSideways (x, blurb.line2.length()-1, blurb.line2);
142 } else {
143 int y (_ySize - hourTickLen() - 4);
144 drawStringSideways (x-1, y, blurb.line1);
145 drawStringSideways (x, y, blurb.line2);
146 }
147 }
148
149
150 // This has to agree with labelEvent.
measureBlurb(EventBlurb & blurb) const151 void Banner::measureBlurb (EventBlurb &blurb) const {
152 blurb.deltaLeft = -1;
153 blurb.deltaRight = 0;
154 }
155
156
drawTitleLine(const Dstr & title unusedParameter)157 void Banner::drawTitleLine (const Dstr &title unusedParameter) {
158 // Lose it.
159 }
160
161
isBanner() const162 const bool Banner::isBanner() const {
163 return true;
164 }
165
166 }
167