Merge branch 'var-subset' of https://github.com/harfbuzz/harfbuzz into var-subset
This commit is contained in:
commit
07f27accb9
|
@ -43,6 +43,7 @@ if (APPLE)
|
|||
endif ()
|
||||
if (WIN32)
|
||||
option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
|
||||
option(HB_HAVE_GDI "Enable GDI integration helpers on Windows" OFF)
|
||||
option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
|
||||
endif ()
|
||||
option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
|
||||
|
@ -77,6 +78,7 @@ if (HB_CHECK)
|
|||
set (HB_HAVE_GRAPHITE2 ON)
|
||||
if (WIN32)
|
||||
set (HB_HAVE_UNISCRIBE ON)
|
||||
set (HB_HAVE_GDI ON)
|
||||
set (HB_HAVE_DIRECTWRITE ON)
|
||||
elseif (APPLE)
|
||||
set (HB_HAVE_CORETEXT ON)
|
||||
|
@ -140,8 +142,8 @@ endif ()
|
|||
|
||||
## Extract variables from Makefile files
|
||||
function (extract_make_variable variable makefile_source)
|
||||
string(REGEX MATCH "${variable} = ([^$]+)\\$" temp ${makefile_source})
|
||||
string(REGEX MATCHALL "[^ \n\t\\]+" listVar ${CMAKE_MATCH_1})
|
||||
string(REGEX MATCH "${variable} = ([^$]+)\\$" temp "${makefile_source}")
|
||||
string(REGEX MATCHALL "[^ \n\t\\]+" listVar "${CMAKE_MATCH_1}")
|
||||
set (${variable} ${listVar} PARENT_SCOPE)
|
||||
endfunction ()
|
||||
|
||||
|
@ -305,6 +307,12 @@ if (APPLE AND HB_HAVE_CORETEXT)
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
if (WIN32 AND HB_HAVE_GDI)
|
||||
add_definitions(-DHAVE_GDI)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
|
||||
list(APPEND THIRD_PARTY_LIBS gdi32)
|
||||
endif ()
|
||||
|
||||
if (WIN32 AND HB_HAVE_UNISCRIBE)
|
||||
add_definitions(-DHAVE_UNISCRIBE)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
|
||||
|
|
|
@ -73,7 +73,7 @@ build_script:
|
|||
- 'if "%compiler%"=="msvc2" cmake --build build --config %configuration%'
|
||||
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://raw.githubusercontent.com/mirror/mingw-w64/023eb04c396d4e8d8fcf604cfababc53dae13398/mingw-w64-headers/include/dwrite_1.h > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make -j3 check || .ci/fail.sh"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --with-gdi --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make -j3 check || .ci/fail.sh"'
|
||||
|
||||
cache:
|
||||
- c:\tools\vcpkg\installed\
|
||||
|
|
23
configure.ac
23
configure.ac
|
@ -361,6 +361,28 @@ AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
|
|||
|
||||
dnl ===========================================================================
|
||||
|
||||
AC_ARG_WITH(gdi,
|
||||
[AS_HELP_STRING([--with-gdi=@<:@yes/no/auto@:>@],
|
||||
[Provide GDI integration helpers @<:@default=no@:>@])],,
|
||||
[with_gdi=no])
|
||||
have_gdi=false
|
||||
if test "x$with_gdi" = "xyes" -o "x$with_gdi" = "xauto"; then
|
||||
AC_CHECK_HEADERS(windows.h, have_gdi=true)
|
||||
fi
|
||||
if test "x$with_gdi" = "xyes" -a "x$have_gdi" != "xtrue"; then
|
||||
AC_MSG_ERROR([gdi support requested but not found])
|
||||
fi
|
||||
if $have_gdi; then
|
||||
GDI_CFLAGS=
|
||||
GDI_LIBS="-lgdi32"
|
||||
AC_SUBST(GDI_CFLAGS)
|
||||
AC_SUBST(GDI_LIBS)
|
||||
AC_DEFINE(HAVE_GDI, 1, [Have GDI library])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GDI, $have_gdi)
|
||||
|
||||
dnl ===========================================================================
|
||||
|
||||
AC_ARG_WITH(directwrite,
|
||||
[AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@],
|
||||
[Use the DirectWrite library (experimental) @<:@default=no@:>@])],,
|
||||
|
@ -510,6 +532,7 @@ Additional shapers (the more the merrier):
|
|||
Platform shapers (not normally needed):
|
||||
CoreText: ${have_coretext}
|
||||
DirectWrite: ${have_directwrite}
|
||||
GDI: ${have_gdi}
|
||||
Uniscribe: ${have_uniscribe}
|
||||
|
||||
Other features:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<SUBSECTION Private>
|
||||
HB_H_IN
|
||||
HB_OT_H_IN
|
||||
HB_AAT_H_IN
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -179,6 +180,7 @@ HB_BUFFER_SERIALIZE_FLAGS_DEFAULT
|
|||
HB_SCRIPT_CANADIAN_ABORIGINAL
|
||||
hb_font_funcs_set_glyph_func
|
||||
hb_font_get_glyph_func_t
|
||||
HB_MATH_GLYPH_PART_FLAG_EXTENDER
|
||||
hb_ot_layout_table_choose_script
|
||||
hb_ot_layout_table_find_script
|
||||
hb_ot_tag_from_language
|
||||
|
@ -367,6 +369,11 @@ hb_ft_font_get_load_flags
|
|||
hb_ft_font_set_funcs
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-gdi</FILE>
|
||||
hb_gdi_face_create
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-glib</FILE>
|
||||
hb_glib_get_unicode_funcs
|
||||
|
@ -600,6 +607,22 @@ hb_ot_math_get_min_connector_overlap
|
|||
hb_ot_math_get_glyph_assembly
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-meta</FILE>
|
||||
hb_ot_meta_t
|
||||
hb_ot_meta_get_entries
|
||||
hb_ot_meta_reference_entry
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-metrics</FILE>
|
||||
hb_ot_metrics_t
|
||||
hb_ot_metrics_get_position
|
||||
hb_ot_metrics_get_variation
|
||||
hb_ot_metrics_get_x_variation
|
||||
hb_ot_metrics_get_y_variation
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-shape</FILE>
|
||||
hb_ot_shape_glyphs_closure
|
||||
|
|
|
@ -82,6 +82,13 @@ HBSOURCES += $(HB_DIRECTWRITE_sources)
|
|||
HBHEADERS += $(HB_DIRECTWRITE_headers)
|
||||
endif
|
||||
|
||||
if HAVE_GDI
|
||||
HBCFLAGS += $(GDI_CXXFLAGS)
|
||||
HBNONPCLIBS += $(GDI_LIBS)
|
||||
HBSOURCES += $(HB_GDI_sources)
|
||||
HBHEADERS += $(HB_GDI_headers)
|
||||
endif
|
||||
|
||||
if HAVE_CORETEXT
|
||||
HBCFLAGS += $(CORETEXT_CFLAGS)
|
||||
HBNONPCLIBS += $(CORETEXT_LIBS)
|
||||
|
@ -313,6 +320,7 @@ harfbuzz.cc: Makefile.sources
|
|||
$(HB_FT_sources) \
|
||||
$(HB_GRAPHITE2_sources) \
|
||||
$(HB_UNISCRIBE_sources) \
|
||||
$(HB_GDI_sources) \
|
||||
$(HB_DIRECTWRITE_sources) \
|
||||
$(HB_CORETEXT_sources) \
|
||||
; do echo '#include "'$$f'"'; done | \
|
||||
|
@ -324,6 +332,7 @@ noinst_PROGRAMS = \
|
|||
main \
|
||||
test \
|
||||
test-buffer-serialize \
|
||||
test-ot-meta \
|
||||
test-ot-name \
|
||||
test-gpos-size-params \
|
||||
test-gsub-would-substitute \
|
||||
|
@ -342,6 +351,10 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc
|
|||
test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
|
||||
test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_ot_meta_SOURCES = test-ot-meta.cc
|
||||
test_ot_meta_CPPFLAGS = $(HBCFLAGS)
|
||||
test_ot_meta_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_ot_name_SOURCES = test-ot-name.cc
|
||||
test_ot_name_CPPFLAGS = $(HBCFLAGS)
|
||||
test_ot_name_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
|
|
@ -89,6 +89,10 @@ HB_BASE_sources = \
|
|||
hb-ot-math-table.hh \
|
||||
hb-ot-math.cc \
|
||||
hb-ot-maxp-table.hh \
|
||||
hb-ot-meta-table.hh \
|
||||
hb-ot-meta.cc \
|
||||
hb-ot-metrics.cc \
|
||||
hb-ot-metrics.hh \
|
||||
hb-ot-name-language-static.hh \
|
||||
hb-ot-name-language.hh \
|
||||
hb-ot-name-table.hh \
|
||||
|
@ -193,6 +197,8 @@ HB_BASE_headers = \
|
|||
hb-ot-font.h \
|
||||
hb-ot-layout.h \
|
||||
hb-ot-math.h \
|
||||
hb-ot-meta.h \
|
||||
hb-ot-metrics.h \
|
||||
hb-ot-name.h \
|
||||
hb-ot-shape.h \
|
||||
hb-ot-var.h \
|
||||
|
@ -224,6 +230,9 @@ HB_CORETEXT_headers = hb-coretext.h
|
|||
HB_DIRECTWRITE_sources = hb-directwrite.cc
|
||||
HB_DIRECTWRITE_headers = hb-directwrite.h
|
||||
|
||||
HB_GDI_sources = hb-gdi.cc
|
||||
HB_GDI_headers = hb-gdi.h
|
||||
|
||||
HB_UNISCRIBE_sources = hb-uniscribe.cc
|
||||
HB_UNISCRIBE_headers = hb-uniscribe.h
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "hb-ot-layout.cc"
|
||||
#include "hb-ot-map.cc"
|
||||
#include "hb-ot-math.cc"
|
||||
#include "hb-ot-meta.cc"
|
||||
#include "hb-ot-metrics.cc"
|
||||
#include "hb-ot-name.cc"
|
||||
#include "hb-ot-shape-complex-arabic.cc"
|
||||
#include "hb-ot-shape-complex-default.cc"
|
||||
|
@ -47,5 +49,6 @@
|
|||
#include "hb-ft.cc"
|
||||
#include "hb-graphite2.cc"
|
||||
#include "hb-uniscribe.cc"
|
||||
#include "hb-gdi.cc"
|
||||
#include "hb-directwrite.cc"
|
||||
#include "hb-coretext.cc"
|
||||
|
|
|
@ -174,9 +174,7 @@ struct feat
|
|||
}
|
||||
|
||||
const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const
|
||||
{
|
||||
return namesZ.bsearch (featureNameCount, feature_type);
|
||||
}
|
||||
{ return namesZ.bsearch (featureNameCount, feature_type); }
|
||||
|
||||
hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const
|
||||
{ return get_feature (feature).get_feature_name_id (); }
|
||||
|
|
|
@ -85,7 +85,7 @@ typedef enum
|
|||
HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39,
|
||||
HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103,
|
||||
|
||||
_HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
|
||||
_HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
} hb_aat_layout_feature_type_t;
|
||||
|
||||
/**
|
||||
|
@ -424,7 +424,7 @@ typedef enum
|
|||
HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2,
|
||||
HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3,
|
||||
|
||||
_HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
|
||||
_HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
} hb_aat_layout_feature_selector_t;
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
|
|
|
@ -94,6 +94,14 @@ struct hb_bimap_t
|
|||
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
|
||||
struct hb_inc_bimap_t : hb_bimap_t
|
||||
{
|
||||
hb_inc_bimap_t () { init (); }
|
||||
|
||||
void init ()
|
||||
{
|
||||
hb_bimap_t::init ();
|
||||
next_value = 0;
|
||||
}
|
||||
|
||||
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
|
||||
* Return the rhs value as the result.
|
||||
*/
|
||||
|
@ -102,12 +110,24 @@ struct hb_inc_bimap_t : hb_bimap_t
|
|||
hb_codepoint_t rhs = forw_map[lhs];
|
||||
if (rhs == HB_MAP_VALUE_INVALID)
|
||||
{
|
||||
rhs = get_population ();
|
||||
rhs = next_value++;
|
||||
set (lhs, rhs);
|
||||
}
|
||||
return rhs;
|
||||
}
|
||||
|
||||
hb_codepoint_t skip ()
|
||||
{ return next_value++; }
|
||||
|
||||
hb_codepoint_t get_next_value () const
|
||||
{ return next_value; }
|
||||
|
||||
void add_set (const hb_set_t *set)
|
||||
{
|
||||
hb_codepoint_t i = HB_SET_VALUE_INVALID;
|
||||
while (hb_set_next (set, &i)) add (i);
|
||||
}
|
||||
|
||||
/* Create an identity map. */
|
||||
bool identity (unsigned int size)
|
||||
{
|
||||
|
@ -138,6 +158,9 @@ struct hb_inc_bimap_t : hb_bimap_t
|
|||
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
|
||||
set (work[rhs], rhs);
|
||||
}
|
||||
|
||||
protected:
|
||||
unsigned int next_value;
|
||||
};
|
||||
|
||||
#endif /* HB_BIMAP_HH */
|
||||
|
|
|
@ -66,6 +66,8 @@
|
|||
#define HB_NO_LAYOUT_COLLECT_GLYPHS
|
||||
#define HB_NO_LAYOUT_UNUSED
|
||||
#define HB_NO_MATH
|
||||
#define HB_NO_META
|
||||
#define HB_NO_METRICS
|
||||
#define HB_NO_MMAP
|
||||
#define HB_NO_NAME
|
||||
#define HB_NO_OPEN
|
||||
|
|
|
@ -539,11 +539,6 @@ protected:
|
|||
Run mRunHead;
|
||||
};
|
||||
|
||||
static inline uint16_t hb_dw_uint16_swap (const uint16_t v)
|
||||
{ return (v >> 8) | (v << 8); }
|
||||
static inline uint32_t hb_dw_uint32_swap (const uint32_t v)
|
||||
{ return (hb_dw_uint16_swap (v) << 16) | hb_dw_uint16_swap (v >> 16); }
|
||||
|
||||
/*
|
||||
* shaper
|
||||
*/
|
||||
|
@ -653,7 +648,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
|||
for (unsigned int i = 0; i < num_features; ++i)
|
||||
{
|
||||
typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
|
||||
hb_dw_uint32_swap (features[i].tag);
|
||||
hb_uint32_swap (features[i].tag);
|
||||
typographic_features.features[i].parameter = features[i].value;
|
||||
}
|
||||
}
|
||||
|
@ -941,7 +936,7 @@ _hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *
|
|||
uint32_t length;
|
||||
void *table_context;
|
||||
BOOL exists;
|
||||
if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_dw_uint32_swap (tag), &data,
|
||||
if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data,
|
||||
&length, &table_context, &exists)))
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#ifdef HAVE_GDI
|
||||
|
||||
#include "hb-gdi.h"
|
||||
|
||||
static hb_blob_t *
|
||||
_hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||
{
|
||||
char *buffer = nullptr;
|
||||
DWORD length = 0;
|
||||
|
||||
HDC hdc = GetDC (nullptr);
|
||||
if (unlikely (!SelectObject (hdc, (HFONT) user_data))) goto fail;
|
||||
|
||||
length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
|
||||
if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc;
|
||||
|
||||
buffer = (char *) malloc (length);
|
||||
if (unlikely (!buffer)) goto fail_with_releasedc;
|
||||
length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
|
||||
if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc_and_free;
|
||||
ReleaseDC (nullptr, hdc);
|
||||
|
||||
return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free);
|
||||
|
||||
fail_with_releasedc_and_free:
|
||||
free (buffer);
|
||||
fail_with_releasedc:
|
||||
ReleaseDC (nullptr, hdc);
|
||||
fail:
|
||||
return hb_blob_get_empty ();
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_gdi_face_create:
|
||||
* @hdc: a HFONT object.
|
||||
*
|
||||
* Return value: #hb_face_t object corresponding to the given input
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_gdi_face_create (HFONT hfont)
|
||||
{
|
||||
return hb_face_create_for_tables (_hb_gdi_reference_table, (void *) hfont, nullptr);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HB_GDI_H
|
||||
#define HB_GDI_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_gdi_face_create (HFONT hfont);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_GDI_H */
|
|
@ -106,32 +106,6 @@ retry:
|
|||
return d;
|
||||
}
|
||||
|
||||
static void hb_graphite2_release_table(const void *data, const void *table_buffer)
|
||||
{
|
||||
hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data;
|
||||
hb_graphite2_tablelist_t *tlist = face_data->tlist;
|
||||
|
||||
hb_graphite2_tablelist_t *prev = nullptr;
|
||||
hb_graphite2_tablelist_t *curr = tlist;
|
||||
while (curr)
|
||||
{
|
||||
if (hb_blob_get_data(curr->blob, nullptr) == table_buffer)
|
||||
{
|
||||
if (prev == nullptr)
|
||||
face_data->tlist.cmpexch(tlist, curr->next);
|
||||
else
|
||||
prev->next = curr->next;
|
||||
hb_blob_destroy(curr->blob);
|
||||
free(curr);
|
||||
break;
|
||||
}
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
static gr_face_ops hb_graphite2_face_ops = { sizeof(gr_face_ops), hb_graphite2_get_table, hb_graphite2_release_table };
|
||||
|
||||
hb_graphite2_face_data_t *
|
||||
_hb_graphite2_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
|
@ -150,7 +124,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
|
|||
return nullptr;
|
||||
|
||||
data->face = face;
|
||||
data->grface = gr_make_face_with_ops (data, &hb_graphite2_face_ops, gr_face_preloadAll);
|
||||
data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll);
|
||||
|
||||
if (unlikely (!data->grface)) {
|
||||
free (data);
|
||||
|
|
|
@ -480,7 +480,7 @@ struct hb_reduce_t
|
|||
|
||||
template <typename Iter,
|
||||
hb_requires (hb_is_iterator (Iter)),
|
||||
typename AccuT = decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>
|
||||
typename AccuT = hb_decay<decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>>
|
||||
AccuT
|
||||
operator () (Iter it)
|
||||
{
|
||||
|
|
|
@ -141,14 +141,15 @@ typedef struct OffsetTable
|
|||
TableRecord &rec = tables.arrayZ[i];
|
||||
hb_blob_t *blob = items[i].blob;
|
||||
rec.tag = items[i].tag;
|
||||
rec.length = hb_blob_get_length (blob);
|
||||
rec.length = blob->length;
|
||||
rec.offset.serialize (c, this);
|
||||
|
||||
/* Allocate room for the table and copy it. */
|
||||
char *start = (char *) c->allocate_size<void> (rec.length);
|
||||
if (unlikely (!start)) {return false;}
|
||||
if (unlikely (!start)) return false;
|
||||
|
||||
memcpy (start, hb_blob_get_data (blob, nullptr), rec.length);
|
||||
if (likely (rec.length))
|
||||
memcpy (start, blob->data, rec.length);
|
||||
|
||||
/* 4-byte alignment. */
|
||||
c->align (4);
|
||||
|
|
|
@ -979,6 +979,14 @@ struct cmap
|
|||
if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Merge this with above or, remove and tweak #final_size
|
||||
// and rebase all the tests expectations
|
||||
HBUINT32 empty;
|
||||
empty = 0;
|
||||
for (unsigned int i = 0; i < 4; ++i) c.copy (empty);
|
||||
}
|
||||
|
||||
c.end_serialize ();
|
||||
|
||||
|
|
|
@ -235,9 +235,9 @@ struct sbix
|
|||
const PNGHeader &png = *blob->as<PNGHeader>();
|
||||
|
||||
extents->x_bearing = x_offset;
|
||||
extents->y_bearing = y_offset;
|
||||
extents->y_bearing = png.IHDR.height + y_offset;
|
||||
extents->width = png.IHDR.width;
|
||||
extents->height = png.IHDR.height;
|
||||
extents->height = -png.IHDR.height;
|
||||
|
||||
/* Convert to font units. */
|
||||
if (strike_ppem)
|
||||
|
|
|
@ -50,9 +50,10 @@ HB_OT_TABLE (OT, head)
|
|||
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
|
||||
HB_OT_ACCELERATOR (OT, cmap)
|
||||
#endif
|
||||
HB_OT_TABLE (OT, hhea)
|
||||
HB_OT_ACCELERATOR (OT, hmtx)
|
||||
HB_OT_TABLE (OT, OS2)
|
||||
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
|
||||
#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS)
|
||||
HB_OT_ACCELERATOR (OT, post)
|
||||
#endif
|
||||
#ifndef HB_NO_NAME
|
||||
|
@ -61,8 +62,12 @@ HB_OT_ACCELERATOR (OT, name)
|
|||
#ifndef HB_NO_STAT
|
||||
HB_OT_TABLE (OT, STAT)
|
||||
#endif
|
||||
#ifndef HB_NO_META
|
||||
HB_OT_ACCELERATOR (OT, meta)
|
||||
#endif
|
||||
|
||||
/* Vertical layout. */
|
||||
HB_OT_TABLE (OT, vhea)
|
||||
HB_OT_ACCELERATOR (OT, vmtx)
|
||||
|
||||
/* TrueType outlines. */
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "hb-ot-cff2-table.hh"
|
||||
#include "hb-ot-hmtx-table.hh"
|
||||
#include "hb-ot-kern-table.hh"
|
||||
#include "hb-ot-meta-table.hh"
|
||||
#include "hb-ot-name-table.hh"
|
||||
#include "hb-ot-post-table.hh"
|
||||
#include "hb-ot-color-cbdt-table.hh"
|
||||
|
|
|
@ -231,32 +231,24 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
|||
|
||||
static hb_bool_t
|
||||
hb_ot_get_font_h_extents (hb_font_t *font,
|
||||
void *font_data,
|
||||
void *font_data HB_UNUSED,
|
||||
hb_font_extents_t *metrics,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
|
||||
metrics->ascender = font->em_scale_y (hmtx.ascender);
|
||||
metrics->descender = font->em_scale_y (hmtx.descender);
|
||||
metrics->line_gap = font->em_scale_y (hmtx.line_gap);
|
||||
// TODO Hook up variations.
|
||||
return hmtx.has_font_extents;
|
||||
return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_HORIZONTAL_ASCENDER, &metrics->ascender) &&
|
||||
_hb_ot_metrics_get_position_common (font, HB_OT_METRICS_HORIZONTAL_DESCENDER, &metrics->descender) &&
|
||||
_hb_ot_metrics_get_position_common (font, HB_OT_METRICS_HORIZONTAL_LINE_GAP, &metrics->line_gap);
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_font_v_extents (hb_font_t *font,
|
||||
void *font_data,
|
||||
void *font_data HB_UNUSED,
|
||||
hb_font_extents_t *metrics,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
|
||||
metrics->ascender = font->em_scale_x (vmtx.ascender);
|
||||
metrics->descender = font->em_scale_x (vmtx.descender);
|
||||
metrics->line_gap = font->em_scale_x (vmtx.line_gap);
|
||||
// TODO Hook up variations.
|
||||
return vmtx.has_font_extents;
|
||||
return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_VERTICAL_ASCENDER, &metrics->ascender) &&
|
||||
_hb_ot_metrics_get_position_common (font, HB_OT_METRICS_VERTICAL_DESCENDER, &metrics->descender) &&
|
||||
_hb_ot_metrics_get_position_common (font, HB_OT_METRICS_VERTICAL_LINE_GAP, &metrics->line_gap);
|
||||
}
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
|
|
|
@ -45,6 +45,8 @@ namespace OT {
|
|||
template <typename T>
|
||||
struct _hea
|
||||
{
|
||||
bool has_data () const { return version.major; }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
#include "hb-open-type.hh"
|
||||
#include "hb-ot-hhea-table.hh"
|
||||
#include "hb-ot-os2-table.hh"
|
||||
#include "hb-ot-var-hvar-table.hh"
|
||||
#include "hb-ot-metrics.hh"
|
||||
|
||||
/*
|
||||
* hmtx -- Horizontal Metrics
|
||||
|
@ -169,28 +169,7 @@ struct hmtxvmtx
|
|||
memset (this, 0, sizeof (*this));
|
||||
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
|
||||
|
||||
bool got_font_extents = false;
|
||||
if (T::os2Tag != HB_TAG_NONE && face->table.OS2->is_typo_metrics ())
|
||||
{
|
||||
ascender = abs (face->table.OS2->sTypoAscender);
|
||||
descender = -abs (face->table.OS2->sTypoDescender);
|
||||
line_gap = face->table.OS2->sTypoLineGap;
|
||||
got_font_extents = (ascender | descender) != 0;
|
||||
}
|
||||
|
||||
hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table<H> (face);
|
||||
const H *_hea_table = _hea_blob->as<H> ();
|
||||
num_advances = _hea_table->numberOfLongMetrics;
|
||||
if (!got_font_extents)
|
||||
{
|
||||
ascender = abs (_hea_table->ascender);
|
||||
descender = -abs (_hea_table->descender);
|
||||
line_gap = _hea_table->lineGap;
|
||||
got_font_extents = (ascender | descender) != 0;
|
||||
}
|
||||
hb_blob_destroy (_hea_blob);
|
||||
|
||||
has_font_extents = got_font_extents;
|
||||
num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics;
|
||||
|
||||
table = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag);
|
||||
|
||||
|
@ -307,12 +286,6 @@ struct hmtxvmtx
|
|||
return get_advance (old_gid);
|
||||
}
|
||||
|
||||
public:
|
||||
bool has_font_extents;
|
||||
int ascender;
|
||||
int descender;
|
||||
int line_gap;
|
||||
|
||||
protected:
|
||||
unsigned int num_metrics;
|
||||
unsigned int num_advances;
|
||||
|
@ -352,12 +325,12 @@ struct hmtxvmtx
|
|||
struct hmtx : hmtxvmtx<hmtx, hhea> {
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx;
|
||||
static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR;
|
||||
static constexpr hb_tag_t os2Tag = HB_OT_TAG_OS2;
|
||||
static constexpr bool is_horizontal = true;
|
||||
};
|
||||
struct vmtx : hmtxvmtx<vmtx, vhea> {
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx;
|
||||
static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR;
|
||||
static constexpr hb_tag_t os2Tag = HB_TAG_NONE;
|
||||
static constexpr bool is_horizontal = false;
|
||||
};
|
||||
|
||||
struct hmtx_accelerator_t : hmtx::accelerator_t {};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
|
||||
* Copyright © 2018 Google, Inc.
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
* Copyright © 2018-2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
|
@ -116,6 +116,8 @@ struct BaseCoordFormat3
|
|||
|
||||
struct BaseCoord
|
||||
{
|
||||
bool has_data () const { return u.format; }
|
||||
|
||||
hb_position_t get_coord (hb_font_t *font,
|
||||
const VariationStore &var_store,
|
||||
hb_direction_t direction) const
|
||||
|
@ -153,14 +155,9 @@ struct BaseCoord
|
|||
|
||||
struct FeatMinMaxRecord
|
||||
{
|
||||
HB_INTERNAL static int cmp (const void *key_, const void *entry_)
|
||||
{
|
||||
hb_tag_t key = * (hb_tag_t *) key_;
|
||||
const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_;
|
||||
return key < (unsigned int) entry.tag ? -1 :
|
||||
key > (unsigned int) entry.tag ? 1 :
|
||||
0;
|
||||
}
|
||||
int cmp (hb_tag_t key) const { return tag.cmp (key); }
|
||||
|
||||
bool has_data () const { return tag; }
|
||||
|
||||
void get_min_max (const BaseCoord **min, const BaseCoord **max) const
|
||||
{
|
||||
|
@ -198,14 +195,9 @@ struct MinMax
|
|||
const BaseCoord **min,
|
||||
const BaseCoord **max) const
|
||||
{
|
||||
/* TODO Replace hb_bsearch() with .bsearch(). */
|
||||
const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *)
|
||||
hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ,
|
||||
featMinMaxRecords.len,
|
||||
FeatMinMaxRecord::static_size,
|
||||
FeatMinMaxRecord::cmp);
|
||||
if (minMaxCoord)
|
||||
minMaxCoord->get_min_max (min, max);
|
||||
const FeatMinMaxRecord &minMaxCoord = featMinMaxRecords.bsearch (feature_tag);
|
||||
if (minMaxCoord.has_data ())
|
||||
minMaxCoord.get_min_max (min, max);
|
||||
else
|
||||
{
|
||||
if (likely (min)) *min = &(this+minCoord);
|
||||
|
@ -271,17 +263,11 @@ struct BaseValues
|
|||
|
||||
struct BaseLangSysRecord
|
||||
{
|
||||
HB_INTERNAL static int cmp (const void *key_, const void *entry_)
|
||||
{
|
||||
hb_tag_t key = * (hb_tag_t *) key_;
|
||||
const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_;
|
||||
return key < (unsigned int) entry.baseLangSysTag ? -1 :
|
||||
key > (unsigned int) entry.baseLangSysTag ? 1 :
|
||||
0;
|
||||
}
|
||||
int cmp (hb_tag_t key) const { return baseLangSysTag.cmp (key); }
|
||||
|
||||
const MinMax &get_min_max () const
|
||||
{ return this+minMax; }
|
||||
bool has_data () const { return baseLangSysTag; }
|
||||
|
||||
const MinMax &get_min_max () const { return this+minMax; }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
|
@ -303,19 +289,14 @@ struct BaseScript
|
|||
{
|
||||
const MinMax &get_min_max (hb_tag_t language_tag) const
|
||||
{
|
||||
/* TODO Replace hb_bsearch() with .bsearch(). */
|
||||
const BaseLangSysRecord* record = (const BaseLangSysRecord *)
|
||||
hb_bsearch (&language_tag, baseLangSysRecords.arrayZ,
|
||||
baseLangSysRecords.len,
|
||||
BaseLangSysRecord::static_size,
|
||||
BaseLangSysRecord::cmp);
|
||||
return record ? record->get_min_max () : this+defaultMinMax;
|
||||
const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag);
|
||||
return record.has_data () ? record.get_min_max () : this+defaultMinMax;
|
||||
}
|
||||
|
||||
const BaseCoord &get_base_coord (int baseline_tag_index) const
|
||||
{ return (this+baseValues).get_base_coord (baseline_tag_index); }
|
||||
|
||||
bool is_empty () const { return !baseValues; }
|
||||
bool has_data () const { return baseValues; }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
|
@ -345,14 +326,9 @@ struct BaseScript
|
|||
struct BaseScriptList;
|
||||
struct BaseScriptRecord
|
||||
{
|
||||
HB_INTERNAL static int cmp (const void *key_, const void *entry_)
|
||||
{
|
||||
hb_tag_t key = * (hb_tag_t *) key_;
|
||||
const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_;
|
||||
return key < (unsigned int) entry.baseScriptTag ? -1 :
|
||||
key > (unsigned int) entry.baseScriptTag ? 1 :
|
||||
0;
|
||||
}
|
||||
int cmp (hb_tag_t key) const { return baseScriptTag.cmp (key); }
|
||||
|
||||
bool has_data () const { return baseScriptTag; }
|
||||
|
||||
const BaseScript &get_base_script (const BaseScriptList *list) const
|
||||
{ return list+baseScript; }
|
||||
|
@ -376,22 +352,11 @@ struct BaseScriptRecord
|
|||
|
||||
struct BaseScriptList
|
||||
{
|
||||
const BaseScriptRecord *find_record (hb_tag_t script) const
|
||||
{
|
||||
/* TODO Replace hb_bsearch() with .bsearch(). */
|
||||
return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ,
|
||||
baseScriptRecords.len,
|
||||
BaseScriptRecord::static_size,
|
||||
BaseScriptRecord::cmp);
|
||||
}
|
||||
|
||||
/* TODO: Or client should handle fallback? */
|
||||
const BaseScript &get_base_script (hb_tag_t script) const
|
||||
{
|
||||
const BaseScriptRecord *record = find_record (script);
|
||||
if (!record) record = find_record ((hb_script_t) HB_TAG ('D','F','L','T'));
|
||||
|
||||
return record ? record->get_base_script (this) : Null (BaseScript);
|
||||
const BaseScriptRecord *record = &baseScriptRecords.bsearch (script);
|
||||
if (!record->has_data ()) record = &baseScriptRecords.bsearch (HB_TAG ('D','F','L','T'));
|
||||
return record->has_data () ? record->get_base_script (this) : Null (BaseScript);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
|
@ -417,9 +382,14 @@ struct Axis
|
|||
const BaseCoord **coord) const
|
||||
{
|
||||
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
|
||||
if (base_script.is_empty ()) return false;
|
||||
if (!base_script.has_data ()) return false;
|
||||
|
||||
if (likely (coord)) *coord = &base_script.get_base_coord ((this+baseTagList).bsearch (baseline));
|
||||
if (likely (coord))
|
||||
{
|
||||
unsigned int tag_index = 0;
|
||||
(this+baseTagList).bfind (baseline, &tag_index);
|
||||
*coord = &base_script.get_base_coord (tag_index);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -431,7 +401,7 @@ struct Axis
|
|||
const BaseCoord **max_coord) const
|
||||
{
|
||||
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
|
||||
if (base_script.is_empty ()) return false;
|
||||
if (!base_script.has_data ()) return false;
|
||||
|
||||
base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);
|
||||
|
||||
|
@ -479,13 +449,14 @@ struct BASE
|
|||
hb_tag_t language_tag,
|
||||
hb_position_t *base) const
|
||||
{
|
||||
const BaseCoord *base_coord;
|
||||
if (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord))
|
||||
const BaseCoord *base_coord = nullptr;
|
||||
if (unlikely (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord) ||
|
||||
!base_coord || !base_coord->has_data ()))
|
||||
return false;
|
||||
|
||||
if (likely (base && base_coord)) *base = base_coord->get_coord (font,
|
||||
get_var_store (),
|
||||
direction);
|
||||
if (likely (base))
|
||||
*base = base_coord->get_coord (font, get_var_store (), direction);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1723,6 +1723,9 @@ struct VarData
|
|||
unsigned int get_region_index_count () const
|
||||
{ return regionIndices.len; }
|
||||
|
||||
unsigned int get_row_size () const
|
||||
{ return shortCount + regionIndices.len; }
|
||||
|
||||
unsigned int get_size () const
|
||||
{ return itemCount * get_row_size (); }
|
||||
|
||||
|
@ -1783,12 +1786,12 @@ struct VarData
|
|||
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
const VarData *src,
|
||||
const hb_bimap_t &inner_map,
|
||||
const hb_inc_bimap_t &inner_map,
|
||||
const hb_bimap_t ®ion_map)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||
itemCount = inner_map.get_population ();
|
||||
itemCount = inner_map.get_next_value ();
|
||||
|
||||
/* Optimize short count */
|
||||
unsigned short ri_count = src->regionIndices.len;
|
||||
|
@ -1802,7 +1805,7 @@ struct VarData
|
|||
for (r = 0; r < ri_count; r++)
|
||||
{
|
||||
delta_sz[r] = kZero;
|
||||
for (unsigned int i = 0; i < inner_map.get_population (); i++)
|
||||
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
|
||||
{
|
||||
unsigned int old = inner_map.backward (i);
|
||||
int16_t delta = src->get_item_delta (old, r);
|
||||
|
@ -1838,8 +1841,7 @@ struct VarData
|
|||
|
||||
for (unsigned int i = 0; i < itemCount; i++)
|
||||
{
|
||||
hb_codepoint_t old = inner_map.backward (i);
|
||||
if (unlikely (old >= src->itemCount)) return_trace (false);
|
||||
unsigned int old = inner_map.backward (i);
|
||||
for (unsigned int r = 0; r < ri_count; r++)
|
||||
if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
|
||||
}
|
||||
|
@ -1847,13 +1849,13 @@ struct VarData
|
|||
return_trace (true);
|
||||
}
|
||||
|
||||
void collect_region_refs (hb_inc_bimap_t ®ion_map, const hb_bimap_t &inner_map) const
|
||||
void collect_region_refs (hb_inc_bimap_t ®ion_map, const hb_inc_bimap_t &inner_map) const
|
||||
{
|
||||
for (unsigned int r = 0; r < regionIndices.len; r++)
|
||||
{
|
||||
unsigned int region = regionIndices[r];
|
||||
if (region_map.has (region)) continue;
|
||||
for (unsigned int i = 0; i < inner_map.get_population (); i++)
|
||||
for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
|
||||
if (get_item_delta (inner_map.backward (i), r) != 0)
|
||||
{
|
||||
region_map.add (region);
|
||||
|
@ -1863,9 +1865,6 @@ struct VarData
|
|||
}
|
||||
|
||||
protected:
|
||||
unsigned int get_row_size () const
|
||||
{ return shortCount + regionIndices.len; }
|
||||
|
||||
const HBUINT8 *get_delta_bytes () const
|
||||
{ return &StructAfter<HBUINT8> (regionIndices); }
|
||||
|
||||
|
@ -1874,7 +1873,7 @@ struct VarData
|
|||
|
||||
int16_t get_item_delta (unsigned int item, unsigned int region) const
|
||||
{
|
||||
if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0;
|
||||
if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
|
||||
const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size ();
|
||||
if (region < shortCount)
|
||||
return ((const HBINT16 *)p)[region];
|
||||
|
@ -1940,20 +1939,20 @@ struct VariationStore
|
|||
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
const VariationStore *src,
|
||||
const hb_array_t <hb_inc_bimap_t> &inner_remaps)
|
||||
const hb_array_t <hb_inc_bimap_t> &inner_maps)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
unsigned int set_count = 0;
|
||||
for (unsigned int i = 0; i < inner_remaps.length; i++)
|
||||
if (inner_remaps[i].get_population () > 0) set_count++;
|
||||
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||
if (inner_maps[i].get_population () > 0) set_count++;
|
||||
|
||||
unsigned int size = min_size + HBUINT32::static_size * set_count;
|
||||
if (unlikely (!c->allocate_size<HBUINT32> (size))) return_trace (false);
|
||||
format = 1;
|
||||
|
||||
hb_inc_bimap_t region_map;
|
||||
for (unsigned int i = 0; i < inner_remaps.length; i++)
|
||||
(src+src->dataSets[i]).collect_region_refs (region_map, inner_remaps[i]);
|
||||
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||
(src+src->dataSets[i]).collect_region_refs (region_map, inner_maps[i]);
|
||||
region_map.sort ();
|
||||
|
||||
if (unlikely (!regions.serialize (c, this)
|
||||
|
@ -1964,11 +1963,11 @@ struct VariationStore
|
|||
*/
|
||||
dataSets.len = set_count;
|
||||
unsigned int set_index = 0;
|
||||
for (unsigned int i = 0; i < inner_remaps.length; i++)
|
||||
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||
{
|
||||
if (inner_remaps[i].get_population () == 0) continue;
|
||||
if (inner_maps[i].get_population () == 0) continue;
|
||||
if (unlikely (!dataSets[set_index++].serialize (c, this)
|
||||
.serialize (c, &(src+src->dataSets[i]), inner_remaps[i], region_map)))
|
||||
.serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map)))
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
|
@ -1993,8 +1992,6 @@ struct VariationStore
|
|||
&scalars[0], num_scalars);
|
||||
}
|
||||
|
||||
const VarRegionList &get_regions () const { return this+regions; }
|
||||
|
||||
unsigned int get_sub_table_count () const { return dataSets.len; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -733,7 +733,7 @@ struct PairPosFormat1
|
|||
+ hb_zip (this+coverage, pairSet)
|
||||
| hb_filter (*glyphs, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_map ([=] (const OffsetTo<PairSet> &_)
|
||||
| hb_map ([glyphs, this] (const OffsetTo<PairSet> &_)
|
||||
{ return (this+_).intersects (glyphs, valueFormat); })
|
||||
| hb_any
|
||||
;
|
||||
|
|
|
@ -248,7 +248,7 @@ struct SingleSubst
|
|||
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
||||
unsigned format = 2;
|
||||
unsigned delta = 0;
|
||||
if (glyphs.len ())
|
||||
if (glyphs)
|
||||
{
|
||||
format = 1;
|
||||
auto get_delta = [=] (hb_codepoint_pair_t _) {
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "hb-map.hh"
|
||||
|
||||
#include "hb-ot-kern-table.hh"
|
||||
#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
|
||||
#include "hb-ot-layout-gdef-table.hh"
|
||||
#include "hb-ot-layout-gsub-table.hh"
|
||||
#include "hb-ot-layout-gpos-table.hh"
|
||||
|
@ -1980,7 +1979,9 @@ typedef enum {
|
|||
HB_OT_LAYOUT_BASELINE_IDEO = HB_TAG('i','d','e','o'),
|
||||
HB_OT_LAYOUT_BASELINE_IDTB = HB_TAG('i','d','t','b'),
|
||||
HB_OT_LAYOUT_BASELINE_MATH = HB_TAG('m','a','t','h'),
|
||||
HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n')
|
||||
HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n'),
|
||||
|
||||
_HB_OT_LAYOUT_BASELINE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
} hb_ot_layout_baseline_t;
|
||||
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ typedef enum { /*< flags >*/
|
|||
* hb_ot_math_glyph_part_t:
|
||||
* @glyph: The glyph index of the variant part
|
||||
* @start_connector_length: The length of the connector on the starting side of the variant part
|
||||
* @end_connection_length: The length of the connector on the ending side of the variant part
|
||||
* @end_connector_length: The length of the connector on the ending side of the variant part
|
||||
* @full_advance: The total advance of the part
|
||||
* @flags: #hb_ot_math_glyph_part_flags_t flags for the part
|
||||
*
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_META_TABLE_HH
|
||||
#define HB_OT_META_TABLE_HH
|
||||
|
||||
#include "hb-open-type.hh"
|
||||
|
||||
/*
|
||||
* meta -- Metadata Table
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/meta
|
||||
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
|
||||
*/
|
||||
#define HB_OT_TAG_meta HB_TAG ('m','e','t','a')
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
struct DataMap
|
||||
{
|
||||
int cmp (hb_tag_t a) const { return tag.cmp (a); }
|
||||
|
||||
hb_tag_t get_tag () const { return tag; }
|
||||
|
||||
hb_blob_t *reference_entry (hb_blob_t *meta_blob) const
|
||||
{ return hb_blob_create_sub_blob (meta_blob, dataZ, dataLength); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (likely (c->check_struct (this) &&
|
||||
dataZ.sanitize (c, base, dataLength)));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag tag; /* A tag indicating the type of metadata. */
|
||||
LOffsetTo<UnsizedArrayOf<HBUINT8>>
|
||||
dataZ; /* Offset in bytes from the beginning of the
|
||||
* metadata table to the data for this tag. */
|
||||
HBUINT32 dataLength; /* Length of the data. The data is not required to
|
||||
* be padded to any byte boundary. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
struct meta
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_meta;
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
void init (hb_face_t *face)
|
||||
{ table = hb_sanitize_context_t ().reference_table<meta> (face); }
|
||||
void fini () { table.destroy (); }
|
||||
|
||||
hb_blob_t *reference_entry (hb_tag_t tag) const
|
||||
{ return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
|
||||
|
||||
unsigned int get_entries (unsigned int start_offset,
|
||||
unsigned int *count,
|
||||
hb_ot_meta_tag_t *entries) const
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
hb_array_t<const DataMap> arr = table->dataMaps.sub_array (start_offset, count);
|
||||
for (unsigned int i = 0; i < arr.length; i++)
|
||||
entries[i] = (hb_ot_meta_tag_t) arr[i].get_tag ();
|
||||
}
|
||||
return table->dataMaps.len;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_blob_ptr_t<meta> table;
|
||||
};
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (likely (c->check_struct (this) &&
|
||||
version == 1 &&
|
||||
dataMaps.sanitize (c, this)));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT32 version; /* Version number of the metadata table — set to 1. */
|
||||
HBUINT32 flags; /* Flags — currently unused; set to 0. */
|
||||
HBUINT32 dataOffset; /* Per Apple specification:
|
||||
* Offset from the beginning of the table to the data.
|
||||
* Per OT specification:
|
||||
* Reserved. Not used; should be set to 0. */
|
||||
LArrayOf<DataMap>
|
||||
dataMaps; /* Array of data map records. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (16, dataMaps);
|
||||
};
|
||||
|
||||
struct meta_accelerator_t : meta::accelerator_t {};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_META_TABLE_HH */
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#ifndef HB_NO_META
|
||||
|
||||
#include "hb-ot-meta-table.hh"
|
||||
|
||||
/**
|
||||
* SECTION:hb-ot-meta
|
||||
* @title: hb-ot-meta
|
||||
* @short_description: OpenType Metadata
|
||||
* @include: hb-ot.h
|
||||
*
|
||||
* Functions for fetching metadata from fonts.
|
||||
**/
|
||||
|
||||
/**
|
||||
* hb_ot_meta_reference_entry:
|
||||
* @face: a face object
|
||||
* @start_offset: iteration's start offset
|
||||
* @entries_count:(inout) (allow-none): buffer size as input, filled size as output
|
||||
* @entries: (out caller-allocates) (array length=entries_count): entries tags buffer
|
||||
*
|
||||
* Return value: Number of all available feature types.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_meta_get_entries (hb_face_t *face,
|
||||
unsigned int start_offset,
|
||||
unsigned int *entries_count, /* IN/OUT. May be NULL. */
|
||||
hb_ot_meta_tag_t *entries /* OUT. May be NULL. */)
|
||||
{
|
||||
return face->table.meta->get_entries (start_offset, entries_count, entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_meta_reference_entry:
|
||||
* @face: a #hb_face_t object.
|
||||
* @meta_tag: tag of metadata you like to have.
|
||||
*
|
||||
* It fetches metadata entry of a given tag from a font.
|
||||
*
|
||||
* Returns: (transfer full): A blob containing the blob.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag)
|
||||
{
|
||||
return face->table.meta->reference_entry (meta_tag);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_META_H
|
||||
#define HB_OT_META_H
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* hb_ot_meta_tag_t:
|
||||
*
|
||||
* From https://docs.microsoft.com/en-us/typography/opentype/spec/meta
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
typedef enum {
|
||||
/*
|
||||
HB_OT_META_APPL = HB_TAG ('a','p','p','l'),
|
||||
HB_OT_META_BILD = HB_TAG ('b','i','l','d'),
|
||||
*/
|
||||
HB_OT_META_DESIGN_LANGUAGES = HB_TAG ('d','l','n','g'),
|
||||
HB_OT_META_SUPPORTED_LANGUAGES= HB_TAG ('s','l','n','g'),
|
||||
|
||||
_HB_OT_META_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
} hb_ot_meta_tag_t;
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_meta_get_entries (hb_face_t *face,
|
||||
unsigned int start_offset,
|
||||
unsigned int *entries_count, /* IN/OUT. May be NULL. */
|
||||
hb_ot_meta_tag_t *entries /* OUT. May be NULL. */);
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_META_H */
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* Copyright © 2018-2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#include "hb-ot-var-mvar-table.hh"
|
||||
#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
|
||||
#include "hb-ot-os2-table.hh"
|
||||
#include "hb-ot-post-table.hh"
|
||||
#include "hb-ot-hhea-table.hh"
|
||||
#include "hb-ot-metrics.hh"
|
||||
#include "hb-ot-face.hh"
|
||||
|
||||
|
||||
static float
|
||||
_fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag)
|
||||
{
|
||||
if (metrics_tag == HB_OT_METRICS_HORIZONTAL_ASCENDER ||
|
||||
metrics_tag == HB_OT_METRICS_VERTICAL_ASCENDER)
|
||||
return fabs ((double) value);
|
||||
if (metrics_tag == HB_OT_METRICS_HORIZONTAL_DESCENDER ||
|
||||
metrics_tag == HB_OT_METRICS_VERTICAL_DESCENDER)
|
||||
return -fabs ((double) value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/* The common part of _get_position logic needed on hb-ot-font and here
|
||||
to be able to have slim builds without the not always needed parts */
|
||||
bool
|
||||
_hb_ot_metrics_get_position_common (hb_font_t *font,
|
||||
hb_ot_metrics_tag_t metrics_tag,
|
||||
hb_position_t *position /* OUT. May be NULL. */)
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
switch ((unsigned) metrics_tag)
|
||||
{
|
||||
#ifndef HB_NO_VAR
|
||||
#define GET_VAR face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords)
|
||||
#else
|
||||
#define GET_VAR .0f
|
||||
#endif
|
||||
#define GET_METRIC_X(TABLE, ATTR) \
|
||||
(face->table.TABLE->has_data () && \
|
||||
(position && (*position = font->em_scalef_x (_fix_ascender_descender ( \
|
||||
face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
|
||||
#define GET_METRIC_Y(TABLE, ATTR) \
|
||||
(face->table.TABLE->has_data () && \
|
||||
(position && (*position = font->em_scalef_y (_fix_ascender_descender ( \
|
||||
face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
|
||||
case HB_OT_METRICS_HORIZONTAL_ASCENDER:
|
||||
return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) ||
|
||||
GET_METRIC_Y (hhea, ascender);
|
||||
case HB_OT_METRICS_HORIZONTAL_DESCENDER:
|
||||
return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoDescender)) ||
|
||||
GET_METRIC_Y (hhea, descender);
|
||||
case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
|
||||
return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) ||
|
||||
GET_METRIC_Y (hhea, lineGap);
|
||||
case HB_OT_METRICS_VERTICAL_ASCENDER: return GET_METRIC_X (vhea, ascender);
|
||||
case HB_OT_METRICS_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender);
|
||||
case HB_OT_METRICS_VERTICAL_LINE_GAP: return GET_METRIC_X (vhea, lineGap);
|
||||
#undef GET_METRIC_Y
|
||||
#undef GET_METRIC_X
|
||||
#undef GET_VAR
|
||||
default: assert (0); return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HB_NO_METRICS
|
||||
|
||||
#if 0
|
||||
static bool
|
||||
_get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_t metrics_tag)
|
||||
{
|
||||
const OT::GaspRange& range = face->table.gasp->get_gasp_range (metrics_tag - HB_TAG ('g','s','p','0'));
|
||||
if (&range == &Null (OT::GaspRange)) return false;
|
||||
if (result) *result = range.rangeMaxPPEM + font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private tags for https://github.com/harfbuzz/harfbuzz/issues/1866 */
|
||||
#define _HB_OT_METRICS_HORIZONTAL_ASCENDER_OS2 HB_TAG ('O','a','s','c')
|
||||
#define _HB_OT_METRICS_HORIZONTAL_ASCENDER_HHEA HB_TAG ('H','a','s','c')
|
||||
#define _HB_OT_METRICS_HORIZONTAL_DESCENDER_OS2 HB_TAG ('O','d','s','c')
|
||||
#define _HB_OT_METRICS_HORIZONTAL_DESCENDER_HHEA HB_TAG ('H','d','s','c')
|
||||
#define _HB_OT_METRICS_HORIZONTAL_LINE_GAP_OS2 HB_TAG ('O','l','g','p')
|
||||
#define _HB_OT_METRICS_HORIZONTAL_LINE_GAP_HHEA HB_TAG ('H','l','g','p')
|
||||
|
||||
/**
|
||||
* hb_ot_metrics_get_position:
|
||||
* @font: a #hb_font_t object.
|
||||
* @metrics_tag: tag of metrics value you like to fetch.
|
||||
* @position: (out) (optional): result of metrics value from the font.
|
||||
*
|
||||
* It fetches metrics value corresponding to a given tag from a font.
|
||||
*
|
||||
* Returns: Whether found the requested metrics in the font.
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_ot_metrics_get_position (hb_font_t *font,
|
||||
hb_ot_metrics_tag_t metrics_tag,
|
||||
hb_position_t *position /* OUT. May be NULL. */)
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
switch ((unsigned) metrics_tag)
|
||||
{
|
||||
case HB_OT_METRICS_HORIZONTAL_ASCENDER:
|
||||
case HB_OT_METRICS_HORIZONTAL_DESCENDER:
|
||||
case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
|
||||
case HB_OT_METRICS_VERTICAL_ASCENDER:
|
||||
case HB_OT_METRICS_VERTICAL_DESCENDER:
|
||||
case HB_OT_METRICS_VERTICAL_LINE_GAP: return _hb_ot_metrics_get_position_common (font, metrics_tag, position);
|
||||
#ifndef HB_NO_VAR
|
||||
#define GET_VAR hb_ot_metrics_get_variation (font, metrics_tag)
|
||||
#else
|
||||
#define GET_VAR 0
|
||||
#endif
|
||||
#define GET_METRIC_X(TABLE, ATTR) \
|
||||
(face->table.TABLE->has_data () && \
|
||||
(position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR)), true))
|
||||
#define GET_METRIC_Y(TABLE, ATTR) \
|
||||
(face->table.TABLE->has_data () && \
|
||||
(position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
|
||||
case HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent);
|
||||
case HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
|
||||
case HB_OT_METRICS_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise);
|
||||
case HB_OT_METRICS_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun);
|
||||
case HB_OT_METRICS_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
|
||||
case HB_OT_METRICS_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
|
||||
case HB_OT_METRICS_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);
|
||||
case HB_OT_METRICS_VERTICAL_CARET_OFFSET: return GET_METRIC_Y (vhea, caretOffset);
|
||||
case HB_OT_METRICS_X_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sxHeight);
|
||||
case HB_OT_METRICS_CAP_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sCapHeight);
|
||||
case HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySubscriptXSize);
|
||||
case HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySubscriptYSize);
|
||||
case HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySubscriptXOffset);
|
||||
case HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySubscriptYOffset);
|
||||
case HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySuperscriptXSize);
|
||||
case HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE: return GET_METRIC_Y (OS2, ySuperscriptYSize);
|
||||
case HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET: return GET_METRIC_X (OS2, ySuperscriptXOffset);
|
||||
case HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET: return GET_METRIC_Y (OS2, ySuperscriptYOffset);
|
||||
case HB_OT_METRICS_STRIKEOUT_SIZE: return GET_METRIC_Y (OS2, yStrikeoutSize);
|
||||
case HB_OT_METRICS_STRIKEOUT_OFFSET: return GET_METRIC_Y (OS2, yStrikeoutPosition);
|
||||
case HB_OT_METRICS_UNDERLINE_SIZE: return GET_METRIC_Y (post->table, underlineThickness);
|
||||
case HB_OT_METRICS_UNDERLINE_OFFSET: return GET_METRIC_Y (post->table, underlinePosition);
|
||||
|
||||
/* Private tags */
|
||||
case _HB_OT_METRICS_HORIZONTAL_ASCENDER_OS2: return GET_METRIC_Y (OS2, sTypoAscender);
|
||||
case _HB_OT_METRICS_HORIZONTAL_ASCENDER_HHEA: return GET_METRIC_Y (hhea, ascender);
|
||||
case _HB_OT_METRICS_HORIZONTAL_DESCENDER_OS2: return GET_METRIC_Y (OS2, sTypoDescender);
|
||||
case _HB_OT_METRICS_HORIZONTAL_DESCENDER_HHEA: return GET_METRIC_Y (hhea, descender);
|
||||
case _HB_OT_METRICS_HORIZONTAL_LINE_GAP_OS2: return GET_METRIC_Y (OS2, sTypoLineGap);
|
||||
case _HB_OT_METRICS_HORIZONTAL_LINE_GAP_HHEA: return GET_METRIC_Y (hhea, lineGap);
|
||||
#undef GET_METRIC_Y
|
||||
#undef GET_METRIC_X
|
||||
#undef GET_VAR
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
/**
|
||||
* hb_ot_metrics_get_variation:
|
||||
* @font:
|
||||
* @metrics_tag:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
float
|
||||
hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
|
||||
{
|
||||
return font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_metrics_get_x_variation:
|
||||
* @font:
|
||||
* @metrics_tag:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_position_t
|
||||
hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
|
||||
{
|
||||
return font->em_scalef_x (hb_ot_metrics_get_variation (font, metrics_tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_metrics_get_y_variation:
|
||||
* @font:
|
||||
* @metrics_tag:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_position_t
|
||||
hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
|
||||
{
|
||||
return font->em_scalef_y (hb_ot_metrics_get_variation (font, metrics_tag));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_H_IN
|
||||
#error "Include <hb-ot.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef HB_OT_METRICS_H
|
||||
#define HB_OT_METRICS_H
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ot-name.h"
|
||||
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/**
|
||||
* hb_ot_metrics_tag_t:
|
||||
*
|
||||
* From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
typedef enum {
|
||||
HB_OT_METRICS_HORIZONTAL_ASCENDER = HB_TAG ('h','a','s','c'),
|
||||
HB_OT_METRICS_HORIZONTAL_DESCENDER = HB_TAG ('h','d','s','c'),
|
||||
HB_OT_METRICS_HORIZONTAL_LINE_GAP = HB_TAG ('h','l','g','p'),
|
||||
HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT = HB_TAG ('h','c','l','a'),
|
||||
HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT = HB_TAG ('h','c','l','d'),
|
||||
HB_OT_METRICS_VERTICAL_ASCENDER = HB_TAG ('v','a','s','c'),
|
||||
HB_OT_METRICS_VERTICAL_DESCENDER = HB_TAG ('v','d','s','c'),
|
||||
HB_OT_METRICS_VERTICAL_LINE_GAP = HB_TAG ('v','l','g','p'),
|
||||
HB_OT_METRICS_HORIZONTAL_CARET_RISE = HB_TAG ('h','c','r','s'),
|
||||
HB_OT_METRICS_HORIZONTAL_CARET_RUN = HB_TAG ('h','c','r','n'),
|
||||
HB_OT_METRICS_HORIZONTAL_CARET_OFFSET = HB_TAG ('h','c','o','f'),
|
||||
HB_OT_METRICS_VERTICAL_CARET_RISE = HB_TAG ('v','c','r','s'),
|
||||
HB_OT_METRICS_VERTICAL_CARET_RUN = HB_TAG ('v','c','r','n'),
|
||||
HB_OT_METRICS_VERTICAL_CARET_OFFSET = HB_TAG ('v','c','o','f'),
|
||||
HB_OT_METRICS_X_HEIGHT = HB_TAG ('x','h','g','t'),
|
||||
HB_OT_METRICS_CAP_HEIGHT = HB_TAG ('c','p','h','t'),
|
||||
HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE = HB_TAG ('s','b','x','s'),
|
||||
HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE = HB_TAG ('s','b','y','s'),
|
||||
HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET = HB_TAG ('s','b','x','o'),
|
||||
HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET = HB_TAG ('s','b','y','o'),
|
||||
HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE = HB_TAG ('s','p','x','s'),
|
||||
HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE = HB_TAG ('s','p','y','s'),
|
||||
HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET = HB_TAG ('s','p','x','o'),
|
||||
HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET = HB_TAG ('s','p','y','o'),
|
||||
HB_OT_METRICS_STRIKEOUT_SIZE = HB_TAG ('s','t','r','s'),
|
||||
HB_OT_METRICS_STRIKEOUT_OFFSET = HB_TAG ('s','t','r','o'),
|
||||
HB_OT_METRICS_UNDERLINE_SIZE = HB_TAG ('u','n','d','s'),
|
||||
HB_OT_METRICS_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o'),
|
||||
|
||||
_HB_OT_METRICS_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
} hb_ot_metrics_tag_t;
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_metrics_get_position (hb_font_t *font,
|
||||
hb_ot_metrics_tag_t metrics_tag,
|
||||
hb_position_t *position /* OUT. May be NULL. */);
|
||||
|
||||
HB_EXTERN float
|
||||
hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
|
||||
|
||||
HB_EXTERN hb_position_t
|
||||
hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_OT_METRICS_H */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HB_OT_METRICS_HH
|
||||
#define HB_OT_METRICS_HH
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
HB_INTERNAL bool
|
||||
_hb_ot_metrics_get_position_common (hb_font_t *font,
|
||||
hb_ot_metrics_tag_t metrics_tag,
|
||||
hb_position_t *position /* OUT. May be NULL. */);
|
||||
|
||||
#endif /* HB_OT_METRICS_HH */
|
|
@ -59,6 +59,10 @@ struct OS2V1Tail
|
|||
|
||||
struct OS2V2Tail
|
||||
{
|
||||
bool has_data () const { return this != &Null (OS2V2Tail); }
|
||||
|
||||
const OS2V2Tail * operator -> () const { return this; }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -115,7 +119,7 @@ struct OS2
|
|||
|
||||
bool is_italic () const { return fsSelection & ITALIC; }
|
||||
bool is_oblique () const { return fsSelection & OBLIQUE; }
|
||||
bool is_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
|
||||
bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
|
||||
|
||||
enum width_class_t {
|
||||
FWIDTH_ULTRA_CONDENSED = 1, /* 50% */
|
||||
|
@ -199,6 +203,7 @@ struct OS2
|
|||
*max_cp = codepoints->get_max ();
|
||||
}
|
||||
|
||||
/* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 */
|
||||
enum font_page_t {
|
||||
HEBREW_FONT_PAGE = 0xB100, // Hebrew Windows 3.1 font page
|
||||
SIMP_ARABIC_FONT_PAGE = 0xB200, // Simplified Arabic Windows 3.1 font page
|
||||
|
@ -208,8 +213,6 @@ struct OS2
|
|||
TRAD_FARSI_FONT_PAGE = 0xBB00, // Traditional Farsi Windows 3.1 font page
|
||||
THAI_FONT_PAGE = 0xDE00 // Thai Windows 3.1 font page
|
||||
};
|
||||
|
||||
// https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
|
||||
font_page_t get_font_page () const
|
||||
{ return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); }
|
||||
|
||||
|
|
|
@ -178,6 +178,8 @@ struct post
|
|||
return false;
|
||||
}
|
||||
|
||||
hb_blob_ptr_t<post> table;
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int get_glyph_count () const
|
||||
|
@ -237,7 +239,6 @@ struct post
|
|||
}
|
||||
|
||||
private:
|
||||
hb_blob_ptr_t<post> table;
|
||||
uint32_t version;
|
||||
const ArrayOf<HBUINT16> *glyphNameIndex;
|
||||
hb_vector_t<uint32_t> index_to_offset;
|
||||
|
@ -245,6 +246,8 @@ struct post
|
|||
hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
|
||||
};
|
||||
|
||||
bool has_data () const { return version.to_int (); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
|
|
@ -129,9 +129,8 @@ struct index_map_subset_plan_t
|
|||
};
|
||||
|
||||
void init (const DeltaSetIndexMap &index_map,
|
||||
unsigned int im_index,
|
||||
hb_inc_bimap_t &outer_map,
|
||||
hb_vector_t<hb_inc_bimap_t> &inner_maps,
|
||||
hb_vector_t<hb_set_t *> &inner_sets,
|
||||
const hb_subset_plan_t *plan)
|
||||
{
|
||||
map_count = 0;
|
||||
|
@ -140,36 +139,27 @@ struct index_map_subset_plan_t
|
|||
max_inners.init ();
|
||||
output_map.init ();
|
||||
|
||||
if (&index_map == &Null(DeltaSetIndexMap))
|
||||
{
|
||||
/* Advance width index map is required. If its offset is missing,
|
||||
* treat it as an indentity map. */
|
||||
if (im_index == ADV_INDEX)
|
||||
{
|
||||
outer_map.add (0);
|
||||
for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
|
||||
{
|
||||
hb_codepoint_t old_gid = gid;
|
||||
(void)plan->old_gid_for_new_gid (gid, &old_gid);
|
||||
inner_maps[0].add (old_gid);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (&index_map == &Null(DeltaSetIndexMap)) return;
|
||||
|
||||
unsigned int last_val = (unsigned int)-1;
|
||||
hb_codepoint_t last_gid = (hb_codepoint_t)-1;
|
||||
hb_codepoint_t gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ());
|
||||
|
||||
outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count ();
|
||||
max_inners.resize (inner_maps.length);
|
||||
for (unsigned i = 0; i < inner_maps.length; i++) max_inners[i] = 0;
|
||||
max_inners.resize (inner_sets.length);
|
||||
for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0;
|
||||
|
||||
/* Search backwards for a map value different from the last map value */
|
||||
for (; gid > 0; gid--)
|
||||
{
|
||||
hb_codepoint_t old_gid = gid - 1;
|
||||
(void)plan->old_gid_for_new_gid (gid - 1, &old_gid);
|
||||
hb_codepoint_t old_gid;
|
||||
if (!plan->old_gid_for_new_gid (gid - 1, &old_gid))
|
||||
{
|
||||
if (last_gid == (hb_codepoint_t)-1)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int v = index_map.map (old_gid);
|
||||
if (last_gid == (hb_codepoint_t)-1)
|
||||
|
@ -187,14 +177,16 @@ struct index_map_subset_plan_t
|
|||
map_count = last_gid;
|
||||
for (gid = 0; gid < map_count; gid++)
|
||||
{
|
||||
hb_codepoint_t old_gid = gid;
|
||||
(void)plan->old_gid_for_new_gid (gid, &old_gid);
|
||||
hb_codepoint_t old_gid;
|
||||
if (plan->old_gid_for_new_gid (gid, &old_gid))
|
||||
{
|
||||
unsigned int v = index_map.map (old_gid);
|
||||
unsigned int outer = v >> 16;
|
||||
unsigned int inner = v & 0xFFFF;
|
||||
outer_map.add (outer);
|
||||
if (inner > max_inners[outer]) max_inners[outer] = inner;
|
||||
inner_maps[outer].add (inner);
|
||||
hb_set_add (inner_sets[outer], inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,10 +201,7 @@ struct index_map_subset_plan_t
|
|||
const hb_vector_t<hb_inc_bimap_t> &inner_maps,
|
||||
const hb_subset_plan_t *plan)
|
||||
{
|
||||
/* Leave output_map empty for an identity map */
|
||||
/* TODO: if retain_gids, convert identity to a customized map, or not subset varstore? */
|
||||
if (input_map == &Null(DeltaSetIndexMap))
|
||||
return;
|
||||
if (input_map == &Null(DeltaSetIndexMap)) return;
|
||||
|
||||
for (unsigned int i = 0; i < max_inners.length; i++)
|
||||
{
|
||||
|
@ -224,12 +213,16 @@ struct index_map_subset_plan_t
|
|||
output_map.resize (map_count);
|
||||
for (hb_codepoint_t gid = 0; gid < output_map.length; gid++)
|
||||
{
|
||||
hb_codepoint_t old_gid = gid;
|
||||
(void)plan->old_gid_for_new_gid (gid, &old_gid);
|
||||
hb_codepoint_t old_gid;
|
||||
if (plan->old_gid_for_new_gid (gid, &old_gid))
|
||||
{
|
||||
unsigned int v = input_map->map (old_gid);
|
||||
unsigned int outer = v >> 16;
|
||||
output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
|
||||
}
|
||||
else
|
||||
output_map[gid] = 0; /* Map unused glyph to outer/inner=0/0 */
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int get_inner_bit_count () const { return inner_bit_count; }
|
||||
|
@ -264,17 +257,53 @@ struct hvarvvar_subset_plan_t
|
|||
index_map_plans.resize (index_maps.length);
|
||||
|
||||
var_store = &_var_store;
|
||||
inner_sets.resize (var_store->get_sub_table_count ());
|
||||
for (unsigned int i = 0; i < inner_sets.length; i++)
|
||||
inner_sets[i] = hb_set_create ();
|
||||
adv_set = hb_set_create ();
|
||||
|
||||
inner_maps.resize (var_store->get_sub_table_count ());
|
||||
|
||||
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||
inner_maps[i].init ();
|
||||
|
||||
for (unsigned int i = 0; i < index_maps.length; i++)
|
||||
index_map_plans[i].init (*index_maps[i], i, outer_map, inner_maps, plan);
|
||||
bool retain_adv_map = false;
|
||||
index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan);
|
||||
if (index_maps[0] == &Null(DeltaSetIndexMap))
|
||||
{
|
||||
retain_adv_map = plan->retain_gids;
|
||||
outer_map.add (0);
|
||||
for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
|
||||
{
|
||||
hb_codepoint_t old_gid;
|
||||
if (plan->old_gid_for_new_gid (gid, &old_gid))
|
||||
hb_set_add (inner_sets[0], old_gid);
|
||||
}
|
||||
hb_set_union (adv_set, inner_sets[0]);
|
||||
}
|
||||
|
||||
for (unsigned int i = 1; i < index_maps.length; i++)
|
||||
index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan);
|
||||
|
||||
outer_map.sort ();
|
||||
for (unsigned int i = 0; i < inner_maps.length; i++)
|
||||
if (inner_maps[i].get_population () > 0) inner_maps[i].sort ();
|
||||
|
||||
if (retain_adv_map)
|
||||
{
|
||||
for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
|
||||
if (hb_set_has (inner_sets[0], gid))
|
||||
inner_maps[0].add (gid);
|
||||
else
|
||||
inner_maps[0].skip ();
|
||||
}
|
||||
else
|
||||
{
|
||||
inner_maps[0].add_set (adv_set);
|
||||
hb_set_subtract (inner_sets[0], adv_set);
|
||||
inner_maps[0].add_set (inner_sets[0]);
|
||||
}
|
||||
|
||||
for (unsigned int i = 1; i < inner_maps.length; i++)
|
||||
inner_maps[i].add_set (inner_sets[i]);
|
||||
|
||||
for (unsigned int i = 0; i < index_maps.length; i++)
|
||||
index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan);
|
||||
|
@ -282,6 +311,9 @@ struct hvarvvar_subset_plan_t
|
|||
|
||||
void fini ()
|
||||
{
|
||||
for (unsigned int i = 0; i < inner_sets.length; i++)
|
||||
hb_set_destroy (inner_sets[i]);
|
||||
hb_set_destroy (adv_set);
|
||||
inner_maps.fini_deep ();
|
||||
index_map_plans.fini_deep ();
|
||||
}
|
||||
|
@ -291,6 +323,10 @@ struct hvarvvar_subset_plan_t
|
|||
hb_vector_t<index_map_subset_plan_t>
|
||||
index_map_plans;
|
||||
const VariationStore *var_store;
|
||||
|
||||
protected:
|
||||
hb_vector_t<hb_set_t *> inner_sets;
|
||||
hb_set_t *adv_set;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -68,7 +68,7 @@ hb_ot_var_get_axis_count (hb_face_t *face);
|
|||
typedef enum { /*< flags >*/
|
||||
HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u,
|
||||
|
||||
_HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu /*< skip >*/
|
||||
_HB_OT_VAR_AXIS_FLAG_MAX_VALUE= HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
} hb_ot_var_axis_flags_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "hb-ot-font.h"
|
||||
#include "hb-ot-layout.h"
|
||||
#include "hb-ot-math.h"
|
||||
#include "hb-ot-meta.h"
|
||||
#include "hb-ot-metrics.h"
|
||||
#include "hb-ot-name.h"
|
||||
#include "hb-ot-shape.h"
|
||||
#include "hb-ot-var.h"
|
||||
|
|
|
@ -179,7 +179,7 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
|
|||
|
||||
unsigned max_glyph =
|
||||
+ hb_iter (all_gids_to_retain)
|
||||
| hb_reduce (hb_max, 0)
|
||||
| hb_reduce (hb_max, 0u)
|
||||
;
|
||||
*num_glyphs = max_glyph + 1;
|
||||
}
|
||||
|
|
|
@ -126,8 +126,12 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED
|
|||
}
|
||||
#endif
|
||||
|
||||
extern "C" hb_unicode_funcs_t *hb_glib_get_unicode_funcs ();
|
||||
extern "C" hb_unicode_funcs_t *hb_icu_get_unicode_funcs ();
|
||||
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
|
||||
#include "hb-glib.h"
|
||||
#endif
|
||||
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
|
||||
#include "hb-icu.h"
|
||||
#endif
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_unicode_funcs_get_default ()
|
||||
|
|
|
@ -105,9 +105,6 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
|||
unsigned int
|
||||
modified_combining_class (hb_codepoint_t u)
|
||||
{
|
||||
/* XXX This hack belongs to the Myanmar shaper. */
|
||||
if (unlikely (u == 0x1037u)) u = 0x103Au;
|
||||
|
||||
/* XXX This hack belongs to the USE shaper (for Tai Tham):
|
||||
* Reorder SAKOT to ensure it comes after any tone marks. */
|
||||
if (unlikely (u == 0x1A60u)) return 254;
|
||||
|
|
|
@ -58,13 +58,6 @@
|
|||
* Functions for using HarfBuzz with the Windows fonts.
|
||||
**/
|
||||
|
||||
|
||||
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
||||
{ return (v >> 8) | (v << 8); }
|
||||
static inline uint32_t hb_uint32_swap (const uint32_t v)
|
||||
{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
|
||||
|
||||
|
||||
typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/(
|
||||
const WCHAR *pwcInChars,
|
||||
int cInChars,
|
||||
|
@ -245,8 +238,9 @@ struct hb_uniscribe_shaper_funcs_t
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
static void free_static_uniscribe_shaper_funcs ();
|
||||
#endif
|
||||
|
||||
static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t<hb_uniscribe_shaper_funcs_t,
|
||||
hb_uniscribe_shaper_funcs_lazy_loader_t>
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
|
||||
#pragma GCC diagnostic warning "-Wbuiltin-macro-redefined"
|
||||
#pragma GCC diagnostic warning "-Wdeprecated"
|
||||
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
|
||||
#pragma GCC diagnostic warning "-Wdisabled-optimization"
|
||||
#pragma GCC diagnostic warning "-Wdouble-promotion"
|
||||
#pragma GCC diagnostic warning "-Wformat=2"
|
||||
|
@ -317,7 +318,8 @@ extern "C" void hb_free_impl(void *ptr);
|
|||
# define HB_FALLTHROUGH /* FALLTHROUGH */
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
/* https://github.com/harfbuzz/harfbuzz/issues/1852 */
|
||||
#if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)))
|
||||
/* Disable certain sanitizer errors. */
|
||||
/* https://github.com/harfbuzz/harfbuzz/issues/1247 */
|
||||
#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
|
||||
|
@ -475,6 +477,11 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
|
|||
/* Size signifying variable-sized array */
|
||||
#define VAR 1
|
||||
|
||||
/* Endian swap, used in Windows related backends */
|
||||
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
||||
{ return (v >> 8) | (v << 8); }
|
||||
static inline uint32_t hb_uint32_swap (const uint32_t v)
|
||||
{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
|
||||
|
||||
/*
|
||||
* Big-endian integers. Here because fundamental.
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-ot.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HB_NO_OPEN
|
||||
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf (stderr, "usage: %s font-file\n", argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
unsigned int count = 0;
|
||||
|
||||
#ifndef HB_NO_META
|
||||
count = hb_ot_meta_get_entries (face, 0, nullptr, nullptr);
|
||||
|
||||
hb_ot_meta_tag_t *tags = (hb_ot_meta_tag_t *)
|
||||
malloc (sizeof (hb_ot_meta_tag_t) * count);
|
||||
hb_ot_meta_get_entries (face, 0, &count, tags);
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
{
|
||||
hb_blob_t *entry = hb_ot_meta_reference_entry (face, tags[i]);
|
||||
printf ("%c%c%c%c, size: %d: %.*s\n",
|
||||
HB_UNTAG (tags[i]), hb_blob_get_length (entry),
|
||||
hb_blob_get_length (entry), hb_blob_get_data (entry, nullptr));
|
||||
hb_blob_destroy (entry);
|
||||
}
|
||||
free (tags);
|
||||
#endif
|
||||
|
||||
hb_face_destroy (face);
|
||||
|
||||
return !count;
|
||||
}
|
|
@ -90,6 +90,8 @@ TEST_PROGS += \
|
|||
test-ot-color \
|
||||
test-ot-ligature-carets \
|
||||
test-ot-name \
|
||||
test-ot-meta \
|
||||
test-ot-metrics \
|
||||
test-ot-tag \
|
||||
test-ot-extents-cff \
|
||||
test-ot-metrics-tt-var \
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -426,9 +426,9 @@ test_hb_ot_color_png (void)
|
|||
g_assert (strncmp (data + 1, "PNG", 3) == 0);
|
||||
hb_font_get_glyph_extents (sbix_font, 1, &extents);
|
||||
g_assert_cmpint (extents.x_bearing, ==, 0);
|
||||
g_assert_cmpint (extents.y_bearing, ==, 0);
|
||||
g_assert_cmpint (extents.y_bearing, ==, 800);
|
||||
g_assert_cmpint (extents.width, ==, 800);
|
||||
g_assert_cmpint (extents.height, ==, 800);
|
||||
g_assert_cmpint (extents.height, ==, -800);
|
||||
hb_blob_destroy (blob);
|
||||
hb_font_destroy (sbix_font);
|
||||
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hb-test.h"
|
||||
|
||||
#include <hb-ot.h>
|
||||
|
||||
/* Unit tests for hb-ot-meta.h */
|
||||
|
||||
static void
|
||||
test_ot_meta_get_entries (void)
|
||||
{
|
||||
hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
|
||||
hb_ot_meta_tag_t entries[2];
|
||||
|
||||
unsigned int entries_count = 2;
|
||||
g_assert_cmpint (hb_ot_meta_get_entries (face, 0, &entries_count, entries), ==, 5);
|
||||
g_assert_cmpint (entries_count, ==, 2);
|
||||
g_assert_cmpint (entries[0], ==, HB_TAG ('a','p','p','l'));
|
||||
g_assert_cmpint (entries[1], ==, HB_TAG ('b','i','l','d'));
|
||||
|
||||
entries_count = 1;
|
||||
g_assert_cmpint (hb_ot_meta_get_entries (face, 2, &entries_count, entries), ==, 5);
|
||||
g_assert_cmpint (entries_count, ==, 1);
|
||||
g_assert_cmpint (entries[0], ==, HB_TAG ('d','l','n','g'));
|
||||
|
||||
entries_count = 2;
|
||||
g_assert_cmpint (hb_ot_meta_get_entries (face, 4, &entries_count, entries), ==, 5);
|
||||
g_assert_cmpint (entries_count, ==, 1);
|
||||
g_assert_cmpint (entries[0], ==, HB_TAG ('s','l','n','g'));
|
||||
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_meta_reference_entry (void)
|
||||
{
|
||||
hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
|
||||
hb_blob_t *dlng = hb_ot_meta_reference_entry (face, HB_OT_META_DESIGN_LANGUAGES);
|
||||
g_assert_cmpint (hb_blob_get_length (dlng), ==, 8);
|
||||
g_assert_cmpmem (hb_blob_get_data (dlng, NULL), 8, "ar,de,fa", 8);
|
||||
hb_blob_destroy (dlng);
|
||||
hb_blob_t *fslf = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('f','s','l','f'));
|
||||
g_assert_cmpint (hb_blob_get_length (fslf), ==, 12);
|
||||
hb_blob_destroy (fslf);
|
||||
hb_blob_t *nacl = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('n','a','c','l'));
|
||||
g_assert_cmpint (hb_blob_get_length (nacl), ==, 0);
|
||||
hb_blob_destroy (nacl);
|
||||
hb_blob_t *slng = hb_ot_meta_reference_entry (face, HB_OT_META_SUPPORTED_LANGUAGES);
|
||||
g_assert_cmpint (hb_blob_get_length (slng), ==, 11);
|
||||
g_assert_cmpmem (hb_blob_get_data (slng, NULL), 11, "ar,de,en,fa", 11);
|
||||
hb_blob_destroy (slng);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
hb_test_init (&argc, &argv);
|
||||
hb_test_add (test_ot_meta_get_entries);
|
||||
hb_test_add (test_ot_meta_reference_entry);
|
||||
return hb_test_run ();
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hb-test.h"
|
||||
|
||||
#include <hb-ot.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* Unit tests for hb-ot-metrics.h */
|
||||
|
||||
static void
|
||||
test_ot_metrics_get_no_var (void)
|
||||
{
|
||||
hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v0.ttf");
|
||||
hb_font_t *font = hb_font_create (face);
|
||||
hb_position_t value;
|
||||
g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_HORIZONTAL_ASCENDER, &value));
|
||||
g_assert_cmpint (value, ==, 1000);
|
||||
g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
|
||||
g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
|
||||
g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, 0);
|
||||
// g_assert_cmpint ((int) hb_ot_metrics_get_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
|
||||
hb_font_destroy (font);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_metrics_get_var (void)
|
||||
{
|
||||
hb_face_t *face = hb_test_open_font_file ("fonts/TestCFF2VF.otf");
|
||||
hb_font_t *font = hb_font_create (face);
|
||||
hb_position_t value;
|
||||
g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_X_HEIGHT, &value));
|
||||
g_assert_cmpint (value, ==, 486);
|
||||
g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
|
||||
g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
|
||||
g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, 0);
|
||||
float coords[] = {100.f};
|
||||
hb_font_set_var_coords_design (font, coords, 1);
|
||||
g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_X_HEIGHT, &value));
|
||||
g_assert_cmpint (value, ==, 478);
|
||||
g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
|
||||
g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
|
||||
g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, -8);
|
||||
hb_font_destroy (font);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
hb_test_init (&argc, &argv);
|
||||
hb_test_add (test_ot_metrics_get_no_var);
|
||||
hb_test_add (test_ot_metrics_get_var);
|
||||
return hb_test_run ();
|
||||
}
|
Binary file not shown.
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "hb-subset.h"
|
||||
|
||||
|
@ -32,6 +33,19 @@ trySubset (hb_face_t *face,
|
|||
}
|
||||
|
||||
hb_face_t *result = hb_subset (face, input);
|
||||
{
|
||||
hb_blob_t *blob = hb_face_reference_blob (result);
|
||||
unsigned int length;
|
||||
const char *data = hb_blob_get_data (blob, &length);
|
||||
|
||||
// Something not optimizable just to access all the blob data
|
||||
unsigned int bytes_count = 0;
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
if (data[i]) ++bytes_count;
|
||||
assert (bytes_count || !length);
|
||||
|
||||
hb_blob_destroy (blob);
|
||||
}
|
||||
hb_face_destroy (result);
|
||||
|
||||
hb_subset_input_destroy (input);
|
||||
|
|
|
@ -89,7 +89,7 @@ for file in os.listdir (parent_path):
|
|||
if 'error' in text:
|
||||
returncode = 1
|
||||
|
||||
if not valgrind and text.strip ():
|
||||
if (not valgrind or returncode) and text.strip ():
|
||||
print (text)
|
||||
|
||||
if returncode != 0:
|
||||
|
|
|
@ -33,7 +33,7 @@ def cmd(command):
|
|||
def timeout(p, is_killed):
|
||||
is_killed['value'] = True
|
||||
p.kill()
|
||||
timer = threading.Timer (2, timeout, [p, is_killed])
|
||||
timer = threading.Timer (8, timeout, [p, is_killed])
|
||||
|
||||
try:
|
||||
timer.start()
|
||||
|
@ -82,6 +82,8 @@ def run_dir (parent_path):
|
|||
global fails
|
||||
for file in os.listdir (parent_path):
|
||||
path = os.path.join(parent_path, file)
|
||||
# TODO: Run on all the fonts not just subset related ones
|
||||
if "subset" not in path: continue
|
||||
|
||||
print ("running subset fuzzer against %s" % path)
|
||||
if valgrind:
|
||||
|
@ -91,7 +93,7 @@ def run_dir (parent_path):
|
|||
if 'error' in text:
|
||||
returncode = 1
|
||||
|
||||
if not valgrind and text.strip ():
|
||||
if (not valgrind or returncode) and text.strip ():
|
||||
print (text)
|
||||
|
||||
if returncode != 0:
|
||||
|
@ -100,8 +102,7 @@ def run_dir (parent_path):
|
|||
|
||||
|
||||
run_dir (os.path.join (srcdir, "..", "subset", "data", "fonts"))
|
||||
# TODO running these tests very slow tests. Fix and re-enable
|
||||
#run_dir (os.path.join (srcdir, "fonts"))
|
||||
run_dir (os.path.join (srcdir, "fonts"))
|
||||
|
||||
if fails:
|
||||
print ("%i subset fuzzer related tests failed." % fails)
|
||||
|
|
Binary file not shown.
|
@ -1 +1,2 @@
|
|||
../fonts/ee39587d13b2afa5499cc79e45780aa79293bbd4.ttf:--font-funcs=ot --show-extents:U+1F42F:[gid1=0+2963<0,2179,2963,-2789>]
|
||||
../fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf:--font-funcs=ot --show-extents:U+1F600:[gid4=0+2550<0,1898,2555,-2405>]
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -15,3 +15,4 @@ b
|
|||
c
|
||||
ac
|
||||
a
|
||||
*
|
||||
|
|
|
@ -67,7 +67,7 @@ def run_test (test, should_check_ots):
|
|||
"--font-file=" + test.font_path,
|
||||
"--output-file=" + out_file,
|
||||
"--unicodes=%s" % test.unicodes (),
|
||||
"--drop-tables+=DSIG,GPOS,GSUB,GDEF,HVAR,VVAR,gvar"]
|
||||
"--drop-tables+=DSIG,GPOS,GSUB,GDEF"]
|
||||
cli_args.extend (test.get_profile_flags ())
|
||||
print (' '.join (cli_args))
|
||||
_, return_code = cmd (cli_args)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue