summaryrefslogtreecommitdiff
path: root/NxWidgets/libnxwidgets/src/cnxfont.cxx
blob: 189cfb9e000e33ba67adb04672209bb25b3241a8 (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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/****************************************************************************
 * NxWidgets/libnxwidgets/src/cnxfont.cxx
 *
 *   Copyright (C) 2012 Gregory Nutt. All rights reserved.
 *   Author: Gregory Nutt <gnutt@nuttx.org>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
 *    me be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/****************************************************************************
 * Included Files
 ****************************************************************************/
 
#include <nuttx/config.h>

#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <cstring>

#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nxfonts.h>

#include "nxconfig.hxx"
#include "cnxstring.hxx"
#include "cstringiterator.hxx"
#include "cnxfont.hxx"
#include "cbitmap.hxx"

/****************************************************************************
 * Pre-Processor Definitions
 ****************************************************************************/

/****************************************************************************
 * CNxFont Method Implementations
 ****************************************************************************/

using namespace NXWidgets;

/**
 * CNxFont Constructor.
 *
 * @param fontid The font ID to use.
 * @param fontColor The font color to use.
 * @param transparentColor The color in the font bitmap used as the
 *    background color.
 */

CNxFont::CNxFont(enum nx_fontid_e fontid, nxgl_mxpixel_t fontColor,
                 nxgl_mxpixel_t transparentColor)
{
  m_fontId           = fontid;
  m_fontHandle       = nxf_getfonthandle(fontid);
  m_pFontSet         = nxf_getfontset(m_fontHandle);
  m_fontColor        = fontColor;
  m_transparentColor = transparentColor;
}

/**
 * Checks if supplied character is blank in the current font.
 *
 * @param letter The character to check.
 * @return True if the glyph contains any pixels to be drawn.  False if
 *   the glyph is blank.
 */

const bool CNxFont::isCharBlank(const nxwidget_char_t letter) const
{
  FAR const struct nx_fontbitmap_s *fbm;

  /* Get the bitmap associated with the character */

  fbm = nxf_getbitmap(m_fontHandle, (uint16_t)letter);
  return (fbm == NULL);
}

/**
 * Draw an individual character of the font to the specified bitmap.
 *
 * @param bitmap The bitmap to draw use. The caller should use
 *   the getFontMetrics method to assure that the buffer will hold
 *   the font.
 * @param letter The character to output.
 *
 * @return The width of the string in pixels.
 */

void CNxFont::drawChar(FAR SBitmap *bitmap, nxwidget_char_t letter)
{
  // Get the NX bitmap associated with the font

  FAR const struct nx_fontbitmap_s *fbm;
  fbm = nxf_getbitmap(m_fontHandle, letter);
  if (fbm)
    {
      // Get information about the font bitmap

      uint8_t fwidth  = fbm->metric.width + fbm->metric.xoffset;
      uint8_t fheight = fbm->metric.height + fbm->metric.yoffset;
      uint8_t fstride = (fwidth * bitmap->bpp + 7) >> 3;

      // Then render the glyph into the bitmap memory

      (void)FONT_RENDERER((FAR nxgl_mxpixel_t*)bitmap->data, fheight,
                          fwidth, fstride, fbm, m_fontColor);
    }
}

/**
 * Get the width of a string in pixels when drawn with this font.
 *
 * @param text The string to check.
 * @return The width of the string in pixels.
 */

nxgl_coord_t CNxFont::getStringWidth(const CNxString &text) const
{
  CStringIterator *iter = text.newStringIterator();

  // Get the width of the string of characters
  // Move to the first character

  unsigned int width = 0;
  if (iter->moveToFirst())
    {
      // moveToFirst returns true if there is at least one character
  
      do
        {
          // Add the width of the font bitmap for this character and
          // move the the next character

          nxwidget_char_t ch = iter->getChar();
          
          width += getCharWidth(ch);
        }
      while (iter->moveToNext());
    }

  // Return the total width

  delete iter;
  return width;
}

/**
 * Get the width of a portion of a string in pixels when drawn with this
 * font.
 *
 * @param text The string to check.
 * @param startIndex The start point of the substring within the string.
 * @param length The length of the substring in chars.
 * @return The width of the substring in pixels.
 */
 
nxgl_coord_t CNxFont::getStringWidth(const CNxString &text,
                                     int startIndex, int length) const
{
  CStringIterator *iter = text.newStringIterator();

  // Get the width of the string of characters

  iter->moveTo(startIndex);
  unsigned int width = 0;

  while (length-- > 0)
    {
      // Add the width of the font bitmap for this character

      nxwidget_char_t ch = iter->getChar();
      width += getCharWidth(ch);

      // Position to the next character in the string

      if (!iter->moveToNext())
        {
          break;
        }
    }

  // Return the total width

  delete iter;
  return width;
}

/**
 * Gets font metrics for a particular character
 *
 * @param letter The character to get the width of.
 * @param metrics The location to return the font metrics
 */

void CNxFont::getCharMetrics(nxwidget_char_t letter,
                             FAR struct nx_fontmetric_s *metrics) const
{
  FAR const struct nx_fontbitmap_s *fbm;

  // Get the font bitmap for this character

  fbm = nxf_getbitmap(m_fontHandle, letter);
  if (fbm)
    {
      // Return the metrics of the font

      memcpy(metrics, &fbm->metric, sizeof(struct nx_fontmetric_s));
    }
  else
    {
      // Use the metrics of a space which has no width and no height
      // but an xoffset equal to the standard width of a space.

      metrics->stride  = (m_pFontSet->spwidth * CONFIG_NXWIDGETS_BPP + 7) >> 3;
      metrics->width   = 0;
      metrics->height  = 0;
      metrics->xoffset = m_pFontSet->spwidth;
      metrics->yoffset = 0;
    }
}

/**
 * Get the width of an individual character.
 *
 * @param letter The character to get the width of.
 * @return The width of the character in pixels.
 */

nxgl_coord_t CNxFont::getCharWidth(nxwidget_char_t letter) const
{
  FAR const struct nx_fontbitmap_s *fbm;
  nxgl_coord_t width;

  /* Get the font bitmap for this character */

  fbm = nxf_getbitmap(m_fontHandle, letter);
  if (fbm)
    {
      /* Return the width of the font -- including the X offset */

      width = fbm->metric.width + fbm->metric.xoffset;
    }
  else
    {
      /* Use the width of a space */

     width = m_pFontSet->spwidth;
    }

  return width;
}