SegDisplay

From VirtualFabWiki
Jump to: navigation, search

This is a Custom GOL Widget, built on the Template.c skeleton given by Microchip.

It draws a 7-segment display on the screen using no fonts. It is scalable and can be made very big and therefore visible.

The primitive involved here is FontSeg.c, a 7 digits display vector font I wrote.

Using the standard GOL Widget DigitalMeter implies using a big font that can eat all of your precious flash memory. So I wrote this simple replacement that is less fancy but uses very little flash and RAM memory, since it draws segments using the Bar primitive.

It can have an arbitrary number of digits.

Syntax

The calling syntax is:

SegDispCreate(ID, left, top, right, bottom, state, Value, NoOfDigits, DotPos, Thickness, pScheme)

where

ID is the unique identifier for the instance
left,top,right,bottom are the coordinates of the rectangle that will enclose the SegDisplay
state is the initial state for the SegDisplay. See States below
Value is the initial displayed value, normally 0.
NoOfDigits is the Number of Digits the SegDisplay will have.
DotPos is the Dot Position for decimal values. Currently not handled in code.
Thickness is the thickness of the drawn segments in pixels. The bigger the SegDisplay, the bigger thickness you will want.
pScheme is the pointer to an existing GOL Scheme where colours are defined. The displayed number will be drawn with TextColor0. Background colour will be CommonBkColor. Frame will be drawn with Color1.

States

This Widget's state can be set to the following possible states:

SD_DISABLED If the widget is set to disabled, everything will be drawn with ColorDisabled.
SD_RIGHT_ALIGN Value is right aligned.
SD_FRAME Frame is displayed.
SD_FIRSTDIGITIS1 This tells that first leftmost digit is a "1" at maximum, i.e. to have a max value 19999 and therefore optimize used width
SD_DRAW all Widget will be redrawn: rectangle cleared, frame and value redrawn
SD_UPDATE Only changed digits will be cleared and redrawn for maximum draw speed
SD_HIDE remove object from screen.

GolSegDisplay.c

/*****************************************************************************
 * Module for Microchip Graphics Library GOL Layer 
 *****************************************************************************
 * FileName:        GolSegDisplay.c
 * Dependencies:    none 
 * Processor:       PIC24F, PIC24H, dsPIC, PIC32
 * Compiler:        MPLAB C30 V3.00
 * Linker:          MPLAB LINK30
 * Company:         VirtualFab
 *
 * Software License Agreement
 *
 * Copyright © 2011 VirtualFab.  All rights reserved.
 * This software is free software. see GPL license at http://www.gnu.org/licenses/gpl.html
 
 * SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
 * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
 * PURPOSE. IN NO EVENT SHALL VIRTUALFAB BE LIABLE OR
 * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
 * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
 * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
 * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
 * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
 * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
 * OR OTHER SIMILAR COSTS.
 *
 * Author                  Date        Comment
 * VirtualFab 		  2011/04/23	Version 1.0 release
 *****************************************************************************/
#include "Graphics/Graphics.h"
#include "GolSegDisplay.h"
#include "FontSeg.h"

/************************************************************************************
 * Function: NumberToString(DWORD Value,XCHAR *pText, BYTE NoOfDigits, BYTE DotPos )
 *
 * Notes: convert the number to string
 *
 *************************************************************************************/
static short NumberToString(DWORD Value, XCHAR *pText, BYTE NoOfDigits, BOOL NoLeadingZeroes) {
    BYTE i;
    BYTE bIndex;
    BYTE NumOfNonZeroDigits = 0;

    for (bIndex = 0; bIndex < NoOfDigits; bIndex++) {
        pText[NoOfDigits - bIndex - 1] = '0' + (Value % 10);
        Value /= 10;
    }

    if (NoLeadingZeroes) {
        for (i = 0; i < NoOfDigits-1; i++) {
            if (pText[i] == '0') {
                pText[i] = ' ';
            } else {
                NumOfNonZeroDigits=NoOfDigits-i;
                i = NoOfDigits;
            }
        }
    } else {
        NumOfNonZeroDigits = NoOfDigits;
    }
    pText[NoOfDigits]=0;
    return (NumOfNonZeroDigits);
}

