src/Makefile.am | 1 src/hb-open-type-private.hh | 20 +++ src/hb-ot-cmap-table.hh | 223 ++++++++++++++++++++++++++++++++++++++++++++ src/hb-ot-font.cc | 1 4 files changed, 242 insertions(+), 3 deletions(-)
New commits: commit c8a47452993b9dee6854bfc866aca4a20142696f Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri May 9 19:55:51 2014 -0400 [ot] Implement cmap subtable format 4 diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index ba2835b..e02c234 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -47,7 +47,59 @@ struct CmapSubtableFormat4 private: inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { + unsigned int segCount; + const USHORT *endCount; + const USHORT *startCount; + const USHORT *idDelta; + const USHORT *idRangeOffset; + const USHORT *glyphIdArray; + unsigned int glyphIdArrayLength; + + segCount = this->segCountX2 / 2; + endCount = this->values; + startCount = endCount + segCount + 1; + idDelta = startCount + segCount; + idRangeOffset = idDelta + segCount; + glyphIdArray = idRangeOffset + segCount; + glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; + + /* Custom bsearch. */ + int min = 0, max = (int) segCount - 1; + unsigned int i; + while (min <= max) + { + int mid = (min + max) / 2; + if (codepoint < startCount[mid]) + max = mid - 1; + else if (codepoint > endCount[mid]) + min = mid + 1; + else + { + i = mid; + goto found; + } + } return false; + + found: + hb_codepoint_t gid; + unsigned int rangeOffset = idRangeOffset[i]; + if (rangeOffset == 0) + gid = codepoint + idDelta[i]; + else + { + /* Somebody has been smoking... */ + unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount; + if (unlikely (index >= glyphIdArrayLength)) + return false; + gid = glyphIdArray[index]; + if (unlikely (!gid)) + return false; + gid += idDelta[i]; + } + + *glyph = gid & 0xFFFF; + return true; } inline bool sanitize (hb_sanitize_context_t *c) { commit 4719621f20dfd6a0377c650a7b4df223c18dc143 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri May 9 16:09:11 2014 -0400 Minor diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 40402fb..d9be744 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -840,7 +840,6 @@ struct GenericArrayOf template <typename SearchType> inline int search (const SearchType &x) const { - /* Hand-coded bsearch here since this is in the hot inner loop. */ unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (!this->array[i].cmp (x)) commit 41ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri May 9 15:35:56 2014 -0400 [ot] Start implementing cmap table diff --git a/src/Makefile.am b/src/Makefile.am index e2dd944..f670e27 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,6 +35,7 @@ HBSOURCES = \ hb-object-private.hh \ hb-open-file-private.hh \ hb-open-type-private.hh \ + hb-ot-cmap-table.hh \ hb-ot-head-table.hh \ hb-ot-hhea-table.hh \ hb-ot-hmtx-table.hh \ diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh new file mode 100644 index 0000000..ba2835b --- /dev/null +++ b/src/hb-ot-cmap-table.hh @@ -0,0 +1,171 @@ +/* + * Copyright © 2014 Google, Inc. + * + * 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): Behdad Esfahbod + */ + +#ifndef HB_OT_CMAP_TABLE_HH +#define HB_OT_CMAP_TABLE_HH + +#include "hb-open-type-private.hh" + + +namespace OT { + + +/* + * cmap -- Character To Glyph Index Mapping Table + */ + +#define HB_OT_TAG_cmap HB_TAG('c','m','a','p') + + +struct CmapSubtableFormat4 +{ + friend struct CmapSubtable; + + private: + inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + { + return false; + } + + inline bool sanitize (hb_sanitize_context_t *c) { + TRACE_SANITIZE (this); + return TRACE_RETURN (c->check_struct (this) && + c->check_range (this, length) && + 16 + 4 * (unsigned int) segCountX2 < length); + } + + protected: + USHORT format; /* Format number is set to 4. */ + USHORT length; /* This is the length in bytes of the + * subtable. */ + USHORT language; /* Ignore. */ + USHORT segCountX2; /* 2 x segCount. */ + USHORT searchRange; /* 2 * (2**floor(log2(segCount))) */ + USHORT entrySelector; /* log2(searchRange/2) */ + USHORT rangeShift; /* 2 x segCount - searchRange */ + + USHORT values[VAR]; +#if 0 + USHORT endCount[segCount]; /* End characterCode for each segment, + * last=0xFFFF. */ + USHORT reservedPad; /* Set to 0. */ + USHORT startCount[segCount]; /* Start character code for each segment. */ + SHORT idDelta[segCount]; /* Delta for all character codes in segment. */ + USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ + USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ +#endif + + public: + DEFINE_SIZE_ARRAY (14, values); +}; + +struct CmapSubtable +{ + inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + { + switch (u.format) { + case 4: return u.format4.get_glyph(codepoint, glyph); + default:return false; + } + } + + inline bool sanitize (hb_sanitize_context_t *c) { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return TRACE_RETURN (false); + switch (u.format) { + case 4: return TRACE_RETURN (u.format4.sanitize (c)); + default:return TRACE_RETURN (true); + } + } + + protected: + union { + USHORT format; /* Format identifier */ + CmapSubtableFormat4 format4; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + + +struct EncodingRecord +{ + int cmp (const EncodingRecord &other) const + { + int ret; + ret = other.platformID.cmp (platformID); + if (ret) return ret; + ret = other.encodingID.cmp (encodingID); + if (ret) return ret; + return 0; + } + + inline bool sanitize (hb_sanitize_context_t *c, void *base) { + TRACE_SANITIZE (this); + return TRACE_RETURN (c->check_struct (this) && + subtable.sanitize (c, base)); + } + + USHORT platformID; /* Platform ID. */ + USHORT encodingID; /* Platform-specific encoding ID. */ + LongOffsetTo<CmapSubtable> + subtable; /* Byte offset from beginning of table to the subtable for this encoding. */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct cmap +{ + static const hb_tag_t tableTag = HB_OT_TAG_cmap; + + inline unsigned int find_subtable (unsigned int platform_id, + unsigned int encoding_id) const + { + EncodingRecord key; + key.platformID.set (platform_id); + key.encodingID.set (encoding_id); + + return encodingRecord.search (key); + } + + inline bool sanitize (hb_sanitize_context_t *c) { + TRACE_SANITIZE (this); + return TRACE_RETURN (c->check_struct (this) && + likely (version == 0) && + encodingRecord.sanitize (c, this)); + } + + USHORT version; /* Table version number (0). */ + ArrayOf<EncodingRecord> encodingRecord; /* Encoding tables. */ + public: + DEFINE_SIZE_ARRAY (4, encodingRecord); +}; + + +} /* namespace OT */ + + +#endif /* HB_OT_CMAP_TABLE_HH */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 1a35057..d2f02a2 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -30,6 +30,7 @@ #include "hb-font-private.hh" +#include "hb-ot-cmap-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" commit c7074b8798048324cb8850c55908ce77fc33d11e Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu May 8 18:24:31 2014 -0400 [otlayout] Add GenericArrayOf::search() diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 79ac719..40402fb 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -837,6 +837,17 @@ struct GenericArrayOf return TRACE_RETURN (true); } + template <typename SearchType> + inline int search (const SearchType &x) const + { + /* Hand-coded bsearch here since this is in the hot inner loop. */ + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + if (!this->array[i].cmp (x)) + return i; + return -1; + } + private: inline bool sanitize_shallow (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); commit 40a479797add42fa42b78d4267920ef75bfb6b9a Author: Behdad Esfahbod <beh...@behdad.org> Date: Thu May 8 18:21:04 2014 -0400 [otlayout] Add GenericSortedArrayOf diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 5a01a81..79ac719 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -949,9 +949,9 @@ struct HeadlessArrayOf /* An array with sorted elements. Supports binary searching. */ -template <typename Type> -struct SortedArrayOf : ArrayOf<Type> { - +template <typename LenType, typename Type> +struct GenericSortedArrayOf : GenericArrayOf<LenType, Type> +{ template <typename SearchType> inline int search (const SearchType &x) const { @@ -972,6 +972,10 @@ struct SortedArrayOf : ArrayOf<Type> { } }; +/* A sorted array with a USHORT number of elements. */ +template <typename Type> +struct SortedArrayOf : GenericSortedArrayOf<USHORT, Type> {}; + } /* namespace OT */
_______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz