DeepCover Embedded Security in IoT: Public-key Secured Data Paths
Dependencies: MaximInterface
Text.cpp
00001 /******************************************************************************* 00002 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #include <algorithm> 00034 #include <functional> 00035 #include <list> 00036 #include "Bitmap.hpp" 00037 #include "Display.hpp" 00038 #include "Text.hpp" 00039 00040 using std::string; 00041 00042 static const int invalidWidthHeight = -1; 00043 00044 static const int characterWidth = 5; 00045 static const int characterHeight = 7; 00046 00047 static const unsigned char printableCharBegin = 0x20; 00048 static const unsigned char printableCharEnd = 0x7E; 00049 00050 static const uint8_t characterMap[][characterHeight] = { 00051 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' ' 00052 {0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20}, // '!' 00053 {0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00}, // '"' 00054 {0x50, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x50}, // '#' 00055 {0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20}, // '$' 00056 {0xC0, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x18}, // '%' 00057 {0x60, 0x90, 0xA0, 0x40, 0xA8, 0x90, 0x68}, // '&' 00058 {0x60, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00}, // ''' 00059 {0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10}, // '(' 00060 {0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40}, // ')' 00061 {0x00, 0x20, 0xA8, 0x70, 0xA8, 0x20, 0x00}, // '*' 00062 {0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00}, // '+' 00063 {0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x40}, // ',' 00064 {0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00}, // '-' 00065 {0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60}, // '.' 00066 {0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00}, // '/' 00067 {0x70, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x70}, // '0' 00068 {0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x70}, // '1' 00069 {0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8}, // '2' 00070 {0xF8, 0x10, 0x20, 0x10, 0x08, 0x88, 0x70}, // '3' 00071 {0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10}, // '4' 00072 {0xF8, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x70}, // '5' 00073 {0x30, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70}, // '6' 00074 {0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40}, // '7' 00075 {0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70}, // '8' 00076 {0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60}, // '9' 00077 {0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00}, // ':' 00078 {0x00, 0x60, 0x60, 0x00, 0x60, 0x20, 0x40}, // ';' 00079 {0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10}, // '<' 00080 {0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00}, // '=' 00081 {0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40}, // '>' 00082 {0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20}, // '?' 00083 {0x70, 0x88, 0x08, 0x68, 0xA8, 0xA8, 0x70}, // '@' 00084 {0x70, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88}, // 'A' 00085 {0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0}, // 'B' 00086 {0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70}, // 'C' 00087 {0xE0, 0x90, 0x88, 0x88, 0x88, 0x90, 0xE0}, // 'D' 00088 {0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8}, // 'E' 00089 {0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80}, // 'F' 00090 {0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x78}, // 'G' 00091 {0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88}, // 'H' 00092 {0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70}, // 'I' 00093 {0x38, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60}, // 'J' 00094 {0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88}, // 'K' 00095 {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8}, // 'L' 00096 {0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88}, // 'M' 00097 {0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88}, // 'N' 00098 {0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70}, // 'O' 00099 {0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80}, // 'P' 00100 {0x70, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68}, // 'Q' 00101 {0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88}, // 'R' 00102 {0x78, 0x80, 0x80, 0x70, 0x08, 0x08, 0xF0}, // 'S' 00103 {0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // 'T' 00104 {0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70}, // 'U' 00105 {0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20}, // 'V' 00106 {0x88, 0x88, 0x88, 0xA8, 0xA8, 0xA8, 0x50}, // 'W' 00107 {0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88}, // 'X' 00108 {0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20}, // 'Y' 00109 {0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8}, // 'Z' 00110 {0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70}, // '[' 00111 {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00}, // '\' 00112 {0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70}, // ']' 00113 {0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00}, // '^' 00114 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8}, // '_' 00115 {0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00}, // '`' 00116 {0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78}, // 'a' 00117 {0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0xF0}, // 'b' 00118 {0x00, 0x00, 0x70, 0x80, 0x80, 0x88, 0x70}, // 'c' 00119 {0x08, 0x08, 0x68, 0x98, 0x88, 0x88, 0x78}, // 'd' 00120 {0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x70}, // 'e' 00121 {0x30, 0x48, 0x40, 0xE0, 0x40, 0x40, 0x40}, // 'f' 00122 {0x00, 0x78, 0x88, 0x88, 0x78, 0x08, 0x70}, // 'g' 00123 {0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88}, // 'h' 00124 {0x20, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70}, // 'i' 00125 {0x10, 0x00, 0x30, 0x10, 0x10, 0x90, 0x60}, // 'j' 00126 {0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90}, // 'k' 00127 {0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70}, // 'l' 00128 {0x00, 0x00, 0xD0, 0xA8, 0xA8, 0x88, 0x88}, // 'm' 00129 {0x00, 0x00, 0xB0, 0xC8, 0x88, 0x88, 0x88}, // 'n' 00130 {0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70}, // 'o' 00131 {0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80}, // 'p' 00132 {0x00, 0x00, 0x68, 0x98, 0x78, 0x08, 0x08}, // 'q' 00133 {0x00, 0x00, 0xB0, 0xC8, 0x80, 0x80, 0x80}, // 'r' 00134 {0x00, 0x00, 0x70, 0x80, 0x70, 0x08, 0xF0}, // 's' 00135 {0x40, 0x40, 0xE0, 0x40, 0x40, 0x48, 0x30}, // 't' 00136 {0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68}, // 'u' 00137 {0x00, 0x00, 0x88, 0x88, 0x88, 0x41, 0x20}, // 'v' 00138 {0x00, 0x00, 0x88, 0x88, 0xA8, 0xA8, 0x50}, // 'w' 00139 {0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88}, // 'x' 00140 {0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0x70}, // 'y' 00141 {0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8}, // 'z' 00142 {0x10, 0x20, 0x20, 0x40, 0x20, 0x20, 0x10}, // '{' 00143 {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}, // '|' 00144 {0x40, 0x20, 0x20, 0x10, 0x20, 0x20, 0x40}, // '}' 00145 {0x00, 0x00, 0x40, 0xA8, 0x10, 0x00, 0x00} // '~' 00146 }; 00147 00148 static bool charPrintable(unsigned char c) { 00149 return (c >= printableCharBegin) && (c <= printableCharEnd); 00150 } 00151 00152 static void removeNonprintableChars(string & s) { 00153 s.erase(std::remove_if(s.begin(), s.end(), 00154 std::not1(std::ptr_fun(charPrintable))), 00155 s.end()); 00156 } 00157 00158 static bool compareStringLength(const string & a, const string & b) { 00159 return a.length() < b.length(); 00160 } 00161 00162 namespace { 00163 00164 // Functor trims string if it exceeds a certain length. 00165 class TrimString { 00166 public: 00167 TrimString(string::size_type maxSize) : maxSize(maxSize) {} 00168 00169 void operator()(string & s) { 00170 if (s.size() > maxSize) { 00171 s.resize(maxSize); 00172 } 00173 } 00174 00175 private: 00176 string::size_type maxSize; 00177 }; 00178 00179 } // namespace 00180 00181 // Split a string based on a character token. Token will be removed. 00182 static std::list<string> tokenizeString(const string & toSplit, char token) { 00183 std::list<string> toSplitLines; 00184 string::size_type beginIdx = 0, endIdx; 00185 do { 00186 endIdx = toSplit.find(token, beginIdx); 00187 toSplitLines.push_back(toSplit.substr( 00188 beginIdx, endIdx == string::npos ? string::npos : endIdx - beginIdx)); 00189 beginIdx = endIdx + 1; 00190 } while (endIdx != string::npos); 00191 return toSplitLines; 00192 } 00193 00194 // Word wrap string into lines based on a specified line length. 00195 static std::list<string> wrapLines(const string & toSplit, 00196 const string::size_type lineLen) { 00197 std::list<string> toSplitLines; 00198 string::size_type beginIdx = 0; 00199 if (lineLen > 0) { 00200 // Split lines as much as necessary. 00201 string::size_type endIdx = lineLen; 00202 while (((toSplit.length() - beginIdx) > lineLen) && 00203 (endIdx != string::npos)) { 00204 endIdx = toSplit.rfind(' ', endIdx); 00205 if ((endIdx == string::npos) || (endIdx <= beginIdx)) { 00206 // Current word is too long to split. Find end of current word. 00207 endIdx = toSplit.find(' ', beginIdx); 00208 } 00209 if (endIdx != string::npos) { 00210 toSplitLines.push_back(toSplit.substr(beginIdx, endIdx - beginIdx)); 00211 beginIdx = endIdx + 1; 00212 endIdx = beginIdx + lineLen; 00213 } 00214 } 00215 } 00216 // Last line is any remaining characters. 00217 toSplitLines.push_back(toSplit.substr(beginIdx, toSplit.length() - beginIdx)); 00218 return toSplitLines; 00219 } 00220 00221 Text::Text() 00222 : text_(), wordWrap_(false), charSpacing_(1), lineSpacing_(1), textLines_(), 00223 preferredWidth_(invalidWidthHeight), 00224 preferredHeight_(invalidWidthHeight) {} 00225 00226 void Text::setText(const string & text) { 00227 if (text_ != text) { 00228 text_ = text; 00229 invalidate(); 00230 preferredWidth_ = preferredHeight_ = invalidWidthHeight; 00231 } 00232 } 00233 00234 void Text::setWordWrap(bool wordWrap) { 00235 if (wordWrap_ != wordWrap) { 00236 wordWrap_ = wordWrap; 00237 invalidate(); 00238 preferredWidth_ = preferredHeight_ = invalidWidthHeight; 00239 } 00240 } 00241 00242 void Text::setLineSpacing(int lineSpacing) { 00243 if (lineSpacing > 0 && lineSpacing_ != lineSpacing) { 00244 lineSpacing_ = lineSpacing ; 00245 invalidate(); 00246 preferredHeight_ = invalidWidthHeight; 00247 } 00248 } 00249 00250 void Text::setCharSpacing(int charSpacing) { 00251 if (charSpacing > 0 && charSpacing_ != charSpacing) { 00252 charSpacing_ = charSpacing; 00253 invalidate(); 00254 preferredWidth_ = invalidWidthHeight; 00255 if (wordWrap()) { 00256 preferredHeight_ = invalidWidthHeight; 00257 } 00258 } 00259 } 00260 00261 int Text::preferredWidth() const { 00262 if (preferredWidth_ == invalidWidthHeight) { 00263 calculateLayout(); 00264 } 00265 return preferredWidth_; 00266 } 00267 00268 int Text::preferredHeight() const { 00269 if (preferredHeight_ == invalidWidthHeight) { 00270 calculateLayout(); 00271 } 00272 return preferredHeight_; 00273 } 00274 00275 void Text::resized() { 00276 preferredWidth_ = invalidWidthHeight; 00277 if (wordWrap()) { 00278 preferredHeight_ = invalidWidthHeight; 00279 } 00280 } 00281 00282 void Text::doRender(Bitmap & bitmap, int xOffset, int yOffset) const { 00283 using std::list; 00284 00285 // Ensure layout is up to date. 00286 if (preferredWidth_ == invalidWidthHeight || 00287 preferredHeight_ == invalidWidthHeight) { 00288 calculateLayout(); 00289 } 00290 00291 // Render each line. 00292 int lineNum = 0; 00293 for (list<string>::const_iterator lineIt = textLines_.begin(); 00294 lineIt != textLines_.end(); ++lineIt) { 00295 // Render each character. 00296 for (string::size_type charNum = 0; charNum < lineIt->length(); ++charNum) { 00297 bitmap.overlay(xOffset + x() + charNum * (characterWidth + charSpacing_), 00298 yOffset + y() + lineNum * (characterHeight + lineSpacing_), 00299 &characterMap[(*lineIt)[charNum] - printableCharBegin][0], 00300 characterHeight, characterWidth); 00301 } 00302 ++lineNum; 00303 } 00304 } 00305 00306 void Text::calculateLayout() const { 00307 using std::list; 00308 00309 // Split string into lines. 00310 textLines_ = tokenizeString(text_, '\n'); 00311 00312 // Remove non-printable characters. 00313 std::for_each(textLines_.begin(), textLines_.end(), removeNonprintableChars); 00314 00315 const int lineLen = 00316 (width() / (characterWidth + charSpacing_)) + 00317 (((width() % (characterWidth + charSpacing_)) >= characterWidth) ? 1 : 0); 00318 const int numLines = 00319 (height() / (characterHeight + lineSpacing_)) + 00320 (((height() % (characterHeight + lineSpacing_)) >= characterHeight) ? 1 00321 : 0); 00322 00323 // Word wrap lines if enabled. 00324 if (wordWrap_) { 00325 list<string>::iterator lineIt = textLines_.begin(); 00326 while (lineIt != textLines_.end()) { 00327 list<string>::iterator nextLineIt = lineIt; 00328 ++nextLineIt; 00329 00330 // Wrap current line. 00331 list<string> wrappedLines = wrapLines(*lineIt, lineLen); 00332 textLines_.splice(lineIt, wrappedLines); 00333 // Remove old line. 00334 textLines_.erase(lineIt); 00335 00336 lineIt = nextLineIt; 00337 } 00338 } 00339 00340 // Calculate preferred size. 00341 string::size_type maxLineLength = 00342 std::max_element(textLines_.begin(), textLines_.end(), 00343 compareStringLength) 00344 ->length(); 00345 preferredWidth_ = (maxLineLength > 0) 00346 ? (maxLineLength * characterWidth) + 00347 ((maxLineLength - 1) * charSpacing_) 00348 : 1; 00349 preferredHeight_ = (textLines_.size() * characterHeight) + 00350 ((textLines_.size() - 1) * lineSpacing_); 00351 00352 // Remove clipped text. 00353 if (textLines_.size() > static_cast<list<string>::size_type>(numLines)) { 00354 textLines_.resize(numLines); 00355 } 00356 std::for_each(textLines_.begin(), textLines_.end(), TrimString(lineLen)); 00357 }
Generated on Tue Jul 12 2022 12:06:49 by 1.7.2