From 9ccb8366f603a9e4a7a3c3f96420a19d4f6fb390 Mon Sep 17 00:00:00 2001 From: Rod Sheeter Date: Wed, 17 Jan 2018 22:09:07 -0800 Subject: [PATCH] Start to sketch APIs for subsetting --- src/Makefile.am | 2 + src/Makefile.sources | 4 ++ src/hb-subset.cc | 0 src/hb-subset.h | 88 +++++++++++++++++++++++++++++++++++++++++++ util/Makefile.am | 3 ++ util/Makefile.sources | 4 ++ util/hb-subset.cc | 61 ++++++++++++++++++++++++++++++ 7 files changed, 162 insertions(+) create mode 100644 src/hb-subset.cc create mode 100644 src/hb-subset.h create mode 100644 util/hb-subset.cc diff --git a/src/Makefile.am b/src/Makefile.am index 833d1f956..dd1c7ae66 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,9 @@ HBNONPCLIBS = HBDEPS = HBSOURCES = $(HB_BASE_sources) HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources) +HBSOURCES += $(HB_SUBSET_sources) HBHEADERS = $(HB_BASE_headers) +HBHEADERS += $(HB_SUBSET_headers) HBNODISTHEADERS = $(HB_NODIST_headers) if HAVE_OT diff --git a/src/Makefile.sources b/src/Makefile.sources index 213aa22f6..f223fcfee 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -181,6 +181,10 @@ HB_UCDN_sources = hb-ucdn.cc HB_ICU_sources = hb-icu.cc HB_ICU_headers = hb-icu.h +# Sources for libharfbuzz-subset +HB_SUBSET_sources = hb-subset.cc +HB_SUBSET_headers = hb-subset.h + HB_GOBJECT_sources = hb-gobject-structs.cc HB_GOBJECT_STRUCTS_headers = hb-gobject-structs.h HB_GOBJECT_headers = hb-gobject.h $(HB_GOBJECT_STRUCTS_headers) diff --git a/src/hb-subset.cc b/src/hb-subset.cc new file mode 100644 index 000000000..e69de29bb diff --git a/src/hb-subset.h b/src/hb-subset.h new file mode 100644 index 000000000..8aaccd6e5 --- /dev/null +++ b/src/hb-subset.h @@ -0,0 +1,88 @@ +/* + * Copyright © 2018 Google + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Rod Sheeter + */ + +#ifndef HB_H_IN +#error "Include instead." +#endif + +#ifndef HB_SUBSET_H +#define HB_SUBSET_H + +#include "hb-common.h" +#include "hb-face.h" + +HB_BEGIN_DECLS + +/* + * hb_subset_profile_t + * Things that change based on target environment, e.g. OS + */ + +typedef struct hb_subset_profile_t hb_subset_profile_t; + +HB_EXTERN hb_subset_profile_t * +hb_subset_profile_create(); + +HB_EXTERN void +hb_subset_profile_destroy(hb_subset_profile_t *profile); + +/* + * hb_subset_input_t + * Things that change based on the input. Characters to keep, etc. + */ + +typedef struct hb_subset_input_t hb_subset_input_t; + +HB_EXTERN hb_subset_input_t * +hb_subset_input_create(); + +HB_EXTERN void +hb_subset_input_destroy(hb_subset_input_t *subset_input); + +/* + * hb_subset_face_t + * Reusable subset-ready plan for a given face. Threadsafe for multiple + * concurrent subset operations. + */ + +typedef struct hb_subset_face_t hb_subset_face_t; + +HB_EXTERN hb_subset_face_t * +hb_subset_face_create(hb_face_t *face); + +HB_EXTERN void +hb_subset_face_destroy(hb_subset_face_t *face); + + +HB_EXTERN hb_bool_t +hb_subset(hb_subset_profile_t *profile, + hb_subset_input_t *input, + hb_subset_face_t *face + hb_blob_t *result /* OUT */); + +HB_END_DECLS + +#endif /* HB_SUBSET_H */ diff --git a/util/Makefile.am b/util/Makefile.am index e6620a237..283dd91ff 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -46,6 +46,9 @@ endif # HAVE_FREETYPE hb_shape_SOURCES = $(HB_SHAPE_sources) bin_PROGRAMS += hb-shape +hb_subset_SOURCES = $(HB_SUBSET_sources) +bin_PROGRAMS += hb-subset + if HAVE_OT hb_ot_shape_closure_SOURCES = $(HB_OT_SHAPE_CLOSURE_sources) bin_PROGRAMS += hb-ot-shape-closure diff --git a/util/Makefile.sources b/util/Makefile.sources index d6c00cc4d..94a5fa8a2 100644 --- a/util/Makefile.sources +++ b/util/Makefile.sources @@ -28,3 +28,7 @@ HB_OT_SHAPE_CLOSURE_sources = \ options.hh \ main-font-text.hh \ $(NULL) + +HB_SUBSET_sources = \ + hb-subset.cc \ + $(NULL) diff --git a/util/hb-subset.cc b/util/hb-subset.cc new file mode 100644 index 000000000..ad7ceb14b --- /dev/null +++ b/util/hb-subset.cc @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "hb-private.hh" +#include "hb-blob.h" + +int +main (int argc, char **argv) +{ + int exit_code = 0; + int fd = open("/tmp/Lobster-Regular.ttf", O_RDONLY); + if (fd == -1) { + perror("Unable to open file"); + exit(1); + } + + void *mapped_file = MAP_FAILED; + char *raw_font = nullptr; + + struct stat stat; + if (fstat(fd, &stat) != -1) { + printf("File is %zu bytes\n", stat.st_size); + + void *mapped_file = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (mapped_file != MAP_FAILED) { + raw_font = static_cast(mapped_file); + } else { + perror("Failed to map file"); + } + } else { + perror("Unable to fstat"); + } + + if (raw_font) { + printf("Mapped file\n"); + for (int i = 0; i < 4; i++) { + printf("%02x", *(raw_font + i)); + } + printf("\n"); + + hb_blob_t *font_blob = hb_blob_create(raw_font, stat.st_size, HB_MEMORY_MODE_READONLY, nullptr, nullptr); + } + + if (mapped_file != MAP_FAILED) { + if (munmap(mapped_file, stat.st_size) == -1) { + perror("Unable to unmap file"); + exit_code = 1; + } + } + + if (close(fd) == -1) { + perror("Unable to close file"); + exit_code = 1; + } + return exit_code; +}