- Language to/from script.
-- blob_from_file?
-
- Add hb-cairo glue
- Add sanitize API (and a cached version, that saves result on blob user-data)
<SECTION>
<FILE>hb-blob</FILE>
hb_blob_create
+hb_blob_create_from_file
hb_blob_create_sub_blob
hb_blob_copy_writable_or_fail
hb_blob_destroy
exit (1);
}
- hb_blob_t *blob = nullptr;
- {
- 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_blob_t *blob = hb_blob_create_from_file (argv[1]);
hb_face_t *face = hb_face_create (blob, 0);
hb_font_t *font = hb_font_create (face);
};
int main (int argc, char** argv) {
- FILE *f = fopen (argv[1], "rb");
- 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);
-
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
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);
const LE_IMAGE_DOS_HEADER* dos_header =
OT::Sanitizer<LE_IMAGE_DOS_HEADER>::lock_instance (font_blob);
-
const NE_RESOURCE_TABLE &rtable = dos_header->get_os2_header ().get_resource_table ();
int shift = rtable.get_shift_value ();
const NE_TYPEINFO& entry = rtable.get_fonts_entry ();
#include <stdio.h>
#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
struct hb_blob_t {
* @destroy: callback to call when @data is not needed anymore.
* @replace: whether to replace an existing data with the same key.
*
- * Return value:
+ * Return value:
*
* Since: 0.9.2
**/
* @blob: a blob.
* @key: key for data to get.
*
- *
*
- * Return value: (transfer none):
+ *
+ * Return value: (transfer none):
*
* Since: 0.9.2
**/
* hb_blob_make_immutable:
* @blob: a blob.
*
- *
+ *
*
* Since: 0.9.2
**/
* hb_blob_is_immutable:
* @blob: a blob.
*
- *
+ *
*
* Return value: TODO
*
* hb_blob_get_length:
* @blob: a blob.
*
- *
+ *
*
* Return value: the length of blob data in bytes.
*
* @blob: a blob.
* @length: (out):
*
- *
*
- * Returns: (transfer none) (array length=length):
+ *
+ * Returns: (transfer none) (array length=length):
*
* Since: 0.9.2
**/
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 ();
+}
HB_EXTERN char *
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
exit (1);
}
- const char *font_data = nullptr;
- int len = 0;
- hb_destroy_func_t destroy;
- 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
-
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+ unsigned int len;
+ const char *font_data = hb_blob_get_data (blob, &len);
printf ("Opened font file %s: %d bytes long\n", argv[1], len);
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);
const OpenTypeFontFile* sanitized = Sanitizer<OpenTypeFontFile>::lock_instance (font_blob);
if (sanitized == &Null (OpenTypeFontFile))
#include "hb-ft.h"
#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>
int
main (int argc, char **argv)
{
- hb_blob_t *blob = nullptr;
-
if (argc != 2) {
fprintf (stderr, "usage: %s font-file\n", argv[0]);
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);
- }
-
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
hb_blob_destroy (blob);
blob = nullptr;
#include "hb.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>
int
main (int argc, char **argv)
{
- hb_blob_t *blob = nullptr;
-
if (argc != 2) {
fprintf (stderr, "usage: %s font-file\n", argv[0]);
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 */
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
hb_blob_destroy (blob);
blob = nullptr;
#include "hb.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>
#ifdef HAVE_FREETYPE
int
main (int argc, char **argv)
{
- hb_blob_t *blob = nullptr;
-
if (argc != 4 && argc != 5) {
fprintf (stderr, "usage: %s font-file lookup-index first-glyph [second-glyph]\n", argv[0]);
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 */
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
hb_face_t *face = hb_face_create (blob, 0 /* first face */);
hb_blob_destroy (blob);
blob = nullptr;
#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>
#ifdef HAVE_FREETYPE
int
main (int argc, char **argv)
{
- hb_blob_t *blob = nullptr;
-
if (argc != 2) {
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
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);
- }
-
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob));
/* Create the face */
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 *
hb_subset_test_open_font (const char *font_path)
{
#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
- gchar* path = g_strdup(font_path);
+ char* path = g_strdup(font_path);
#endif
- size_t length;
- 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! */
+ return hb_face_create (hb_blob_create_from_file (path), 0);
}
static inline hb_subset_input_t *
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 */
static inline void
}
-hb_bool_t debug = false;
-
static gchar *
shapers_to_string (void)
{
{
{"version", 0, G_OPTION_FLAG_NO_ARG,
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}
};
g_option_context_add_main_entries (context, entries, nullptr);
hb_blob_t *blob = nullptr;
/* Create the blob */
- {
- char *font_data;
- 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 (!font_file)
- fail (true, "No font file set");
-
- if (0 == strcmp (font_file, "-")) {
- /* read it */
- GString *gs = g_string_new (nullptr);
- char buf[BUFSIZ];
+ if (!font_file)
+ fail (true, "No font file set");
+
+ if (0 == strcmp (font_file, "-")) {
+ /* read it */
+ GString *gs = g_string_new (nullptr);
+ char buf[BUFSIZ];
#if defined(_WIN32) || defined(__CYGWIN__)
- setmode (fileno (stdin), O_BINARY);
+ setmode (fileno (stdin), O_BINARY);
#endif
- while (!feof (stdin)) {
- size_t ret = fread (buf, 1, sizeof (buf), stdin);
- if (ferror (stdin))
- fail (false, "Failed reading font from standard input: %s",
- strerror (errno));
- 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);
- }
- }
+ while (!feof (stdin)) {
+ size_t ret = fread (buf, 1, sizeof (buf), stdin);
+ if (ferror (stdin))
+ fail (false, "Failed reading font from standard input: %s",
+ strerror (errno));
+ g_string_append_len (gs, buf, ret);
}
-
- if (debug)
- mm = HB_MEMORY_MODE_DUPLICATE;
-
- blob = hb_blob_create (font_data, len, mm, user_data, destroy);
+ char *font_data = g_string_free (gs, false);
+ blob = hb_blob_create (font_data, gs->len,
+ HB_MEMORY_MODE_WRITABLE, font_data,
+ (hb_destroy_func_t) g_free);
+ } else {
+ blob = hb_blob_create_from_file (font_file);
}
/* Create the face */
#include <glib.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);
-extern hb_bool_t debug;
-
struct option_group_t
{
virtual void add_options (struct option_parser_t *parser) = 0;
direction (HB_DIRECTION_INVALID),
lines (0), scale_bits (0) {}
~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)