|
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 |
}
|