Maxim Integrated / Mbed OS MAXREFDES155#

Dependencies:   MaximInterface

Committer:
IanBenzMaxim
Date:
Wed May 03 16:08:59 2017 -0500
Revision:
11:989eabe2a376
Parent:
10:71359af61af8
Child:
13:6a6225690c2e
Changed to always using scanline encoding for bitmaps.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
IanBenzMaxim 0:33d4e66780c0 1 /*******************************************************************************
IanBenzMaxim 0:33d4e66780c0 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
IanBenzMaxim 0:33d4e66780c0 3 *
IanBenzMaxim 0:33d4e66780c0 4 * Permission is hereby granted, free of charge, to any person obtaining a
IanBenzMaxim 0:33d4e66780c0 5 * copy of this software and associated documentation files (the "Software"),
IanBenzMaxim 0:33d4e66780c0 6 * to deal in the Software without restriction, including without limitation
IanBenzMaxim 0:33d4e66780c0 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
IanBenzMaxim 0:33d4e66780c0 8 * and/or sell copies of the Software, and to permit persons to whom the
IanBenzMaxim 0:33d4e66780c0 9 * Software is furnished to do so, subject to the following conditions:
IanBenzMaxim 0:33d4e66780c0 10 *
IanBenzMaxim 0:33d4e66780c0 11 * The above copyright notice and this permission notice shall be included
IanBenzMaxim 0:33d4e66780c0 12 * in all copies or substantial portions of the Software.
IanBenzMaxim 0:33d4e66780c0 13 *
IanBenzMaxim 0:33d4e66780c0 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
IanBenzMaxim 0:33d4e66780c0 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
IanBenzMaxim 0:33d4e66780c0 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IanBenzMaxim 0:33d4e66780c0 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
IanBenzMaxim 0:33d4e66780c0 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
IanBenzMaxim 0:33d4e66780c0 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
IanBenzMaxim 0:33d4e66780c0 20 * OTHER DEALINGS IN THE SOFTWARE.
IanBenzMaxim 0:33d4e66780c0 21 *
IanBenzMaxim 0:33d4e66780c0 22 * Except as contained in this notice, the name of Maxim Integrated
IanBenzMaxim 0:33d4e66780c0 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
IanBenzMaxim 0:33d4e66780c0 24 * Products, Inc. Branding Policy.
IanBenzMaxim 0:33d4e66780c0 25 *
IanBenzMaxim 0:33d4e66780c0 26 * The mere transfer of this software does not imply any licenses
IanBenzMaxim 0:33d4e66780c0 27 * of trade secrets, proprietary technology, copyrights, patents,
IanBenzMaxim 0:33d4e66780c0 28 * trademarks, maskwork rights, or any other form of intellectual
IanBenzMaxim 0:33d4e66780c0 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
IanBenzMaxim 0:33d4e66780c0 30 * ownership rights.
IanBenzMaxim 0:33d4e66780c0 31 *******************************************************************************/
IanBenzMaxim 0:33d4e66780c0 32
IanBenzMaxim 0:33d4e66780c0 33 #include <algorithm>
IanBenzMaxim 0:33d4e66780c0 34 #include <functional>
IanBenzMaxim 0:33d4e66780c0 35 #include <list>
IanBenzMaxim 0:33d4e66780c0 36 #include "Bitmap.hpp"
IanBenzMaxim 0:33d4e66780c0 37 #include "Display.hpp"
IanBenzMaxim 0:33d4e66780c0 38 #include "Text.hpp"
IanBenzMaxim 0:33d4e66780c0 39
IanBenzMaxim 0:33d4e66780c0 40 using std::string;
IanBenzMaxim 0:33d4e66780c0 41
IanBenzMaxim 8:a0d75dff3c9b 42 static const int invalidWidthHeight = -1;
IanBenzMaxim 8:a0d75dff3c9b 43
IanBenzMaxim 8:a0d75dff3c9b 44 static const int characterWidth = 5;
IanBenzMaxim 8:a0d75dff3c9b 45 static const int characterHeight = 7;
IanBenzMaxim 0:33d4e66780c0 46
IanBenzMaxim 0:33d4e66780c0 47 static const unsigned char printableCharBegin = 0x20;
IanBenzMaxim 0:33d4e66780c0 48 static const unsigned char printableCharEnd = 0x7E;
IanBenzMaxim 0:33d4e66780c0 49
IanBenzMaxim 11:989eabe2a376 50 static const uint8_t characterMap[][characterHeight] = {
IanBenzMaxim 11:989eabe2a376 51 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // ' '
IanBenzMaxim 11:989eabe2a376 52 { 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20 }, // '!'
IanBenzMaxim 11:989eabe2a376 53 { 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00 }, // '"'
IanBenzMaxim 11:989eabe2a376 54 { 0x50, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x50 }, // '#'
IanBenzMaxim 11:989eabe2a376 55 { 0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20 }, // '$'
IanBenzMaxim 11:989eabe2a376 56 { 0xC0, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x18 }, // '%'
IanBenzMaxim 11:989eabe2a376 57 { 0x60, 0x90, 0xA0, 0x40, 0xA8, 0x90, 0x68 }, // '&'
IanBenzMaxim 11:989eabe2a376 58 { 0x60, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00 }, // '''
IanBenzMaxim 11:989eabe2a376 59 { 0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10 }, // '('
IanBenzMaxim 11:989eabe2a376 60 { 0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40 }, // ')'
IanBenzMaxim 11:989eabe2a376 61 { 0x00, 0x20, 0xA8, 0x70, 0xA8, 0x20, 0x00 }, // '*'
IanBenzMaxim 11:989eabe2a376 62 { 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00 }, // '+'
IanBenzMaxim 11:989eabe2a376 63 { 0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x40 }, // ','
IanBenzMaxim 11:989eabe2a376 64 { 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00 }, // '-'
IanBenzMaxim 11:989eabe2a376 65 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 }, // '.'
IanBenzMaxim 11:989eabe2a376 66 { 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00 }, // '/'
IanBenzMaxim 11:989eabe2a376 67 { 0x70, 0x88, 0x98, 0xA8, 0xC8, 0x88, 0x70 }, // '0'
IanBenzMaxim 11:989eabe2a376 68 { 0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x70 }, // '1'
IanBenzMaxim 11:989eabe2a376 69 { 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xF8 }, // '2'
IanBenzMaxim 11:989eabe2a376 70 { 0xF8, 0x10, 0x20, 0x10, 0x08, 0x88, 0x70 }, // '3'
IanBenzMaxim 11:989eabe2a376 71 { 0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10 }, // '4'
IanBenzMaxim 11:989eabe2a376 72 { 0xF8, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x70 }, // '5'
IanBenzMaxim 11:989eabe2a376 73 { 0x30, 0x40, 0x80, 0xF0, 0x88, 0x88, 0x70 }, // '6'
IanBenzMaxim 11:989eabe2a376 74 { 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40 }, // '7'
IanBenzMaxim 11:989eabe2a376 75 { 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70 }, // '8'
IanBenzMaxim 11:989eabe2a376 76 { 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60 }, // '9'
IanBenzMaxim 11:989eabe2a376 77 { 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00 }, // ':'
IanBenzMaxim 11:989eabe2a376 78 { 0x00, 0x60, 0x60, 0x00, 0x60, 0x20, 0x40 }, // ';'
IanBenzMaxim 11:989eabe2a376 79 { 0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10 }, // '<'
IanBenzMaxim 11:989eabe2a376 80 { 0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00 }, // '='
IanBenzMaxim 11:989eabe2a376 81 { 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40 }, // '>'
IanBenzMaxim 11:989eabe2a376 82 { 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20 }, // '?'
IanBenzMaxim 11:989eabe2a376 83 { 0x70, 0x88, 0x08, 0x68, 0xA8, 0xA8, 0x70 }, // '@'
IanBenzMaxim 11:989eabe2a376 84 { 0x70, 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88 }, // 'A'
IanBenzMaxim 11:989eabe2a376 85 { 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0xF0 }, // 'B'
IanBenzMaxim 11:989eabe2a376 86 { 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70 }, // 'C'
IanBenzMaxim 11:989eabe2a376 87 { 0xE0, 0x90, 0x88, 0x88, 0x88, 0x90, 0xE0 }, // 'D'
IanBenzMaxim 11:989eabe2a376 88 { 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0xF8 }, // 'E'
IanBenzMaxim 11:989eabe2a376 89 { 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80 }, // 'F'
IanBenzMaxim 11:989eabe2a376 90 { 0x70, 0x88, 0x80, 0xB8, 0x88, 0x88, 0x78 }, // 'G'
IanBenzMaxim 11:989eabe2a376 91 { 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88 }, // 'H'
IanBenzMaxim 11:989eabe2a376 92 { 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70 }, // 'I'
IanBenzMaxim 11:989eabe2a376 93 { 0x38, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60 }, // 'J'
IanBenzMaxim 11:989eabe2a376 94 { 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88 }, // 'K'
IanBenzMaxim 11:989eabe2a376 95 { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8 }, // 'L'
IanBenzMaxim 11:989eabe2a376 96 { 0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88 }, // 'M'
IanBenzMaxim 11:989eabe2a376 97 { 0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88 }, // 'N'
IanBenzMaxim 11:989eabe2a376 98 { 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70 }, // 'O'
IanBenzMaxim 11:989eabe2a376 99 { 0xF0, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80 }, // 'P'
IanBenzMaxim 11:989eabe2a376 100 { 0x70, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68 }, // 'Q'
IanBenzMaxim 11:989eabe2a376 101 { 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88 }, // 'R'
IanBenzMaxim 11:989eabe2a376 102 { 0x78, 0x80, 0x80, 0x70, 0x08, 0x08, 0xF0 }, // 'S'
IanBenzMaxim 11:989eabe2a376 103 { 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, // 'T'
IanBenzMaxim 11:989eabe2a376 104 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70 }, // 'U'
IanBenzMaxim 11:989eabe2a376 105 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20 }, // 'V'
IanBenzMaxim 11:989eabe2a376 106 { 0x88, 0x88, 0x88, 0xA8, 0xA8, 0xA8, 0x50 }, // 'W'
IanBenzMaxim 11:989eabe2a376 107 { 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88 }, // 'X'
IanBenzMaxim 11:989eabe2a376 108 { 0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20 }, // 'Y'
IanBenzMaxim 11:989eabe2a376 109 { 0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8 }, // 'Z'
IanBenzMaxim 11:989eabe2a376 110 { 0x70, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70 }, // '['
IanBenzMaxim 11:989eabe2a376 111 { 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00 }, // '\'
IanBenzMaxim 11:989eabe2a376 112 { 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70 }, // ']'
IanBenzMaxim 11:989eabe2a376 113 { 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00 }, // '^'
IanBenzMaxim 11:989eabe2a376 114 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8 }, // '_'
IanBenzMaxim 11:989eabe2a376 115 { 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00 }, // '`'
IanBenzMaxim 11:989eabe2a376 116 { 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78 }, // 'a'
IanBenzMaxim 11:989eabe2a376 117 { 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0xF0 }, // 'b'
IanBenzMaxim 11:989eabe2a376 118 { 0x00, 0x00, 0x70, 0x80, 0x80, 0x88, 0x70 }, // 'c'
IanBenzMaxim 11:989eabe2a376 119 { 0x08, 0x08, 0x68, 0x98, 0x88, 0x88, 0x78 }, // 'd'
IanBenzMaxim 11:989eabe2a376 120 { 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x70 }, // 'e'
IanBenzMaxim 11:989eabe2a376 121 { 0x30, 0x48, 0x40, 0xE0, 0x40, 0x40, 0x40 }, // 'f'
IanBenzMaxim 11:989eabe2a376 122 { 0x00, 0x78, 0x88, 0x88, 0x78, 0x08, 0x70 }, // 'g'
IanBenzMaxim 11:989eabe2a376 123 { 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88 }, // 'h'
IanBenzMaxim 11:989eabe2a376 124 { 0x20, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70 }, // 'i'
IanBenzMaxim 11:989eabe2a376 125 { 0x10, 0x00, 0x30, 0x10, 0x10, 0x90, 0x60 }, // 'j'
IanBenzMaxim 11:989eabe2a376 126 { 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90 }, // 'k'
IanBenzMaxim 11:989eabe2a376 127 { 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70 }, // 'l'
IanBenzMaxim 11:989eabe2a376 128 { 0x00, 0x00, 0xD0, 0xA8, 0xA8, 0x88, 0x88 }, // 'm'
IanBenzMaxim 11:989eabe2a376 129 { 0x00, 0x00, 0xB0, 0xC8, 0x88, 0x88, 0x88 }, // 'n'
IanBenzMaxim 11:989eabe2a376 130 { 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70 }, // 'o'
IanBenzMaxim 11:989eabe2a376 131 { 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80 }, // 'p'
IanBenzMaxim 11:989eabe2a376 132 { 0x00, 0x00, 0x68, 0x98, 0x78, 0x08, 0x08 }, // 'q'
IanBenzMaxim 11:989eabe2a376 133 { 0x00, 0x00, 0xB0, 0xC8, 0x80, 0x80, 0x80 }, // 'r'
IanBenzMaxim 11:989eabe2a376 134 { 0x00, 0x00, 0x70, 0x80, 0x70, 0x08, 0xF0 }, // 's'
IanBenzMaxim 11:989eabe2a376 135 { 0x40, 0x40, 0xE0, 0x40, 0x40, 0x48, 0x30 }, // 't'
IanBenzMaxim 11:989eabe2a376 136 { 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68 }, // 'u'
IanBenzMaxim 11:989eabe2a376 137 { 0x00, 0x00, 0x88, 0x88, 0x88, 0x41, 0x20 }, // 'v'
IanBenzMaxim 11:989eabe2a376 138 { 0x00, 0x00, 0x88, 0x88, 0xA8, 0xA8, 0x50 }, // 'w'
IanBenzMaxim 11:989eabe2a376 139 { 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88 }, // 'x'
IanBenzMaxim 11:989eabe2a376 140 { 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0x70 }, // 'y'
IanBenzMaxim 11:989eabe2a376 141 { 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8 }, // 'z'
IanBenzMaxim 11:989eabe2a376 142 { 0x10, 0x20, 0x20, 0x40, 0x20, 0x20, 0x10 }, // '{'
IanBenzMaxim 11:989eabe2a376 143 { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, // '|'
IanBenzMaxim 11:989eabe2a376 144 { 0x40, 0x20, 0x20, 0x10, 0x20, 0x20, 0x40 }, // '}'
IanBenzMaxim 11:989eabe2a376 145 { 0x00, 0x00, 0x40, 0xA8, 0x10, 0x00, 0x00 } // '~'
IanBenzMaxim 0:33d4e66780c0 146 };
IanBenzMaxim 0:33d4e66780c0 147
IanBenzMaxim 0:33d4e66780c0 148 static bool charPrintable(unsigned char c)
IanBenzMaxim 0:33d4e66780c0 149 {
IanBenzMaxim 0:33d4e66780c0 150 return (c >= printableCharBegin) && (c <= printableCharEnd);
IanBenzMaxim 0:33d4e66780c0 151 }
IanBenzMaxim 0:33d4e66780c0 152
IanBenzMaxim 0:33d4e66780c0 153 static void removeNonprintableChars(string & s)
IanBenzMaxim 0:33d4e66780c0 154 {
IanBenzMaxim 3:d2799d8497c0 155 s.erase(std::remove_if(s.begin(), s.end(), std::not1(std::ptr_fun(charPrintable))), s.end());
IanBenzMaxim 0:33d4e66780c0 156 }
IanBenzMaxim 0:33d4e66780c0 157
IanBenzMaxim 0:33d4e66780c0 158 static bool compareStringLength(const string & a, const string & b)
IanBenzMaxim 0:33d4e66780c0 159 {
IanBenzMaxim 0:33d4e66780c0 160 return a.length() < b.length();
IanBenzMaxim 0:33d4e66780c0 161 }
IanBenzMaxim 0:33d4e66780c0 162
IanBenzMaxim 0:33d4e66780c0 163 // Functor trims string if it exceeds a certain length.
IanBenzMaxim 0:33d4e66780c0 164 class TrimString
IanBenzMaxim 0:33d4e66780c0 165 {
IanBenzMaxim 0:33d4e66780c0 166 public:
IanBenzMaxim 0:33d4e66780c0 167 TrimString(string::size_type maxSize) : maxSize(maxSize) { }
IanBenzMaxim 0:33d4e66780c0 168
IanBenzMaxim 0:33d4e66780c0 169 void operator()(string & s)
IanBenzMaxim 0:33d4e66780c0 170 {
IanBenzMaxim 0:33d4e66780c0 171 if (s.size() > maxSize)
IanBenzMaxim 0:33d4e66780c0 172 {
IanBenzMaxim 0:33d4e66780c0 173 s.resize(maxSize);
IanBenzMaxim 0:33d4e66780c0 174 }
IanBenzMaxim 0:33d4e66780c0 175 }
IanBenzMaxim 0:33d4e66780c0 176
IanBenzMaxim 0:33d4e66780c0 177 private:
IanBenzMaxim 0:33d4e66780c0 178 string::size_type maxSize;
IanBenzMaxim 0:33d4e66780c0 179 };
IanBenzMaxim 0:33d4e66780c0 180
IanBenzMaxim 0:33d4e66780c0 181 // Split a string based on a character token. Token will be removed.
IanBenzMaxim 0:33d4e66780c0 182 static std::list<string> tokenizeString(const string & toSplit, char token)
IanBenzMaxim 0:33d4e66780c0 183 {
IanBenzMaxim 0:33d4e66780c0 184 std::list<string> toSplitLines;
IanBenzMaxim 0:33d4e66780c0 185 string::size_type beginIdx = 0, endIdx;
IanBenzMaxim 0:33d4e66780c0 186 do
IanBenzMaxim 0:33d4e66780c0 187 {
IanBenzMaxim 0:33d4e66780c0 188 endIdx = toSplit.find(token, beginIdx);
IanBenzMaxim 0:33d4e66780c0 189 toSplitLines.push_back(toSplit.substr(beginIdx, endIdx == string::npos ? string::npos : endIdx - beginIdx));
IanBenzMaxim 0:33d4e66780c0 190 beginIdx = endIdx + 1;
IanBenzMaxim 0:33d4e66780c0 191 } while (endIdx != string::npos);
IanBenzMaxim 0:33d4e66780c0 192 return toSplitLines;
IanBenzMaxim 0:33d4e66780c0 193 }
IanBenzMaxim 0:33d4e66780c0 194
IanBenzMaxim 0:33d4e66780c0 195 // Word wrap string into lines based on a specified line length.
IanBenzMaxim 0:33d4e66780c0 196 static std::list<string> wrapLines(const string & toSplit, const string::size_type lineLen)
IanBenzMaxim 0:33d4e66780c0 197 {
IanBenzMaxim 0:33d4e66780c0 198 std::list<string> toSplitLines;
IanBenzMaxim 0:33d4e66780c0 199 string::size_type beginIdx = 0;
IanBenzMaxim 0:33d4e66780c0 200 if (lineLen > 0)
IanBenzMaxim 0:33d4e66780c0 201 {
IanBenzMaxim 0:33d4e66780c0 202 // Split lines as much as necessary.
IanBenzMaxim 0:33d4e66780c0 203 string::size_type endIdx = lineLen;
IanBenzMaxim 0:33d4e66780c0 204 while (((toSplit.length() - beginIdx) > lineLen) && (endIdx != string::npos))
IanBenzMaxim 0:33d4e66780c0 205 {
IanBenzMaxim 0:33d4e66780c0 206 endIdx = toSplit.rfind(' ', endIdx);
IanBenzMaxim 0:33d4e66780c0 207 if ((endIdx == string::npos) || (endIdx <= beginIdx))
IanBenzMaxim 0:33d4e66780c0 208 {
IanBenzMaxim 0:33d4e66780c0 209 // Current word is too long to split. Find end of current word.
IanBenzMaxim 0:33d4e66780c0 210 endIdx = toSplit.find(' ', beginIdx);
IanBenzMaxim 0:33d4e66780c0 211 }
IanBenzMaxim 0:33d4e66780c0 212 if (endIdx != string::npos)
IanBenzMaxim 0:33d4e66780c0 213 {
IanBenzMaxim 0:33d4e66780c0 214 toSplitLines.push_back(toSplit.substr(beginIdx, endIdx - beginIdx));
IanBenzMaxim 0:33d4e66780c0 215 beginIdx = endIdx + 1;
IanBenzMaxim 0:33d4e66780c0 216 endIdx = beginIdx + lineLen;
IanBenzMaxim 0:33d4e66780c0 217 }
IanBenzMaxim 0:33d4e66780c0 218 }
IanBenzMaxim 0:33d4e66780c0 219 }
IanBenzMaxim 0:33d4e66780c0 220 // Last line is any remaining characters.
IanBenzMaxim 0:33d4e66780c0 221 toSplitLines.push_back(toSplit.substr(beginIdx, toSplit.length() - beginIdx));
IanBenzMaxim 0:33d4e66780c0 222 return toSplitLines;
IanBenzMaxim 0:33d4e66780c0 223 }
IanBenzMaxim 0:33d4e66780c0 224
IanBenzMaxim 8:a0d75dff3c9b 225 Text::Text() : m_text(), m_wordWrap(false), m_charSpacing(1), m_lineSpacing(1),
IanBenzMaxim 8:a0d75dff3c9b 226 m_textLines(), m_preferredWidth(invalidWidthHeight), m_preferredHeight(invalidWidthHeight) { }
IanBenzMaxim 0:33d4e66780c0 227
IanBenzMaxim 6:0c9050b02876 228 void Text::setText(const string & text)
IanBenzMaxim 0:33d4e66780c0 229 {
IanBenzMaxim 0:33d4e66780c0 230 if (m_text != text)
IanBenzMaxim 0:33d4e66780c0 231 {
IanBenzMaxim 0:33d4e66780c0 232 m_text = text;
IanBenzMaxim 8:a0d75dff3c9b 233 invalidate();
IanBenzMaxim 8:a0d75dff3c9b 234 m_preferredWidth = m_preferredHeight = invalidWidthHeight;
IanBenzMaxim 0:33d4e66780c0 235 }
IanBenzMaxim 0:33d4e66780c0 236 }
IanBenzMaxim 0:33d4e66780c0 237
IanBenzMaxim 0:33d4e66780c0 238 void Text::setWordWrap(bool wordWrap)
IanBenzMaxim 0:33d4e66780c0 239 {
IanBenzMaxim 0:33d4e66780c0 240 if (m_wordWrap != wordWrap)
IanBenzMaxim 0:33d4e66780c0 241 {
IanBenzMaxim 0:33d4e66780c0 242 m_wordWrap = wordWrap;
IanBenzMaxim 8:a0d75dff3c9b 243 invalidate();
IanBenzMaxim 8:a0d75dff3c9b 244 m_preferredWidth = m_preferredHeight = invalidWidthHeight;
IanBenzMaxim 0:33d4e66780c0 245 }
IanBenzMaxim 0:33d4e66780c0 246 }
IanBenzMaxim 0:33d4e66780c0 247
IanBenzMaxim 8:a0d75dff3c9b 248 void Text::setLineSpacing(int lineSpacing)
IanBenzMaxim 0:33d4e66780c0 249 {
IanBenzMaxim 8:a0d75dff3c9b 250 if (lineSpacing > 0 && m_lineSpacing != lineSpacing)
IanBenzMaxim 0:33d4e66780c0 251 {
IanBenzMaxim 0:33d4e66780c0 252 m_lineSpacing = lineSpacing;
IanBenzMaxim 8:a0d75dff3c9b 253 invalidate();
IanBenzMaxim 8:a0d75dff3c9b 254 m_preferredHeight = invalidWidthHeight;
IanBenzMaxim 8:a0d75dff3c9b 255 }
IanBenzMaxim 8:a0d75dff3c9b 256 }
IanBenzMaxim 8:a0d75dff3c9b 257
IanBenzMaxim 8:a0d75dff3c9b 258 void Text::setCharSpacing(int charSpacing)
IanBenzMaxim 8:a0d75dff3c9b 259 {
IanBenzMaxim 8:a0d75dff3c9b 260 if (charSpacing > 0 && m_charSpacing != charSpacing)
IanBenzMaxim 8:a0d75dff3c9b 261 {
IanBenzMaxim 8:a0d75dff3c9b 262 m_charSpacing = charSpacing;
IanBenzMaxim 8:a0d75dff3c9b 263 invalidate();
IanBenzMaxim 8:a0d75dff3c9b 264 m_preferredWidth = invalidWidthHeight;
IanBenzMaxim 8:a0d75dff3c9b 265 if (wordWrap())
IanBenzMaxim 8:a0d75dff3c9b 266 {
IanBenzMaxim 8:a0d75dff3c9b 267 m_preferredHeight = invalidWidthHeight;
IanBenzMaxim 8:a0d75dff3c9b 268 }
IanBenzMaxim 0:33d4e66780c0 269 }
IanBenzMaxim 0:33d4e66780c0 270 }
IanBenzMaxim 0:33d4e66780c0 271
IanBenzMaxim 8:a0d75dff3c9b 272 int Text::preferredWidth() const
IanBenzMaxim 8:a0d75dff3c9b 273 {
IanBenzMaxim 8:a0d75dff3c9b 274 if (m_preferredWidth == invalidWidthHeight)
IanBenzMaxim 8:a0d75dff3c9b 275 {
IanBenzMaxim 8:a0d75dff3c9b 276 calculateLayout();
IanBenzMaxim 8:a0d75dff3c9b 277 }
IanBenzMaxim 8:a0d75dff3c9b 278 return m_preferredWidth;
IanBenzMaxim 8:a0d75dff3c9b 279 }
IanBenzMaxim 8:a0d75dff3c9b 280
IanBenzMaxim 8:a0d75dff3c9b 281 int Text::preferredHeight() const
IanBenzMaxim 0:33d4e66780c0 282 {
IanBenzMaxim 8:a0d75dff3c9b 283 if (m_preferredHeight == invalidWidthHeight)
IanBenzMaxim 0:33d4e66780c0 284 {
IanBenzMaxim 8:a0d75dff3c9b 285 calculateLayout();
IanBenzMaxim 8:a0d75dff3c9b 286 }
IanBenzMaxim 8:a0d75dff3c9b 287 return m_preferredHeight;
IanBenzMaxim 8:a0d75dff3c9b 288 }
IanBenzMaxim 8:a0d75dff3c9b 289
IanBenzMaxim 8:a0d75dff3c9b 290 void Text::resized()
IanBenzMaxim 8:a0d75dff3c9b 291 {
IanBenzMaxim 8:a0d75dff3c9b 292 m_preferredWidth = invalidWidthHeight;
IanBenzMaxim 8:a0d75dff3c9b 293 if (wordWrap())
IanBenzMaxim 8:a0d75dff3c9b 294 {
IanBenzMaxim 8:a0d75dff3c9b 295 m_preferredHeight = invalidWidthHeight;
IanBenzMaxim 0:33d4e66780c0 296 }
IanBenzMaxim 0:33d4e66780c0 297 }
IanBenzMaxim 8:a0d75dff3c9b 298
IanBenzMaxim 10:71359af61af8 299 void Text::doRender(Bitmap & bitmap, int xOffset, int yOffset) const
IanBenzMaxim 8:a0d75dff3c9b 300 {
IanBenzMaxim 8:a0d75dff3c9b 301 using std::list;
IanBenzMaxim 0:33d4e66780c0 302
IanBenzMaxim 8:a0d75dff3c9b 303 // Ensure layout is up to date.
IanBenzMaxim 8:a0d75dff3c9b 304 if (m_preferredWidth == invalidWidthHeight || m_preferredHeight == invalidWidthHeight)
IanBenzMaxim 8:a0d75dff3c9b 305 {
IanBenzMaxim 8:a0d75dff3c9b 306 calculateLayout();
IanBenzMaxim 8:a0d75dff3c9b 307 }
IanBenzMaxim 8:a0d75dff3c9b 308
IanBenzMaxim 8:a0d75dff3c9b 309 // Render each line.
IanBenzMaxim 8:a0d75dff3c9b 310 int lineNum = 0;
IanBenzMaxim 8:a0d75dff3c9b 311 for (list<string>::const_iterator lineIt = m_textLines.begin(); lineIt != m_textLines.end(); lineIt++)
IanBenzMaxim 8:a0d75dff3c9b 312 {
IanBenzMaxim 8:a0d75dff3c9b 313 // Render each character.
IanBenzMaxim 8:a0d75dff3c9b 314 for (string::size_type charNum = 0; charNum < lineIt->length(); charNum++)
IanBenzMaxim 8:a0d75dff3c9b 315 {
IanBenzMaxim 10:71359af61af8 316 bitmap.overlay(
IanBenzMaxim 10:71359af61af8 317 xOffset + x() + charNum * (characterWidth + m_charSpacing),
IanBenzMaxim 11:989eabe2a376 318 yOffset + y() + lineNum * (characterHeight + m_lineSpacing),
IanBenzMaxim 11:989eabe2a376 319 &characterMap[(*lineIt)[charNum] - printableCharBegin][0],
IanBenzMaxim 11:989eabe2a376 320 characterHeight,
IanBenzMaxim 11:989eabe2a376 321 characterWidth
IanBenzMaxim 10:71359af61af8 322 );
IanBenzMaxim 8:a0d75dff3c9b 323 }
IanBenzMaxim 8:a0d75dff3c9b 324 lineNum++;
IanBenzMaxim 8:a0d75dff3c9b 325 }
IanBenzMaxim 8:a0d75dff3c9b 326 }
IanBenzMaxim 8:a0d75dff3c9b 327
IanBenzMaxim 8:a0d75dff3c9b 328 void Text::calculateLayout() const
IanBenzMaxim 0:33d4e66780c0 329 {
IanBenzMaxim 0:33d4e66780c0 330 using std::list;
IanBenzMaxim 0:33d4e66780c0 331
IanBenzMaxim 0:33d4e66780c0 332 // Split string into lines.
IanBenzMaxim 0:33d4e66780c0 333 m_textLines = tokenizeString(m_text, '\n');
IanBenzMaxim 0:33d4e66780c0 334
IanBenzMaxim 0:33d4e66780c0 335 // Remove non-printable characters.
IanBenzMaxim 0:33d4e66780c0 336 std::for_each(m_textLines.begin(), m_textLines.end(), removeNonprintableChars);
IanBenzMaxim 0:33d4e66780c0 337
IanBenzMaxim 8:a0d75dff3c9b 338 const int lineLen =
IanBenzMaxim 0:33d4e66780c0 339 (width() / (characterWidth + m_charSpacing)) +
IanBenzMaxim 0:33d4e66780c0 340 (((width() % (characterWidth + m_charSpacing)) >= characterWidth) ? 1 : 0);
IanBenzMaxim 8:a0d75dff3c9b 341 const int numLines =
IanBenzMaxim 0:33d4e66780c0 342 (height() / (characterHeight + m_lineSpacing)) +
IanBenzMaxim 0:33d4e66780c0 343 (((height() % (characterHeight + m_lineSpacing)) >= characterHeight) ? 1 : 0);
IanBenzMaxim 0:33d4e66780c0 344
IanBenzMaxim 0:33d4e66780c0 345 // Word wrap lines if enabled.
IanBenzMaxim 0:33d4e66780c0 346 if (m_wordWrap)
IanBenzMaxim 0:33d4e66780c0 347 {
IanBenzMaxim 0:33d4e66780c0 348 list<string>::iterator lineIt = m_textLines.begin();
IanBenzMaxim 0:33d4e66780c0 349 while (lineIt != m_textLines.end())
IanBenzMaxim 0:33d4e66780c0 350 {
IanBenzMaxim 0:33d4e66780c0 351 list<string>::iterator nextLineIt = lineIt;
IanBenzMaxim 0:33d4e66780c0 352 nextLineIt++;
IanBenzMaxim 0:33d4e66780c0 353
IanBenzMaxim 0:33d4e66780c0 354 // Wrap current line.
IanBenzMaxim 0:33d4e66780c0 355 list<string> wrappedLines = wrapLines(*lineIt, lineLen);
IanBenzMaxim 0:33d4e66780c0 356 m_textLines.splice(lineIt, wrappedLines);
IanBenzMaxim 0:33d4e66780c0 357 // Remove old line.
IanBenzMaxim 0:33d4e66780c0 358 m_textLines.erase(lineIt);
IanBenzMaxim 0:33d4e66780c0 359
IanBenzMaxim 0:33d4e66780c0 360 lineIt = nextLineIt;
IanBenzMaxim 0:33d4e66780c0 361 }
IanBenzMaxim 0:33d4e66780c0 362 }
IanBenzMaxim 0:33d4e66780c0 363
IanBenzMaxim 0:33d4e66780c0 364 // Calculate preferred size.
IanBenzMaxim 0:33d4e66780c0 365 string::size_type maxLineLength =
IanBenzMaxim 0:33d4e66780c0 366 std::max_element(m_textLines.begin(), m_textLines.end(), compareStringLength)->length();
IanBenzMaxim 0:33d4e66780c0 367 m_preferredWidth = (maxLineLength > 0) ?
IanBenzMaxim 0:33d4e66780c0 368 (maxLineLength * characterWidth) + ((maxLineLength - 1) * m_charSpacing) : 1;
IanBenzMaxim 0:33d4e66780c0 369 m_preferredHeight =
IanBenzMaxim 0:33d4e66780c0 370 (m_textLines.size() * characterHeight) + ((m_textLines.size() - 1) * m_lineSpacing);
IanBenzMaxim 0:33d4e66780c0 371
IanBenzMaxim 0:33d4e66780c0 372 // Remove clipped text.
IanBenzMaxim 8:a0d75dff3c9b 373 if (m_textLines.size() > static_cast<list<string>::size_type>(numLines))
IanBenzMaxim 0:33d4e66780c0 374 m_textLines.resize(numLines);
IanBenzMaxim 0:33d4e66780c0 375 std::for_each(m_textLines.begin(), m_textLines.end(), TrimString(lineLen));
IanBenzMaxim 0:33d4e66780c0 376 }