drawer.cpp

Go to the documentation of this file.
00001 /*
00002  * drawer.cpp
00003  *
00004  * Copyright (C) 2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * Dumb drawer that just writes to ASCII strings.  Helpful for testing.
00032  */
00033 
00034 // includes --------------------------------------------------------------------
00035 #include "drawer.h"             // always include our own header first!
00036 
00037 #include "common/wave_ex.h"
00038 
00039 
00040 namespace dialog {
00041 
00042 /// \ingroup dialog
00043 /*@{*/
00044 
00045 
00046 // Drawer interface destructor
00047 Drawer::~Drawer(void) throw() { }
00048 TextDrawer::~TextDrawer(void) throw() { }
00049 
00050 
00051 static const int s_maxText              = 147;
00052 static const int s_maxDim               = s_maxText + 1;
00053 
00054 
00055 ////////////////////////////////////////////////////////////////////////////////
00056 //
00057 //      static helper methods
00058 //
00059 ////////////////////////////////////////////////////////////////////////////////
00060 
00061 
00062 ////////////////////////////////////////////////////////////////////////////////
00063 //
00064 //      TDI -- class that implements the TextDrawer interface
00065 //
00066 ////////////////////////////////////////////////////////////////////////////////
00067 
00068 class TDI : public TextDrawer {
00069 public:
00070         ~TDI(void) throw() { }
00071 
00072         // public class methods ------------------------------------------------
00073         void initialize(IN int borderSize) throw();
00074 
00075         // dialog::Drawer class interface methods ------------------------------
00076         font_size_t getFontSizing(IN eElementType type,
00077                                 IN const char * text) {
00078                         font_size_t fs;
00079                         fs.width = strlen(text);
00080                         fs.height = 1;
00081                         return fs;
00082                 }
00083 
00084         border_size_t getBorderSizing(IN eElementType type) {
00085                         border_size_t bs;
00086                         bs.size = m_borderSize;
00087                         return bs;
00088                 }
00089 
00090         void drawString(IN eElementType type,
00091                                 IN const point_t& pos,
00092                                 IN const char * text);
00093 
00094         void drawRectWithBorder(IN eElementType type,
00095                                 IN const rect_t& r);
00096 
00097         void drawCircle(IN const point_t& pos,
00098                                 IN float radius) { /* not implemented! */ };
00099 
00100         // dialog::TextDrawer class interface methods --------------------------
00101         void writeToStream(IO std::ostream& stream);
00102 
00103 private:
00104         // private helper methods ----------------------------------------------
00105         struct row_t {
00106                 char            text[s_maxDim];
00107         };
00108 
00109         void markUsed(IN int iRow) throw() {
00110                         ASSERT(iRow >= 0 && iRow < s_maxDim,
00111                             "Bad row index: %d", iRow);
00112                         row_t& r = m_rows[iRow];
00113                         if (!r.text[0]) {
00114                                 r.text[0] = ' ';
00115                         }
00116                 }
00117 
00118         // private member data -------------------------------------------------
00119         row_t           m_rows[s_maxDim];
00120         int             m_borderSize;
00121 };
00122 
00123 
00124 
00125 void
00126 TDI::initialize
00127 (
00128 IN int borderSize
00129 )
00130 throw()
00131 {
00132         ASSERT2(borderSize > 0, "Bad border size: " << borderSize);
00133 
00134         m_borderSize = borderSize;
00135         for (int y = 0; y < s_maxDim; ++y) {
00136                 row_t& r = m_rows[y];
00137 
00138                 r.text[0] = 0;          // flag as unused
00139                 for (int x = 1; x < s_maxText; ++x) {
00140                         r.text[x] = ' ';
00141                 }
00142                 r.text[s_maxText] = 0;  // null-terminate
00143         }
00144 }
00145 
00146 
00147 
00148 ////////////////////////////////////////////////////////////////////////////////
00149 //
00150 //      TDI -- dialog::Drawer and dialog::TextDrawer class interface methods
00151 //
00152 ////////////////////////////////////////////////////////////////////////////////
00153 
00154 
00155 void
00156 TDI::drawString
00157 (
00158 IN eElementType type,
00159 IN const point_t& pos,
00160 IN const char * text
00161 )
00162 {
00163         ASSERT(text, "null");
00164         ASSERT2(pos.y >= 0 && pos.y < s_maxDim, "bad pos.y: " << pos.y);
00165 
00166         int L = strlen(text);
00167         ASSERT2(pos.x >= 0 && pos.x + L < s_maxDim, "bad pos.x: " << pos.x
00168             << "   or bad L: " << L);
00169 
00170         row_t& r = m_rows[pos.y];
00171         this->markUsed(pos.y);
00172         for (int i = 0; i < L; ++i) {
00173                 r.text[pos.x + i] = text[i];
00174         }
00175 }
00176 
00177 
00178 
00179 void
00180 TDI::drawRectWithBorder
00181 (
00182 IN eElementType type,
00183 IN const rect_t& r
00184 )
00185 {
00186         ASSERT2(r.isValid(), "bad r");
00187         ASSERT2(r.top >= 0, "bad top: " << r.top);
00188         ASSERT2(r.left >= 0, "bad left: " << r.left);
00189         ASSERT2(r.right < s_maxDim, "bad right: " << r.right);
00190         ASSERT2(r.bottom < s_maxDim, "bad bottom: " << r.bottom);
00191 
00192         // top and bottom rows
00193         row_t& tRow = m_rows[r.top];
00194         row_t& bRow = m_rows[r.bottom - 1];
00195         this->markUsed(r.top);
00196         this->markUsed(r.bottom - 1);
00197         tRow.text[r.left] = '/';
00198         tRow.text[r.right - 1] = '\\';
00199         bRow.text[r.left] = '\\';
00200         bRow.text[r.right - 1] = '/';
00201         for (int i = r.left + 1; i < r.right - 1; ++i) {
00202                 tRow.text[i] = '-';
00203                 bRow.text[i] = '-';
00204         }
00205 
00206         // intermediate rows: just endpoints
00207         for (int i = r.top + 1; i < r.bottom - 1; ++i) {
00208                 row_t& row = m_rows[i];
00209                 this->markUsed(i);
00210                 row.text[r.left] = '|';
00211                 row.text[r.right - 1] = '|';
00212         }
00213 }
00214 
00215 
00216 
00217 void
00218 TDI::writeToStream
00219 (
00220 IO std::ostream& stream
00221 )
00222 {
00223         for (int i = 0; i < s_maxDim; ++i) {
00224                 const row_t& r = m_rows[i];
00225                 if (!r.text[0])
00226                         continue;               // skip this row--unused
00227                 stream << r.text << "\n";
00228         }
00229 }
00230 
00231 
00232 
00233 ////////////////////////////////////////////////////////////////////////////////
00234 //
00235 //      public API
00236 //
00237 ////////////////////////////////////////////////////////////////////////////////
00238 
00239 smart_ptr<TextDrawer>
00240 TextDrawer::create
00241 (
00242 IN int borderSize
00243 )
00244 {
00245         ASSERT2(borderSize > 0, "Bad border size: " << borderSize);
00246 
00247         smart_ptr<TDI> local = new TDI;
00248         ASSERT(local, "out of memory");
00249 
00250         local->initialize(borderSize);
00251 
00252         return local;
00253 }
00254 
00255 
00256 
00257 };      // dialog namespace
00258