/*********************************************************************************************************
 * Function: GOLSEGDISPLAY  *SegDispCreate(WORD ID, SHORT left, SHORT top, SHORT right, SHORT bottom, WORD state,
 *                               DWORD Value, BYTE NoOfDigits, BYTE DotPos, GOL_SCHEME *pScheme)
 *
 * Notes: Creates a GOLSEGDISPLAY object and adds it to the current active list.
 *        If the creation is successful, the pointer to the created Object
 *        is returned. If not successful, NULL is returned.
 *
 **********************************************************************************************************/
GOLSEGDISPLAY *SegDispCreate(
        WORD ID,
        SHORT left,
        SHORT top,
        SHORT right,
        SHORT bottom,
        WORD state,
        DWORD Value,
        BYTE NoOfDigits,
        BYTE DotPos,
        BYTE Thickness,
        GOL_SCHEME *pScheme
        ) {
    GOLSEGDISPLAY *pSd = NULL;
    pSd = GFX_malloc(sizeof (GOLSEGDISPLAY));
    if (pSd == NULL)
        return (pSd);

    pSd->hdr.ID = ID; // unique id assigned for referencing
    pSd->hdr.pNxtObj = NULL; // initialize pointer to NULL
    pSd->hdr.type = OBJ_CUSTOM; //OBJ_GOLSEGDISPLAY;  // set object type
    pSd->hdr.left = left; // left,top corner
    pSd->hdr.top = top;
    pSd->hdr.right = right; // right buttom corner
    pSd->hdr.bottom = bottom;
    pSd->CurrentValue = Value; // initial value to be displayed
    pSd->hdr.state = state;
    pSd->NoOfDigits = NoOfDigits; // number of digits to be displayed
    pSd->DotPos = DotPos; // position of decimal point
    pSd->Thickness = Thickness; //
    pSd->DigitHeight = bottom - top -Thickness; // Heigth for the segments
    if(state & SD_FIRSTDIGITIS1)
        pSd->DigitWidth = ((right - left -SD_INDENT-Thickness*2) / (NoOfDigits-1))-SD_INDENT-Thickness*2-1; // Spacing between the segments range ex.0-19999
    else
        pSd->DigitWidth = ((right - left ) / NoOfDigits)-SD_INDENT-Thickness*2-1; // Spacing between the segments range ex.0-99999
    pSd->hdr.DrawObj = SdDraw; // draw function
    pSd->hdr.MsgObj = SdTranslateMsg; // message function
    pSd->hdr.MsgDefaultObj = NULL; // default message function
    pSd->hdr.FreeObj = NULL; // free function

    // Set the color scheme to be used
    if (pScheme == NULL)
        pSd->hdr.pGolScheme = _pDefaultGolScheme;
    else
        pSd->hdr.pGolScheme = (GOL_SCHEME *) pScheme;

    if (pSd->CurrentValue != 0) {
        // Set the text height
    }
    GOLAddObject((OBJ_HEADER *) pSd);
    return (pSd);
}

/*********************************************************************
 * Function: SdSetValue(GOLSEGDISPLAY *pSd, DWORD Value)
 *
 * Notes: Sets the value to be displayed.
 *
 ********************************************************************/
void SdSetValue(GOLSEGDISPLAY *pSd, DWORD Value) {
    // store the previous and current value to be displayed
    pSd->PreviousValue = pSd->CurrentValue;
    pSd->CurrentValue = Value;
}

/*********************************************************************
 * Function: WORD SdTranslateMsg(void *pObj, GOL_MSG *pMsg)
 *
 * Notes: Evaluates the message if the object will be affected by the
 *		 message or not.
 *
 **********************************************************************/
WORD SdTranslateMsg(void *pObj, GOL_MSG *pMsg) {
    GOLSEGDISPLAY *pSd;
    pSd = (GOLSEGDISPLAY *) pObj;

    // Evaluate if the message is for the static text
    // Check if disabled first
    if (GetState(pSd, SD_DISABLED))
        return (OBJ_MSG_INVALID);

#ifdef USE_TOUCHSCREEN
    if (pMsg->type == TYPE_TOUCHSCREEN && pMsg->uiEvent==EVENT_RELEASE) {
        // Check if it falls in static text control borders
        if (
                (pSd->hdr.left < pMsg->param1) &&
                (pSd->hdr.right > pMsg->param1) &&
                (pSd->hdr.top < pMsg->param2) &&
                (pSd->hdr.bottom > pMsg->param2)
                ) {
            return (SD_MSG_SELECTED);
        }
    }
#endif
    return (OBJ_MSG_INVALID);
}

