Blame lib/ppmdfont.c

Packit 78deda
#include <stdio.h>
Packit 78deda
#include <assert.h>
Packit 78deda
#include <errno.h>
Packit 78deda
#include <string.h>
Packit 78deda
Packit 78deda
#include "netpbm/mallocvar.h"
Packit 78deda
#include "pm.h"
Packit 78deda
#include "ppmdfont.h"
Packit 78deda
Packit 78deda
Packit 78deda
extern struct ppmd_font ppmd_standardfont;
Packit 78deda
Packit 78deda
static const struct ppmd_font * currentFontP = &ppmd_standardfont;
Packit 78deda
Packit 78deda
static void
Packit 78deda
readGlyphHeader(FILE *                    const ifP,
Packit 78deda
                struct ppmd_glyphHeader * const glyphHeaderP) {
Packit 78deda
Packit 78deda
    glyphHeaderP->commandCount = fgetc(ifP);
Packit 78deda
    glyphHeaderP->skipBefore   = fgetc(ifP);
Packit 78deda
    glyphHeaderP->skipAfter    = fgetc(ifP);
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
static void
Packit 78deda
readGlyphCommand(FILE *                     const ifP,
Packit 78deda
                 struct ppmd_glyphCommand * const glyphCommandP) {
Packit 78deda
Packit 78deda
    glyphCommandP->verb = fgetc(ifP);
Packit 78deda
    glyphCommandP->x    = fgetc(ifP);
Packit 78deda
    glyphCommandP->y    = fgetc(ifP);
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
static void
Packit 78deda
readCharacter(FILE *              const ifP,
Packit 78deda
              struct ppmd_glyph * const glyphP) {
Packit 78deda
Packit 78deda
    unsigned int commandNum;
Packit 78deda
    struct ppmd_glyphCommand * commandList;
Packit 78deda
Packit 78deda
    readGlyphHeader(ifP, &glyphP->header);
Packit 78deda
Packit 78deda
    MALLOCARRAY(commandList, glyphP->header.commandCount);
Packit 78deda
Packit 78deda
    if (commandList == NULL)
Packit 78deda
        pm_error("Insufficient memory to create a %u-command "
Packit 78deda
                 "command list.", glyphP->header.commandCount);
Packit 78deda
Packit 78deda
    for (commandNum = 0;
Packit 78deda
         commandNum < glyphP->header.commandCount;
Packit 78deda
         ++commandNum) {
Packit 78deda
Packit 78deda
        readGlyphCommand(ifP, &commandList[commandNum]);
Packit 78deda
    }
Packit 78deda
    glyphP->commandList = commandList;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
static void
Packit 78deda
readFontHeader(FILE *                   const ifP,
Packit 78deda
               struct ppmd_fontHeader * const fontHeaderP) {
Packit 78deda
    
Packit 78deda
    size_t rc;
Packit 78deda
Packit 78deda
    rc = fread(&fontHeaderP->signature, 1, sizeof(fontHeaderP->signature),
Packit 78deda
               ifP);
Packit 78deda
Packit 78deda
    if (rc != sizeof(fontHeaderP->signature))
Packit 78deda
        pm_error("Unable to read the header from the font file.  "
Packit 78deda
                 "errno=%d (%s)", errno, strerror(errno));
Packit 78deda
Packit 78deda
    fontHeaderP->format         = fgetc(ifP);
Packit 78deda
    fontHeaderP->characterCount = fgetc(ifP);
Packit 78deda
    fontHeaderP->firstCodePoint = fgetc(ifP);
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
void
Packit 78deda
ppmd_set_font(const struct ppmd_font * const newFontP) {
Packit 78deda
Packit 78deda
    currentFontP = newFontP;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
const struct ppmd_font *
Packit 78deda
ppmd_get_font(void) {
Packit 78deda
Packit 78deda
    return currentFontP;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
void
Packit 78deda
ppmd_read_font(FILE *                        const ifP,
Packit 78deda
               const struct ppmd_font **     const fontPP) {
Packit 78deda
Packit 78deda
    unsigned int relativeCodePoint;
Packit 78deda
    struct ppmd_glyph * glyphTable;
Packit 78deda
    struct ppmd_font * fontP;
Packit 78deda
Packit 78deda
    MALLOCVAR(fontP);
Packit 78deda
    if (fontP == NULL)
Packit 78deda
        pm_error("Insufficient memory for font header");
Packit 78deda
Packit 78deda
    readFontHeader(ifP, &fontP->header);
Packit 78deda
Packit 78deda
    MALLOCARRAY(glyphTable, fontP->header.characterCount);
Packit 78deda
    if (glyphTable == NULL)
Packit 78deda
        pm_error("Insufficient memory to store %u characters",
Packit 78deda
                 fontP->header.characterCount);
Packit 78deda
Packit 78deda
    for (relativeCodePoint = 0;
Packit 78deda
         relativeCodePoint < fontP->header.characterCount;
Packit 78deda
         ++relativeCodePoint) {
Packit 78deda
Packit 78deda
        readCharacter(ifP, &glyphTable[relativeCodePoint]);
Packit 78deda
    }
Packit 78deda
    fontP->glyphTable = glyphTable;
Packit 78deda
    *fontPP = fontP;
Packit 78deda
}
Packit 78deda
Packit 78deda
Packit 78deda
Packit 78deda
void
Packit 78deda
ppmd_free_font(const struct ppmd_font * const fontP) {
Packit 78deda
Packit 78deda
    unsigned int relativeCodePoint;
Packit 78deda
Packit 78deda
    for (relativeCodePoint = 0;
Packit 78deda
         relativeCodePoint < fontP->header.characterCount;
Packit 78deda
         ++relativeCodePoint) {
Packit 78deda
        
Packit 78deda
        free((void*)fontP->glyphTable[relativeCodePoint].commandList);
Packit 78deda
    }
Packit 78deda
    free((void*)fontP->glyphTable);
Packit 78deda
    free((void*)fontP);
Packit 78deda
}