/usr/src/castle-game-engine-4.1.1/fonts/castlebitmapfonts.pas is in castle-game-engine-src 4.1.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | {
Copyright 2002-2013 Michalis Kamburelis.
This file is part of "Castle Game Engine".
"Castle Game Engine" is free software; see the file COPYING.txt,
included in this distribution, for details about the copyright.
"Castle Game Engine" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
}
{ Bitmap fonts types.
Bitmap fonts are a 2D bit array, indicating which pixel is drawn.
They may be represented using types in this unit.
We also have CastleFont2Pascal unit that can even convert such fonts
to Pascal units, to embed fonts inside Pascal code.
Types in this unit were defined with the idea to
easily use them with OpenGL @code(glBitmap) and @code(glPixelStorei)
procedures (see e.g. unit @link(CastleGLBitmapFonts) that does exactly this).
However, this unit does @italic(not) depend on OpenGL, it's generally-usable.
}
unit CastleBitmapFonts;
interface
type
TBitmapCharInfo = record
{ Alignment can be used e.g. with OpenGL's
glPixelStorei(GL_UNPACK_ALIGNMENT, ...).
This is always 1, 2, 4 or 8. }
Alignment: Cardinal;
{ @groupbegin
These fields can be used e.g. with OpenGL's glBitmap }
XOrig, YOrig, XMove, YMove: Single;
Width, Height: Cardinal;
{ @groupend }
end;
{ @name record defines the bitmap character.
@name will not be directly used as a type of some variable.
Instead, we use it only to define @link(PBitmapChar).
Sample character may look like this :
@longcode(#
CharX = record
Info: TBitmapCharInfo
Data: packed array[0..23]of byte;
end =
( Info : ( Alignment : 2;
XOrig : 0; YOrig : 0;
XMove : 10; YMove : 0;
Width : 8; Height : 12 );
Data : ($AA, $00,
$BB, $00,
....
);
);
#)
Notes about example above: The row has
@link(TBitmapCharInfo.Width Width) = 8 which means that
we need only 8 bits (one byte) to store it.
But since @link(TBitmapCharInfo.Alignment Alignment) = 2,
we need to use some multiply of 2 bytes
to store a row, which means that each row actually uses 2 bytes
(even though the contents of 2nd byte are always meaningless).
E.g. if you will pass this data to OpenGL, you should appropriately
use @code(glPixelStorei), so that OpenGL knows that data is aligned
to 2 bytes, and then 2nd byte of each row will indeed be ignored
by OpenGL.
Sure, this is rather extreme example, since in this
case we're wasting half memory just to get Alignment = 2.
Well, this is only an example. Also, Alignment may sometimes
give us better speed. E.g. for OpenGL's glBitmap (even though
if you will use OpenGL's display list, it will not actually
matter that much, since then OpenGL will probably internally convert
to the best alignment anyway).
Summing the example, we have 2 bytes and 12 rows
(@link(TBitmapCharInfo.Height Height) = 2)
so we need 24 bytes to store this character.
The precise formula to calculate how many bytes are used to store
a character is
@unorderedList(
@item( @code(RoundUpToMultiple( (Char.Info.Width + 7) div 8,
Char.Info.Alignment ) * Char.Info.Height) )
@item( Or, more readable, @code(
BitmapCharRowByteLength(Char.Info.Width, Char.Info.Alignment)
* Char.Info.Height ) )
@item( Or, even more readable, just @code(
BitmapCharRowByteLength(Char) * Char.Info.Height) )
)
Rows are specified in @link(Data) from lower to upper
(just like OpenGL's @code(glBitmap) likes).
Note that this is @italic(packed) record so I'm sure that
@longcode(#
SizeOf(record
Info: TBitmapCharInfo;
Data: packed array[0..n]of byte;
) = SizeOf(TBitmapCharInfo) + (n+1) * SizeOf(Byte)
#)
I.e. there's no padding between Info and Data. }
TBitmapChar = packed record
Info: TBitmapCharInfo;
Data: packed array[0 .. MaxInt - 1 - SizeOf(TBitmapCharInfo)]of byte;
end;
PBitmapChar = ^TBitmapChar;
TBitmapFontArray = array [char] of PBitmapChar;
TBitmapFont = class
public
Data: TBitmapFontArray;
end;
function BitmapCharRowByteLength(Width, Alignment: Cardinal): Cardinal; overload;
function BitmapCharRowByteLength(BitmapChar: PBitmapChar): Cardinal; overload;
implementation
uses CastleUtils;
function BitmapCharRowByteLength(Width, Alignment: Cardinal): Cardinal;
begin
Result := RoundUpToMultiply((Width + 7) div 8, Alignment);
end;
function BitmapCharRowByteLength(BitmapChar: PBitmapChar): Cardinal;
begin
Result := BitmapCharRowByteLength(BitmapChar^.Info.Width, BitmapChar^.Info.Alignment);
end;
end.
|