//*****************************************************************************
//
// Returns information on the glyphs contained within a given font block.
//
//*****************************************************************************
static uint32_t
FATWrapperFontBlockCodepointsGet(uint8_t *pui8FontID,
                                 uint16_t ui16BlockIndex,
                                 uint32_t *pui32Start)
{
    tFontBlock sBlock;
    tFontFile *psFont;
    bool bRetcode;

    //
    // Parameter sanity check.
    //
    ASSERT(pui8FontID);

    //
    // Get a pointer to our instance data.
    //
    psFont = (tFontFile *)pui8FontID;

    ASSERT(psFont->bInUse);

    //
    // Have we been passed a valid block index?
    //
    if(ui16BlockIndex >= psFont->sFontHeader.ui16NumBlocks)
    {
        //
        // No - return an error.
        //
        return(0);
    }

    //
    // Is this block header cached?
    //
    if(ui16BlockIndex < MAX_FONT_BLOCKS)
    {
        //
        // Yes - return the information from our cached copy.
        //
        *pui32Start = psFont->psBlocks[ui16BlockIndex].ui32StartCodepoint;
        return(psFont->psBlocks[ui16BlockIndex].ui32NumCodepoints);
    }
    else
    {
        //
        // We don't have the block header cached so read it from the
        // SDCard.  First move the file pointer to the expected position.
        //
        bRetcode = FATWrapperFontBlockHeaderGet(&psFont->sFile, &sBlock,
                                                ui16BlockIndex);
        if(bRetcode)
        {
            *pui32Start = sBlock.ui32StartCodepoint;
            return(sBlock.ui32NumCodepoints);
        }
        else
        {
            UARTprintf("Error reading block header!\n");
        }
    }

    //
    // If we get here, something horrible happened so return a failure.
    //
    *pui32Start = 0;
    return(0);
}
//*****************************************************************************
//
// Retrieves the data for a particular font glyph.  This function returns
// a pointer to the glyph data in linear, random access memory if the glyph
// exists or NULL if not.
//
//*****************************************************************************
static const uint8_t *
FATWrapperFontGlyphDataGet(uint8_t *pui8FontID,
                           uint32_t ui32Codepoint,
                           uint8_t *pui8Width)
{
    tFontFile *psFont;
    uint32_t ui32Loop, ui32GlyphOffset, ui32TableOffset;
    UINT uiRead;
    tFontBlock sBlock;
    tFontBlock *psBlock;
    bool bRetcode;
    FRESULT iFResult;

    //
    // Parameter sanity check.
    //
    ASSERT(pui8FontID);
    ASSERT(pui8Width);

    //
    // If passed a NULL codepoint, return immediately.
    //
    if(!ui32Codepoint)
    {
        return(0);
    }

    //
    // Get a pointer to our instance data.
    //
    psFont = (tFontFile *)pui8FontID;

    ASSERT(psFont->bInUse);

    //
    // Look for the trivial case - do we have this glyph in our glyph store
    // already?
    //
    if(psFont->ui32CurrentGlyph == ui32Codepoint)
    {
        //
        // We struck gold - we already have this glyph in our buffer.  Return
        // the width (from the second byte of the data) and a pointer to the
        // glyph data.
        //
        *pui8Width = psFont->pui8GlyphStore[1];
        return(psFont->pui8GlyphStore);
    }

    //
    // First find the block that contains the glyph we've been asked for.
    //
    for(ui32Loop = 0; ui32Loop < psFont->sFontHeader.ui16NumBlocks; ui32Loop++)
    {
        if(ui32Loop < MAX_FONT_BLOCKS)
        {
            psBlock = &psFont->psBlocks[ui32Loop];
        }
        else
        {
            bRetcode = FATWrapperFontBlockHeaderGet(&psFont->sFile, &sBlock,
                                                    ui32Loop);
            psBlock = &sBlock;
            if(!bRetcode)
            {
                //
                // We failed to read the block header so return an error.
                //
                return(0);
            }
        }

        //
        // Does the requested character exist in this block?
        //
        if((ui32Codepoint >= (psBlock->ui32StartCodepoint)) &&
          ((ui32Codepoint < (psBlock->ui32StartCodepoint +
            psBlock->ui32NumCodepoints))))
        {
            //
            // The glyph is in this block. Calculate the offset of it's
            // glyph table entry in the file.
            //
            ui32TableOffset = psBlock->ui32GlyphTableOffset +
                            ((ui32Codepoint - psBlock->ui32StartCodepoint) *
                            sizeof(uint32_t));

            //
            // Move the file pointer to the offset position.
            //
            iFResult = f_lseek(&psFont->sFile, ui32TableOffset);

            if(iFResult != FR_OK)
            {
                return(0);
            }

            //
            // Read the glyph data offset.
            //
            iFResult = f_read(&psFont->sFile, &ui32GlyphOffset,
                             sizeof(uint32_t), &uiRead);

            //
            // Return if there was an error or if the offset is 0 (which
            // indicates that the character is not included in the font.
            //
            if((iFResult != FR_OK) || (uiRead != sizeof(uint32_t)) ||
                !ui32GlyphOffset)
            {
                return(0);
            }

            //
            // Move the file pointer to the start of the glyph data remembering
            // that the glyph table offset is relative to the start of the
            // block not the start of the file (so we add the table offset
            // here).
            //
            iFResult = f_lseek(&psFont->sFile, (psBlock->ui32GlyphTableOffset +
                              ui32GlyphOffset));

            if(iFResult != FR_OK)
            {
                return(0);
            }

            //
            // Read the first byte of the glyph data to find out how long it
            // is.
            //
            iFResult = f_read(&psFont->sFile, psFont->pui8GlyphStore, 1,
                              &uiRead);

            if((iFResult != FR_OK) || !uiRead)
            {
                return(0);
            }

            //
            // Now read the glyph data.
            //
            iFResult = f_read(&psFont->sFile, psFont->pui8GlyphStore + 1,
                              psFont->pui8GlyphStore[0] - 1, &uiRead);

            if((iFResult != FR_OK) ||
               (uiRead != (psFont->pui8GlyphStore[0] - 1)))
            {
                return(0);
            }

            //
            // If we get here, things are good. Return a pointer to the glyph
            // store data.
            //
            psFont->ui32CurrentGlyph = ui32Codepoint;
            *pui8Width = psFont->pui8GlyphStore[1];
            return(psFont->pui8GlyphStore);
        }
    }

    //
    // If we get here, the codepoint doesn't exist in the font so return an
    // error.
    //
    return(0);
}
Ejemplo n.º 3
0
//*****************************************************************************
//
// Returns information on the glyphs contained within a given font block.
//
//*****************************************************************************
static unsigned long
FATWrapperFontBlockCodepointsGet(unsigned char *pucFontId,
                                 unsigned short usBlockIndex,
                                 unsigned long *pulStart)
{
    tFontBlock sBlock;
    tFontFile *pFont;
    tBoolean bRetcode;

    //
    // Parameter sanity check.
    //
    ASSERT(pucFontId);

    //
    // Get a pointer to our instance data.
    //
    pFont = (tFontFile *)pucFontId;

    ASSERT(pFont->bInUse);

    //
    // Have we been passed a valid block index?
    //
    if(usBlockIndex >= pFont->sFontHeader.usNumBlocks)
    {
        //
        // No - return an error.
        //
        return(0);
    }

    //
    // Is this block header cached?
    //
    if(usBlockIndex < MAX_FONT_BLOCKS)
    {
        //
        // Yes - return the information from our cached copy.
        //
        *pulStart = pFont->pBlocks[usBlockIndex].ulStartCodepoint;
        return(pFont->pBlocks[usBlockIndex].ulNumCodepoints);
    }
    else
    {
        //
        // We don't have the block header cached so read it from the
        // SDCard.  First move the file pointer to the expected position.
        //
        bRetcode = FATWrapperFontBlockHeaderGet(&pFont->sFile, &sBlock,
                                                usBlockIndex);
        if(bRetcode)
        {
            *pulStart = sBlock.ulStartCodepoint;
            return(sBlock.ulNumCodepoints);
        }
        else
        {
            UARTprintf("Error reading block header!\n");
        }
    }

    //
    // If we get here, something horrible happened so return a failure.
    //
    *pulStart = 0;
    return(0);
}