| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 | 
							- /**
 
-  * Copyright (c) 2017-2018 Tara Keeling
 
-  * 
 
-  * This software is released under the MIT License.
 
-  * https://opensource.org/licenses/MIT
 
-  */
 
- #include <stdio.h>
 
- #include <string.h>
 
- #include <stdint.h>
 
- #include <math.h>
 
- #include "gds_private.h"
 
- #include "gds.h"
 
- #include "gds_font.h"
 
- #include "gds_draw.h"
 
- #include "gds_err.h"
 
- static int RoundUpFontHeight( const struct GDS_FontDef* Font ) {
 
-     int Height = Font->Height;
 
-     if ( ( Height % 8 ) != 0 ) {
 
-         return ( ( Height + 7 ) / 8 ) * 8;
 
-     }
 
-     return Height;
 
- }
 
- static const uint8_t* GetCharPtr( const struct GDS_FontDef* Font, char Character ) {
 
-     return &Font->FontData[ ( Character - Font->StartChar ) * ( ( Font->Width * ( RoundUpFontHeight( Font ) / 8 ) ) + 1 ) ];
 
- }
 
- void GDS_FontDrawChar( struct GDS_Device* Device, char Character, int x, int y, int Color ) {
 
-     const uint8_t* GlyphData = NULL;
 
-     int GlyphColumnLen = 0;
 
-     int CharStartX =  0;
 
-     int CharStartY = 0;
 
-     int CharWidth = 0;
 
-     int CharHeight = 0;
 
-     int CharEndX = 0;
 
-     int CharEndY = 0;
 
-     int OffsetX = 0;
 
-     int OffsetY = 0;
 
-     int YByte = 0;
 
-     int YBit = 0;
 
-     int i = 0;
 
-     NullCheck( ( GlyphData = GetCharPtr( Device->Font, Character ) ), return );
 
-     if ( Character >= Device->Font->StartChar && Character <= Device->Font->EndChar ) {
 
-         /* The first byte in the glyph data is the width of the character in pixels, skip over */
 
-         GlyphData++;
 
-         GlyphColumnLen = RoundUpFontHeight( Device->Font ) / 8;
 
-         
 
-         CharWidth = GDS_FontGetCharWidth( Device, Character );
 
-         CharHeight = GDS_FontGetHeight( Device );
 
-         CharStartX = x;
 
-         CharStartY = y;
 
-         
 
-         CharEndX = CharStartX + CharWidth;
 
-         CharEndY = CharStartY + CharHeight;
 
-         /* If the character is partially offscreen offset the end by
 
-         * distance between (coord) and 0.
 
-         */
 
-         OffsetX = ( CharStartX < 0 ) ? abs( CharStartX ) : 0;
 
-         OffsetY = ( CharStartY < 0 ) ? abs( CharStartY ) : 0;
 
-         /* This skips into the proper column within the glyph data */
 
-         GlyphData+= ( OffsetX * GlyphColumnLen );
 
-         CharStartX+= OffsetX;
 
-         CharStartY+= OffsetY;
 
-         /* Do not attempt to draw if this character is entirely offscreen */
 
-         if ( CharEndX < 0 || CharStartX >= Device->TextWidth || CharEndY < 0 || CharStartY >= Device->Height ) {
 
-             ClipDebug( x, y );
 
-             return;
 
-         }
 
-         /* Do not attempt to draw past the end of the screen */
 
-         CharEndX = ( CharEndX >= Device->TextWidth ) ? Device->TextWidth - 1 : CharEndX;
 
-         CharEndY = ( CharEndY >= Device->Height ) ? Device->Height - 1 : CharEndY;
 
- 		Device->Dirty = true;
 
-         for ( x = CharStartX; x < CharEndX; x++ ) {
 
-             for ( y = CharStartY, i = 0; y < CharEndY && i < CharHeight; y++, i++ ) {
 
-                 YByte = ( i + OffsetY ) / 8;
 
-                 YBit = ( i + OffsetY ) & 0x07;
 
-                 if ( GlyphData[ YByte ] & BIT( YBit ) ) {
 
-                     DrawPixel( Device, x, y, Color );
 
-                 }            
 
-             }
 
-             GlyphData+= GlyphColumnLen;
 
-         }
 
-     }
 
- }
 
- const struct GDS_FontDef* GDS_SetFont( struct GDS_Device* Display, const struct GDS_FontDef* Font ) {
 
- 	const struct GDS_FontDef* OldFont = Display->Font;
 
-     Display->FontForceProportional = false;
 
-     Display->FontForceMonospace = false;
 
-     Display->Font = Font;
 
-     return OldFont;
 
- }
 
- void GDS_FontForceProportional( struct GDS_Device* Display, bool Force ) {
 
-     Display->FontForceProportional = Force;
 
- }
 
- void GDS_FontForceMonospace( struct GDS_Device* Display, bool Force ) {
 
-     Display->FontForceMonospace = Force;
 
- }
 
- int GDS_FontGetWidth( struct GDS_Device* Display ) {
 
-     return Display->Font->Width;
 
- }
 
- int GDS_FontGetHeight( struct GDS_Device* Display ) {
 
-     return Display->Font->Height;
 
- }
 
