mirror of
https://github.com/lexborisov/Modest
synced 2024-11-22 05:41:32 +03:00
Redesigned MyFONT; Added new example for get glyph metrics.
This commit is contained in:
parent
3a6dbfba0f
commit
40cf5dc937
@ -23,7 +23,7 @@ endif
|
||||
find_files_h = $(wildcard $(dir)/*.h)
|
||||
find_files_c = $(wildcard $(dir)/*.c)
|
||||
|
||||
SUBDIRS := selectors declarations
|
||||
SUBDIRS := selectors declarations font
|
||||
HDRS += $(foreach dir,$(SUBDIRS),$(find_files_h))
|
||||
SRCS += $(foreach dir,$(SUBDIRS),$(find_files_c))
|
||||
|
||||
|
143
examples/font/glyph_metrics.c
Normal file
143
examples/font/glyph_metrics.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (C) 2016 Alexander Borisov
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Author: lex.borisov@gmail.com (Alexander Borisov)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <myfont/myfont.h>
|
||||
#include <myhtml/encoding.h>
|
||||
|
||||
void usage(const char *path, float font_size, unsigned long codepoint)
|
||||
{
|
||||
printf("Usage:\n");
|
||||
printf("\tprogram [char in UTF-8] [font fize in px] [font path]\n");
|
||||
printf("\tdefault: program \"x\" %.f %s\n\n", font_size, path);
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
/* set and get params */
|
||||
const char *path = "../third_party/font/Arkhip.ttf";
|
||||
float font_size = 200.0f;
|
||||
|
||||
unsigned long codepoint;
|
||||
myhtml_encoding_ascii_utf_8_to_codepoint((unsigned char*)"x", &codepoint);
|
||||
|
||||
if (argc == 2) {
|
||||
if(myhtml_encoding_ascii_utf_8_to_codepoint((const unsigned char*)argv[1], &codepoint) == 0) {
|
||||
fprintf(stderr, "Bad char code point\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else if (argc == 3) {
|
||||
long num = strtol(argv[2], NULL, 0);
|
||||
|
||||
if(num < 1) {
|
||||
fprintf(stderr, "To small font size param\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
font_size = (float)num;
|
||||
}
|
||||
else if (argc == 4) {
|
||||
path = argv[3];
|
||||
}
|
||||
else {
|
||||
usage(path, font_size, codepoint);
|
||||
}
|
||||
|
||||
myfont_font_t *mf = myfont_create();
|
||||
myfont_init(mf);
|
||||
|
||||
myfont_status_t mf_status = myfont_load(mf, path);
|
||||
|
||||
if(mf_status) {
|
||||
myfont_destroy(mf, true);
|
||||
|
||||
if(mf_status == MyFONT_STATUS_ERROR_FILE_OPEN) {
|
||||
fprintf(stderr, "Can't open font file %s\n", path);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Can't load font file %s\n", path);
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char data[5];
|
||||
size_t len = myhtml_encoding_codepoint_to_ascii_utf_8(codepoint, data);
|
||||
data[len] = '\0';
|
||||
|
||||
/* work code */
|
||||
uint16_t glyph_index = myfont_glyph_index_by_codepoint(mf, codepoint, NULL);
|
||||
|
||||
float baseline = myfont_metrics_baseline(mf, font_size);
|
||||
float ascender = myfont_metrics_ascender(mf, font_size);
|
||||
float descender = myfont_metrics_descender(mf, font_size);
|
||||
float x_height = myfont_metrics_x_height(mf, font_size);
|
||||
float cap_height = myfont_metrics_cap_height(mf, font_size);
|
||||
float offset = myfont_metrics_glyph_offset_y(mf, codepoint, font_size, NULL);
|
||||
float width = myfont_metrics_width(mf, codepoint, font_size, NULL);
|
||||
float height = myfont_metrics_height(mf, codepoint, font_size, NULL);
|
||||
|
||||
/* print result */
|
||||
printf("Font file: %s\n", path);
|
||||
printf("Font size: %.fpx\n\n", font_size);
|
||||
|
||||
printf("Metrics for code point %lu (%s):\n", codepoint, data);
|
||||
printf("\tBaseline: %.05f\n", baseline);
|
||||
printf("\tAscender: %.05f\n", ascender);
|
||||
printf("\tDescender: %.05f\n", descender);
|
||||
printf("\tX-Height: %.05f\n", x_height);
|
||||
printf("\tCap-Height: %.05f\n", cap_height);
|
||||
printf("\tWidth: %.05f\n", width);
|
||||
printf("\tHeight: %.05f\n", height);
|
||||
|
||||
/* print html svg */
|
||||
printf("\n<svg width=\"%f\" height=\"%f\">\n", width + 4.0f, descender + 4.0f);
|
||||
printf("\t<line x1=%f y1=%f x2=%f y2=%f style=\"stroke:rgb(0,124,110);stroke-width:1\" />\n", 0.0f, ascender, width, ascender);
|
||||
printf("\t<line x1=%f y1=%f x2=%f y2=%f style=\"stroke:rgb(140,0,110);stroke-width:1\" />\n", 0.0f, cap_height, width, cap_height);
|
||||
printf("\t<line x1=%f y1=%f x2=%f y2=%f style=\"stroke:rgb(140,124,110);stroke-width:1\" />\n", 0.0f, x_height, width, x_height);
|
||||
printf("\t<line x1=%f y1=%f x2=%f y2=%f style=\"stroke:rgb(0,255,0);stroke-width:1\" />\n", 0.0f, baseline, width, baseline);
|
||||
printf("\t<line x1=%f y1=%f x2=%f y2=%f style=\"stroke:rgb(255,0,0);stroke-width:1\" />\n", 0.0f, descender, width, descender);
|
||||
|
||||
if(glyph_index < mf->table_maxp.numGlyphs) {
|
||||
myfont_table_glyph_t *glyph = &mf->table_glyf.cache[glyph_index];
|
||||
|
||||
printf("\t<polyline points=\"");
|
||||
for(size_t i = 0; i < glyph->pointCount; i++) {
|
||||
|
||||
float x = (float)((glyph->head.xMax + glyph->simple.xCoordinates[i]) - glyph->head.xMax) * font_size / ((float)mf->table_head.unitsPerEm);
|
||||
float y = (float)((glyph->head.yMax - glyph->simple.yCoordinates[i])) * font_size / ((float)mf->table_head.unitsPerEm);
|
||||
|
||||
printf("%f,%f ", x, (y + offset));
|
||||
}
|
||||
printf("\" />\n");
|
||||
}
|
||||
|
||||
printf("</svg>\n");
|
||||
|
||||
myfont_destroy(mf, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -208,10 +208,9 @@ typedef myfont_table_cmap_t;
|
||||
|
||||
#include <myfont/myfont.h>
|
||||
|
||||
void myfont_load_table_cmap(myfont_font_t *mf);
|
||||
myfont_status_t myfont_load_table_cmap(myfont_font_t *mf);
|
||||
|
||||
uint16_t myfont_glyph_index_by_code(myfont_font_t *mf, unsigned long char_code);
|
||||
uint16_t myfont_glyph_index_by_code_on_entry(myfont_tcmap_entry_t *entry, unsigned long char_code);
|
||||
uint16_t myfont_glyph_index_by_codepoint(myfont_font_t *mf, unsigned long char_code, myfont_status_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -99,13 +99,13 @@ typedef myfont_table_glyf_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_glyf(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_glyf(struct myfont_font *mf);
|
||||
|
||||
void myfont_glyf_load(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint16_t glyph_index);
|
||||
void myfont_glyf_load_data(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint32_t offset);
|
||||
void myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
void myfont_glyf_load_simple_flags(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
void myfont_glyf_load_simple_coordinates(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint16_t glyph_index);
|
||||
myfont_status_t myfont_glyf_load_data(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load_simple_flags(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load_simple_coordinates(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -53,7 +53,7 @@ typedef myfont_table_head_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_head(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_head(struct myfont_font *mf);
|
||||
|
||||
float myfont_head_yMax_pixel(struct myfont_font *mf, float font_size);
|
||||
|
||||
|
@ -54,7 +54,7 @@ typedef myfont_table_hhea_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_hhea(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_hhea(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -45,7 +45,7 @@ typedef myfont_table_hmtx_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_hmtx(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_hmtx(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -38,7 +38,7 @@ typedef myfont_table_loca_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_loca(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_loca(struct myfont_font *mf);
|
||||
|
||||
uint32_t myfont_loca_get_offset(struct myfont_font *mf, uint16_t glyph_index);
|
||||
|
||||
|
@ -51,7 +51,7 @@ typedef myfont_table_maxp_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_maxp(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_maxp(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -100,9 +100,10 @@ void * myfont_malloc(myfont_font_t* mf, size_t size);
|
||||
void * myfont_calloc(myfont_font_t* mf, size_t count, size_t size);
|
||||
void myfont_free(myfont_font_t *mf, void* data);
|
||||
|
||||
void myfont_load(myfont_font_t *mf, const char *filepath);
|
||||
myfont_status_t myfont_load(myfont_font_t *mf, const char *filepath);
|
||||
|
||||
void myfont_font_print_exists_table(myfont_font_t *mf, FILE *file);
|
||||
myfont_status_t myfont_check_required_tables(myfont_font_t *mf);
|
||||
|
||||
float myfont_metrics_baseline(myfont_font_t *mf, float font_size);
|
||||
float myfont_metrics_ascender(myfont_font_t *mf, float font_size);
|
||||
@ -112,9 +113,9 @@ float myfont_metrics_x_height(myfont_font_t *mf, float font_size);
|
||||
float myfont_metrics_cap_height(myfont_font_t *mf, float font_size);
|
||||
float myfont_metrics_font_height(myfont_font_t *mf, float font_size);
|
||||
|
||||
float myfont_metrics_width(myfont_font_t *mf, unsigned long codepoint, float font_size);
|
||||
float myfont_metrics_height(myfont_font_t *mf, unsigned long codepoint, float font_size);
|
||||
float myfont_metrics_glyph_offset_y(myfont_font_t *mf, unsigned long codepoint, float font_size);
|
||||
float myfont_metrics_width(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status);
|
||||
float myfont_metrics_height(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status);
|
||||
float myfont_metrics_glyph_offset_y(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status);
|
||||
|
||||
myfont_status_t myfont_load_table(myfont_font_t *mf, void *table, size_t size, enum myfont_table_key tkey);
|
||||
|
||||
|
@ -89,8 +89,56 @@ extern "C" {
|
||||
*/
|
||||
enum myfont_status {
|
||||
MyFONT_STATUS_OK = 0x000000,
|
||||
MyFONT_STATUS_ERROR_MEMORY_ALLOCATION = 0x070000,
|
||||
MyFONT_STATUS_NOT_FOUND = 0x070001,
|
||||
MyFONT_STATUS_ERROR_MEMORY_ALLOCATION = 0x070001,
|
||||
MyFONT_STATUS_NOT_FOUND = 0x070002,
|
||||
MyFONT_STATUS_ERROR_TABLE_BROKEN = 0x070003,
|
||||
MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING = 0x070004,
|
||||
MyFONT_STATUS_ERROR_TABLE_LACKS_REQUIRED = 0x070004,
|
||||
MyFONT_STATUS_ERROR_FILE_OPEN = 0x070030,
|
||||
MyFONT_STATUS_ERROR_FILE_SEEK = 0x070031,
|
||||
MyFONT_STATUS_ERROR_FILE_READ = 0x070032,
|
||||
MyFONT_STATUS_ERROR_FILE_TELL = 0x070033,
|
||||
MyFONT_STATUS_ERROR_FILE_CLOSE = 0x070034,
|
||||
MyFONT_STATUS_ERROR_FILE_TOO_SMALL = 0x070035,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CMAP = 0x070040,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HEAD = 0x070041,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HHEA = 0x070042,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HMTX = 0x070043,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_MAXP = 0x070044,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_NAME = 0x070045,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_OS_2 = 0x070046,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_POST = 0x070047,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CVT = 0x070048,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_FPGM = 0x070049,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GLYF = 0x07004a,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_LOCA = 0x07004b,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_PREP = 0x07004c,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GASP = 0x07004d,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CFF = 0x07004e,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VORG = 0x07004f,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_SVG = 0x070050,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_EBDT = 0x070051,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_EBLC = 0x070052,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_EBSC = 0x070053,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CBDT = 0x070054,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CBLC = 0x070055,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_BASE = 0x070056,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GDEF = 0x070057,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GPOS = 0x070058,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GSUB = 0x070059,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_JSTF = 0x07005a,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_MATH = 0x07005b,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_DSIG = 0x07005c,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HDMX = 0x07005d,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_KERN = 0x07005e,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_LTSH = 0x07005f,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_PCLT = 0x070060,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VDMX = 0x070061,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VHEA = 0x070062,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VMTX = 0x070063,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_COLR = 0x070064,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CPAL = 0x070065,
|
||||
MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND = 0x070100,
|
||||
}
|
||||
typedef myfont_status_t;
|
||||
|
||||
|
@ -60,7 +60,7 @@ typedef myfont_table_name_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_name(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_name(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -90,7 +90,7 @@ typedef myfont_table_os_2_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_os_2(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_os_2(struct myfont_font *mf);
|
||||
|
||||
int8_t myfont_os_2_panose(struct myfont_font *mf, myfont_table_os_2_panose_t id);
|
||||
|
||||
|
@ -52,7 +52,7 @@ typedef myfont_table_pclt_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_pclt(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_pclt(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -54,7 +54,7 @@ typedef myfont_table_vhea_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_vhea(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_vhea(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -45,7 +45,7 @@ typedef myfont_table_vmtx_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_vmtx(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_vmtx(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -127,6 +127,7 @@ enum myhtml_encoding_status myhtml_encoding_decode_x_user_defined(unsigned const
|
||||
size_t myhtml_encoding_codepoint_to_ascii_utf_8(size_t codepoint, char *data);
|
||||
size_t myhtml_encoding_codepoint_to_lowercase_ascii_utf_8(size_t codepoint, char *data);
|
||||
size_t myhtml_encoding_codepoint_to_ascii_utf_16(size_t codepoint, char *data);
|
||||
size_t myhtml_encoding_ascii_utf_8_to_codepoint(const unsigned char* data, size_t* codepoint);
|
||||
|
||||
void myhtml_encoding_result_clean(myhtml_encoding_result_t *res);
|
||||
|
||||
|
@ -20,18 +20,18 @@
|
||||
|
||||
#include "myfont/cmap.h"
|
||||
|
||||
void myfont_table_cmap_format_0(myfont_font_t *mf, myfont_tcmap_entry_t *entry, size_t offset)
|
||||
myfont_status_t myfont_table_cmap_format_0(myfont_font_t *mf, myfont_tcmap_entry_t *entry, size_t offset)
|
||||
{
|
||||
if(mf->file_size < (offset + 260)) {
|
||||
entry->header = NULL;
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
myfont_tcmap_format_0_t *f0 = (myfont_tcmap_format_0_t*)myfont_calloc(mf, 1, sizeof(myfont_tcmap_format_0_t));
|
||||
|
||||
if(f0 == NULL) {
|
||||
entry->header = NULL;
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
uint8_t *data = &mf->file_data[offset];
|
||||
@ -42,20 +42,25 @@ void myfont_table_cmap_format_0(myfont_font_t *mf, myfont_tcmap_entry_t *entry,
|
||||
memcpy(f0->glyphIdArray, data, 256);
|
||||
|
||||
entry->header = (void *)f0;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
void myfont_table_cmap_format_4(myfont_font_t *mf, myfont_tcmap_entry_t *entry, size_t offset)
|
||||
myfont_status_t myfont_table_cmap_format_4(myfont_font_t *mf, myfont_tcmap_entry_t *entry, size_t offset)
|
||||
{
|
||||
uint8_t *data = &mf->file_data[offset];
|
||||
|
||||
myfont_tcmap_format_4_t *f4 = (myfont_tcmap_format_4_t*)myfont_calloc(mf, 1, sizeof(myfont_tcmap_format_4_t));
|
||||
|
||||
if(f4 == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
offset += MyFONT_TCMAP_FORMAT_4_FIRST_LENGTH;
|
||||
if(mf->file_size < offset)
|
||||
return;
|
||||
|
||||
if(mf->file_size < offset) {
|
||||
myfont_free(mf, f4);
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
f4->length = myfont_read_u16(&data);
|
||||
f4->language = myfont_read_u16(&data);
|
||||
@ -69,22 +74,22 @@ void myfont_table_cmap_format_4(myfont_font_t *mf, myfont_tcmap_entry_t *entry,
|
||||
|
||||
offset += sizeof(uint16_t) * (f4->segCount * 5);
|
||||
if(mf->file_size < offset)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* init mem */
|
||||
if((f4->endCount = (uint16_t *)myfont_calloc(mf, f4->segCount, sizeof(uint16_t))) == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
if((f4->startCount = (uint16_t *)myfont_calloc(mf, f4->segCount, sizeof(uint16_t))) == NULL) {
|
||||
myfont_free(mf, f4->endCount); f4->endCount = NULL;
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
if((f4->idDelta = (int16_t *)myfont_calloc(mf, f4->segCount, sizeof(int16_t))) == NULL) {
|
||||
myfont_free(mf, f4->endCount); f4->endCount = NULL;
|
||||
myfont_free(mf, f4->startCount); f4->startCount = NULL;
|
||||
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
if((f4->idRangeOffset = (uint16_t *)myfont_calloc(mf, f4->segCount, sizeof(uint16_t))) == NULL) {
|
||||
@ -92,7 +97,7 @@ void myfont_table_cmap_format_4(myfont_font_t *mf, myfont_tcmap_entry_t *entry,
|
||||
myfont_free(mf, f4->startCount); f4->startCount = NULL;
|
||||
myfont_free(mf, f4->idDelta); f4->idDelta = NULL;
|
||||
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
if((f4->glyphIdArray = (uint16_t *)myfont_calloc(mf, f4->numGlyphId, sizeof(uint16_t))) == NULL) {
|
||||
@ -101,7 +106,7 @@ void myfont_table_cmap_format_4(myfont_font_t *mf, myfont_tcmap_entry_t *entry,
|
||||
myfont_free(mf, f4->idDelta); f4->idDelta = NULL;
|
||||
myfont_free(mf, f4->idRangeOffset); f4->idRangeOffset = NULL;
|
||||
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
/* read data */
|
||||
@ -128,26 +133,41 @@ void myfont_table_cmap_format_4(myfont_font_t *mf, myfont_tcmap_entry_t *entry,
|
||||
}
|
||||
|
||||
entry->header = (void *)f4;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
uint16_t myfont_glyph_index_by_code_format_0(myfont_tcmap_format_0_t *f0, unsigned long codepoint)
|
||||
uint16_t myfont_glyph_index_by_code_format_0(myfont_tcmap_format_0_t *f0, unsigned long codepoint, myfont_status_t* status)
|
||||
{
|
||||
if(status)
|
||||
*status = MyFONT_STATUS_OK;
|
||||
|
||||
if(codepoint < 256)
|
||||
return (uint16_t)f0->glyphIdArray[codepoint];
|
||||
|
||||
if(status)
|
||||
*status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t myfont_glyph_index_by_code_format_4(myfont_tcmap_format_4_t *f4, unsigned long codepoint)
|
||||
uint16_t myfont_glyph_index_by_code_format_4(myfont_tcmap_format_4_t *f4, unsigned long codepoint, myfont_status_t* status)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
if(status)
|
||||
*status = MyFONT_STATUS_OK;
|
||||
|
||||
for(i = 0; i < f4->segCount; i++)
|
||||
if(codepoint <= f4->endCount[i])
|
||||
break;
|
||||
|
||||
if(i >= f4->segCount || codepoint < f4->startCount[i])
|
||||
if(i >= f4->segCount || codepoint < f4->startCount[i]) {
|
||||
if(status)
|
||||
*status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(f4->idRangeOffset[i] == 0) {
|
||||
return (codepoint + (uint16_t)f4->idDelta[i]) & 0xFFFF;
|
||||
@ -161,12 +181,16 @@ uint16_t myfont_glyph_index_by_code_format_4(myfont_tcmap_format_4_t *f4, unsign
|
||||
}
|
||||
}
|
||||
|
||||
if(status)
|
||||
*status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t myfont_glyph_index_by_code(myfont_font_t *mf, unsigned long codepoint)
|
||||
uint16_t myfont_glyph_index_by_codepoint(myfont_font_t *mf, unsigned long codepoint, myfont_status_t* status)
|
||||
{
|
||||
uint16_t i, index = 0, tcout = mf->table_cmap.header.numTables;
|
||||
myfont_status_t mf_status;
|
||||
|
||||
for(i = 0; i < tcout; i++)
|
||||
{
|
||||
@ -174,47 +198,42 @@ uint16_t myfont_glyph_index_by_code(myfont_font_t *mf, unsigned long codepoint)
|
||||
|
||||
switch (entry->format) {
|
||||
case 0:
|
||||
index = myfont_glyph_index_by_code_format_0((myfont_tcmap_format_0_t *)(entry->header), codepoint);
|
||||
index = myfont_glyph_index_by_code_format_0((myfont_tcmap_format_0_t *)(entry->header), codepoint, &mf_status);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
index = myfont_glyph_index_by_code_format_4((myfont_tcmap_format_4_t *)(entry->header), codepoint);
|
||||
index = myfont_glyph_index_by_code_format_4((myfont_tcmap_format_4_t *)(entry->header), codepoint, &mf_status);
|
||||
break;
|
||||
|
||||
default:
|
||||
mf_status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
|
||||
break;
|
||||
};
|
||||
|
||||
if(index)
|
||||
break;
|
||||
if(mf_status == MyFONT_STATUS_OK) {
|
||||
if(status)
|
||||
*status = MyFONT_STATUS_OK;
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
uint16_t myfont_glyph_index_by_code_on_entry(myfont_tcmap_entry_t *entry, unsigned long codepoint)
|
||||
{
|
||||
switch (entry->format) {
|
||||
case 0:
|
||||
return myfont_glyph_index_by_code_format_0((myfont_tcmap_format_0_t *)(entry->header), codepoint);
|
||||
|
||||
case 4:
|
||||
return myfont_glyph_index_by_code_format_4((myfont_tcmap_format_4_t *)(entry->header), codepoint);
|
||||
|
||||
default:
|
||||
break;
|
||||
};
|
||||
if(status)
|
||||
*status = MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void myfont_load_table_cmap(myfont_font_t *mf)
|
||||
myfont_status_t myfont_load_table_cmap(myfont_font_t *mf)
|
||||
{
|
||||
myfont_table_cmap_t *tcmap = &mf->table_cmap;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_cmap];
|
||||
|
||||
if(table_offset == 0)
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
if(mf->file_size < (table_offset + 4))
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* get current data */
|
||||
uint8_t *data = &mf->file_data[table_offset];
|
||||
@ -224,22 +243,22 @@ void myfont_load_table_cmap(myfont_font_t *mf)
|
||||
tcmap->header.numTables = myfont_read_u16(&data);
|
||||
|
||||
if(tcmap->header.numTables == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
size_t size_records = sizeof(myfont_tcmap_record_t) * tcmap->header.numTables;
|
||||
size_t size_entries = sizeof(myfont_tcmap_entry_t) * tcmap->header.numTables;
|
||||
|
||||
if(mf->file_size < (size_records + size_entries))
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
if((tcmap->records = (myfont_tcmap_record_t *)myfont_malloc(mf, size_records)) == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
if((tcmap->entries = (myfont_tcmap_entry_t *)myfont_malloc(mf, size_entries)) == NULL) {
|
||||
tcmap->records = NULL;
|
||||
myfont_free(mf, tcmap->records);
|
||||
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < tcmap->header.numTables; i++) {
|
||||
@ -253,7 +272,7 @@ void myfont_load_table_cmap(myfont_font_t *mf)
|
||||
uint32_t offset = tcmap->records[i].offset + table_offset;
|
||||
|
||||
if(mf->file_size <= offset)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
data = &mf->file_data[offset];
|
||||
tcmap->entries[i].format = myfont_read_u16(&data);
|
||||
@ -271,6 +290,9 @@ void myfont_load_table_cmap(myfont_font_t *mf)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -208,10 +208,9 @@ typedef myfont_table_cmap_t;
|
||||
|
||||
#include "myfont/myfont.h"
|
||||
|
||||
void myfont_load_table_cmap(myfont_font_t *mf);
|
||||
myfont_status_t myfont_load_table_cmap(myfont_font_t *mf);
|
||||
|
||||
uint16_t myfont_glyph_index_by_code(myfont_font_t *mf, unsigned long char_code);
|
||||
uint16_t myfont_glyph_index_by_code_on_entry(myfont_tcmap_entry_t *entry, unsigned long char_code);
|
||||
uint16_t myfont_glyph_index_by_codepoint(myfont_font_t *mf, unsigned long char_code, myfont_status_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -20,43 +20,49 @@
|
||||
|
||||
#include "myfont/glyf.h"
|
||||
|
||||
void myfont_load_table_glyf(struct myfont_font *mf)
|
||||
myfont_status_t myfont_load_table_glyf(struct myfont_font *mf)
|
||||
{
|
||||
memset(&mf->table_glyf, 0, sizeof(myfont_table_glyf_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_glyf] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
if(mf->table_maxp.numGlyphs == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_glyph_t *glyphs = (myfont_table_glyph_t*)myfont_calloc(mf, mf->table_maxp.numGlyphs, sizeof(myfont_table_glyph_t));
|
||||
|
||||
if(glyphs == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
for(uint16_t i = 0; i < mf->table_maxp.numGlyphs; i++) {
|
||||
for(uint16_t i = 0; i < mf->table_maxp.numGlyphs; i++)
|
||||
{
|
||||
uint32_t offset = mf->cache.tables_offset[MyFONT_TKEY_glyf] + mf->table_loca.offsets[i];
|
||||
myfont_glyf_load_data(mf, &glyphs[i], offset);
|
||||
myfont_status_t status = myfont_glyf_load_data(mf, &glyphs[i], offset);
|
||||
|
||||
if(status)
|
||||
return status;
|
||||
}
|
||||
|
||||
mf->table_glyf.cache = glyphs;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
void myfont_glyf_load(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint16_t glyph_index)
|
||||
myfont_status_t myfont_glyf_load(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint16_t glyph_index)
|
||||
{
|
||||
memset(glyph, 0, sizeof(myfont_table_glyph_t));
|
||||
|
||||
if(mf->table_maxp.numGlyphs == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
uint16_t offset = myfont_loca_get_offset(mf, glyph_index);
|
||||
offset += mf->cache.tables_offset[MyFONT_TKEY_glyf];
|
||||
|
||||
myfont_glyf_load_data(mf, glyph, offset);
|
||||
return myfont_glyf_load_data(mf, glyph, offset);
|
||||
}
|
||||
|
||||
void myfont_glyf_load_data(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint32_t offset)
|
||||
myfont_status_t myfont_glyf_load_data(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint32_t offset)
|
||||
{
|
||||
memset(&glyph->head, 0, sizeof(myfont_table_glyf_head_t));
|
||||
|
||||
@ -66,7 +72,7 @@ void myfont_glyf_load_data(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint3
|
||||
// load head
|
||||
offset += 10;
|
||||
if(offset > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
glyph->head.numberOfContours = myfont_read_16(&data);
|
||||
glyph->head.xMin = myfont_read_16(&data);
|
||||
@ -75,19 +81,22 @@ void myfont_glyf_load_data(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint3
|
||||
glyph->head.yMax = myfont_read_16(&data);
|
||||
|
||||
if(glyph->head.numberOfContours > 0)
|
||||
myfont_glyf_load_simple(mf, glyph, data, offset);
|
||||
return myfont_glyf_load_simple(mf, glyph, data, offset);
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
void myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset)
|
||||
myfont_status_t myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset)
|
||||
{
|
||||
uint16_t *endPtsOfContours = (uint16_t *)myfont_calloc(mf, glyph->head.numberOfContours, sizeof(uint16_t));
|
||||
|
||||
if(endPtsOfContours == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
offset = offset + (glyph->head.numberOfContours * 2) + 2;
|
||||
|
||||
if(offset > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
for(uint16_t i = 0; i < glyph->head.numberOfContours; i++) {
|
||||
endPtsOfContours[i] = myfont_read_u16(&data);
|
||||
@ -98,36 +107,36 @@ void myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uin
|
||||
glyph->pointCount = endPtsOfContours[(glyph->head.numberOfContours - 1)] + 1;
|
||||
|
||||
/* instruction */
|
||||
if(glyph->simple.instructionLength == 0)
|
||||
return;
|
||||
|
||||
offset += glyph->simple.instructionLength;
|
||||
if(offset > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
glyph->simple.instructions = (uint8_t *)myfont_calloc(mf, glyph->simple.instructionLength, sizeof(uint8_t));
|
||||
if(glyph->simple.instructionLength) {
|
||||
glyph->simple.instructions = (uint8_t *)myfont_calloc(mf, glyph->simple.instructionLength, sizeof(uint8_t));
|
||||
|
||||
if(glyph->simple.instructions == NULL)
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
memcpy(glyph->simple.instructions, data, glyph->simple.instructionLength);
|
||||
data += glyph->simple.instructionLength;
|
||||
}
|
||||
|
||||
if(glyph->simple.instructions == NULL)
|
||||
return;
|
||||
|
||||
memcpy(glyph->simple.instructions, data, glyph->simple.instructionLength);
|
||||
data += glyph->simple.instructionLength;
|
||||
|
||||
myfont_glyf_load_simple_flags(mf, glyph, data, offset);
|
||||
return myfont_glyf_load_simple_flags(mf, glyph, data, offset);
|
||||
}
|
||||
|
||||
void myfont_glyf_load_simple_flags(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset)
|
||||
myfont_status_t myfont_glyf_load_simple_flags(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset)
|
||||
{
|
||||
uint8_t *flags = (uint8_t *)myfont_calloc(mf, glyph->pointCount, sizeof(uint8_t));
|
||||
|
||||
if(flags == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
uint16_t i = 0;
|
||||
while(i < glyph->pointCount)
|
||||
{
|
||||
if(offset >= mf->file_size) {
|
||||
myfont_free(mf, flags);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
flags[i] = myfont_read_u8(&data); offset++;
|
||||
@ -136,7 +145,7 @@ void myfont_glyf_load_simple_flags(myfont_font_t *mf, myfont_table_glyph_t *glyp
|
||||
{
|
||||
if(offset >= mf->file_size) {
|
||||
myfont_free(mf, flags);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
uint8_t repeat = myfont_read_u8(&data); offset++;
|
||||
@ -144,7 +153,7 @@ void myfont_glyf_load_simple_flags(myfont_font_t *mf, myfont_table_glyph_t *glyp
|
||||
|
||||
if(repeat > (glyph->pointCount - i)) {
|
||||
myfont_free(mf, flags);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
while(repeat--) {
|
||||
@ -159,20 +168,20 @@ void myfont_glyf_load_simple_flags(myfont_font_t *mf, myfont_table_glyph_t *glyp
|
||||
|
||||
glyph->simple.flags = flags;
|
||||
|
||||
myfont_glyf_load_simple_coordinates(mf, glyph, data, offset);
|
||||
return myfont_glyf_load_simple_coordinates(mf, glyph, data, offset);
|
||||
}
|
||||
|
||||
void myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset)
|
||||
myfont_status_t myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset)
|
||||
{
|
||||
/* alloc resources */
|
||||
int16_t *xCoordinates = (int16_t *)myfont_calloc(mf, glyph->pointCount, sizeof(int16_t));
|
||||
if(xCoordinates == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
int16_t *yCoordinates = (int16_t *)myfont_calloc(mf, glyph->pointCount, sizeof(int16_t));
|
||||
if(yCoordinates == NULL) {
|
||||
myfont_free(mf, xCoordinates);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
uint8_t *flags = glyph->simple.flags;
|
||||
@ -186,7 +195,7 @@ void myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t
|
||||
if(offset >= mf->file_size) {
|
||||
myfont_free(mf, xCoordinates);
|
||||
myfont_free(mf, yCoordinates);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_x_ShortVector) {
|
||||
@ -203,7 +212,7 @@ void myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t
|
||||
if(offset >= mf->file_size) {
|
||||
myfont_free(mf, xCoordinates);
|
||||
myfont_free(mf, yCoordinates);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_x_ShortVector) {
|
||||
@ -226,7 +235,7 @@ void myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t
|
||||
if(offset >= mf->file_size) {
|
||||
myfont_free(mf, xCoordinates);
|
||||
myfont_free(mf, yCoordinates);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_y_ShortVector) {
|
||||
@ -242,7 +251,7 @@ void myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t
|
||||
if(offset >= mf->file_size) {
|
||||
myfont_free(mf, xCoordinates);
|
||||
myfont_free(mf, yCoordinates);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
if(flags[i] & MyFONT_GLYF_SML_FLAGS_p_y_ShortVector) {
|
||||
@ -258,6 +267,8 @@ void myfont_glyf_load_simple_coordinates(myfont_font_t *mf, myfont_table_glyph_t
|
||||
|
||||
glyph->simple.xCoordinates = xCoordinates;
|
||||
glyph->simple.yCoordinates = yCoordinates;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,13 +99,13 @@ typedef myfont_table_glyf_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_glyf(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_glyf(struct myfont_font *mf);
|
||||
|
||||
void myfont_glyf_load(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint16_t glyph_index);
|
||||
void myfont_glyf_load_data(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint32_t offset);
|
||||
void myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
void myfont_glyf_load_simple_flags(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
void myfont_glyf_load_simple_coordinates(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint16_t glyph_index);
|
||||
myfont_status_t myfont_glyf_load_data(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load_simple(myfont_font_t *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load_simple_flags(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
myfont_status_t myfont_glyf_load_simple_coordinates(struct myfont_font *mf, myfont_table_glyph_t *glyph, uint8_t *data, uint32_t offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -20,18 +20,18 @@
|
||||
|
||||
#include "myfont/head.h"
|
||||
|
||||
void myfont_load_table_head(struct myfont_font *mf)
|
||||
myfont_status_t myfont_load_table_head(struct myfont_font *mf)
|
||||
{
|
||||
memset(&mf->table_head, 0, sizeof(myfont_table_head_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_head] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_head_t *thead = &mf->table_head;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_head];
|
||||
|
||||
if(mf->file_size < (table_offset + 16 + 4 + 16 + 8 + 4 + 6))
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* get current data */
|
||||
uint8_t *data = &mf->file_data[table_offset];
|
||||
@ -66,6 +66,8 @@ void myfont_load_table_head(struct myfont_font *mf)
|
||||
thead->fontDirectionHint = myfont_read_16(&data);
|
||||
thead->indexToLocFormat = myfont_read_16(&data);
|
||||
thead->glyphDataFormat = myfont_read_16(&data);
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
float myfont_head_yMax_pixel(struct myfont_font *mf, float font_size)
|
||||
|
@ -53,7 +53,7 @@ typedef myfont_table_head_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_head(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_head(struct myfont_font *mf);
|
||||
|
||||
float myfont_head_yMax_pixel(struct myfont_font *mf, float font_size);
|
||||
|
||||
|
@ -20,18 +20,18 @@
|
||||
|
||||
#include "myfont/hhea.h"
|
||||
|
||||
void myfont_load_table_hhea(myfont_font_t *mf)
|
||||
myfont_status_t myfont_load_table_hhea(myfont_font_t *mf)
|
||||
{
|
||||
memset(&mf->table_hhea, 0, sizeof(myfont_table_hhea_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_hhea] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_hhea_t *thhea = &mf->table_hhea;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_hhea];
|
||||
|
||||
if(mf->file_size < (table_offset + 8 + 6 + 2 + 22 + 2))
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* get current data */
|
||||
uint8_t *data = &mf->file_data[table_offset];
|
||||
@ -57,4 +57,6 @@ void myfont_load_table_hhea(myfont_font_t *mf)
|
||||
thhea->metricDataFormat = myfont_read_16(&data);
|
||||
|
||||
thhea->numberOfHMetrics = myfont_read_u16(&data);
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ typedef myfont_table_hhea_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_hhea(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_hhea(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -20,12 +20,12 @@
|
||||
|
||||
#include "myfont/hmtx.h"
|
||||
|
||||
void myfont_load_table_hmtx(struct myfont_font *mf)
|
||||
myfont_status_t myfont_load_table_hmtx(struct myfont_font *mf)
|
||||
{
|
||||
memset(&mf->table_hmtx, 0, sizeof(myfont_table_hmtx_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_hmtx] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_hmtx_t *thmtx = &mf->table_hmtx;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_hmtx];
|
||||
@ -35,15 +35,15 @@ void myfont_load_table_hmtx(struct myfont_font *mf)
|
||||
uint16_t num_metrics = mf->table_hhea.numberOfHMetrics;
|
||||
|
||||
if(num_metrics == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
if(mf->file_size < (table_offset + (num_metrics * 2)))
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
myfont_long_hor_metric_t *lhor_metric = (myfont_long_hor_metric_t *)myfont_calloc(mf, num_metrics, sizeof(myfont_long_hor_metric_t));
|
||||
|
||||
if(lhor_metric == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
for(uint16_t i = 0; i < num_metrics; i++) {
|
||||
lhor_metric[i].advanceWidth = myfont_read_u16(&data);
|
||||
@ -52,5 +52,7 @@ void myfont_load_table_hmtx(struct myfont_font *mf)
|
||||
|
||||
thmtx->hMetrics = lhor_metric;
|
||||
thmtx->leftSideBearing = NULL;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ typedef myfont_table_hmtx_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_hmtx(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_hmtx(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -20,12 +20,12 @@
|
||||
|
||||
#include "myfont/loca.h"
|
||||
|
||||
void myfont_load_table_loca(struct myfont_font *mf)
|
||||
myfont_status_t myfont_load_table_loca(struct myfont_font *mf)
|
||||
{
|
||||
memset(&mf->table_loca, 0, sizeof(myfont_table_loca_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_loca] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_loca_t *tloca = &mf->table_loca;
|
||||
uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_loca];
|
||||
@ -35,20 +35,20 @@ void myfont_load_table_loca(struct myfont_font *mf)
|
||||
uint16_t numGlyph = mf->table_maxp.numGlyphs;
|
||||
|
||||
if(numGlyph == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_BROKEN;
|
||||
|
||||
numGlyph++;
|
||||
|
||||
tloca->offsets = (uint32_t *)myfont_calloc(mf, numGlyph, sizeof(uint32_t));
|
||||
|
||||
if(tloca->offsets == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
if(mf->table_head.indexToLocFormat)
|
||||
{
|
||||
if(mf->file_size < (table_offset + (numGlyph * 4))) {
|
||||
myfont_free(mf, tloca->offsets);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < numGlyph; i++) {
|
||||
@ -59,13 +59,15 @@ void myfont_load_table_loca(struct myfont_font *mf)
|
||||
{
|
||||
if(mf->file_size < (table_offset + (numGlyph * 2))) {
|
||||
myfont_free(mf, tloca->offsets);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < numGlyph; i++) {
|
||||
tloca->offsets[i] = myfont_read_u16(&data) * 2;
|
||||
}
|
||||
}
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
uint32_t myfont_loca_get_offset(struct myfont_font *mf, uint16_t glyph_index)
|
||||
|
@ -38,7 +38,7 @@ typedef myfont_table_loca_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_loca(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_loca(struct myfont_font *mf);
|
||||
|
||||
uint32_t myfont_loca_get_offset(struct myfont_font *mf, uint16_t glyph_index);
|
||||
|
||||
|
@ -20,18 +20,18 @@
|
||||
|
||||
#include "myfont/maxp.h"
|
||||
|
||||
void myfont_load_table_maxp(myfont_font_t *mf)
|
||||
myfont_status_t myfont_load_table_maxp(myfont_font_t *mf)
|
||||
{
|
||||
memset(&mf->table_maxp, 0, sizeof(myfont_table_maxp_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_maxp] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_maxp_t *tmaxp = &mf->table_maxp;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_maxp];
|
||||
|
||||
if((table_offset + 4) > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* get current data */
|
||||
uint8_t *data = &mf->file_data[table_offset];
|
||||
@ -41,7 +41,7 @@ void myfont_load_table_maxp(myfont_font_t *mf)
|
||||
if(myfont_table_version_major(tmaxp->version) == 1)
|
||||
{
|
||||
if((table_offset + 4 + 28) > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
tmaxp->numGlyphs = myfont_read_u16(&data);
|
||||
tmaxp->maxPoints = myfont_read_u16(&data);
|
||||
@ -60,10 +60,12 @@ void myfont_load_table_maxp(myfont_font_t *mf)
|
||||
}
|
||||
else {
|
||||
if((table_offset + 4 + 2) > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
tmaxp->numGlyphs = myfont_read_u16(&data);
|
||||
}
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ typedef myfont_table_maxp_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_maxp(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_maxp(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -110,47 +110,47 @@ void myfont_free(myfont_font_t *mf, void* data)
|
||||
mchar_async_free(mf->mchar, mf->mchar_node_id, data);
|
||||
}
|
||||
|
||||
void myfont_load(myfont_font_t *mf, const char *filepath)
|
||||
myfont_status_t myfont_load(myfont_font_t *mf, const char *filepath)
|
||||
{
|
||||
FILE *fh = fopen(filepath, "rb");
|
||||
if(fh == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_FILE_OPEN;
|
||||
|
||||
if(fseek(fh, 0L, SEEK_END)) {
|
||||
fclose(fh);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_FILE_SEEK;
|
||||
}
|
||||
|
||||
long file_size = ftell(fh);
|
||||
if(file_size == -1) {
|
||||
fclose(fh);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_FILE_TELL;
|
||||
}
|
||||
|
||||
if(fseek(fh, 0L, SEEK_SET)) {
|
||||
fclose(fh);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_FILE_SEEK;
|
||||
}
|
||||
|
||||
if(file_size > 0)
|
||||
mf->file_size = (size_t)file_size;
|
||||
else
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_FILE_TOO_SMALL;
|
||||
|
||||
mf->file_data = (uint8_t*)myhtml_malloc(file_size);
|
||||
|
||||
if(mf->file_data == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
if(fread(mf->file_data, 1, file_size, fh) != file_size) {
|
||||
fclose(fh);
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_FILE_READ;
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
|
||||
if(mf->file_size < 12)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
uint8_t *data = (uint8_t*)mf->file_data;
|
||||
|
||||
@ -162,7 +162,7 @@ void myfont_load(myfont_font_t *mf, const char *filepath)
|
||||
mf->header.rangeShift = myfont_read_u16(&data);
|
||||
|
||||
if(mf->file_size < (12 + (mf->header.numTables * 16)))
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
for(uint16_t i = 0; i < mf->header.numTables; i++)
|
||||
{
|
||||
@ -216,24 +216,70 @@ void myfont_load(myfont_font_t *mf, const char *filepath)
|
||||
};
|
||||
}
|
||||
|
||||
if(myfont_check_required_tables(mf))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LACKS_REQUIRED;
|
||||
|
||||
mf->file_path = (char *)myhtml_calloc(strlen(filepath), sizeof(char));
|
||||
|
||||
if(mf->file_path) {
|
||||
strncpy(mf->file_path, filepath, strlen(filepath));
|
||||
}
|
||||
|
||||
myfont_load_table_cmap(mf);
|
||||
myfont_load_table_head(mf);
|
||||
myfont_load_table_name(mf);
|
||||
myfont_load_table_os_2(mf);
|
||||
myfont_load_table_maxp(mf);
|
||||
myfont_load_table_hhea(mf);
|
||||
myfont_load_table_hmtx(mf);
|
||||
myfont_load_table_loca(mf);
|
||||
myfont_load_table_glyf(mf);
|
||||
myfont_load_table_vhea(mf);
|
||||
myfont_load_table_vmtx(mf);
|
||||
myfont_load_table_pclt(mf);
|
||||
myfont_status_t status;
|
||||
|
||||
if((status = myfont_load_table_cmap(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_CMAP;
|
||||
|
||||
if((status = myfont_load_table_head(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_HEAD;
|
||||
|
||||
if((status = myfont_load_table_name(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_NAME;
|
||||
|
||||
if((status = myfont_load_table_os_2(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_OS_2;
|
||||
|
||||
if((status = myfont_load_table_maxp(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_MAXP;
|
||||
|
||||
if((status = myfont_load_table_hhea(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_HHEA;
|
||||
|
||||
if((status = myfont_load_table_hmtx(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_HMTX;
|
||||
|
||||
if((status = myfont_load_table_loca(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_LOCA;
|
||||
|
||||
if((status = myfont_load_table_glyf(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_GLYF;
|
||||
|
||||
if((status = myfont_load_table_vhea(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_VHEA;
|
||||
|
||||
if((status = myfont_load_table_vmtx(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_VMTX;
|
||||
|
||||
if((status = myfont_load_table_pclt(mf)))
|
||||
return MyFONT_STATUS_ERROR_TABLE_LOAD_PCLT;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
myfont_status_t myfont_check_required_tables(myfont_font_t *mf)
|
||||
{
|
||||
if(mf->cache.tables_offset[ MyFONT_TKEY_cmap ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_glyf ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_head ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_hhea ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_hmtx ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_loca ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_maxp ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_name ] == 0 ||
|
||||
mf->cache.tables_offset[ MyFONT_TKEY_post ] == 0)
|
||||
return MyFONT_STATUS_ERROR_TABLE_LACKS_REQUIRED;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
void myfont_font_print_exists_table(myfont_font_t *mf, FILE *file)
|
||||
@ -250,7 +296,7 @@ void myfont_font_print_exists_table(myfont_font_t *mf, FILE *file)
|
||||
// metrics
|
||||
float myfont_metrics_baseline(myfont_font_t *mf, float font_size)
|
||||
{
|
||||
return (float)(mf->table_hhea.Ascender) * font_size / ((float)mf->table_head.unitsPerEm);
|
||||
return (float)(mf->table_hhea.Ascender) * font_size / ((float)(mf->table_head.unitsPerEm));
|
||||
}
|
||||
|
||||
float myfont_metrics_ascender(myfont_font_t *mf, float font_size)
|
||||
@ -260,12 +306,12 @@ float myfont_metrics_ascender(myfont_font_t *mf, float font_size)
|
||||
|
||||
float myfont_metrics_descender(myfont_font_t *mf, float font_size)
|
||||
{
|
||||
return (float)(mf->table_hhea.Ascender - mf->table_hhea.Descender) * font_size / ((float)mf->table_head.unitsPerEm);
|
||||
return (float)(mf->table_hhea.Ascender - mf->table_hhea.Descender) * font_size / ((float)(mf->table_head.unitsPerEm));
|
||||
}
|
||||
|
||||
float myfont_metrics_line_gap(myfont_font_t *mf, float font_size)
|
||||
{
|
||||
return (float)(mf->table_hhea.LineGap) * font_size / ((float)mf->table_head.unitsPerEm);
|
||||
return (float)(mf->table_hhea.LineGap) * font_size / ((float)(mf->table_head.unitsPerEm));
|
||||
}
|
||||
|
||||
float myfont_metrics_x_height(myfont_font_t *mf, float font_size)
|
||||
@ -283,17 +329,16 @@ float myfont_metrics_x_height(myfont_font_t *mf, float font_size)
|
||||
|
||||
if(xheight == 0)
|
||||
{
|
||||
uint16_t glyph_index = myfont_glyph_index_by_code(mf, (unsigned long)('x'));
|
||||
myfont_status_t mf_status;
|
||||
uint16_t glyph_index = myfont_glyph_index_by_codepoint(mf, (unsigned long)('x'), &mf_status);
|
||||
|
||||
if(glyph_index) {
|
||||
myfont_table_glyph_t glyph;
|
||||
myfont_glyf_load(mf, &glyph, glyph_index);
|
||||
|
||||
xheight = glyph.head.yMax;
|
||||
if(mf_status == MyFONT_STATUS_OK) {
|
||||
myfont_table_glyph_t *glyph = &mf->table_glyf.cache[glyph_index];
|
||||
xheight = glyph->head.yMax;
|
||||
}
|
||||
}
|
||||
|
||||
return (float)(mf->table_hhea.Ascender - xheight) * font_size / (float)mf->table_head.unitsPerEm;
|
||||
return (float)((mf->table_hhea.Ascender) - xheight) * font_size / (float)(mf->table_head.unitsPerEm);
|
||||
}
|
||||
|
||||
float myfont_metrics_cap_height(myfont_font_t *mf, float font_size)
|
||||
@ -310,17 +355,16 @@ float myfont_metrics_cap_height(myfont_font_t *mf, float font_size)
|
||||
|
||||
if(cap_height == 0)
|
||||
{
|
||||
uint16_t glyph_index = myfont_glyph_index_by_code(mf, (unsigned long)('H'));
|
||||
myfont_status_t mf_status;
|
||||
uint16_t glyph_index = myfont_glyph_index_by_codepoint(mf, (unsigned long)('H'), &mf_status);
|
||||
|
||||
if(glyph_index) {
|
||||
myfont_table_glyph_t glyph;
|
||||
myfont_glyf_load(mf, &glyph, glyph_index);
|
||||
|
||||
cap_height = glyph.head.yMax;
|
||||
if(mf_status == MyFONT_STATUS_OK) {
|
||||
myfont_table_glyph_t *glyph = &mf->table_glyf.cache[glyph_index];
|
||||
cap_height = glyph->head.yMax;
|
||||
}
|
||||
}
|
||||
|
||||
return(float)(mf->table_hhea.Ascender - cap_height) * font_size / (float)mf->table_head.unitsPerEm;
|
||||
return(float)((mf->table_hhea.Ascender) - cap_height) * font_size / (float)(mf->table_head.unitsPerEm);
|
||||
}
|
||||
|
||||
float myfont_metrics_font_height(myfont_font_t *mf, float font_size)
|
||||
@ -329,37 +373,57 @@ float myfont_metrics_font_height(myfont_font_t *mf, float font_size)
|
||||
}
|
||||
|
||||
// width, height and ...
|
||||
float myfont_metrics_width(myfont_font_t *mf, unsigned long codepoint, float font_size)
|
||||
float myfont_metrics_width(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status)
|
||||
{
|
||||
if(mf->table_hhea.numberOfHMetrics == 0 || mf->table_hmtx.hMetrics == NULL)
|
||||
return 0.0f;
|
||||
|
||||
uint16_t glyph_index = myfont_glyph_index_by_code(mf, codepoint);
|
||||
uint16_t width = mf->table_hmtx.hMetrics[glyph_index].advanceWidth;
|
||||
myfont_status_t mf_status;
|
||||
|
||||
uint16_t reso = mf->table_head.unitsPerEm;
|
||||
float fsize = (float)width * font_size / (float)reso;
|
||||
uint16_t glyph_index = myfont_glyph_index_by_codepoint(mf, codepoint, &mf_status);
|
||||
|
||||
return fsize;
|
||||
if(mf_status) {
|
||||
if(status)
|
||||
*status = mf_status;
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return (float)(mf->table_hmtx.hMetrics[glyph_index].advanceWidth) * font_size / (float)(mf->table_head.unitsPerEm);
|
||||
}
|
||||
|
||||
float myfont_metrics_height(myfont_font_t *mf, unsigned long codepoint, float font_size)
|
||||
float myfont_metrics_height(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status)
|
||||
{
|
||||
if(mf->table_vhea.numOfLongVerMetrics == 0 || mf->table_vmtx.vMetrics == NULL)
|
||||
return myfont_metrics_font_height(mf, font_size);
|
||||
|
||||
uint16_t glyph_index = myfont_glyph_index_by_code(mf, codepoint);
|
||||
uint16_t height = mf->table_vmtx.vMetrics[glyph_index].advanceHeight;
|
||||
myfont_status_t mf_status;
|
||||
|
||||
uint16_t reso = mf->table_head.unitsPerEm;
|
||||
float fsize = (float)height * font_size / (float)reso;
|
||||
uint16_t glyph_index = myfont_glyph_index_by_codepoint(mf, codepoint, &mf_status);
|
||||
|
||||
return fsize;
|
||||
if(mf_status) {
|
||||
if(status)
|
||||
*status = mf_status;
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return (float)(mf->table_vmtx.vMetrics[glyph_index].advanceHeight) * font_size / (float)(mf->table_head.unitsPerEm);
|
||||
}
|
||||
|
||||
float myfont_metrics_glyph_offset_y(myfont_font_t *mf, unsigned long codepoint, float font_size)
|
||||
float myfont_metrics_glyph_offset_y(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status)
|
||||
{
|
||||
uint16_t glyph_index = myfont_glyph_index_by_code(mf, codepoint);
|
||||
myfont_status_t mf_status;
|
||||
|
||||
uint16_t glyph_index = myfont_glyph_index_by_codepoint(mf, codepoint, &mf_status);
|
||||
|
||||
if(mf_status) {
|
||||
if(status)
|
||||
*status = mf_status;
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return (float)((mf->table_hhea.Ascender - mf->table_glyf.cache[glyph_index].head.yMax)) * font_size / ((float)mf->table_head.unitsPerEm);
|
||||
}
|
||||
|
||||
|
@ -100,9 +100,10 @@ void * myfont_malloc(myfont_font_t* mf, size_t size);
|
||||
void * myfont_calloc(myfont_font_t* mf, size_t count, size_t size);
|
||||
void myfont_free(myfont_font_t *mf, void* data);
|
||||
|
||||
void myfont_load(myfont_font_t *mf, const char *filepath);
|
||||
myfont_status_t myfont_load(myfont_font_t *mf, const char *filepath);
|
||||
|
||||
void myfont_font_print_exists_table(myfont_font_t *mf, FILE *file);
|
||||
myfont_status_t myfont_check_required_tables(myfont_font_t *mf);
|
||||
|
||||
float myfont_metrics_baseline(myfont_font_t *mf, float font_size);
|
||||
float myfont_metrics_ascender(myfont_font_t *mf, float font_size);
|
||||
@ -112,9 +113,9 @@ float myfont_metrics_x_height(myfont_font_t *mf, float font_size);
|
||||
float myfont_metrics_cap_height(myfont_font_t *mf, float font_size);
|
||||
float myfont_metrics_font_height(myfont_font_t *mf, float font_size);
|
||||
|
||||
float myfont_metrics_width(myfont_font_t *mf, unsigned long codepoint, float font_size);
|
||||
float myfont_metrics_height(myfont_font_t *mf, unsigned long codepoint, float font_size);
|
||||
float myfont_metrics_glyph_offset_y(myfont_font_t *mf, unsigned long codepoint, float font_size);
|
||||
float myfont_metrics_width(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status);
|
||||
float myfont_metrics_height(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status);
|
||||
float myfont_metrics_glyph_offset_y(myfont_font_t *mf, unsigned long codepoint, float font_size, myfont_status_t* status);
|
||||
|
||||
myfont_status_t myfont_load_table(myfont_font_t *mf, void *table, size_t size, enum myfont_table_key tkey);
|
||||
|
||||
|
@ -89,8 +89,56 @@ extern "C" {
|
||||
*/
|
||||
enum myfont_status {
|
||||
MyFONT_STATUS_OK = 0x000000,
|
||||
MyFONT_STATUS_ERROR_MEMORY_ALLOCATION = 0x070000,
|
||||
MyFONT_STATUS_NOT_FOUND = 0x070001,
|
||||
MyFONT_STATUS_ERROR_MEMORY_ALLOCATION = 0x070001,
|
||||
MyFONT_STATUS_NOT_FOUND = 0x070002,
|
||||
MyFONT_STATUS_ERROR_TABLE_BROKEN = 0x070003,
|
||||
MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING = 0x070004,
|
||||
MyFONT_STATUS_ERROR_TABLE_LACKS_REQUIRED = 0x070004,
|
||||
MyFONT_STATUS_ERROR_FILE_OPEN = 0x070030,
|
||||
MyFONT_STATUS_ERROR_FILE_SEEK = 0x070031,
|
||||
MyFONT_STATUS_ERROR_FILE_READ = 0x070032,
|
||||
MyFONT_STATUS_ERROR_FILE_TELL = 0x070033,
|
||||
MyFONT_STATUS_ERROR_FILE_CLOSE = 0x070034,
|
||||
MyFONT_STATUS_ERROR_FILE_TOO_SMALL = 0x070035,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CMAP = 0x070040,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HEAD = 0x070041,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HHEA = 0x070042,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HMTX = 0x070043,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_MAXP = 0x070044,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_NAME = 0x070045,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_OS_2 = 0x070046,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_POST = 0x070047,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CVT = 0x070048,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_FPGM = 0x070049,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GLYF = 0x07004a,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_LOCA = 0x07004b,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_PREP = 0x07004c,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GASP = 0x07004d,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CFF = 0x07004e,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VORG = 0x07004f,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_SVG = 0x070050,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_EBDT = 0x070051,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_EBLC = 0x070052,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_EBSC = 0x070053,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CBDT = 0x070054,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CBLC = 0x070055,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_BASE = 0x070056,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GDEF = 0x070057,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GPOS = 0x070058,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_GSUB = 0x070059,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_JSTF = 0x07005a,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_MATH = 0x07005b,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_DSIG = 0x07005c,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_HDMX = 0x07005d,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_KERN = 0x07005e,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_LTSH = 0x07005f,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_PCLT = 0x070060,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VDMX = 0x070061,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VHEA = 0x070062,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_VMTX = 0x070063,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_COLR = 0x070064,
|
||||
MyFONT_STATUS_ERROR_TABLE_LOAD_CPAL = 0x070065,
|
||||
MyFONT_STATUS_ERROR_GLYPH_NOT_FOUND = 0x070100,
|
||||
}
|
||||
typedef myfont_status_t;
|
||||
|
||||
|
@ -20,19 +20,19 @@
|
||||
|
||||
#include "myfont/name.h"
|
||||
|
||||
void myfont_load_table_name(myfont_font_t *mf)
|
||||
myfont_status_t myfont_load_table_name(myfont_font_t *mf)
|
||||
{
|
||||
memset(&mf->table_name, 0, sizeof(myfont_table_name_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_name] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_name_t *tname = &mf->table_name;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_name];
|
||||
uint32_t pos = table_offset + 6;
|
||||
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* get current data */
|
||||
uint8_t *data = &mf->file_data[table_offset];
|
||||
@ -44,11 +44,14 @@ void myfont_load_table_name(myfont_font_t *mf)
|
||||
pos = pos + (tname->count * 12);
|
||||
if(pos > mf->file_size) {
|
||||
tname->count = 0;
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
myfont_record_t *record = (myfont_record_t *)myfont_calloc(mf, tname->count, sizeof(myfont_record_t));
|
||||
|
||||
if(record == NULL)
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
for(uint16_t i = 0; i < tname->count; i++) {
|
||||
record[i].platformID = myfont_read_u16(&data);
|
||||
record[i].encodingID = myfont_read_u16(&data);
|
||||
@ -64,20 +67,20 @@ void myfont_load_table_name(myfont_font_t *mf)
|
||||
{
|
||||
pos += 2;
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
tname->langTagCount = myfont_read_u16(&data);
|
||||
|
||||
pos = pos + (tname->langTagCount * 4);
|
||||
if(pos > mf->file_size) {
|
||||
tname->langTagCount = 0;
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
myfont_ltag_record_t *lang_record = (myfont_ltag_record_t *)myfont_calloc(mf, tname->langTagCount, sizeof(myfont_ltag_record_t));
|
||||
|
||||
if(lang_record == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
for(uint16_t i = 0; i < tname->count; i++) {
|
||||
lang_record[i].length = myfont_read_u16(&data);
|
||||
@ -86,5 +89,7 @@ void myfont_load_table_name(myfont_font_t *mf)
|
||||
|
||||
tname->langTagRecord = lang_record;
|
||||
}
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ typedef myfont_table_name_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_name(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_name(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -20,12 +20,12 @@
|
||||
|
||||
#include "myfont/os_2.h"
|
||||
|
||||
void myfont_load_table_os_2(myfont_font_t *mf)
|
||||
myfont_status_t myfont_load_table_os_2(myfont_font_t *mf)
|
||||
{
|
||||
memset(&mf->table_os_2, 0, sizeof(myfont_table_os_2_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_OS_2] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_os_2_t *tos_2 = &mf->table_os_2;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_OS_2];
|
||||
@ -35,7 +35,7 @@ void myfont_load_table_os_2(myfont_font_t *mf)
|
||||
uint32_t pos = table_offset + 32 + 10 + 16 + 4 + 16;
|
||||
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
tos_2->version = myfont_read_u16(&data);
|
||||
tos_2->xAvgCharWidth = myfont_read_16(&data);
|
||||
@ -78,7 +78,7 @@ void myfont_load_table_os_2(myfont_font_t *mf)
|
||||
case 1:
|
||||
pos += 8;
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
tos_2->ulCodePageRange1 = myfont_read_u32(&data);
|
||||
tos_2->ulCodePageRange2 = myfont_read_u32(&data);
|
||||
@ -89,7 +89,7 @@ void myfont_load_table_os_2(myfont_font_t *mf)
|
||||
case 4:
|
||||
pos += 18;
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
tos_2->ulCodePageRange1 = myfont_read_u32(&data);
|
||||
tos_2->ulCodePageRange2 = myfont_read_u32(&data);
|
||||
@ -103,7 +103,7 @@ void myfont_load_table_os_2(myfont_font_t *mf)
|
||||
case 5:
|
||||
pos += 22;
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
tos_2->ulCodePageRange1 = myfont_read_u32(&data);
|
||||
tos_2->ulCodePageRange2 = myfont_read_u32(&data);
|
||||
@ -119,6 +119,8 @@ void myfont_load_table_os_2(myfont_font_t *mf)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
int8_t myfont_os_2_panose(myfont_font_t *mf, myfont_table_os_2_panose_t id)
|
||||
|
@ -90,7 +90,7 @@ typedef myfont_table_os_2_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_os_2(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_os_2(struct myfont_font *mf);
|
||||
|
||||
int8_t myfont_os_2_panose(struct myfont_font *mf, myfont_table_os_2_panose_t id);
|
||||
|
||||
|
@ -20,19 +20,19 @@
|
||||
|
||||
#include "myfont/pclt.h"
|
||||
|
||||
void myfont_load_table_pclt(struct myfont_font *mf)
|
||||
myfont_status_t myfont_load_table_pclt(struct myfont_font *mf)
|
||||
{
|
||||
memset(&mf->table_pclt, 0, sizeof(myfont_table_pclt_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_PCLT] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_pclt_t *tpclt = &mf->table_pclt;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_PCLT];
|
||||
|
||||
uint32_t pos = table_offset + 4 + 16 + 16 + 8 + 6 + 4;
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* get current data */
|
||||
uint8_t *data = &mf->file_data[table_offset];
|
||||
@ -60,5 +60,7 @@ void myfont_load_table_pclt(struct myfont_font *mf)
|
||||
tpclt->widthType = (char)myfont_read_u8(&data);
|
||||
tpclt->serifStyle = myfont_read_u8(&data);
|
||||
tpclt->reserved = myfont_read_u8(&data);
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ typedef myfont_table_pclt_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_pclt(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_pclt(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -20,18 +20,18 @@
|
||||
|
||||
#include "myfont/vhea.h"
|
||||
|
||||
void myfont_load_table_vhea(myfont_font_t *mf)
|
||||
myfont_status_t myfont_load_table_vhea(myfont_font_t *mf)
|
||||
{
|
||||
memset(&mf->table_vhea, 0, sizeof(myfont_table_vhea_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_vhea] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_vhea_t *tvhea = &mf->table_vhea;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_vhea];
|
||||
|
||||
if((table_offset + 4 + 32) > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
/* get current data */
|
||||
uint8_t *data = &mf->file_data[table_offset];
|
||||
@ -53,6 +53,8 @@ void myfont_load_table_vhea(myfont_font_t *mf)
|
||||
tvhea->reserved4 = myfont_read_16(&data);
|
||||
tvhea->metricDataFormat = myfont_read_16(&data);
|
||||
tvhea->numOfLongVerMetrics = myfont_read_u16(&data);
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,7 +54,7 @@ typedef myfont_table_vhea_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_vhea(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_vhea(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -20,12 +20,12 @@
|
||||
|
||||
#include "myfont/vmtx.h"
|
||||
|
||||
void myfont_load_table_vmtx(myfont_font_t *mf)
|
||||
myfont_status_t myfont_load_table_vmtx(myfont_font_t *mf)
|
||||
{
|
||||
memset(&mf->table_vmtx, 0, sizeof(myfont_table_vmtx_t));
|
||||
|
||||
if(mf->cache.tables_offset[MyFONT_TKEY_vmtx] == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
myfont_table_vmtx_t *tvmtx = &mf->table_vmtx;
|
||||
const uint32_t table_offset = mf->cache.tables_offset[MyFONT_TKEY_vmtx];
|
||||
@ -35,43 +35,51 @@ void myfont_load_table_vmtx(myfont_font_t *mf)
|
||||
uint16_t num_metrics = mf->table_vhea.numOfLongVerMetrics;
|
||||
|
||||
if(num_metrics == 0)
|
||||
return;
|
||||
return MyFONT_STATUS_OK;
|
||||
|
||||
uint32_t pos = table_offset + (num_metrics * 4);
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
|
||||
myfont_long_ver_metric_t *lver_metric = (myfont_long_ver_metric_t *)myfont_calloc(mf, num_metrics, sizeof(myfont_long_ver_metric_t));
|
||||
|
||||
if(lver_metric == NULL)
|
||||
return;
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
|
||||
for(uint16_t i = 0; i < num_metrics; i++) {
|
||||
lver_metric[i].advanceHeight = myfont_read_u16(&data);
|
||||
lver_metric[i].topSideBearing = myfont_read_16(&data);
|
||||
}
|
||||
|
||||
tvmtx->vMetrics = lver_metric;
|
||||
|
||||
if(mf->table_maxp.numGlyphs <= mf->table_vhea.numOfLongVerMetrics)
|
||||
return;
|
||||
if(mf->table_maxp.numGlyphs <= mf->table_vhea.numOfLongVerMetrics) {
|
||||
myfont_free(mf, lver_metric);
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
uint16_t numOfTSB = mf->table_maxp.numGlyphs - mf->table_vhea.numOfLongVerMetrics;
|
||||
|
||||
pos = pos + (numOfTSB * 2);
|
||||
if(pos > mf->file_size)
|
||||
return;
|
||||
|
||||
if(pos > mf->file_size) {
|
||||
myfont_free(mf, lver_metric);
|
||||
return MyFONT_STATUS_ERROR_TABLE_UNEXPECTED_ENDING;
|
||||
}
|
||||
|
||||
int16_t *topSideBearing = (int16_t *)myfont_calloc(mf, numOfTSB, sizeof(int16_t));
|
||||
|
||||
if(topSideBearing == NULL)
|
||||
return;
|
||||
if(topSideBearing == NULL) {
|
||||
myfont_free(mf, lver_metric);
|
||||
return MyFONT_STATUS_ERROR_MEMORY_ALLOCATION;
|
||||
}
|
||||
|
||||
for(uint16_t i = 0; i < num_metrics; i++) {
|
||||
topSideBearing[i] = myfont_read_16(&data);
|
||||
}
|
||||
|
||||
tvmtx->vMetrics = lver_metric;
|
||||
tvmtx->topSideBearing = topSideBearing;
|
||||
|
||||
return MyFONT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ typedef myfont_table_vmtx_t;
|
||||
|
||||
struct myfont_font;
|
||||
|
||||
void myfont_load_table_vmtx(struct myfont_font *mf);
|
||||
myfont_status_t myfont_load_table_vmtx(struct myfont_font *mf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -1098,6 +1098,41 @@ size_t myhtml_encoding_codepoint_to_lowercase_ascii_utf_8(size_t codepoint, char
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t myhtml_encoding_ascii_utf_8_to_codepoint(const unsigned char* data, size_t* codepoint)
|
||||
{
|
||||
if (*data < 0x80){
|
||||
/* 0xxxxxxx */
|
||||
*codepoint = (size_t)*data;
|
||||
return 1;
|
||||
}
|
||||
else if ((*data & 0xe0) == 0xc0) {
|
||||
/* 110xxxxx 10xxxxxx */
|
||||
*codepoint = (data[0] ^ (0xC0 & data[0])) << 6;
|
||||
*codepoint |= (data[1] ^ (0x80 & data[1]));
|
||||
|
||||
return 2;
|
||||
}
|
||||
else if ((*data & 0xf0) == 0xe0) {
|
||||
/* 1110xxxx 10xxxxxx 10xxxxxx */
|
||||
*codepoint = (data[0] ^ (0xE0 & data[0])) << 12;
|
||||
*codepoint |= (data[1] ^ (0x80 & data[1])) << 6;
|
||||
*codepoint |= (data[2] ^ (0x80 & data[2]));
|
||||
|
||||
return 3;
|
||||
}
|
||||
else if ((*data & 0xf8) == 0xf0) {
|
||||
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
|
||||
*codepoint = (data[0] ^ (0xF0 & data[0])) << 18;
|
||||
*codepoint |= (data[1] ^ (0x80 & data[1])) << 12;
|
||||
*codepoint |= (data[2] ^ (0x80 & data[2])) << 6;
|
||||
*codepoint |= (data[3] ^ (0x80 & data[3]));
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t myhtml_encoding_codepoint_to_ascii_utf_16(size_t codepoint, char *data)
|
||||
{
|
||||
if((codepoint >> 16)) {
|
||||
|
@ -127,6 +127,7 @@ enum myhtml_encoding_status myhtml_encoding_decode_x_user_defined(unsigned const
|
||||
size_t myhtml_encoding_codepoint_to_ascii_utf_8(size_t codepoint, char *data);
|
||||
size_t myhtml_encoding_codepoint_to_lowercase_ascii_utf_8(size_t codepoint, char *data);
|
||||
size_t myhtml_encoding_codepoint_to_ascii_utf_16(size_t codepoint, char *data);
|
||||
size_t myhtml_encoding_ascii_utf_8_to_codepoint(const unsigned char* data, size_t* codepoint);
|
||||
|
||||
void myhtml_encoding_result_clean(myhtml_encoding_result_t *res);
|
||||
|
||||
|
@ -1403,7 +1403,7 @@ void myhtml_queue_add(myhtml_tree_t *tree, size_t begin, myhtml_token_node_t* to
|
||||
|
||||
if(tree->flags & MyHTML_TREE_FLAGS_SINGLE_MODE) {
|
||||
myhtml_parser_worker(0, qnode);
|
||||
while(myhtml_rules_tree_dispatcher(tree, token)){};
|
||||
myhtml_parser_stream(0, qnode);
|
||||
|
||||
tree->current_qnode = mythread_queue_node_malloc_limit(tree->myhtml->thread, tree->queue, 4, NULL);
|
||||
}
|
||||
@ -1414,7 +1414,7 @@ void myhtml_queue_add(myhtml_tree_t *tree, size_t begin, myhtml_token_node_t* to
|
||||
#else
|
||||
|
||||
myhtml_parser_worker(0, qnode);
|
||||
while(myhtml_rules_tree_dispatcher(tree, token)){};
|
||||
myhtml_parser_stream(0, qnode);
|
||||
|
||||
tree->current_qnode = mythread_queue_node_malloc_limit(tree->myhtml->thread, tree->queue, 4, NULL);
|
||||
|
||||
|
@ -185,7 +185,21 @@ void myhtml_parser_worker(mythread_id_t thread_id, mythread_queue_node_t *qnode)
|
||||
myhtml_tree_t* tree = qnode->tree;
|
||||
myhtml_token_node_t* token = qnode->token;
|
||||
|
||||
if(qnode->tree->parse_flags & MyHTML_TREE_PARSE_FLAGS_WITHOUT_PROCESS_TOKEN) {
|
||||
/*
|
||||
* Tree can not be built without tokens
|
||||
*
|
||||
* MyHTML_TREE_PARSE_FLAGS_WITHOUT_PROCESS_TOKEN == 3
|
||||
* MyHTML_TREE_PARSE_FLAGS_WITHOUT_BUILD_TREE == 1
|
||||
*
|
||||
* MyHTML_TREE_PARSE_FLAGS_WITHOUT_PROCESS_TOKEN include MyHTML_TREE_PARSE_FLAGS_WITHOUT_BUILD_TREE
|
||||
*
|
||||
* if set only MyHTML_TREE_PARSE_FLAGS_WITHOUT_BUILD_TREE and check only for MyHTML_TREE_PARSE_FLAGS_WITHOUT_PROCESS_TOKEN
|
||||
* return true
|
||||
* we need check both, 1 and 2
|
||||
*/
|
||||
if((qnode->tree->parse_flags & MyHTML_TREE_PARSE_FLAGS_WITHOUT_PROCESS_TOKEN) &&
|
||||
(qnode->tree->parse_flags & 2))
|
||||
{
|
||||
if(tree->callback_before_token)
|
||||
tree->callback_before_token_ctx = tree->callback_before_token(tree, token, tree->callback_before_token_ctx);
|
||||
|
||||
|
@ -257,24 +257,26 @@ void myhtml_tokenizer_pause(myhtml_tree_t* tree)
|
||||
|
||||
void myhtml_tokenizer_calc_current_namespace(myhtml_tree_t* tree, myhtml_token_node_t* token_node)
|
||||
{
|
||||
if(tree->flags & MyHTML_TREE_FLAGS_SINGLE_MODE)
|
||||
{
|
||||
myhtml_tokenizer_state_set(tree) = tree->state_of_builder;
|
||||
}
|
||||
else {
|
||||
if(token_node->tag_id == MyHTML_TAG_MATH ||
|
||||
token_node->tag_id == MyHTML_TAG_SVG ||
|
||||
token_node->tag_id == MyHTML_TAG_FRAMESET)
|
||||
if((tree->parse_flags & MyHTML_TREE_PARSE_FLAGS_WITHOUT_BUILD_TREE) == 0) {
|
||||
if(tree->flags & MyHTML_TREE_FLAGS_SINGLE_MODE)
|
||||
{
|
||||
tree->token_namespace = token_node;
|
||||
myhtml_tokenizer_state_set(tree) = tree->state_of_builder;
|
||||
}
|
||||
else if(tree->token_namespace && (token_node->type & MyHTML_TOKEN_TYPE_CLOSE) == 0) {
|
||||
const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, token_node->tag_id);
|
||||
|
||||
if(tag_ctx->data_parser != MyHTML_TOKENIZER_STATE_DATA)
|
||||
else {
|
||||
if(token_node->tag_id == MyHTML_TAG_MATH ||
|
||||
token_node->tag_id == MyHTML_TAG_SVG ||
|
||||
token_node->tag_id == MyHTML_TAG_FRAMESET)
|
||||
{
|
||||
myhtml_tree_wait_for_last_done_token(tree, token_node);
|
||||
myhtml_tokenizer_state_set(tree) = tree->state_of_builder;
|
||||
tree->token_namespace = token_node;
|
||||
}
|
||||
else if(tree->token_namespace && (token_node->type & MyHTML_TOKEN_TYPE_CLOSE) == 0) {
|
||||
const myhtml_tag_context_t *tag_ctx = myhtml_tag_get_by_id(tree->tags, token_node->tag_id);
|
||||
|
||||
if(tag_ctx->data_parser != MyHTML_TOKENIZER_STATE_DATA)
|
||||
{
|
||||
myhtml_tree_wait_for_last_done_token(tree, token_node);
|
||||
myhtml_tokenizer_state_set(tree) = tree->state_of_builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user