From fd92a3dde32fd10df30c9eeb97641bc3c15b1e9b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2008 03:11:09 -0500 Subject: [PATCH] Starting public interface --- src/{Makefile => Makefile.ng} | 0 src/hb-ot-layout-gdef-private.h | 17 +++--- src/hb-ot-layout-gsub-private.h | 3 +- src/hb-ot-layout-open-private.h | 96 +++++++++++++++++++++++---------- src/hb-ot-layout-private.h | 51 ++++++++++++++++++ src/hb-ot-layout.cc | 67 +++++++++++++++++++++++ src/hb-ot-layout.h | 35 ++++++++++-- src/main.cc | 1 + 8 files changed, 227 insertions(+), 43 deletions(-) rename src/{Makefile => Makefile.ng} (100%) create mode 100644 src/hb-ot-layout-private.h create mode 100644 src/hb-ot-layout.cc diff --git a/src/Makefile b/src/Makefile.ng similarity index 100% rename from src/Makefile rename to src/Makefile.ng diff --git a/src/hb-ot-layout-gdef-private.h b/src/hb-ot-layout-gdef-private.h index 6442221c1..39d2d8751 100644 --- a/src/hb-ot-layout-gdef-private.h +++ b/src/hb-ot-layout-gdef-private.h @@ -27,16 +27,15 @@ #ifndef HB_OT_LAYOUT_GDEF_PRIVATE_H #define HB_OT_LAYOUT_GDEF_PRIVATE_H -#include "hb-private.h" -#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" #include "hb-ot-layout-open-private.h" #define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \ - inline const Type& name (uint16_t glyph_id) { \ + inline const Type& name (hb_ot_layout_glyph_t glyph_id) { \ const Coverage &c = get_coverage (); \ - int c_index = c.get_coverage (glyph_id); \ + hb_ot_layout_coverage_t c_index = c.get_coverage (glyph_id); \ return (*this)[c_index]; \ } @@ -73,7 +72,7 @@ struct AttachList { friend struct GDEF; private: - /* const AttachPoint& get_attach_points (uint16_t glyph_id); */ + /* const AttachPoint& get_attach_points (hb_ot_layout_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points); private: @@ -206,7 +205,7 @@ struct LigCaretList { friend struct GDEF; private: - /* const LigGlyph& get_lig_glyph (uint16_t glyph_id); */ + /* const LigGlyph& get_lig_glyph (hb_ot_layout_glyph_t glyph_id); */ DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph); private: @@ -241,17 +240,15 @@ struct GDEF { DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef); /* Returns 0 if not found. */ - inline int get_glyph_class (uint16_t glyph_id) const { + inline int get_glyph_class (hb_ot_layout_glyph_t glyph_id) const { return get_glyph_class_def ().get_class (glyph_id); } /* Returns 0 if not found. */ - inline int get_mark_attachment_type (uint16_t glyph_id) const { + inline int get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const { return get_mark_attach_class_def ().get_class (glyph_id); } - /* TODO get_glyph_property */ - /* TODO get_attach and get_lig_caret */ private: diff --git a/src/hb-ot-layout-gsub-private.h b/src/hb-ot-layout-gsub-private.h index 46b538e0d..8ce77054f 100644 --- a/src/hb-ot-layout-gsub-private.h +++ b/src/hb-ot-layout-gsub-private.h @@ -27,8 +27,7 @@ #ifndef HB_OT_LAYOUT_GSUB_PRIVATE_H #define HB_OT_LAYOUT_GSUB_PRIVATE_H -#include "hb-private.h" -#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" #include "hb-ot-layout-open-private.h" #include "hb-ot-layout-gdef-private.h" diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 04054df61..a095c640a 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -27,8 +27,7 @@ #ifndef HB_OT_LAYOUT_OPEN_PRIVATE_H #define HB_OT_LAYOUT_OPEN_PRIVATE_H -#include "hb-private.h" -#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" /* @@ -89,6 +88,9 @@ return *(const Type *)((const char*)this + array[i]); \ } +/* A record array type is like an array type, but it contains a table + * of records to the objects. Each record has a tag, and an offset + * relative to the beginning of the current object. */ #define DEFINE_RECORD_ARRAY_TYPE(Type, array, num) \ DEFINE_RECORD_ACCESSOR(Type, array, num) \ DEFINE_LEN_AND_SIZE(Record, array, num) @@ -104,6 +106,37 @@ } \ /* TODO: implement find_tag() */ + +#define DEFINE_ARRAY_INTERFACE(Type, name) \ + inline const Type& get_##name (unsigned int i) const { \ + return (*this)[i]; \ + } \ + inline unsigned int get_##name##_count (void) const { \ + return this->get_len (); \ + } +#define DEFINE_INDEX_ARRAY_INTERFACE(name) \ + inline unsigned int get_##name##_index (unsigned int i) const { \ + return (*this)[i]; \ + } \ + inline unsigned int get_##name##_count (void) const { \ + return this->get_len (); \ + } + +#define DEFINE_FIND_TAG_INTERFACE(Type, name) \ + inline const Type* find_##name (hb_tag_t tag) const { \ + for (unsigned int i = 0; i < this->get_len (); i++) \ + if (tag == (*this)[i].tag) \ + return &(*this)[i]; \ + return NULL; \ + } \ + inline const Type& get_##name_by_tag (hb_tag_t tag) const { \ + for (unsigned int i = 0; i < this->get_len (); i++) \ + if (tag == (*this)[i].tag) \ + return (*this)[i]; \ + return Null##Type; \ + } + + /* * List types */ @@ -144,13 +177,15 @@ /* get_for_data() is a static class method returning a reference to an * instance of Type located at the input data location. It's just a * fancy cast! */ -#define STATIC_DEFINE_GET_FOR_DATA0(const, Type) \ - static inline const Type& get_for_data (const char *data) { \ - return *(const Type*)data; \ - } #define STATIC_DEFINE_GET_FOR_DATA(Type) \ - STATIC_DEFINE_GET_FOR_DATA0(const, Type) \ - STATIC_DEFINE_GET_FOR_DATA0( , Type) + static inline const Type& get_for_data (const char *data) { \ + extern const Type &Null##Type; \ + if (HB_UNLIKELY (data == NULL)) return Null##Type; \ + return *(const Type*)data; \ + } \ + static inline Type& get_for_data (char *data) { \ + return *(Type*)data; \ + } #define DEFINE_ACCESSOR(Type, name, Name) \ @@ -297,8 +332,9 @@ struct TTCHeader; typedef struct TableDirectory { - friend struct OpenTypeFontFile; + friend struct OffsetTable; + inline bool is_null (void) const { return length == 0; } inline const Tag& get_tag (void) const { return tag; } inline unsigned long get_checksum (void) const { return checkSum; } inline unsigned long get_offset (void) const { return offset; } @@ -312,17 +348,19 @@ typedef struct TableDirectory { ULONG length; /* Length of this table. */ } OpenTypeTable; DEFINE_NULL_ASSERT_SIZE (TableDirectory, 16); +DEFINE_NULL_ALIAS (OpenTypeTable, TableDirectory); typedef struct OffsetTable { friend struct OpenTypeFontFile; friend struct TTCHeader; - // XXX private: - // Add get_num_tables and get_table... + DEFINE_ARRAY_INTERFACE (OpenTypeTable, table); + DEFINE_FIND_TAG_INTERFACE (OpenTypeTable, table); + + private: /* OpenTypeTables, in no particular order */ DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables); - // TODO: Implement find_table private: Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ @@ -427,9 +465,9 @@ typedef struct Record { DEFINE_NULL_ASSERT_SIZE (Record, 6); struct LangSys { - /* Feature indices, in no particular order */ - DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); - + + DEFINE_INDEX_ARRAY_INTERFACE (feature); + /* Returns -1 if none */ inline int get_required_feature_index (void) const { if (reqFeatureIndex == 0xffff) @@ -437,7 +475,9 @@ struct LangSys { return reqFeatureIndex;; } - /* TODO implement find_feature */ + private: + /* Feature indices, in no particular order */ + DEFINE_ARRAY_TYPE (USHORT, featureIndex, featureCount); private: Offset lookupOrder; /* = Null (reserved for an offset to a @@ -490,6 +530,10 @@ private: DEFINE_NULL_ASSERT_SIZE (ScriptList, 2); struct Feature { + + DEFINE_INDEX_ARRAY_INTERFACE (lookup); + + private: /* LookupList indices, in no particular order */ DEFINE_ARRAY_TYPE (USHORT, lookupIndex, lookupCount); @@ -583,7 +627,7 @@ struct CoverageFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount); - inline int get_coverage (uint16_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { GlyphID gid; gid = glyph_id; // TODO: bsearch @@ -605,7 +649,7 @@ struct CoverageRangeRecord { friend struct CoverageFormat2; private: - inline int get_coverage (uint16_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return startCoverageIndex + (glyph_id - start); return -1; @@ -627,7 +671,7 @@ struct CoverageFormat2 { /* CoverageRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount); - inline int get_coverage (uint16_t glyph_id) const { + inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { // TODO: bsearch for (unsigned int i = 0; i < rangeCount; i++) { int coverage = rangeRecord[i].get_coverage (glyph_id); @@ -657,8 +701,7 @@ struct Coverage { } } - /* Returns -1 if not covered. */ - int get_coverage (uint16_t glyph_id) const { + hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const { switch (u.coverageFormat) { case 1: return u.format1.get_coverage(glyph_id); case 2: return u.format2.get_coverage(glyph_id); @@ -687,7 +730,7 @@ struct ClassDefFormat1 { /* GlyphIDs, in sorted numerical order */ DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount); - inline int get_class (uint16_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { if (glyph_id >= startGlyph && glyph_id < startGlyph + glyphCount) return classValueArray[glyph_id - startGlyph]; return 0; @@ -706,7 +749,7 @@ struct ClassRangeRecord { friend struct ClassDefFormat2; private: - inline int get_class (uint16_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { if (glyph_id >= start && glyph_id <= end) return classValue; return 0; @@ -727,7 +770,7 @@ struct ClassDefFormat2 { /* ClassRangeRecords, in sorted numerical start order */ DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount); - inline int get_class (uint16_t glyph_id) const { + inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { // TODO: bsearch for (int i = 0; i < rangeCount; i++) { int classValue = rangeRecord[i].get_class (glyph_id); @@ -756,8 +799,7 @@ struct ClassDef { } } - /* Returns 0 if not found. */ - int get_class (uint16_t glyph_id) const { + hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const { switch (u.classFormat) { case 1: return u.format1.get_class(glyph_id); case 2: return u.format2.get_class(glyph_id); @@ -835,8 +877,6 @@ typedef struct GSUBGPOS { DEFINE_LIST_ACCESSOR(Feature, feature);/* get_feature_list, get_feature(i) */ DEFINE_LIST_ACCESSOR(Lookup, lookup); /* get_lookup_list, get_lookup(i) */ - /* TODO implement find_script */ - private: Fixed_Version version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000 */ diff --git a/src/hb-ot-layout-private.h b/src/hb-ot-layout-private.h new file mode 100644 index 000000000..c364b2198 --- /dev/null +++ b/src/hb-ot-layout-private.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine 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. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_LAYOUT_PRIVATE_H +#define HB_OT_LAYOUT_PRIVATE_H + +#ifndef HB_OT_LAYOUT_CC +#error "This file should only be included from hb-ot-layout.c" +#endif + +#include "hb-private.h" +#include "hb-ot-layout.h" + +struct GDEF; +struct GSUB; +struct GPOS; + +HB_BEGIN_DECLS(); + +struct _HB_OT_Layout { + GDEF *gdef; + GSUB *gsub; + GPOS *gpos; +}; + +HB_END_DECLS(); + +#endif /* HB_OT_LAYOUT_PRIVATE_H */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc new file mode 100644 index 000000000..ca3b951ac --- /dev/null +++ b/src/hb-ot-layout.cc @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007,2008 Red Hat, Inc. + * + * This is part of HarfBuzz, an OpenType Layout engine 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. + * + * Red Hat Author(s): Behdad Esfahbod + */ + +#define HB_OT_LAYOUT_CC + +#include "hb-ot-layout.h" +#include "hb-ot-layout-private.h" + +#include "hb-ot-layout-open-private.h" +#include "hb-ot-layout-gdef-private.h" +#include "hb-ot-layout-gsub-private.h" + +#include + +HB_OT_Layout * +hb_ot_layout_create (const char *font_data, + int face_index) +{ + HB_OT_Layout *layout = (HB_OT_Layout *) calloc (1, sizeof (HB_OT_Layout)); + + const OpenTypeFontFile &ot = OpenTypeFontFile::get_for_data (font_data); + const OpenTypeFontFace &font = ot[face_index]; + + layout->gdef = font.find_table (GDEF::Tag); + layout->gsub = font.find_table (GSUB::Tag); + layout->gpos = font.find_table (GPOS::Tag); + + return layout; +} + +void +hb_ot_layout_destroy (HB_OT_Layout *layout) +{ + free (layout); +} + +hb_ot_layout_glyph_properties_t +hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph); + +void +hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph, + hb_ot_layout_glyph_properties_t properties); diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 554be08a5..786e4acff 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -24,8 +24,8 @@ * Red Hat Author(s): Behdad Esfahbod */ -#ifndef HB_OT_LAYOUT_OPEN_H -#define HB_OT_LAYOUT_OPEN_H +#ifndef HB_OT_LAYOUT_H +#define HB_OT_LAYOUT_H #include "hb-common.h" @@ -38,6 +38,35 @@ typedef uint32_t hb_tag_t; ((const char *) s)[2], \ ((const char *) s)[3])) +typedef uint16_t hb_ot_layout_glyph_properties_t; +typedef uint16_t hb_ot_layout_glyph_t; +typedef uint16_t hb_ot_layout_class_t; +typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */ + +typedef struct _HB_OT_Layout HB_OT_Layout; + +HB_OT_Layout * +hb_ot_layout_create (const char *font_data, + int face_index); + +void +hb_ot_layout_destroy (HB_OT_Layout *layout); + +/* TODO +HB_OT_Layout * +hb_ot_layout_create_sanitize (char *data, + make_writable_func); +*/ + +hb_ot_layout_glyph_properties_t +hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph); + +void +hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout, + hb_ot_layout_glyph_t glyph, + hb_ot_layout_glyph_properties_t properties); + HB_END_DECLS(); -#endif /* HB_OT_LAYOUT_OPEN_H */ +#endif /* HB_OT_LAYOUT_H */ diff --git a/src/main.cc b/src/main.cc index edb805a1d..41a70c739 100644 --- a/src/main.cc +++ b/src/main.cc @@ -24,6 +24,7 @@ * Red Hat Author(s): Behdad Esfahbod */ +#define HB_OT_LAYOUT_CC #include "hb-ot-layout-open-private.h" #include "hb-ot-layout-gdef-private.h" #include "hb-ot-layout-gsub-private.h"