/*********************************************************************
 * Function: WORD SdDraw(void *pObj)
 *
 * Notes: This is the state machine to display the changing numbers.
 *
 **********************************************************************/
WORD SdDraw(void *pObj) {

    typedef enum {
        SD_STATE_IDLE,
        SD_STATE_FRAME,
        SD_STATE_INIT,
        SD_STATE_SETALIGN,
        SD_STATE_DRAWTEXT
    } SD_DRAW_STATES;

    volatile static GOLSEGDISPLAY *pSd = NULL;
    static SD_DRAW_STATES state = SD_STATE_IDLE;
    static SHORT charCtr = 0;
    static XCHAR CurValue[SD_WIDTH], PreValue[SD_WIDTH];
    XCHAR ch = 0, pch = 0;
    static SHORT NumOfNonZeroDigits;
    static UINT16 PosX,PosY;

    pSd = (GOLSEGDISPLAY *) pObj;

    if (IsDeviceBusy())
        return (0);

    switch (state) {
        case SD_STATE_IDLE:
            SetClip(CLIP_DISABLE);

            if (GetState(pSd, SD_DRAW)) {
                SetColor(pSd->hdr.pGolScheme->CommonBkColor);
                if (Bar(pSd->hdr.left, pSd->hdr.top, pSd->hdr.right, pSd->hdr.bottom) == 0)
                    return (0);
            }
            // if the draw state was to hide then state is still IDLE STATE so no need to change state
            if (GetState(pSd, SD_HIDE))
                return (1);
            state = SD_STATE_FRAME;

        case SD_STATE_FRAME:
            if (GetState(pSd, SD_DRAW | SD_FRAME) == (SD_DRAW | SD_FRAME)) {
                // show frame if specified to be shown
                SetLineType(SOLID_LINE);
                SetLineThickness(NORMAL_LINE);
                if (!GetState(pSd, SD_DISABLED)) {
                    // show enabled color
                    SetColor(pSd->hdr.pGolScheme->Color1);
                    if (Rectangle(pSd->hdr.left, pSd->hdr.top, pSd->hdr.right, pSd->hdr.bottom) == 0)
                        return (0);
                } else {
                    // show disabled color
                    SetColor(pSd->hdr.pGolScheme->ColorDisabled);
                    if (Rectangle(pSd->hdr.left, pSd->hdr.top, pSd->hdr.right, pSd->hdr.bottom) == 0)
                        return (0);
                }
            }

            // set clipping area, text will only appear inside the static text area.
            //SetClip(CLIP_ENABLE);
            //SetClipRgn(pSd->hdr.left + SD_INDENT, pSd->hdr.top, pSd->hdr.right - SD_INDENT, pSd->hdr.bottom);
            state = SD_STATE_INIT;

        case SD_STATE_INIT:
            if (IsDeviceBusy())
                return (0);

            // set the text color
            if (!GetState(pSd, SD_DISABLED)) {
                SetColor(pSd->hdr.pGolScheme->TextColor0);
            } else {
                SetColor(pSd->hdr.pGolScheme->TextColorDisabled);
            }

            // convert the values to be displayed in string format
            NumberToString(pSd->PreviousValue, PreValue, pSd->NoOfDigits, TRUE);
            NumOfNonZeroDigits = NumberToString(pSd->CurrentValue, CurValue, pSd->NoOfDigits, TRUE);

            // use the font specified in the object
            SetFont(pSd->hdr.pGolScheme->pFont);

            state = SD_STATE_SETALIGN; // go to drawing of text

        case SD_STATE_SETALIGN:
            if (!charCtr) {

                // Display text with right alignment
                if (GetState(pSd, (SD_RIGHT_ALIGN))) {
                    if(GetState(pSd, SD_FIRSTDIGITIS1))
                        PosX=pSd->hdr.right+ SD_INDENT + pSd->Thickness - (pSd->DigitWidth + SD_INDENT + pSd->Thickness) * (NumOfNonZeroDigits-1) ;
                    else
                        PosX=pSd->hdr.right - (pSd->DigitWidth + SD_INDENT + pSd->Thickness) * NumOfNonZeroDigits ;
                    PosY= pSd->hdr.top+ SD_INDENT+pSd->Thickness;
                }// Display text with left alignment
                else {
                    PosX = pSd->hdr.left;
                    PosY = pSd->hdr.top;
                }
            }

            state = SD_STATE_DRAWTEXT;

        case SD_STATE_DRAWTEXT:
            pch = *(PreValue + charCtr);
            ch = *(CurValue + charCtr);
            FontSegSetSize(pSd->DigitHeight, pSd->DigitWidth, pSd->Thickness);

            // output one character at time until a newline character or a NULL character is sampled
            while ((0x0000 != ch)) {
                if (IsDeviceBusy()) return (0); // device is busy return

                if (GetState(pSd, SD_DRAW)) {
                    SetColor(pSd->hdr.pGolScheme->CommonBkColor);
                    FontSegPrintDigit(pch, PosX, PosY);
                } else if (GetState(pSd, SD_UPDATE)) {
                    if (pch != ch) {
                        SetColor(pSd->hdr.pGolScheme->CommonBkColor);
                        FontSegPrintDigit(pch, PosX, PosY);
                    }
                }

                SetColor(pSd->hdr.pGolScheme->TextColor0);

                // render the character
                //while(!OutChar(ch));
                FontSegPrintDigit(ch, PosX, PosY);
                if(GetState(pSd, SD_FIRSTDIGITIS1) && charCtr==0)
                    PosX += pSd->Thickness * 2 + SD_INDENT;
                else
                    PosX += pSd->DigitWidth + pSd->Thickness * 2 + SD_INDENT * 2;
                //pSd->hdr.left  pSd->hdr.top   pSd->hdr.right   pSd->hdr.bottom
                charCtr++; // update to next character
                ch = *(CurValue + charCtr);
                pch = *(PreValue + charCtr);
            }

            // end of text string is reached no more lines to display
            charCtr = 0;
            //SetClip(CLIP_DISABLE); // remove clipping
            state = SD_STATE_IDLE; // go back to IDLE state
            return (1);
    }

    return (1);
}

