Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
CharacterBitmap.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 
5 using SharpFont;
6 
7 using SiliconStudio.Core;
8 using SiliconStudio.Core.Mathematics;
9 
10 namespace SiliconStudio.Paradox.Graphics.Font
11 {
12  /// <summary>
13  /// A bitmap representing a given character
14  /// </summary>
15  internal sealed class CharacterBitmap : IDisposable
16  {
17  private readonly int width;
18  private readonly int rows;
19  private readonly int pitch;
20  private readonly int grayLevels;
21 
22  private readonly PixelMode pixelMode;
23 
24  private readonly IntPtr buffer;
25 
26  private bool disposed;
27 
28  /// <summary>
29  /// Initializes a new instance of the <see cref="CharacterBitmap"/> representing a null bitmap.
30  /// </summary>
31  public CharacterBitmap()
32  {
33  }
34 
35  /// <summary>
36  /// Initializes a new instance of the <see cref="CharacterBitmap"/> class from a data array.
37  /// </summary>
38  /// <param name="pixelMode">The data format of the bitmap data</param>
39  /// <param name="data">The bitmap data</param>
40  /// <param name="borderSize">The size of the border around the image</param>
41  /// <param name="width">The width of the bitmap </param>
42  /// <param name="rows">The height of the bitmap</param>
43  /// <param name="pitch">The pitch of the bitmap</param>
44  /// <param name="grayLevels">The number of gray levels of the bitmap</param>
45  public CharacterBitmap(IntPtr data, ref Int2 borderSize, int width, int rows, int pitch, int grayLevels, PixelMode pixelMode)
46  {
47  // add one empty border to each side of the bitmap
48  width += 2 * borderSize.X;
49  rows += 2 * borderSize.Y;
50 
51  buffer = Utilities.AllocateMemory(width * rows, 1);
52 
53  if (pixelMode == PixelMode.Mono)
54  CopyAndAddBordersFromMono(data, buffer, ref borderSize, width, rows, pitch);
55  else
56  CopyAndAddBordersFromGrays(data, buffer, ref borderSize, width, rows);
57 
58  this.width = width;
59  this.rows = rows;
60  this.pitch = width;
61  this.grayLevels = grayLevels;
62  this.pixelMode = pixelMode;
63  }
64 
65  private static unsafe void CopyAndAddBordersFromGrays(IntPtr data, IntPtr dataBytes, ref Int2 borderSize, int width, int rows)
66  {
67  var widthLessBorders = width - (borderSize.X << 1);
68  var rowsLessBorders = rows - (borderSize.Y << 1);
69 
70  var resetBorderLineSize = width * borderSize.Y;
71  Utilities.ClearMemory(dataBytes, 0, resetBorderLineSize);
72  Utilities.ClearMemory(dataBytes + width * rows - resetBorderLineSize, 0, resetBorderLineSize); // set last border lines to null
73 
74  var src = (byte*)data;
75  var dst = (byte*)dataBytes + resetBorderLineSize;
76 
77  // set the middle of the image
78  for (int row = 0; row < rowsLessBorders; row++)
79  {
80  for (int c = 0; c < borderSize.X; c++)
81  {
82  *dst = 0;
83  ++dst;
84  }
85 
86  for (int c = 0; c < widthLessBorders; c++)
87  {
88  *dst = *src;
89 
90  ++dst;
91  ++src;
92  }
93 
94  for (int c = 0; c < borderSize.X; c++)
95  {
96  *dst = 0;
97  ++dst;
98  }
99  }
100  }
101 
102  private static unsafe void CopyAndAddBordersFromMono(IntPtr data, IntPtr dataBytes, ref Int2 borderSize, int width, int rows, int srcPitch)
103  {
104  var rowsLessBorders = rows - (borderSize.Y << 1);
105 
106  var resetBorderLineSize = width * borderSize.Y;
107  Utilities.ClearMemory(dataBytes, 0, resetBorderLineSize); // set first border lines to null
108  Utilities.ClearMemory(dataBytes + rows * width - resetBorderLineSize, 0, resetBorderLineSize); // set last border lines to null
109 
110  var rowSrc = (byte*)data;
111  var dst = (byte*)dataBytes + resetBorderLineSize;
112 
113  // copy each row one by one
114  for (int row = 0; row < rowsLessBorders; row++)
115  {
116  var src = rowSrc;
117  var col = 0;
118 
119  for (int c = 0; c < borderSize.X; c++)
120  dst[col++] = 0;
121 
122  while (true)
123  {
124  byte mask = 0x80;
125  for (int k = 0; k < 8; k++)
126  {
127  dst[col] = (*src & mask) != 0 ? byte.MaxValue : (byte)0;
128 
129  mask >>= 1;
130  ++col;
131 
132  if (col >= width - borderSize.X)
133  goto EndRow;
134  }
135  ++src;
136  }
137 
138  EndRow:
139  for (int c = 0; c < borderSize.X; ++c)
140  dst[col++] = 0;
141 
142  rowSrc += srcPitch;
143  dst += width;
144  }
145  }
146 
147  /// <summary>
148  /// Gets a value indicating whether the <see cref="CharacterBitmap"/> has been disposed.
149  /// </summary>
150  public bool IsDisposed
151  {
152  get
153  {
154  return disposed;
155  }
156  }
157 
158  /// <summary>
159  /// Gets the number of bitmap rows.
160  /// </summary>
161  public int Rows
162  {
163  get
164  {
165  if (disposed)
166  throw new ObjectDisposedException("CharacterBitmap", "Cannot access a disposed object.");
167 
168  return rows;
169  }
170  }
171 
172  /// <summary>
173  /// Gets the number of pixels in bitmap row.
174  /// </summary>
175  public int Width
176  {
177  get
178  {
179  if (disposed)
180  throw new ObjectDisposedException("CharacterBitmap", "Cannot access a disposed object.");
181 
182  return width;
183  }
184  }
185 
186  /// <summary><para>
187  /// Gets the pitch's absolute value is the number of bytes taken by one bitmap row, including padding. However,
188  /// the pitch is positive when the bitmap has a ‘down’ flow, and negative when it has an ‘up’ flow. In all
189  /// cases, the pitch is an offset to add to a bitmap pointer in order to go down one row.
190  /// </para><para>
191  /// Note that ‘padding’ means the alignment of a bitmap to a byte border, and FreeType functions normally align
192  /// to the smallest possible integer value.
193  /// </para><para>
194  /// For the B/W rasterizer, ‘pitch’ is always an even number.
195  /// </para></summary>
196  public int Pitch
197  {
198  get
199  {
200  if (disposed)
201  throw new ObjectDisposedException("CharacterBitmap", "Cannot access a disposed object.");
202 
203  return pitch;
204  }
205  }
206 
207  /// <summary>
208  /// Gets a typeless pointer to the bitmap buffer. This value should be aligned on 32-bit boundaries in most
209  /// cases.
210  /// </summary>
211  public IntPtr Buffer
212  {
213  get
214  {
215  if (disposed)
216  throw new ObjectDisposedException("CharacterBitmap", "Cannot access a disposed object.");
217 
218  return buffer;
219  }
220  }
221 
222  /// <summary>
223  /// Gets the number of gray levels used in the bitmap. This field is only used with
224  /// <see cref="SharpFont.PixelMode.Gray"/>.
225  /// </summary>
226  public int GrayLevels
227  {
228  get
229  {
230  if (disposed)
231  throw new ObjectDisposedException("CharacterBitmap", "Cannot access a disposed object.");
232 
233  return grayLevels;
234  }
235  }
236 
237  /// <summary>
238  /// Gets the pixel mode, i.e., how pixel bits are stored.
239  /// </summary>
240  public PixelMode PixelMode
241  {
242  get
243  {
244  if (disposed)
245  throw new ObjectDisposedException("CharacterBitmap", "Cannot access a disposed object.");
246 
247  return pixelMode;
248  }
249  }
250 
251  public void Dispose()
252  {
253  if(IsDisposed)
254  return;
255 
256  Utilities.FreeMemory(buffer);
257 
258  disposed = true;
259  }
260  }
261 }
SharpDX.DirectWrite.Font Font
SiliconStudio.Paradox.Graphics.Buffer Buffer
Definition: BasicEffect.cs:15
Represents a three dimensional mathematical vector.
Definition: Int2.cs:41