[API] Changes to main shape API
hb_shape() now accepts a shaper_options and a shaper_list argument. Both can be set to NULL to emulate previous API. And in most situations they are expected to be set to NULL. hb_shape() also returns a boolean for now. If shaper_list is NULL, the return value can be ignored. shaper_options is ignored for now, but otherwise it should be a NULL-terminated list of strings. shaper_list is a NULL-terminated list of strings. Currently recognized strings are "ot" for native OpenType Layout implementation, "uniscribe" for the Uniscribe backend, and "fallback" for the non-complex backend (that will be implemented shortly). The fallback backend never fails. The env var HB_SHAPER_LIST is also parsed and honored. It's a colon-separated list of shaper names. The fallback shaper is invoked if none of the env-listed shapers succeed. New API hb_buffer_guess_properties() added.
This commit is contained in:
parent
57692adf12
commit
02aeca985b
2
TODO
2
TODO
|
@ -23,8 +23,6 @@ API issues to fix before 1.0:
|
||||||
|
|
||||||
- Add sanitize API (and a cached version, that saves result on blob user-data)
|
- Add sanitize API (and a cached version, that saves result on blob user-data)
|
||||||
|
|
||||||
- hb_shape() currently does a bit more than hb_ot_shape(). Shouldn't.
|
|
||||||
|
|
||||||
- Add glib GBoxedType stuff and introspection
|
- Add glib GBoxedType stuff and introspection
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -138,12 +138,21 @@ AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype)
|
||||||
|
|
||||||
dnl ===========================================================================
|
dnl ===========================================================================
|
||||||
|
|
||||||
|
have_ot=true;
|
||||||
|
if $have_ot; then
|
||||||
|
AC_DEFINE(HAVE_OT, 1, [Have native OpenType Layout backend])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(HAVE_OT, $have_ot)
|
||||||
|
|
||||||
|
dnl ===========================================================================
|
||||||
|
|
||||||
AC_CHECK_HEADERS(usp10.h windows.h, have_uniscribe=true, have_uniscribe=false)
|
AC_CHECK_HEADERS(usp10.h windows.h, have_uniscribe=true, have_uniscribe=false)
|
||||||
if $have_uniscribe; then
|
if $have_uniscribe; then
|
||||||
UNISCRIBE_CFLAGS=
|
UNISCRIBE_CFLAGS=
|
||||||
UNISCRIBE_LIBS="-lusp10 -lgdi32"
|
UNISCRIBE_LIBS="-lusp10 -lgdi32"
|
||||||
AC_SUBST(UNISCRIBE_CFLAGS)
|
AC_SUBST(UNISCRIBE_CFLAGS)
|
||||||
AC_SUBST(UNISCRIBE_LIBS)
|
AC_SUBST(UNISCRIBE_LIBS)
|
||||||
|
AC_DEFINE(HAVE_UNISCRIBE, 1, [Have Uniscribe backend])
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
|
AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ HBSOURCES = \
|
||||||
hb-buffer-private.hh \
|
hb-buffer-private.hh \
|
||||||
hb-buffer.cc \
|
hb-buffer.cc \
|
||||||
hb-common.cc \
|
hb-common.cc \
|
||||||
|
hb-fallback-shape-private.hh \
|
||||||
|
hb-fallback-shape.cc \
|
||||||
hb-font-private.hh \
|
hb-font-private.hh \
|
||||||
hb-font.cc \
|
hb-font.cc \
|
||||||
hb-mutex-private.hh \
|
hb-mutex-private.hh \
|
||||||
|
@ -30,6 +32,7 @@ HBSOURCES = \
|
||||||
hb-shape.cc \
|
hb-shape.cc \
|
||||||
hb-unicode-private.hh \
|
hb-unicode-private.hh \
|
||||||
hb-unicode.cc \
|
hb-unicode.cc \
|
||||||
|
hb-ot-tag.cc \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
HBHEADERS = \
|
HBHEADERS = \
|
||||||
hb.h \
|
hb.h \
|
||||||
|
@ -42,6 +45,11 @@ HBHEADERS = \
|
||||||
hb-version.h \
|
hb-version.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES += \
|
||||||
|
$(srcdir)/hb-version.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
if HAVE_OT
|
||||||
HBSOURCES += \
|
HBSOURCES += \
|
||||||
hb-ot-layout.cc \
|
hb-ot-layout.cc \
|
||||||
hb-ot-layout-common-private.hh \
|
hb-ot-layout-common-private.hh \
|
||||||
|
@ -62,7 +70,6 @@ HBSOURCES += \
|
||||||
hb-ot-shape-complex-private.hh \
|
hb-ot-shape-complex-private.hh \
|
||||||
hb-ot-shape-normalize.cc \
|
hb-ot-shape-normalize.cc \
|
||||||
hb-ot-shape-private.hh \
|
hb-ot-shape-private.hh \
|
||||||
hb-ot-tag.cc \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
HBHEADERS += \
|
HBHEADERS += \
|
||||||
hb-ot.h \
|
hb-ot.h \
|
||||||
|
@ -70,10 +77,7 @@ HBHEADERS += \
|
||||||
hb-ot-shape.h \
|
hb-ot-shape.h \
|
||||||
hb-ot-tag.h \
|
hb-ot-tag.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
endif
|
||||||
MAINTAINERCLEANFILES += \
|
|
||||||
$(srcdir)/hb-version.h \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
if HAVE_GLIB
|
if HAVE_GLIB
|
||||||
HBCFLAGS += $(GLIB_CFLAGS)
|
HBCFLAGS += $(GLIB_CFLAGS)
|
||||||
|
|
|
@ -94,6 +94,7 @@ struct _hb_buffer_t {
|
||||||
HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
|
HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
|
||||||
HB_INTERNAL void reverse (void);
|
HB_INTERNAL void reverse (void);
|
||||||
HB_INTERNAL void reverse_clusters (void);
|
HB_INTERNAL void reverse_clusters (void);
|
||||||
|
HB_INTERNAL void guess_properties (void);
|
||||||
|
|
||||||
HB_INTERNAL void swap_buffers (void);
|
HB_INTERNAL void swap_buffers (void);
|
||||||
HB_INTERNAL void clear_output (void);
|
HB_INTERNAL void clear_output (void);
|
||||||
|
|
|
@ -402,6 +402,35 @@ hb_buffer_t::reverse_clusters (void)
|
||||||
reverse_range (start, i);
|
reverse_range (start, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hb_buffer_t::guess_properties (void)
|
||||||
|
{
|
||||||
|
/* If script is set to INVALID, guess from buffer contents */
|
||||||
|
if (props.script == HB_SCRIPT_INVALID) {
|
||||||
|
for (unsigned int i = 0; i < len; i++) {
|
||||||
|
hb_script_t script = hb_unicode_script (unicode, info[i].codepoint);
|
||||||
|
if (likely (script != HB_SCRIPT_COMMON &&
|
||||||
|
script != HB_SCRIPT_INHERITED &&
|
||||||
|
script != HB_SCRIPT_UNKNOWN)) {
|
||||||
|
props.script = script;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If direction is set to INVALID, guess from script */
|
||||||
|
if (props.direction == HB_DIRECTION_INVALID) {
|
||||||
|
props.direction = hb_script_get_horizontal_direction (props.script);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If language is not set, use default language from locale */
|
||||||
|
if (props.language == HB_LANGUAGE_INVALID) {
|
||||||
|
/* TODO get_default_for_script? using $LANGUAGE */
|
||||||
|
props.language = hb_language_get_default ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
dump_var_allocation (const hb_buffer_t *buffer)
|
dump_var_allocation (const hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
|
@ -675,6 +704,12 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
|
||||||
buffer->reverse_clusters ();
|
buffer->reverse_clusters ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hb_buffer_guess_properties (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
buffer->guess_properties ();
|
||||||
|
}
|
||||||
|
|
||||||
#define ADD_UTF(T) \
|
#define ADD_UTF(T) \
|
||||||
HB_STMT_START { \
|
HB_STMT_START { \
|
||||||
const T *next = (const T *) text + item_offset; \
|
const T *next = (const T *) text + item_offset; \
|
||||||
|
|
|
@ -132,6 +132,9 @@ hb_buffer_reverse (hb_buffer_t *buffer);
|
||||||
void
|
void
|
||||||
hb_buffer_reverse_clusters (hb_buffer_t *buffer);
|
hb_buffer_reverse_clusters (hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
void
|
||||||
|
hb_buffer_guess_properties (hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
|
||||||
/* Filling the buffer in */
|
/* Filling the buffer in */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2011 Google, Inc.
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
* Google Author(s): Behdad Esfahbod
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_FALLBACK_SHAPE_PRIVATE_HH
|
||||||
|
#define HB_FALLBACK_SHAPE_PRIVATE_HH
|
||||||
|
|
||||||
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
#include "hb-shape.h"
|
||||||
|
|
||||||
|
|
||||||
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
HB_INTERNAL hb_bool_t
|
||||||
|
hb_fallback_shape (hb_font_t *font,
|
||||||
|
hb_buffer_t *buffer,
|
||||||
|
const hb_feature_t *features,
|
||||||
|
unsigned int num_features,
|
||||||
|
const char *shaper_options);
|
||||||
|
|
||||||
|
|
||||||
|
HB_END_DECLS
|
||||||
|
|
||||||
|
#endif /* HB_FALLBACK_SHAPE_PRIVATE_HH */
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2011 Google, Inc.
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
* Google Author(s): Behdad Esfahbod
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hb-fallback-shape-private.hh"
|
||||||
|
|
||||||
|
#include "hb-buffer-private.hh"
|
||||||
|
|
||||||
|
hb_bool_t
|
||||||
|
hb_fallback_shape (hb_font_t *font,
|
||||||
|
hb_buffer_t *buffer,
|
||||||
|
const hb_feature_t *features,
|
||||||
|
unsigned int num_features,
|
||||||
|
const char *shaper_options)
|
||||||
|
{
|
||||||
|
buffer->guess_properties ();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -428,16 +428,21 @@ hb_ot_shape_execute (hb_ot_shape_plan_t *plan,
|
||||||
hb_ot_shape_execute_internal (&c);
|
hb_ot_shape_execute_internal (&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
hb_bool_t
|
||||||
hb_ot_shape (hb_font_t *font,
|
hb_ot_shape (hb_font_t *font,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
const hb_feature_t *features,
|
const hb_feature_t *features,
|
||||||
unsigned int num_features)
|
unsigned int num_features,
|
||||||
|
const char *shaper_options)
|
||||||
{
|
{
|
||||||
hb_ot_shape_plan_t plan;
|
hb_ot_shape_plan_t plan;
|
||||||
|
|
||||||
|
buffer->guess_properties ();
|
||||||
|
|
||||||
hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features);
|
hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features);
|
||||||
hb_ot_shape_execute (&plan, font, buffer, features, num_features);
|
hb_ot_shape_execute (&plan, font, buffer, features, num_features);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,12 @@
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
void
|
hb_bool_t
|
||||||
hb_ot_shape (hb_font_t *font,
|
hb_ot_shape (hb_font_t *font,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
const hb_feature_t *features,
|
const hb_feature_t *features,
|
||||||
unsigned int num_features);
|
unsigned int num_features,
|
||||||
|
const char *shaper_options);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
127
src/hb-shape.cc
127
src/hb-shape.cc
|
@ -30,62 +30,89 @@
|
||||||
|
|
||||||
#include "hb-buffer-private.hh"
|
#include "hb-buffer-private.hh"
|
||||||
|
|
||||||
#include "hb-ot-shape.h"
|
#ifdef HAVE_UNISCRIBE
|
||||||
|
# include "hb-uniscribe.h"
|
||||||
#ifdef HAVE_GRAPHITE
|
|
||||||
#include "hb-graphite.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_OT
|
||||||
|
# include "hb-ot-shape.h"
|
||||||
|
#endif
|
||||||
|
#include "hb-fallback-shape-private.hh"
|
||||||
|
|
||||||
|
typedef hb_bool_t (*hb_shape_func_t) (hb_font_t *font,
|
||||||
|
hb_buffer_t *buffer,
|
||||||
|
const hb_feature_t *features,
|
||||||
|
unsigned int num_features,
|
||||||
|
const char *shaper_options);
|
||||||
|
|
||||||
|
#define HB_SHAPER_IMPLEMENT(name) {#name, hb_##name##_shape}
|
||||||
|
static const struct hb_shaper_pair_t {
|
||||||
|
const char name[16];
|
||||||
|
hb_shape_func_t func;
|
||||||
|
} shapers[] = {
|
||||||
|
/* v--- Add new shapers in the right place here */
|
||||||
|
#ifdef HAVE_UNISCRIBE
|
||||||
|
HB_SHAPER_IMPLEMENT (uniscribe),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_OT
|
||||||
|
HB_SHAPER_IMPLEMENT (ot),
|
||||||
|
#endif
|
||||||
|
HB_SHAPER_IMPLEMENT (fallback) /* should be last */
|
||||||
|
};
|
||||||
|
#undef HB_SHAPER_IMPLEMENT
|
||||||
|
|
||||||
static void
|
static class static_shaper_list_t {
|
||||||
hb_shape_internal (hb_font_t *font,
|
public:
|
||||||
hb_buffer_t *buffer,
|
static_shaper_list_t (void) {
|
||||||
const hb_feature_t *features,
|
char *env = getenv ("HB_SHAPER_LIST");
|
||||||
unsigned int num_features)
|
shaper_list = NULL;
|
||||||
|
if (!env || !*env)
|
||||||
|
return;
|
||||||
|
unsigned int count = 3; /* initial, fallback, null */
|
||||||
|
for (const char *p = env; (p == strchr (p, ':')) && p++; )
|
||||||
|
count++;
|
||||||
|
if (count <= ARRAY_LENGTH (static_shaper_list))
|
||||||
|
shaper_list = static_shaper_list;
|
||||||
|
else
|
||||||
|
shaper_list = (const char **) malloc (count * sizeof (shaper_list[0]));
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
shaper_list[count++] = env;
|
||||||
|
for (char *p = env; (p == strchr (p, ':')) && (*p = '\0', TRUE) && p++; )
|
||||||
|
shaper_list[count++] = p;
|
||||||
|
shaper_list[count++] = "fallback";
|
||||||
|
shaper_list[count] = NULL;
|
||||||
|
}
|
||||||
|
const char **shaper_list;
|
||||||
|
const char *static_shaper_list[10];
|
||||||
|
} env_shaper_list;
|
||||||
|
|
||||||
|
hb_bool_t
|
||||||
|
hb_shape (hb_font_t *font,
|
||||||
|
hb_buffer_t *buffer,
|
||||||
|
const hb_feature_t *features,
|
||||||
|
unsigned int num_features,
|
||||||
|
const char *shaper_options,
|
||||||
|
const char **shaper_list)
|
||||||
{
|
{
|
||||||
hb_ot_shape (font, buffer, features, num_features);
|
if (likely (!shaper_list))
|
||||||
}
|
shaper_list = env_shaper_list.shaper_list;
|
||||||
|
|
||||||
void
|
if (likely (!shaper_list)) {
|
||||||
hb_shape (hb_font_t *font,
|
for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
|
||||||
hb_buffer_t *buffer,
|
if (likely (shapers[i].func (font, buffer,
|
||||||
const hb_feature_t *features,
|
features, num_features,
|
||||||
unsigned int num_features)
|
shaper_options)))
|
||||||
{
|
return TRUE;
|
||||||
hb_segment_properties_t orig_props;
|
} else {
|
||||||
|
while (*shaper_list) {
|
||||||
orig_props = buffer->props;
|
for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
|
||||||
|
if (0 == strcmp (*shaper_list, shapers[i].name) &&
|
||||||
/* If script is set to INVALID, guess from buffer contents */
|
likely (shapers[i].func (font, buffer,
|
||||||
if (buffer->props.script == HB_SCRIPT_INVALID) {
|
features, num_features,
|
||||||
hb_unicode_funcs_t *unicode = buffer->unicode;
|
shaper_options)))
|
||||||
unsigned int count = buffer->len;
|
return TRUE;
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
shaper_list++;
|
||||||
hb_script_t script = hb_unicode_script (unicode, buffer->info[i].codepoint);
|
|
||||||
if (likely (script != HB_SCRIPT_COMMON &&
|
|
||||||
script != HB_SCRIPT_INHERITED &&
|
|
||||||
script != HB_SCRIPT_UNKNOWN)) {
|
|
||||||
buffer->props.script = script;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return FALSE;
|
||||||
/* If direction is set to INVALID, guess from script */
|
|
||||||
if (buffer->props.direction == HB_DIRECTION_INVALID) {
|
|
||||||
buffer->props.direction = hb_script_get_horizontal_direction (buffer->props.script);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If language is not set, use default language from locale */
|
|
||||||
if (buffer->props.language == HB_LANGUAGE_INVALID) {
|
|
||||||
/* TODO get_default_for_script? using $LANGUAGE */
|
|
||||||
buffer->props.language = hb_language_get_default ();
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_shape_internal (font, buffer, features, num_features);
|
|
||||||
|
|
||||||
buffer->props = orig_props;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,14 @@ typedef struct _hb_feature_t {
|
||||||
unsigned int end;
|
unsigned int end;
|
||||||
} hb_feature_t;
|
} hb_feature_t;
|
||||||
|
|
||||||
void
|
|
||||||
hb_shape (hb_font_t *font,
|
hb_bool_t
|
||||||
hb_buffer_t *buffer,
|
hb_shape (hb_font_t *font,
|
||||||
const hb_feature_t *features,
|
hb_buffer_t *buffer,
|
||||||
unsigned int num_features);
|
const hb_feature_t *features,
|
||||||
|
unsigned int num_features,
|
||||||
|
const char *shaper_options,
|
||||||
|
const char **shaper_list);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
|
@ -56,13 +56,6 @@ DWORD GetFontData(
|
||||||
);
|
);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
|
||||||
fallback_shape (hb_font_t *font,
|
|
||||||
hb_buffer_t *buffer)
|
|
||||||
{
|
|
||||||
DEBUG_MSG (UNISCRIBE, NULL, "Fallback shaper invoked");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
populate_log_font (LOGFONTW *lf,
|
populate_log_font (LOGFONTW *lf,
|
||||||
HDC hdc,
|
HDC hdc,
|
||||||
|
@ -78,18 +71,19 @@ populate_log_font (LOGFONTW *lf,
|
||||||
lf->lfFaceName[i] = family_name[i];
|
lf->lfFaceName[i] = family_name[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
hb_bool_t
|
||||||
hb_uniscribe_shape (hb_font_t *font,
|
hb_uniscribe_shape (hb_font_t *font,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
const hb_feature_t *features,
|
const hb_feature_t *features,
|
||||||
unsigned int num_features)
|
unsigned int num_features,
|
||||||
|
const char *shaper_options)
|
||||||
{
|
{
|
||||||
|
buffer->guess_properties ();
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (unlikely (!buffer->len)) {
|
if (unlikely (!buffer->len))
|
||||||
fallback:
|
return TRUE;
|
||||||
fallback_shape (font, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
|
||||||
|
@ -138,10 +132,10 @@ retry:
|
||||||
ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
|
ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
|
||||||
|
|
||||||
|
|
||||||
#define FALLBACK(...) \
|
#define FAIL(...) \
|
||||||
HB_STMT_START { \
|
HB_STMT_START { \
|
||||||
DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \
|
DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \
|
||||||
goto fallback; \
|
return FALSE; \
|
||||||
} HB_STMT_END;
|
} HB_STMT_END;
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,7 +158,7 @@ retry:
|
||||||
script_tags,
|
script_tags,
|
||||||
&item_count);
|
&item_count);
|
||||||
if (unlikely (FAILED (hr)))
|
if (unlikely (FAILED (hr)))
|
||||||
FALLBACK ("ScriptItemizeOpenType() failed: %d", hr);
|
FAIL ("ScriptItemizeOpenType() failed: %d", hr);
|
||||||
|
|
||||||
#undef MAX_ITEMS
|
#undef MAX_ITEMS
|
||||||
|
|
||||||
|
@ -178,17 +172,13 @@ retry:
|
||||||
hb_blob_t *blob = hb_face_get_blob (font->face);
|
hb_blob_t *blob = hb_face_get_blob (font->face);
|
||||||
unsigned int blob_length;
|
unsigned int blob_length;
|
||||||
const char *blob_data = hb_blob_get_data (blob, &blob_length);
|
const char *blob_data = hb_blob_get_data (blob, &blob_length);
|
||||||
if (unlikely (!blob_length)) {
|
if (unlikely (!blob_length))
|
||||||
hb_blob_destroy (blob);
|
FAIL ("Empty font blob");
|
||||||
FALLBACK ("Empty font blob");
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD num_fonts_installed;
|
DWORD num_fonts_installed;
|
||||||
HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
|
HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
|
||||||
if (unlikely (!fh)) {
|
if (unlikely (!fh))
|
||||||
hb_blob_destroy (blob);
|
FAIL ("AddFontMemResourceEx() failed");
|
||||||
FALLBACK ("AddFontMemResourceEx() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FREE stuff, specially when taking fallback... */
|
/* FREE stuff, specially when taking fallback... */
|
||||||
|
|
||||||
|
@ -230,16 +220,16 @@ retry:
|
||||||
(int *) &glyphs_len);
|
(int *) &glyphs_len);
|
||||||
|
|
||||||
if (unlikely (items[i].a.fNoGlyphIndex))
|
if (unlikely (items[i].a.fNoGlyphIndex))
|
||||||
FALLBACK ("ScriptShapeOpenType() set fNoGlyphIndex");
|
FAIL ("ScriptShapeOpenType() set fNoGlyphIndex");
|
||||||
if (unlikely (hr == E_OUTOFMEMORY))
|
if (unlikely (hr == E_OUTOFMEMORY))
|
||||||
{
|
{
|
||||||
buffer->ensure (buffer->allocated * 2);
|
buffer->ensure (buffer->allocated * 2);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
FALLBACK ("Buffer resize failed");
|
FAIL ("Buffer resize failed");
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
if (unlikely (FAILED (hr)))
|
if (unlikely (FAILED (hr)))
|
||||||
FALLBACK ("ScriptShapeOpenType() failed: %d", hr);
|
FAIL ("ScriptShapeOpenType() failed: %d", hr);
|
||||||
|
|
||||||
hr = ScriptPlaceOpenType (hdc,
|
hr = ScriptPlaceOpenType (hdc,
|
||||||
&script_cache,
|
&script_cache,
|
||||||
|
@ -261,7 +251,7 @@ retry:
|
||||||
offsets + glyphs_offset,
|
offsets + glyphs_offset,
|
||||||
NULL);
|
NULL);
|
||||||
if (unlikely (FAILED (hr)))
|
if (unlikely (FAILED (hr)))
|
||||||
FALLBACK ("ScriptPlaceOpenType() failed: %d", hr);
|
FAIL ("ScriptPlaceOpenType() failed: %d", hr);
|
||||||
|
|
||||||
glyphs_offset += glyphs_len;
|
glyphs_offset += glyphs_len;
|
||||||
}
|
}
|
||||||
|
@ -285,9 +275,9 @@ retry:
|
||||||
|
|
||||||
buffer->ensure (glyphs_len);
|
buffer->ensure (glyphs_len);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
FALLBACK ("Buffer in error");
|
FAIL ("Buffer in error");
|
||||||
|
|
||||||
#undef FALLBACK
|
#undef FAIL
|
||||||
|
|
||||||
/* Set glyph infos */
|
/* Set glyph infos */
|
||||||
for (unsigned int i = 0; i < glyphs_len; i++)
|
for (unsigned int i = 0; i < glyphs_len; i++)
|
||||||
|
@ -317,7 +307,7 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wow, done! */
|
/* Wow, done! */
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,12 @@
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
void
|
hb_bool_t
|
||||||
hb_uniscribe_shape (hb_font_t *font,
|
hb_uniscribe_shape (hb_font_t *font,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
const hb_feature_t *features,
|
const hb_feature_t *features,
|
||||||
unsigned int num_features);
|
unsigned int num_features,
|
||||||
|
const char *shaper_options);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
|
@ -370,7 +370,7 @@ _hb_cr_text_glyphs (cairo_t *cr,
|
||||||
len = strlen (utf8);
|
len = strlen (utf8);
|
||||||
hb_buffer_add_utf8 (hb_buffer, utf8, len, 0, len);
|
hb_buffer_add_utf8 (hb_buffer, utf8, len, 0, len);
|
||||||
|
|
||||||
hb_shape (hb_font, hb_buffer, features, num_features);
|
hb_shape (hb_font, hb_buffer, features, num_features, NULL, NULL);
|
||||||
|
|
||||||
num_glyphs = hb_buffer_get_length (hb_buffer);
|
num_glyphs = hb_buffer_get_length (hb_buffer);
|
||||||
hb_glyph = hb_buffer_get_glyph_infos (hb_buffer, NULL);
|
hb_glyph = hb_buffer_get_glyph_infos (hb_buffer, NULL);
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
#include "hb-uniscribe.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_GLIB
|
#ifdef HAVE_GLIB
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
@ -97,7 +96,7 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
hb_buffer_add_utf8 (buffer, "test", 4, 0, 4);
|
hb_buffer_add_utf8 (buffer, "test", 4, 0, 4);
|
||||||
|
|
||||||
hb_uniscribe_shape (font, buffer, NULL, 0);
|
hb_shape (font, buffer, NULL, 0, NULL, NULL);
|
||||||
|
|
||||||
unsigned int count = hb_buffer_get_length (buffer);
|
unsigned int count = hb_buffer_get_length (buffer);
|
||||||
hb_glyph_info_t *infos = hb_buffer_get_glyph_infos (buffer, NULL);
|
hb_glyph_info_t *infos = hb_buffer_get_glyph_infos (buffer, NULL);
|
||||||
|
|
|
@ -110,7 +110,7 @@ test_shape (void)
|
||||||
hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
|
hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
|
||||||
hb_buffer_add_utf8 (buffer, TesT, 4, 0, 4);
|
hb_buffer_add_utf8 (buffer, TesT, 4, 0, 4);
|
||||||
|
|
||||||
hb_shape (font, buffer, NULL, 0);
|
hb_shape (font, buffer, NULL, 0, NULL, NULL);
|
||||||
|
|
||||||
len = hb_buffer_get_length (buffer);
|
len = hb_buffer_get_length (buffer);
|
||||||
glyphs = hb_buffer_get_glyph_infos (buffer, NULL);
|
glyphs = hb_buffer_get_glyph_infos (buffer, NULL);
|
||||||
|
|
Loading…
Reference in New Issue