GolSegDisplay.h

/*****************************************************************************
 * Module for Microchip Graphics Library GOL Layer 
 *****************************************************************************
 * FileName:        GolSegDisplay.h
 * Dependencies:    None 
 * Processor:       PIC24F, PIC24H, dsPIC, PIC32
 * Compiler:       	MPLAB C30 V3.00
 * Linker:          MPLAB LINK30
 * Company:         Microchip Technology Incorporated
 *
 * Company:         VirtualFab
 *
 * Software License Agreement
 *
 * Copyright © 2011 VirtualFab.  All rights reserved.
 * This software is free software. see GPL license at http://www.gnu.org/licenses/gpl.html
 *
* SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
 * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
 * PURPOSE. IN NO EVENT SHALL VIRTUALFAB BE LIABLE OR
 * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
 * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
 * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
 * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
 * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
 * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
 * OR OTHER SIMILAR COSTS.
 * 
 *                         Date        Comment
 * VirtualFab 		  2011/04/23	Version 1.0 release
 *****************************************************************************/
#ifndef _GOLSEGDISPLAY_H
    #define _GOLSEGDISPLAY_H

    #include <Graphics/GOL.h>


/*********************************************************************
* Object States Definition:
*********************************************************************/
    #define SD_DISABLED         0x0002  // Bit for disabled state - no clear will be done.
    #define SD_RIGHT_ALIGN      0x0004  // Bit to indicate value is left aligned.
    #define SD_FRAME            0x0010  // Bit to indicate frame is displayed.
    #define SD_FIRSTDIGITIS1    0x0020  // Bit to indicate first digit is a "1" to maximize used width
    #define SD_DRAW             0x4000  // Bit to indicate object must be redrawn.
    #define SD_UPDATE           0x2000  // Bit to indicate that only text must be redrawn.
    #define SD_HIDE             0x8000  // Bit to remove object from screen.

/* Indent constant for the text used in the frame. */
    #define SD_INDENT   0x04        // Text indent constant.

/* User should change this value depending on the number of digits he wants to display */
    #define SD_WIDTH    0x0A        // This value should be more than the no of digits displayed

// The structure contains data for the control
typedef struct
{
    OBJ_HEADER  hdr;            // Generic header for all Objects (see OBJ_HEADER).
    DWORD       CurrentValue;   // Current value
    DWORD       PreviousValue;  // Previous value
    BYTE        NoOfDigits;     // Number of digits to be displayed
    BYTE        DigitHeight;    // Heigth for the digits - based on object's height
    BYTE        DigitWidth;     // Width for the digits - based on object's Width / NoOfDigits
    BYTE        Thickness;      // Thickness for the drawing of segments
    BYTE        DotPos;         // Position of decimal point
} GOLSEGDISPLAY;

