60 #define PCF_PROPERTIES (1<<0)
61 #define PCF_ACCELERATORS (1<<1)
62 #define PCF_METRICS (1<<2)
63 #define PCF_BITMAPS (1<<3)
64 #define PCF_INK_METRICS (1<<4)
65 #define PCF_BDF_ENCODINGS (1<<5)
66 #define PCF_SWIDTHS (1<<6)
67 #define PCF_GLYPH_NAMES (1<<7)
68 #define PCF_BDF_ACCELERATORS (1<<8)
70 #define PCF_DEFAULT_FORMAT 0x00000000
71 #define PCF_INKBOUNDS 0x00000200
72 #define PCF_ACCEL_W_INKBOUNDS 0x00000100
73 #define PCF_COMPRESSED_METRICS 0x00000100
75 #define PCF_GLYPH_PAD_MASK (3<<0)
76 #define PCF_BYTE_MASK (1<<2)
77 #define PCF_BIT_MASK (1<<3)
78 #define PCF_SCAN_UNIT_MASK (3<<4)
93 struct PCFMetricsTable
99 struct PCFEncodingTable
102 short min_char_or_byte2;
103 short max_char_or_byte2;
109 struct PCFAcceleratorTable
112 unsigned char noOverlap;
113 unsigned char constantMetrics;
114 unsigned char terminalFont;
115 unsigned char constantWidth;
116 unsigned char inkInside;
117 unsigned char inkMetrics;
118 unsigned char drawDirection;
119 unsigned char padding;
125 struct PCFMetricsEntry
127 int left_sided_bearing;
128 int right_side_bearing;
130 int character_ascent;
131 int character_descent;
132 int character_attributes;
136 struct BitmapCharacter
155 m_pEncodingTable = 0;
165 void CBitmapFont::Reset()
169 for (
int i = 0; i < m_nCharacters; i++)
171 if (m_pCharacters[i].pCoordinatesX)
173 delete [] m_pCharacters[i].pCoordinatesX;
174 delete [] m_pCharacters[i].pCoordinatesY;
178 delete [] m_pCharacters;
182 delete [] m_pEncodingTable;
183 m_pEncodingTable = 0;
190 void CBitmapFont::Init(
int nCharacters)
194 m_nCharacters = nCharacters;
196 m_pCharacters =
new BitmapCharacter[m_nCharacters];
200 for (
int i = 0; i < m_nCharacters; i++)
202 m_pCharacters[i].pCoordinatesX = 0;
203 m_pCharacters[i].pCoordinatesY = 0;
204 m_pCharacters[i].nCoordinates = 0;
205 m_pCharacters[i].nWidth = 0;
208 m_nMaxEncoding = 256;
209 m_pEncodingTable =
new int[m_nMaxEncoding];
211 for (i = 0; i < m_nMaxEncoding; i++)
212 m_pEncodingTable[i] = -1;
215 bool CBitmapFont::GetCharacterInformation(
unsigned char encoding,
int *&pCoordinatesX,
int *&pCoordinatesY,
int &nCoordinates,
int &nWidth)
const
217 const int nIndex = m_pEncodingTable[encoding];
222 pCoordinatesX = m_pCharacters[nIndex].pCoordinatesX;
223 pCoordinatesY = m_pCharacters[nIndex].pCoordinatesY;
224 nCoordinates = m_pCharacters[nIndex].nCoordinates;
225 nWidth = m_pCharacters[nIndex].nWidth;
230 void CBitmapFont::SetGlyph(
int nIndex,
int *pCoordinatesX,
int *pCoordinatesY,
int nCoordinates,
int nWidth,
int nAscent,
int nDescent)
232 if (m_pCharacters[nIndex].pCoordinatesY)
234 delete [] m_pCharacters[nIndex].pCoordinatesY;
235 delete [] m_pCharacters[nIndex].pCoordinatesY;
238 m_pCharacters[nIndex].pCoordinatesX =
new int[nCoordinates];
239 m_pCharacters[nIndex].pCoordinatesY =
new int[nCoordinates];
240 m_pCharacters[nIndex].nCoordinates = nCoordinates;
241 m_pCharacters[nIndex].nWidth = nWidth;
244 for (
int i = 0; i < nCoordinates; i++)
246 m_pCharacters[nIndex].pCoordinatesX[i] = pCoordinatesX[i];
247 m_pCharacters[nIndex].pCoordinatesY[i] = pCoordinatesY[i];
251 void CBitmapFont::AddEncoding(
int nEncoding,
int nIndex)
253 if (nIndex >= m_nCharacters)
255 printf(
"error: encoding %i indexed invalid glyph index %i (%i glyphs)\n", nEncoding, nIndex, m_nCharacters);
259 if (nEncoding < 0 || nEncoding >= m_nMaxEncoding)
261 printf(
"error: encoding %i is not valid\n", nEncoding);
265 m_pEncodingTable[nEncoding] = nIndex;
275 unsigned short result = 0;
277 result |= (x & 0x00ff) << 8;
278 result |= (x & 0xff00) >> 8;
288 unsigned int result = 0;
290 result |= (x & 0x000000ff) << 24;
291 result |= (x & 0x0000ff00) << 8;
292 result |= (x & 0x00ff0000) >> 8;
293 result |= (x & 0xff000000) >> 24;
301 FILE *f = fopen(pFilePath,
"rb");
304 printf(
"error: could not open file for reading\n");
308 fseek(f, 0, SEEK_END);
309 const int nFileSize = ftell(f);
310 fseek(f, 0, SEEK_SET);
313 unsigned char *pBuffer =
new unsigned char[nFileSize];
316 if (fread(pBuffer, nFileSize, 1, f) != 1)
318 printf(
"error: could not read file\n");
324 if (strncmp((
char *) pBuffer,
"\1fcp", 4) != 0)
326 printf(
"error: file header is not a valid PCF header\n");
333 TOCEntry *pTOCEntries = (TOCEntry *) (pBuffer + 8);
334 TOCEntry *pBitmapTOCEntry = 0;
335 TOCEntry *pAcceleratorTOCEntry = 0;
336 TOCEntry *pMetricsTOCEntry = 0;
337 TOCEntry *pEncodingTOCEntry = 0;
341 for (i = 0; i < nTableCount; i++)
345 printf(
"error: inverse bit order not implmeented\n");
350 switch (pTOCEntries[i].type)
352 case PCF_BITMAPS: pBitmapTOCEntry = pTOCEntries + i;
break;
354 case PCF_METRICS: pMetricsTOCEntry = pTOCEntries + i;
break;
360 if (!pBitmapTOCEntry || !pAcceleratorTOCEntry || !pMetricsTOCEntry || !pEncodingTOCEntry)
362 printf(
"error: PCF does not contain all tables\n");
368 PCFAcceleratorTable *pAcceleratorTable = (PCFAcceleratorTable *) (pBuffer + pAcceleratorTOCEntry->offset);
375 PCFMetricsTable *pMetricsTable = (PCFMetricsTable *) (pBuffer + pMetricsTOCEntry->offset);
381 PCFEncodingTable *pEncodingTable = (PCFEncodingTable *) (pBuffer + pEncodingTOCEntry->offset);
389 if (pEncodingTable->min_byte1 != 0 || pEncodingTable->max_byte1 != 0)
391 printf(
"error: 2 byte encoding not implemented\n");
396 const short *pEncodingData = (
const short *) (pBuffer + pEncodingTOCEntry->offset + 14);
399 int *pBitmapTable = (
int *) (pBuffer + pBitmapTOCEntry->offset);
403 const int nBitmapSize =
my_invert_byte_order_int(pBitmapTable[2 + nGlyphs + (nBitmapFormat & 3)], nBitmapFormat & PCF_BYTE_MASK);
404 const int *pGlyphOffsets = pBitmapTable + 2;
406 int nBytesPerLine = 0;
407 switch (nBitmapFormat & 3)
409 case 0: nBytesPerLine = 1;
410 case 1: nBytesPerLine = 2;
411 case 2: nBytesPerLine = 4;
414 if (nBytesPerLine == 0)
416 printf(
"error: bitmap format invalid\n");
425 if (nBitmapSize % nGlyphs != 0)
427 printf(
"error: irregular glyph size\n");
432 const int nBytesPerGlyph = nBitmapSize / nGlyphs;
434 if (nBytesPerGlyph % nBytesPerLine != 0)
436 printf(
"error: irregular line size\n");
441 const int nLinesPerGlyph = nBytesPerGlyph / nBytesPerLine;
443 if (pMetricsTable->metrics_count != nGlyphs)
445 printf(
"error: glyph count does not match metrics count\n");
454 int *pCoordinatesX =
new int[nLinesPerGlyph * nBytesPerLine * 8];
455 int *pCoordinatesY =
new int[nLinesPerGlyph * nBytesPerLine * 8];
457 for (
int n = 0; n < nGlyphs; n++)
459 const unsigned char *pGlyphBitmapData = ((
const unsigned char *) (pBitmapTable + 6 + nGlyphs)) +
my_invert_byte_order_int(pGlyphOffsets[n], nBitmapFormat & PCF_BYTE_MASK);
462 int nCoordinates = 0;
464 for (
int i = 0; i < nLinesPerGlyph; i++)
466 for (
int j = 0; j < nBytesPerLine; j++)
468 const unsigned char value = pGlyphBitmapData[i * nBytesPerLine + j];
470 for (
int k = 0; k < 8; k++)
471 if ((value << k) & 128)
473 pCoordinatesX[nCoordinates] = j * 8 + k;
474 pCoordinatesY[nCoordinates] = i;
481 int nWidth, nAscent, nDescent;
485 const unsigned char *pMetricsData = (
unsigned char *) (pBuffer + pMetricsTOCEntry->offset + 6);
486 nWidth = pMetricsData[n * 5 + 2] - 0x80;
487 nAscent = pMetricsData[n * 5 + 3] - 0x80;
488 nDescent = pMetricsData[n * 5 + 4] - 0x80;
492 const short *pMetricsData = (
short *) (pBuffer + pMetricsTOCEntry->offset + 6);
499 SetGlyph(n, pCoordinatesX, pCoordinatesY, nCoordinates, nWidth, nAscent, nDescent);
503 for (i = pEncodingTable->min_char_or_byte2; i <= pEncodingTable->max_char_or_byte2; i++)
506 AddEncoding(i, nIndex);
512 m_nFontHeight = pAcceleratorTable->fontAscent + pAcceleratorTable->fontDescent;
515 delete [] pCoordinatesX;
516 delete [] pCoordinatesY;
524 const int nLength = (int) strlen(pText);
528 for (
int i = 0; i < nLength; i++)
530 int *pCoordinatesX, *pCoordinatesY;
531 int nCoordinates, nWidth;
533 if (pText[i] ==
'\n')
539 if (GetCharacterInformation(pText[i], pCoordinatesX, pCoordinatesY, nCoordinates, nWidth))
541 for (
int j = 0; j < nCoordinates; j++)
554 unsigned char r, g, b;
558 DrawText(pImage, pText, x, y, r, g, b);
void DrawText(CByteImage *pImage, const char *pText, int x, int y, unsigned char r=0, unsigned char g=0, unsigned char b=0) const
void GetRGBValues(Color color, unsigned char &r, unsigned char &g, unsigned char &b)
void DrawPoint(CByteImage *pImage, const Vec2d &point, int r=255, int g=255, int b=255)
Draws a point into a CByteImage.
#define PCF_COMPRESSED_METRICS
static short my_invert_byte_order_short(short x, int bInvert=false)
#define PCF_BDF_ENCODINGS
static unsigned int my_invert_byte_order_int(unsigned int x, int bInvert=false)
Data structure for the representation of 8-bit grayscale images and 24-bit RGB (or HSV) color images ...
bool LoadPCFFont(const char *pFilePath)