Implement HlPutCharacter() routine
All checks were successful
Builds / ExectOS (i686) (push) Successful in 29s
Builds / ExectOS (amd64) (push) Successful in 30s

This commit is contained in:
Rafal Kupiec 2024-03-10 17:02:30 +01:00
parent 4bff86c570
commit bb44caee31
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
3 changed files with 161 additions and 0 deletions

View File

@ -12,6 +12,7 @@
#include <xttypes.h>
#include <xtdefs.h>
/* SSF2 font header */
typedef struct _SSFN_FONT_HEADER
{

View File

@ -136,3 +136,156 @@ HlInitializeFrameBuffer(VOID)
/* Return success */
return STATUS_SUCCESS;
}
/**
* Puts a wide character on the framebuffer at the given position and color using the SSFN font.
*
* @param PositionX
* Supplies the X coordinate of the character.
*
* @param PositionY
* Supplies the Y coordinate of the character.
*
* @param Color
* Supplies the font color.
*
* @param WideCharacter
* Supplies the wide character to be drawn on the framebuffer.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
HlPutCharacter(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color,
IN WCHAR WideCharacter)
{
UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;
PUCHAR Character, CharacterMapping, Fragment;
UINT_PTR GlyphPixel, Pixel;
PSSFN_FONT_HEADER FbFont;
/* Get pointers to font data */
FbFont = (PSSFN_FONT_HEADER)HlpFrameBufferData.Font;
CharacterMapping = (PUCHAR)FbFont + FbFont->CharactersOffset;
/* Find the character in the font's character table */
Character = 0;
for(Index = 0; Index < 0x110000; Index++)
{
if(CharacterMapping[0] == 0xFF)
{
/* Skip 65535 code points */
Index += 65535;
CharacterMapping++;
}
else if((CharacterMapping[0] & 0xC0) == 0xC0)
{
/* Skip (N << 8 + additional byte) + 1 code points (up to 16128) */
Index += (((CharacterMapping[0] & 0x3F) << 8) | CharacterMapping[1]);
CharacterMapping += 2;
}
else if((CharacterMapping[0] & 0xC0) == 0x80)
{
/* Skip N + 1 code points (up to 64) */
Index += (CharacterMapping[0] & 0x3F);
CharacterMapping++;
}
else
{
/* There's a glyph for this character, check if it matches */
if(Index == WideCharacter)
{
/* Found the character, break loop */
Character = CharacterMapping;
break;
}
/* Move to next character table entry */
CharacterMapping += (6 + CharacterMapping[1] * (CharacterMapping[0] & 0x40 ? 6 : 5));
}
}
/* Make sure the character has been found in the font */
if(!Character)
{
/* Character not found, don't draw anything */
return;
}
/* Find the glyph position on the frame buffer */
GlyphPixel = (UINT_PTR)HlpFrameBufferData.Address + PositionY * HlpFrameBufferData.Pitch + PositionX * 4;
/* Check all kerning fragments */
Mapping = 0;
CharacterMapping = Character + 6;
for(Index = 0; Index < Character[1]; Index++)
{
/* Check if number of fragments is not exceeded */
if(CharacterMapping[0] == 255 && CharacterMapping[1] == 255)
{
/* Get next mapping */
continue;
}
/* Get pointer to fragment */
Fragment = (PUCHAR)FbFont + (CharacterMapping[2] |
(CharacterMapping[3] << 8) |
(CharacterMapping[4] << 16) |
((Character[0] & 0x40) ? (CharacterMapping[5] << 24) : 0));
/* Check if fragment is printable */
if((Fragment[0] & 0xE0) != 0x80)
{
/* Skip fragment */
continue;
}
/* Get initial glyph line */
GlyphPixel += (CharacterMapping[1] - Mapping) * HlpFrameBufferData.Pitch;
Mapping = CharacterMapping[1];
/* Extract glyph data from fragments table and advance */
Glyph = ((Fragment[0] & 0x1F) + 1) << 3;
GlyphLimit = Fragment[1] + 1;
Fragment += 2;
/* Look for kerning group for next code point */
CurrentFragment = 1;
while(GlyphLimit--)
{
Pixel = GlyphPixel;
for(Line = 0; Line < Glyph; Line++)
{
/* Decode compressed offsets */
if(CurrentFragment > 0x80)
{
/* Advance to next fragment */
Fragment++;
CurrentFragment = 1;
}
/* Check if pixel should be drawn */
if(*Fragment & CurrentFragment)
{
/* Draw glyph pixel */
*((PULONG)Pixel) = Color;
}
/* Advance pixel pointer */
Pixel += 4;
CurrentFragment <<= 1;
}
/* Advance to next line and increase mapping */
GlyphPixel += HlpFrameBufferData.Pitch;
Mapping++;
}
/* Get next mapping */
CharacterMapping += Character[0] & 0x40 ? 6 : 5;
}
}

View File

@ -55,6 +55,13 @@ XTAPI
XTSTATUS
HlInitializeFrameBuffer(VOID);
XTAPI
VOID
HlPutCharacter(IN ULONG PositionX,
IN ULONG PositionY,
IN ULONG Color,
IN WCHAR WideCharacter);
XTFASTCALL
VOID
HlSetRunLevel(IN KRUNLEVEL RunLevel);