#define SD_MSG_SELECTED 1001  // GOLSEGDISPLAY selected action ID

/*********************************************************************
* Macros:  SdGetValue(pSd)
*
* Overview: This macro returns the current 
*			value used for the object.
*
* PreCondition: none
*
* Input: pSd - Pointer to the object.
*
* Output: Returns the value used.
*
* Side Effects: none
*
********************************************************************/
    #define SdGetValue(pSd) pSd->Cvalue

/*********************************************************************
* Function: SdSetValue(GOLSEGDISPLAY *pSd,  DWORD Value)
*
* Overview: This function sets the value that will be used for the object.
*
* PreCondition: none
*
* Input: pSd - The pointer to the object whose value will be modified. 
* 		 Value -  New value to be set for the SegDisplay.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
void    SdSetValue(GOLSEGDISPLAY *pSd, DWORD Value);

/*********************************************************************
* Macros:  SdIncVal(pSd, deltaValue)
*
* Overview: This macro is used to directly increment the value. 
*
* PreCondition: none
*
* Input: pSd - Pointer to the object.
*		 deltaValue - Number to be added to the current SegDisplay value.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
    #define SdIncVal(pSd, deltaValue)    SdSetValue(pSd, (pSd->Cvalue + deltaValue))

/*********************************************************************
* Macros:  SdDecVal(pSd, deltaValue)
*
* Overview: This macro is used to directly decrement the value. 
*
* PreCondition: none
*
* Input: pSd - Pointer to the object.
*        deltaValue - Number to be subtracted to the current SegDisplay value.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
    #define SdDecVal(pSd, deltaValue)    SdSetValue(pSd, (pSd->Cvalue - deltaValue))

/*********************************************************************
* Function: GOLSEGDISPLAY  *SegDispCreate(WORD ID, SHORT left, SHORT top, SHORT right, SHORT bottom, 
*								  WORD state , DWORD Value, BYTE NoOfDigits, BYTE DotPos, GOL_SCHEME *pScheme)
*
* Overview: This function creates a GOLSEGDISPLAY object with the 
*			parameters given. It automatically attaches the new 
*			object into a global linked list of objects and returns 
*			the address of the object.
*
* PreCondition: none
*
* Input: ID - Unique user defined ID for the object instance.
*        left - Left most position of the object.
* 		 top - Top most position of the object. 
*		 right - Right most position of the object.
*		 bottom - Bottom most position of the object.
*        state - Sets the initial state of the object.
*        Value - Sets the initial value to be displayed
*        NoOfDigits - Sets the number of digits to be displayed
*        DotPos - Sets the position of decimal point in the display
*        Thickness - Sets the thickness for the segments to display
*        pScheme - Pointer to the style scheme. Set to NULL if 
*				   default style scheme is used.
*
* Output: Returns the pointer to the object created.
*
* Example:
*	GOL_SCHEME *pScheme;
*	GOLSEGDISPLAY *pSd;
*		
*		pScheme = GOLCreateScheme();
*		state = SD_DRAW | SD_FRAME | SD_CENTER_ALIGN;
*		SegDispCreate(ID_GOLSEGDISPLAY1,  // ID
*		         30,80,235,160,           // dimension
*		         state,                   // has frame and center aligned
*		         789,4,1,                 // to display 078.9
*                       3,                       // draws 3-pixels wide bars for the segments
*		         pScheme);                // use given scheme
*		
*		while(!SdDraw(pSd));		  // draw the object
*
* Side Effects: none
*
********************************************************************/
GOLSEGDISPLAY    *SegDispCreate
                (
                    WORD        ID,
                    SHORT       left,
                    SHORT       top,
                    SHORT       right,
                    SHORT       bottom,
                    WORD        state,
                    DWORD       Value,
                    BYTE        NoOfDigits,
                    BYTE        DotPos,
                    BYTE        Thickness,
                    GOL_SCHEME  *pScheme
                );

