Add hb_blob_create_from_file, a new API (#926)
This commit is contained in:
parent
4fa1c6705a
commit
ce17340b23
2
TODO
2
TODO
|
@ -17,8 +17,6 @@ API additions
|
||||||
|
|
||||||
- Language to/from script.
|
- Language to/from script.
|
||||||
|
|
||||||
- blob_from_file?
|
|
||||||
|
|
||||||
- Add hb-cairo glue
|
- Add hb-cairo glue
|
||||||
|
|
||||||
- Add sanitize API (and a cached version, that saves result on blob user-data)
|
- Add sanitize API (and a cached version, that saves result on blob user-data)
|
||||||
|
|
|
@ -8,6 +8,7 @@ HB_EXTERN
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>hb-blob</FILE>
|
<FILE>hb-blob</FILE>
|
||||||
hb_blob_create
|
hb_blob_create
|
||||||
|
hb_blob_create_from_file
|
||||||
hb_blob_create_sub_blob
|
hb_blob_create_sub_blob
|
||||||
hb_blob_copy_writable_or_fail
|
hb_blob_copy_writable_or_fail
|
||||||
hb_blob_destroy
|
hb_blob_destroy
|
||||||
|
|
|
@ -219,38 +219,7 @@ int main (int argc, char **argv)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_blob_t *blob = nullptr;
|
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
|
||||||
{
|
|
||||||
const char *font_data;
|
|
||||||
unsigned int len;
|
|
||||||
hb_destroy_func_t destroy;
|
|
||||||
void *user_data;
|
|
||||||
hb_memory_mode_t mm;
|
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
|
|
||||||
font_data = g_mapped_file_get_contents (mf);
|
|
||||||
len = g_mapped_file_get_length (mf);
|
|
||||||
destroy = (hb_destroy_func_t) g_mapped_file_unref;
|
|
||||||
user_data = (void *) mf;
|
|
||||||
mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
|
||||||
#else
|
|
||||||
FILE *f = fopen (argv[1], "rb");
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
len = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
font_data = (const char *) malloc (len);
|
|
||||||
if (!font_data) len = 0;
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
destroy = free;
|
|
||||||
user_data = (void *) font_data;
|
|
||||||
fclose (f);
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blob = hb_blob_create (font_data, len, mm, user_data, destroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_face_t *face = hb_face_create (blob, 0);
|
hb_face_t *face = hb_face_create (blob, 0);
|
||||||
hb_font_t *font = hb_font_create (face);
|
hb_font_t *font = hb_font_create (face);
|
||||||
|
|
||||||
|
|
|
@ -538,22 +538,13 @@ struct LE_IMAGE_DOS_HEADER {
|
||||||
};
|
};
|
||||||
|
|
||||||
int main (int argc, char** argv) {
|
int main (int argc, char** argv) {
|
||||||
FILE *f = fopen (argv[1], "rb");
|
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
unsigned int len = ftell (f);
|
|
||||||
rewind (f);
|
|
||||||
const char *font_data = (const char *) malloc (len);
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
|
|
||||||
|
|
||||||
OT::Sanitizer<LE_IMAGE_DOS_HEADER> sanitizer;
|
OT::Sanitizer<LE_IMAGE_DOS_HEADER> sanitizer;
|
||||||
hb_blob_t *blob = hb_blob_create (font_data, len, HB_MEMORY_MODE_WRITABLE,
|
|
||||||
(void *) font_data, free);
|
|
||||||
hb_blob_t *font_blob = sanitizer.sanitize (blob);
|
hb_blob_t *font_blob = sanitizer.sanitize (blob);
|
||||||
const LE_IMAGE_DOS_HEADER* dos_header =
|
const LE_IMAGE_DOS_HEADER* dos_header =
|
||||||
OT::Sanitizer<LE_IMAGE_DOS_HEADER>::lock_instance (font_blob);
|
OT::Sanitizer<LE_IMAGE_DOS_HEADER>::lock_instance (font_blob);
|
||||||
|
|
||||||
|
|
||||||
const NE_RESOURCE_TABLE &rtable = dos_header->get_os2_header ().get_resource_table ();
|
const NE_RESOURCE_TABLE &rtable = dos_header->get_os2_header ().get_resource_table ();
|
||||||
int shift = rtable.get_shift_value ();
|
int shift = rtable.get_shift_value ();
|
||||||
const NE_TYPEINFO& entry = rtable.get_fonts_entry ();
|
const NE_TYPEINFO& entry = rtable.get_fonts_entry ();
|
||||||
|
|
131
src/hb-blob.cc
131
src/hb-blob.cc
|
@ -43,6 +43,10 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
|
||||||
struct hb_blob_t {
|
struct hb_blob_t {
|
||||||
|
@ -273,7 +277,7 @@ hb_blob_destroy (hb_blob_t *blob)
|
||||||
* @destroy: callback to call when @data is not needed anymore.
|
* @destroy: callback to call when @data is not needed anymore.
|
||||||
* @replace: whether to replace an existing data with the same key.
|
* @replace: whether to replace an existing data with the same key.
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -292,9 +296,9 @@ hb_blob_set_user_data (hb_blob_t *blob,
|
||||||
* @blob: a blob.
|
* @blob: a blob.
|
||||||
* @key: key for data to get.
|
* @key: key for data to get.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* Return value: (transfer none):
|
*
|
||||||
|
* Return value: (transfer none):
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -310,7 +314,7 @@ hb_blob_get_user_data (hb_blob_t *blob,
|
||||||
* hb_blob_make_immutable:
|
* hb_blob_make_immutable:
|
||||||
* @blob: a blob.
|
* @blob: a blob.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -327,7 +331,7 @@ hb_blob_make_immutable (hb_blob_t *blob)
|
||||||
* hb_blob_is_immutable:
|
* hb_blob_is_immutable:
|
||||||
* @blob: a blob.
|
* @blob: a blob.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Return value: TODO
|
* Return value: TODO
|
||||||
*
|
*
|
||||||
|
@ -344,7 +348,7 @@ hb_blob_is_immutable (hb_blob_t *blob)
|
||||||
* hb_blob_get_length:
|
* hb_blob_get_length:
|
||||||
* @blob: a blob.
|
* @blob: a blob.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Return value: the length of blob data in bytes.
|
* Return value: the length of blob data in bytes.
|
||||||
*
|
*
|
||||||
|
@ -361,9 +365,9 @@ hb_blob_get_length (hb_blob_t *blob)
|
||||||
* @blob: a blob.
|
* @blob: a blob.
|
||||||
* @length: (out):
|
* @length: (out):
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* Returns: (transfer none) (array length=length):
|
*
|
||||||
|
* Returns: (transfer none) (array length=length):
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -502,3 +506,114 @@ _try_writable (hb_blob_t *blob)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
#undef fstat
|
||||||
|
#define fstat(a,b) _fstati64(a,b)
|
||||||
|
#undef stat
|
||||||
|
#define stat _stati64
|
||||||
|
|
||||||
|
#ifndef S_ISREG
|
||||||
|
# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
|
||||||
|
#endif
|
||||||
|
#endif // defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
|
||||||
|
#ifndef _O_BINARY
|
||||||
|
# define _O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAP_FAILED
|
||||||
|
# define MAP_FAILED ((void *) -1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct hb_mapped_file_t
|
||||||
|
{
|
||||||
|
char *contents;
|
||||||
|
unsigned long length;
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
HANDLE mapping;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_hb_mapped_file_destroy (hb_mapped_file_t *file)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
munmap (file->contents, file->length);
|
||||||
|
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
UnmapViewOfFile (file->contents);
|
||||||
|
CloseHandle (file->mapping);
|
||||||
|
#else
|
||||||
|
free (file->contents);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
free (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_blob_create_from_file:
|
||||||
|
* @file_name: font filename.
|
||||||
|
*
|
||||||
|
* Returns: A hb_blob_t pointer with the content of the file
|
||||||
|
*
|
||||||
|
* Since: REPLACEME
|
||||||
|
**/
|
||||||
|
hb_blob_t *
|
||||||
|
hb_blob_create_from_file (const char *file_name)
|
||||||
|
{
|
||||||
|
// Adopted from glib's gmappedfile.c with Matthias Clasen and
|
||||||
|
// Allison Lortie permission but changed to suit our need.
|
||||||
|
bool writable = false;
|
||||||
|
hb_memory_mode_t mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
||||||
|
|
||||||
|
int fd = open (file_name, (writable ? O_RDWR : O_RDONLY) | _O_BINARY, 0);
|
||||||
|
if (unlikely (fd == -1)) return hb_blob_get_empty ();
|
||||||
|
|
||||||
|
hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (sizeof (hb_mapped_file_t), 1);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (unlikely (fstat (fd, &st) == -1)) goto fail;
|
||||||
|
|
||||||
|
// If the file size is 0 and isn't regular, give up
|
||||||
|
if (unlikely (st.st_size == 0 && S_ISREG (st.st_mode))) goto fail;
|
||||||
|
|
||||||
|
file->length = (unsigned long) st.st_size;
|
||||||
|
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
file->contents = (char *) mmap (nullptr, file->length,
|
||||||
|
writable ? PROT_READ|PROT_WRITE : PROT_READ,
|
||||||
|
MAP_PRIVATE, fd, 0);
|
||||||
|
if (unlikely (file->contents == MAP_FAILED)) goto fail;
|
||||||
|
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
file->mapping = CreateFileMapping ((HANDLE) _get_osfhandle (fd), nullptr,
|
||||||
|
writable ? PAGE_WRITECOPY : PAGE_READONLY,
|
||||||
|
0, 0, nullptr);
|
||||||
|
if (unlikely (file->mapping == nullptr)) goto fail;
|
||||||
|
|
||||||
|
file->contents = (char *) MapViewOfFile (file->mapping,
|
||||||
|
writable ? FILE_MAP_COPY : FILE_MAP_READ,
|
||||||
|
0, 0, 0);
|
||||||
|
if (unlikely (file->contents == nullptr))
|
||||||
|
{
|
||||||
|
CloseHandle (file->mapping);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
file->contents = (char *) malloc (file->length);
|
||||||
|
if (unlikely (!file->contents)) goto fail;
|
||||||
|
read (fd, file->contents, file->length);
|
||||||
|
mm = HB_MEMORY_MODE_WRITABLE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
close (fd);
|
||||||
|
return hb_blob_create (file->contents, file->length, mm, (void *) file,
|
||||||
|
(hb_destroy_func_t) _hb_mapped_file_destroy);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close (fd);
|
||||||
|
free (file);
|
||||||
|
return hb_blob_get_empty ();
|
||||||
|
}
|
||||||
|
|
|
@ -123,6 +123,8 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
|
||||||
HB_EXTERN char *
|
HB_EXTERN char *
|
||||||
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
|
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
|
||||||
|
|
||||||
|
HB_EXTERN hb_blob_t *
|
||||||
|
hb_blob_create_from_file (const char *file_name);
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
|
|
26
src/main.cc
26
src/main.cc
|
@ -49,32 +49,12 @@ main (int argc, char **argv)
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *font_data = nullptr;
|
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
|
||||||
int len = 0;
|
unsigned int len;
|
||||||
hb_destroy_func_t destroy;
|
const char *font_data = hb_blob_get_data (blob, &len);
|
||||||
hb_memory_mode_t mm;
|
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
|
|
||||||
font_data = g_mapped_file_get_contents (mf);
|
|
||||||
len = g_mapped_file_get_length (mf);
|
|
||||||
destroy = (hb_destroy_func_t) g_mapped_file_unref;
|
|
||||||
mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
|
||||||
#else
|
|
||||||
FILE *f = fopen (argv[1], "rb");
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
len = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
font_data = (const char *) malloc (len);
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
destroy = free;
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
printf ("Opened font file %s: %d bytes long\n", argv[1], len);
|
printf ("Opened font file %s: %d bytes long\n", argv[1], len);
|
||||||
|
|
||||||
Sanitizer<OpenTypeFontFile> sanitizer;
|
Sanitizer<OpenTypeFontFile> sanitizer;
|
||||||
hb_blob_t *blob = hb_blob_create (font_data, len, mm, (void *) font_data, destroy);
|
|
||||||
hb_blob_t *font_blob = sanitizer.sanitize (blob);
|
hb_blob_t *font_blob = sanitizer.sanitize (blob);
|
||||||
const OpenTypeFontFile* sanitized = Sanitizer<OpenTypeFontFile>::lock_instance (font_blob);
|
const OpenTypeFontFile* sanitized = Sanitizer<OpenTypeFontFile>::lock_instance (font_blob);
|
||||||
if (sanitized == &Null (OpenTypeFontFile))
|
if (sanitized == &Null (OpenTypeFontFile))
|
||||||
|
|
|
@ -32,57 +32,17 @@
|
||||||
#include "hb-ft.h"
|
#include "hb-ft.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
# include <glib.h>
|
|
||||||
# if !GLIB_CHECK_VERSION (2, 22, 0)
|
|
||||||
# define g_mapped_file_unref g_mapped_file_free
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
hb_blob_t *blob = nullptr;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf (stderr, "usage: %s font-file\n", argv[0]);
|
fprintf (stderr, "usage: %s font-file\n", argv[0]);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the blob */
|
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
|
||||||
{
|
|
||||||
const char *font_data;
|
|
||||||
unsigned int len;
|
|
||||||
hb_destroy_func_t destroy;
|
|
||||||
void *user_data;
|
|
||||||
hb_memory_mode_t mm;
|
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
|
|
||||||
font_data = g_mapped_file_get_contents (mf);
|
|
||||||
len = g_mapped_file_get_length (mf);
|
|
||||||
destroy = (hb_destroy_func_t) g_mapped_file_unref;
|
|
||||||
user_data = (void *) mf;
|
|
||||||
mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
|
||||||
#else
|
|
||||||
FILE *f = fopen (argv[1], "rb");
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
len = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
font_data = (const char *) malloc (len);
|
|
||||||
if (!font_data) len = 0;
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
destroy = free;
|
|
||||||
user_data = (void *) font_data;
|
|
||||||
fclose (f);
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blob = hb_blob_create (font_data, len, mm, user_data, destroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
|
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
blob = nullptr;
|
blob = nullptr;
|
||||||
|
|
|
@ -29,58 +29,18 @@
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
#include "hb-ot.h"
|
#include "hb-ot.h"
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
# include <glib.h>
|
|
||||||
# if !GLIB_CHECK_VERSION (2, 22, 0)
|
|
||||||
# define g_mapped_file_unref g_mapped_file_free
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
hb_blob_t *blob = nullptr;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf (stderr, "usage: %s font-file\n", argv[0]);
|
fprintf (stderr, "usage: %s font-file\n", argv[0]);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the blob */
|
|
||||||
{
|
|
||||||
const char *font_data;
|
|
||||||
unsigned int len;
|
|
||||||
hb_destroy_func_t destroy;
|
|
||||||
void *user_data;
|
|
||||||
hb_memory_mode_t mm;
|
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
|
|
||||||
font_data = g_mapped_file_get_contents (mf);
|
|
||||||
len = g_mapped_file_get_length (mf);
|
|
||||||
destroy = (hb_destroy_func_t) g_mapped_file_unref;
|
|
||||||
user_data = (void *) mf;
|
|
||||||
mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
|
||||||
#else
|
|
||||||
FILE *f = fopen (argv[1], "rb");
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
len = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
font_data = (const char *) malloc (len);
|
|
||||||
if (!font_data) len = 0;
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
destroy = free;
|
|
||||||
user_data = (void *) font_data;
|
|
||||||
fclose (f);
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blob = hb_blob_create (font_data, len, mm, user_data, destroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the face */
|
/* Create the face */
|
||||||
|
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
|
||||||
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
|
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
blob = nullptr;
|
blob = nullptr;
|
||||||
|
|
|
@ -29,13 +29,6 @@
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
#include "hb-ot.h"
|
#include "hb-ot.h"
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
# include <glib.h>
|
|
||||||
# if !GLIB_CHECK_VERSION (2, 22, 0)
|
|
||||||
# define g_mapped_file_unref g_mapped_file_free
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef HAVE_FREETYPE
|
#ifdef HAVE_FREETYPE
|
||||||
|
@ -45,46 +38,13 @@
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
hb_blob_t *blob = nullptr;
|
|
||||||
|
|
||||||
if (argc != 4 && argc != 5) {
|
if (argc != 4 && argc != 5) {
|
||||||
fprintf (stderr, "usage: %s font-file lookup-index first-glyph [second-glyph]\n", argv[0]);
|
fprintf (stderr, "usage: %s font-file lookup-index first-glyph [second-glyph]\n", argv[0]);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the blob */
|
|
||||||
{
|
|
||||||
const char *font_data;
|
|
||||||
unsigned int len;
|
|
||||||
hb_destroy_func_t destroy;
|
|
||||||
void *user_data;
|
|
||||||
hb_memory_mode_t mm;
|
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
|
|
||||||
font_data = g_mapped_file_get_contents (mf);
|
|
||||||
len = g_mapped_file_get_length (mf);
|
|
||||||
destroy = (hb_destroy_func_t) g_mapped_file_unref;
|
|
||||||
user_data = (void *) mf;
|
|
||||||
mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
|
||||||
#else
|
|
||||||
FILE *f = fopen (argv[1], "rb");
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
len = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
font_data = (const char *) malloc (len);
|
|
||||||
if (!font_data) len = 0;
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
destroy = free;
|
|
||||||
user_data = (void *) font_data;
|
|
||||||
fclose (f);
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blob = hb_blob_create (font_data, len, mm, user_data, destroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the face */
|
/* Create the face */
|
||||||
|
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
|
||||||
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
|
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
blob = nullptr;
|
blob = nullptr;
|
||||||
|
|
42
src/test.cc
42
src/test.cc
|
@ -28,13 +28,6 @@
|
||||||
|
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
# include <glib.h>
|
|
||||||
# if !GLIB_CHECK_VERSION (2, 22, 0)
|
|
||||||
# define g_mapped_file_unref g_mapped_file_free
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef HAVE_FREETYPE
|
#ifdef HAVE_FREETYPE
|
||||||
|
@ -44,45 +37,12 @@
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
hb_blob_t *blob = nullptr;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
|
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the blob */
|
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
|
||||||
{
|
|
||||||
const char *font_data;
|
|
||||||
unsigned int len;
|
|
||||||
hb_destroy_func_t destroy;
|
|
||||||
void *user_data;
|
|
||||||
hb_memory_mode_t mm;
|
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
|
||||||
GMappedFile *mf = g_mapped_file_new (argv[1], false, nullptr);
|
|
||||||
font_data = g_mapped_file_get_contents (mf);
|
|
||||||
len = g_mapped_file_get_length (mf);
|
|
||||||
destroy = (hb_destroy_func_t) g_mapped_file_unref;
|
|
||||||
user_data = (void *) mf;
|
|
||||||
mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
|
||||||
#else
|
|
||||||
FILE *f = fopen (argv[1], "rb");
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
len = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
font_data = (const char *) malloc (len);
|
|
||||||
if (!font_data) len = 0;
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
destroy = free;
|
|
||||||
user_data = (void *) font_data;
|
|
||||||
fclose (f);
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
blob = hb_blob_create (font_data, len, mm, user_data, destroy);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob));
|
printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob));
|
||||||
|
|
||||||
/* Create the face */
|
/* Create the face */
|
||||||
|
|
|
@ -47,64 +47,16 @@ typedef short bool;
|
||||||
|
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
static inline char *
|
|
||||||
hb_subset_test_read_file (const char *path,
|
|
||||||
size_t *length /* OUT */)
|
|
||||||
{
|
|
||||||
FILE *fp = fopen (path, "rb");
|
|
||||||
|
|
||||||
long file_length = 0;
|
|
||||||
char *buffer = NULL;
|
|
||||||
if (fp && fseek (fp, 0, SEEK_END) == 0)
|
|
||||||
{
|
|
||||||
file_length = ftell(fp);
|
|
||||||
rewind (fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_length > 0)
|
|
||||||
{
|
|
||||||
buffer = (char *) calloc (file_length + 1, sizeof (char));
|
|
||||||
if (buffer && fread (buffer, 1, file_length, fp) == (size_t) file_length)
|
|
||||||
{
|
|
||||||
*length = file_length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
free (buffer);
|
|
||||||
buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fp)
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline hb_face_t *
|
static inline hb_face_t *
|
||||||
hb_subset_test_open_font (const char *font_path)
|
hb_subset_test_open_font (const char *font_path)
|
||||||
{
|
{
|
||||||
#if GLIB_CHECK_VERSION(2,37,2)
|
#if GLIB_CHECK_VERSION(2,37,2)
|
||||||
gchar* path = g_test_build_filename(G_TEST_DIST, font_path, NULL);
|
char* path = g_test_build_filename(G_TEST_DIST, font_path, NULL);
|
||||||
#else
|
#else
|
||||||
gchar* path = g_strdup(font_path);
|
char* path = g_strdup(font_path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t length;
|
return hb_face_create (hb_blob_create_from_file (path), 0);
|
||||||
char *font_data = hb_subset_test_read_file(path, &length);
|
|
||||||
|
|
||||||
if (font_data != NULL) {
|
|
||||||
hb_blob_t *blob = hb_blob_create (font_data,
|
|
||||||
length,
|
|
||||||
HB_MEMORY_MODE_READONLY,
|
|
||||||
font_data,
|
|
||||||
free);
|
|
||||||
hb_face_t *face = hb_face_create (blob, 0);
|
|
||||||
hb_blob_destroy (blob);
|
|
||||||
return face;
|
|
||||||
}
|
|
||||||
g_assert (false);
|
|
||||||
return NULL; /* Shut up, compiler! */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline hb_subset_input_t *
|
static inline hb_subset_input_t *
|
||||||
|
|
|
@ -87,39 +87,6 @@ hb_test_run (void)
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Helpers for loading test fonts */
|
|
||||||
static inline hb_face_t *
|
|
||||||
hb_test_load_face (const char *path)
|
|
||||||
{
|
|
||||||
const char *font_data = NULL;
|
|
||||||
unsigned int len = 0;
|
|
||||||
hb_blob_t *blob = NULL;
|
|
||||||
hb_face_t *face = NULL;
|
|
||||||
|
|
||||||
FILE *f = fopen (path, "rb");
|
|
||||||
if (!f) {
|
|
||||||
perror (path);
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek (f, 0, SEEK_END);
|
|
||||||
len = ftell (f);
|
|
||||||
fseek (f, 0, SEEK_SET);
|
|
||||||
font_data = (const char *) malloc (len);
|
|
||||||
if (!font_data) len = 0;
|
|
||||||
len = fread ((char *) font_data, 1, len, f);
|
|
||||||
fclose (f);
|
|
||||||
|
|
||||||
blob = hb_blob_create (font_data, len, HB_MEMORY_MODE_READONLY, 0, free);
|
|
||||||
face = hb_face_create (blob, 0 /* first face */);
|
|
||||||
hb_blob_destroy (blob);
|
|
||||||
return face;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Bugzilla helpers */
|
/* Bugzilla helpers */
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
@ -65,8 +65,6 @@ fail (hb_bool_t suggest_help, const char *format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hb_bool_t debug = false;
|
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
shapers_to_string (void)
|
shapers_to_string (void)
|
||||||
{
|
{
|
||||||
|
@ -107,7 +105,6 @@ option_parser_t::add_main_options (void)
|
||||||
{
|
{
|
||||||
{"version", 0, G_OPTION_FLAG_NO_ARG,
|
{"version", 0, G_OPTION_FLAG_NO_ARG,
|
||||||
G_OPTION_ARG_CALLBACK, (gpointer) &show_version, "Show version numbers", nullptr},
|
G_OPTION_ARG_CALLBACK, (gpointer) &show_version, "Show version numbers", nullptr},
|
||||||
{"debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Free all resources before exit", nullptr},
|
|
||||||
{nullptr}
|
{nullptr}
|
||||||
};
|
};
|
||||||
g_option_context_add_main_entries (context, entries, nullptr);
|
g_option_context_add_main_entries (context, entries, nullptr);
|
||||||
|
@ -649,74 +646,29 @@ font_options_t::get_font (void) const
|
||||||
hb_blob_t *blob = nullptr;
|
hb_blob_t *blob = nullptr;
|
||||||
|
|
||||||
/* Create the blob */
|
/* Create the blob */
|
||||||
{
|
if (!font_file)
|
||||||
char *font_data;
|
fail (true, "No font file set");
|
||||||
unsigned int len = 0;
|
|
||||||
hb_destroy_func_t destroy;
|
|
||||||
void *user_data;
|
|
||||||
hb_memory_mode_t mm;
|
|
||||||
|
|
||||||
/* This is a hell of a lot of code for just reading a file! */
|
if (0 == strcmp (font_file, "-")) {
|
||||||
if (!font_file)
|
/* read it */
|
||||||
fail (true, "No font file set");
|
GString *gs = g_string_new (nullptr);
|
||||||
|
char buf[BUFSIZ];
|
||||||
if (0 == strcmp (font_file, "-")) {
|
|
||||||
/* read it */
|
|
||||||
GString *gs = g_string_new (nullptr);
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
setmode (fileno (stdin), O_BINARY);
|
setmode (fileno (stdin), O_BINARY);
|
||||||
#endif
|
#endif
|
||||||
while (!feof (stdin)) {
|
while (!feof (stdin)) {
|
||||||
size_t ret = fread (buf, 1, sizeof (buf), stdin);
|
size_t ret = fread (buf, 1, sizeof (buf), stdin);
|
||||||
if (ferror (stdin))
|
if (ferror (stdin))
|
||||||
fail (false, "Failed reading font from standard input: %s",
|
fail (false, "Failed reading font from standard input: %s",
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
g_string_append_len (gs, buf, ret);
|
g_string_append_len (gs, buf, ret);
|
||||||
}
|
|
||||||
len = gs->len;
|
|
||||||
font_data = g_string_free (gs, false);
|
|
||||||
user_data = font_data;
|
|
||||||
destroy = (hb_destroy_func_t) g_free;
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
} else {
|
|
||||||
GError *error = nullptr;
|
|
||||||
GMappedFile *mf = g_mapped_file_new (font_file, false, &error);
|
|
||||||
if (mf) {
|
|
||||||
font_data = g_mapped_file_get_contents (mf);
|
|
||||||
len = g_mapped_file_get_length (mf);
|
|
||||||
if (len) {
|
|
||||||
destroy = (hb_destroy_func_t) g_mapped_file_unref;
|
|
||||||
user_data = (void *) mf;
|
|
||||||
mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
|
|
||||||
} else
|
|
||||||
g_mapped_file_unref (mf);
|
|
||||||
} else {
|
|
||||||
fail (false, "%s", error->message);
|
|
||||||
//g_error_free (error);
|
|
||||||
}
|
|
||||||
if (!len) {
|
|
||||||
/* GMappedFile is buggy, it doesn't fail if file isn't regular.
|
|
||||||
* Try reading.
|
|
||||||
* https://bugzilla.gnome.org/show_bug.cgi?id=659212 */
|
|
||||||
GError *error = nullptr;
|
|
||||||
gsize l;
|
|
||||||
if (g_file_get_contents (font_file, &font_data, &l, &error)) {
|
|
||||||
len = l;
|
|
||||||
destroy = (hb_destroy_func_t) g_free;
|
|
||||||
user_data = (void *) font_data;
|
|
||||||
mm = HB_MEMORY_MODE_WRITABLE;
|
|
||||||
} else {
|
|
||||||
fail (false, "%s", error->message);
|
|
||||||
//g_error_free (error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
char *font_data = g_string_free (gs, false);
|
||||||
if (debug)
|
blob = hb_blob_create (font_data, gs->len,
|
||||||
mm = HB_MEMORY_MODE_DUPLICATE;
|
HB_MEMORY_MODE_WRITABLE, font_data,
|
||||||
|
(hb_destroy_func_t) g_free);
|
||||||
blob = hb_blob_create (font_data, len, mm, user_data, destroy);
|
} else {
|
||||||
|
blob = hb_blob_create_from_file (font_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the face */
|
/* Create the face */
|
||||||
|
|
|
@ -52,14 +52,8 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib/gprintf.h>
|
#include <glib/gprintf.h>
|
||||||
|
|
||||||
#if !GLIB_CHECK_VERSION (2, 22, 0)
|
|
||||||
# define g_mapped_file_unref g_mapped_file_free
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN G_GNUC_PRINTF (2, 3);
|
void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN G_GNUC_PRINTF (2, 3);
|
||||||
|
|
||||||
extern hb_bool_t debug;
|
|
||||||
|
|
||||||
struct option_group_t
|
struct option_group_t
|
||||||
{
|
{
|
||||||
virtual void add_options (struct option_parser_t *parser) = 0;
|
virtual void add_options (struct option_parser_t *parser) = 0;
|
||||||
|
|
|
@ -40,8 +40,7 @@ struct view_cairo_t
|
||||||
direction (HB_DIRECTION_INVALID),
|
direction (HB_DIRECTION_INVALID),
|
||||||
lines (0), scale_bits (0) {}
|
lines (0), scale_bits (0) {}
|
||||||
~view_cairo_t (void) {
|
~view_cairo_t (void) {
|
||||||
if (debug)
|
cairo_debug_reset_static_data ();
|
||||||
cairo_debug_reset_static_data ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init (hb_buffer_t *buffer, const font_options_t *font_opts)
|
void init (hb_buffer_t *buffer, const font_options_t *font_opts)
|
||||||
|
|
Loading…
Reference in New Issue