- int GDS_FontGetCharWidth( struct GDS_Device* Display, char Character ) {
 
-     const uint8_t* CharPtr = NULL;
 
-     int Width = 0;
 
-     if ( Character >= Display->Font->StartChar && Character <= Display->Font->EndChar ) {
 
-         CharPtr = GetCharPtr( Display->Font, Character );
 
-         Width = ( Display->Font->Monospace == true ) ? Display->Font->Width : *CharPtr;
 
-         if ( Display->FontForceMonospace == true ) {
 
-             Width = Display->Font->Width;
 
-         }
 
-         if ( Display->FontForceProportional == true ) {
 
-             Width = *CharPtr;
 
-         }
 
-     }
 
-     return Width;
 
- }
 
- int GDS_FontGetMaxCharsPerRow( struct GDS_Device* Display ) {
 
-     return Display->TextWidth / Display->Font->Width;
 
- }
 
- int GDS_FontGetMaxCharsPerColumn( struct GDS_Device* Display ) {
 
-     return Display->Height / Display->Font->Height;    
 
- }
 
- int GDS_FontGetCharHeight( struct GDS_Device* Display ) {
 
-     return Display->Font->Height;
 
- }
 
- int GDS_FontMeasureString( struct GDS_Device* Display, const char* Text ) {
 
-     int Width = 0;
 
-     int Len = 0;
 
-     NullCheck( Text, return 0 );
 
-     for ( Len = strlen( Text ); Len >= 0; Len--, Text++ ) {
 
-         if ( *Text >= Display->Font->StartChar && *Text <= Display->Font->EndChar ) {
 
-             Width+= GDS_FontGetCharWidth( Display, *Text );
 
-         }
 
-     }
 
-     return Width;
 
- }
 
- void GDS_FontDrawString( struct GDS_Device* Display, int x, int y, const char* Text, int Color ) {
 
-     int Len = 0;
 
-     int i = 0;
 
-     NullCheck( Text, return );
 
-     for ( Len = strlen( Text ), i = 0; i < Len; i++ ) {
 
-         GDS_FontDrawChar( Display, *Text, x, y, Color );
 
-         x+= GDS_FontGetCharWidth( Display, *Text );
 
-         Text++;
 
-     }
 
- }
 
- void GDS_FontDrawAnchoredString( struct GDS_Device* Display, TextAnchor Anchor, const char* Text, int Color ) {
 
-     int x = 0;
 
-     int y = 0;
 
-     NullCheck( Text, return );
 
-     GDS_FontGetAnchoredStringCoords( Display, &x, &y, Anchor, Text );
 
-     GDS_FontDrawString( Display, x, y, Text, Color );
 
- }
 
- void GDS_FontGetAnchoredStringCoords( struct GDS_Device* Display, int* OutX, int* OutY, TextAnchor Anchor, const char* Text ) {
 
-     int StringWidth = 0;
 
-     int StringHeight = 0;
 
-     NullCheck( OutX, return );
 
-     NullCheck( OutY, return );
 
-     NullCheck( Text, return );
 
-     StringWidth = GDS_FontMeasureString( Display, Text );
 
-     StringHeight = GDS_FontGetCharHeight( Display );
 
-     switch ( Anchor ) {
 
-         case TextAnchor_East: {
 
-             *OutY = ( Display->Height / 2 ) - ( StringHeight / 2 );
 
-             *OutX = ( Display->TextWidth - StringWidth );
 
-             break;
 
-         }
 
-         case TextAnchor_West: {
 
-             *OutY = ( Display->Height / 2 ) - ( StringHeight / 2 );
 
-             *OutX = 0;
 
-             break;
 
-         }
 
-         case TextAnchor_North: {
 
-             *OutX = ( Display->TextWidth / 2 ) - ( StringWidth / 2 );
 
-             *OutY = 0;
 
-             break;
 
-         }
 
-         case TextAnchor_South: {
 
-             *OutX = ( Display->TextWidth / 2 ) - ( StringWidth / 2 );
 
-             *OutY = ( Display->Height - StringHeight );
 
-             
 
-             break;
 
-         }
 
-         case TextAnchor_NorthEast: {
 
-             *OutX = ( Display->TextWidth - StringWidth );
 
-             *OutY = 0;
 
-             break;
 
-         }
 
-         case TextAnchor_NorthWest: {
 
-             *OutY = 0;
 
-             *OutX = 0;
 
-             break;
 
-         }
 
-         case TextAnchor_SouthEast: {
 
-             *OutY = ( Display->Height - StringHeight );
 
-             *OutX = ( Display->TextWidth - StringWidth );
 
-             break;
 
-         }
 
-         case TextAnchor_SouthWest: {
 
-             *OutY = ( Display->Height - StringHeight );
 
-             *OutX = 0;
 
-             break;
 
-         }
 
-         case TextAnchor_Center: {
 
-             *OutY = ( Display->Height / 2 ) - ( StringHeight / 2 );
 
-             *OutX = ( Display->TextWidth / 2 ) - ( StringWidth / 2 );
 
-             break;
 
-         }
 
-         default: {
 
-             *OutX = 128;
 
-             *OutY = 64;
 
-             
 
-             break;
 
-         }
 
-     };
 
- }
 
 
  |