/*********************************************************************
* Function: WORD SdTranslateMsg(void *pObj, GOL_MSG *pMsg)
*
* Overview: This function evaluates the message from a user if the 
*			message will affect the object or not. The table below 
*			enumerates the translated messages for each event of the 
*			touch screen and keyboard inputs.
*
*    	Translated Message   Input Source  Events         				Description
*     	##################   ############  ######         				###########
*		SD_MSG_SELECTED      Touch Screen  EVENT_PRESS, EVENT_RELEASE   If events occurs and the x,y position falls in the area of the SegDisplay.
*		OBJ_MSG_INVALID		 Any		   Any			If the message did not affect the object.
*
* PreCondition: none
*
* Input: pSd   - The pointer to the object where the message will be
*				 evaluated to check if the message will affect the object.
*        pMsg  - Pointer to the message struct containing the message from 
*        		 the user interface.
*
* Output: Returns the translated message depending on the received GOL message:
*		  - SD_MSG_SELECTED – SegDisplay is selected
*    	  - OBJ_MSG_INVALID – SegDisplay is not affected
*
* Example:
*   Usage is similar to BtnTranslateMsg() example.
*
* Side Effects: none
*
********************************************************************/
WORD            SdTranslateMsg(void *pObj, GOL_MSG *pMsg);

/*********************************************************************
* Function: WORD SdDraw(void *pObj)
*
* Overview: This function renders the object on the screen using 
*			the current parameter settings. Location of the object 
*			is determined by the left, top, right and bottom 
*			parameters. The colors used are dependent on the state 
*			of the object. The font used is determined by the style 
*			scheme set.
*			
*			When rendering objects of the same type, each object must 
*			be rendered completely before the rendering of the next 
*			object is started. This is to avoid incomplete object rendering.
*
* PreCondition: Object must be created before this function is called.
*
* Input: pSd - Pointer to the object to be rendered.
*        
* Output: Returns the status of the drawing
*		  - 1 - If the rendering was completed and 
*		  - 0 - If the rendering is not yet finished. 
*		  Next call to the function will resume the 
*		  rendering on the pending drawing state.
*
* Example:
*   See SegDispCreate() Example.
*
* Side Effects: none
*
********************************************************************/
WORD SdDraw(void *pObj); 
#endif // _GOLSEGDISPLAY_H

FontSeg.c

#include "GenericTypeDefs.h"
#include "FontSeg.h"
#include "Graphics/Graphics.h"
const unsigned char asegs[11] = {
    0b0000000,
    0b0111111,
    0b0000110,
    0b1011011,
    0b1001111,
    0b1100110,
    0b1101101,
    0b1111101,
    0b0000111,
    0b1111111,
    0b1101111
};

UINT16 SegCoords[7][4];

void FontSegSetSize(UINT8 sizeY, UINT8 sizeX, UINT8 thickness) {
    //UINT8 sizeX = sizeY * 5 / 7;

    SegCoords[0][0] = 0;
    SegCoords[0][1] = 0;
    SegCoords[0][2] = sizeX + thickness;
    SegCoords[0][3] = thickness;

    SegCoords[1][0] = sizeX;
    SegCoords[1][1] = 0;
    SegCoords[1][2] = sizeX + thickness;
    SegCoords[1][3] = sizeY / 2 + thickness;

    SegCoords[2][0] = sizeX;
    SegCoords[2][1] = sizeY / 2;
    SegCoords[2][2] = sizeX + thickness;
    SegCoords[2][3] = sizeY + thickness;

    SegCoords[3][0] = 0;
    SegCoords[3][1] = sizeY;
    SegCoords[3][2] = sizeX + thickness;
    SegCoords[3][3] = sizeY + thickness;

    SegCoords[4][0] = 0;
    SegCoords[4][1] = sizeY / 2;
    SegCoords[4][2] = thickness;
    SegCoords[4][3] = sizeY + thickness;

    SegCoords[5][0] = 0;
    SegCoords[5][1] = 0;
    SegCoords[5][2] = thickness;
    SegCoords[5][3] = sizeY / 2 + thickness;

    SegCoords[6][0] = 0;
    SegCoords[6][1] = sizeY / 2;
    SegCoords[6][2] = sizeX + thickness;
    SegCoords[6][3] = sizeY / 2 + thickness;
}

void FontSegPrintDigit(char d, UINT16 x, UINT16 y) {
    UINT8 segs, i;
    segs = d - '0' + 1;
    if (segs > 10) segs = 0;
    for (i = 0; i < 7; i++) {
        if (asegs[segs] & (1 << i))
            Bar(x + SegCoords[i][0], y + SegCoords[i][1], x + SegCoords[i][2], y + SegCoords[i][3]);
    }
}


FontSeg.h

void FontSegSetSize(UINT8, UINT8, UINT8);
void FontSegPrintDigit(char, UINT16, UINT16);