[v2 PATCH 5/5] dwrite: Add a stub Arabic shaper.
Nikolay Sivov
nsivov at codeweavers.com
Thu Jan 21 07:36:54 CST 2021
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/dwrite/Makefile.in | 3 +-
dlls/dwrite/dwrite_private.h | 71 +++++++++++++++++++++---------------
dlls/dwrite/opentype.c | 3 +-
dlls/dwrite/shape.c | 42 +++++++++++++++++++--
dlls/dwrite/shapers/arabic.c | 66 +++++++++++++++++++++++++++++++++
5 files changed, 150 insertions(+), 35 deletions(-)
create mode 100644 dlls/dwrite/shapers/arabic.c
diff --git a/dlls/dwrite/Makefile.in b/dlls/dwrite/Makefile.in
index c91ad0bd167..feac36f3cb2 100644
--- a/dlls/dwrite/Makefile.in
+++ b/dlls/dwrite/Makefile.in
@@ -17,4 +17,5 @@ C_SRCS = \
mirror.c \
opentype.c \
scripts.c \
- shape.c
+ shape.c \
+ shapers/arabic.c
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 485fcdb1f16..76d49ae5104 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -536,9 +536,51 @@ struct scriptshaping_context;
typedef void (*p_apply_context_lookup)(struct scriptshaping_context *context, unsigned int lookup_index);
+enum shaping_feature_flags
+{
+ FEATURE_GLOBAL = 0x1,
+ FEATURE_GLOBAL_SEARCH = 0x2,
+ FEATURE_MANUAL_ZWNJ = 0x4,
+ FEATURE_MANUAL_ZWJ = 0x8,
+ FEATURE_MANUAL_JOINERS = FEATURE_MANUAL_ZWNJ | FEATURE_MANUAL_ZWJ,
+};
+
+struct shaping_feature
+{
+ unsigned int tag;
+ unsigned int index;
+ unsigned int flags;
+ unsigned int max_value;
+ unsigned int default_value;
+ unsigned int mask;
+ unsigned int shift;
+ unsigned int stage;
+};
+
+struct shaping_features
+{
+ struct shaping_feature *features;
+ size_t count;
+ size_t capacity;
+ unsigned int stage;
+};
+
+struct shaper
+{
+ void (*collect_features)(struct scriptshaping_context *context, struct shaping_features *features);
+ void (*setup_masks)(struct scriptshaping_context *context, const struct shaping_features *features);
+};
+
+extern const struct shaper arabic_shaper DECLSPEC_HIDDEN;
+
+extern void shape_enable_feature(struct shaping_features *features, unsigned int tag,
+ unsigned int flags) DECLSPEC_HIDDEN;
+extern void shape_start_next_stage(struct shaping_features *features) DECLSPEC_HIDDEN;
+
struct scriptshaping_context
{
struct scriptshaping_cache *cache;
+ const struct shaper *shaper;
unsigned int script;
UINT32 language_tag;
@@ -615,35 +657,6 @@ extern struct scriptshaping_cache *create_scriptshaping_cache(void *context,
extern void release_scriptshaping_cache(struct scriptshaping_cache*) DECLSPEC_HIDDEN;
extern struct scriptshaping_cache *fontface_get_shaping_cache(struct dwrite_fontface *fontface) DECLSPEC_HIDDEN;
-enum shaping_feature_flags
-{
- FEATURE_GLOBAL = 0x1,
- FEATURE_GLOBAL_SEARCH = 0x2,
- FEATURE_MANUAL_ZWNJ = 0x4,
- FEATURE_MANUAL_ZWJ = 0x8,
- FEATURE_MANUAL_JOINERS = FEATURE_MANUAL_ZWNJ | FEATURE_MANUAL_ZWJ,
-};
-
-struct shaping_feature
-{
- unsigned int tag;
- unsigned int index;
- unsigned int flags;
- unsigned int max_value;
- unsigned int default_value;
- unsigned int mask;
- unsigned int shift;
- unsigned int stage;
-};
-
-struct shaping_features
-{
- struct shaping_feature *features;
- size_t count;
- size_t capacity;
- unsigned int stage;
-};
-
extern void opentype_layout_scriptshaping_cache_init(struct scriptshaping_cache *cache) DECLSPEC_HIDDEN;
extern DWORD opentype_layout_find_script(const struct scriptshaping_cache *cache, DWORD kind, DWORD tag,
unsigned int *script_index) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index a025227dfda..20534460d09 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -4647,7 +4647,8 @@ static void opentype_layout_set_glyph_masks(struct scriptshaping_context *contex
for (g = 0; g < context->glyph_count; ++g)
context->glyph_infos[g].mask = context->global_mask;
- /* FIXME: set shaper masks */
+ if (context->shaper->setup_masks)
+ context->shaper->setup_masks(context, features);
for (r = 0, start_char = 0; r < context->user_features.range_count; ++r)
{
diff --git a/dlls/dwrite/shape.c b/dlls/dwrite/shape.c
index 567ec5fa54f..53b392c88e2 100644
--- a/dlls/dwrite/shape.c
+++ b/dlls/dwrite/shape.c
@@ -27,6 +27,7 @@
#define COBJMACROS
#include "dwrite_private.h"
+#include "scripts.h"
#include "winternl.h"
#include "wine/debug.h"
@@ -135,6 +136,17 @@ static void shape_add_feature(struct shaping_features *features, unsigned int ta
shape_add_feature_full(features, tag, FEATURE_GLOBAL, 1);
}
+void shape_enable_feature(struct shaping_features *features, unsigned int tag,
+ unsigned int flags)
+{
+ shape_add_feature_full(features, tag, FEATURE_GLOBAL | flags, 1);
+}
+
+void shape_start_next_stage(struct shaping_features *features)
+{
+ features->stage++;
+}
+
static int features_sorting_compare(const void *a, const void *b)
{
const struct shaping_feature *left = a, *right = b;
@@ -187,6 +199,21 @@ static void shape_merge_features(struct scriptshaping_context *context, struct s
features->count = j + 1;
}
+static const struct shaper null_shaper;
+
+static void shape_set_shaper(struct scriptshaping_context *context)
+{
+ switch (context->script)
+ {
+ case Script_Arabic:
+ case Script_Syriac:
+ context->shaper = &arabic_shaper;
+ break;
+ default:
+ context->shaper = &null_shaper;
+ }
+}
+
HRESULT shape_get_positions(struct scriptshaping_context *context, const unsigned int *scripts)
{
static const struct shaping_feature common_features[] =
@@ -206,6 +233,8 @@ HRESULT shape_get_positions(struct scriptshaping_context *context, const unsigne
unsigned int script_index, language_index, script, i;
struct shaping_features features = { 0 };
+ shape_set_shaper(context);
+
for (i = 0; i < ARRAY_SIZE(common_features); ++i)
shape_add_feature_full(&features, common_features[i].tag, FEATURE_GLOBAL | common_features[i].flags, 1);
@@ -279,20 +308,25 @@ HRESULT shape_get_glyphs(struct scriptshaping_context *context, const unsigned i
struct shaping_features features = { 0 };
unsigned int i;
+ shape_set_shaper(context);
+
if (!context->is_sideways)
{
if (context->is_rtl)
{
- shape_add_feature(&features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','a'));
+ shape_enable_feature(&features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','a'), 0);
shape_add_feature_full(&features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','m'), 0, 1);
}
else
{
- shape_add_feature(&features, DWRITE_MAKE_OPENTYPE_TAG('l','t','r','a'));
- shape_add_feature(&features, DWRITE_MAKE_OPENTYPE_TAG('l','t','r','m'));
+ shape_enable_feature(&features, DWRITE_MAKE_OPENTYPE_TAG('l','t','r','a'), 0);
+ shape_enable_feature(&features, DWRITE_MAKE_OPENTYPE_TAG('l','t','r','m'), 0);
}
}
+ if (context->shaper->collect_features)
+ context->shaper->collect_features(context, &features);
+
for (i = 0; i < ARRAY_SIZE(common_features); ++i)
shape_add_feature(&features, common_features[i]);
@@ -303,7 +337,7 @@ HRESULT shape_get_glyphs(struct scriptshaping_context *context, const unsigned i
shape_add_feature(&features, horizontal_features[i]);
}
else
- shape_add_feature_full(&features, DWRITE_MAKE_OPENTYPE_TAG('v','e','r','t'), FEATURE_GLOBAL | FEATURE_GLOBAL_SEARCH, 1);
+ shape_enable_feature(&features, DWRITE_MAKE_OPENTYPE_TAG('v','e','r','t'), FEATURE_GLOBAL_SEARCH);
shape_merge_features(context, &features);
diff --git a/dlls/dwrite/shapers/arabic.c b/dlls/dwrite/shapers/arabic.c
new file mode 100644
index 00000000000..d8c6c9495c0
--- /dev/null
+++ b/dlls/dwrite/shapers/arabic.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright HarfBuzz Project authors
+ * Copyright 2020 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "dwrite_private.h"
+
+static const unsigned int arabic_features[] =
+{
+ DWRITE_MAKE_OPENTYPE_TAG('i','s','o','l'),
+ DWRITE_MAKE_OPENTYPE_TAG('f','i','n','a'),
+ DWRITE_MAKE_OPENTYPE_TAG('f','i','n','2'),
+ DWRITE_MAKE_OPENTYPE_TAG('f','i','n','3'),
+ DWRITE_MAKE_OPENTYPE_TAG('m','e','d','i'),
+ DWRITE_MAKE_OPENTYPE_TAG('m','e','d','2'),
+ DWRITE_MAKE_OPENTYPE_TAG('i','n','i','t'),
+};
+
+static void arabic_collect_features(struct scriptshaping_context *context,
+ struct shaping_features *features)
+{
+ unsigned int i;
+
+ shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('c','c','m','p'), 0);
+ shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('l','o','c','l'), 0);
+ shape_start_next_stage(features);
+
+ for (i = 0; i < ARRAY_SIZE(arabic_features); ++i)
+ {
+ shape_enable_feature(features, arabic_features[i], 0);
+ shape_start_next_stage(features);
+ }
+
+ shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('r','l','i','g'), FEATURE_MANUAL_ZWJ);
+
+ shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('r','c','l','t'), FEATURE_MANUAL_ZWJ);
+ shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('c','a','l','t'), FEATURE_MANUAL_ZWJ);
+ shape_start_next_stage(features);
+
+ shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('m','s','e','t'), 0);
+}
+
+static void arabic_setup_masks(struct scriptshaping_context *context,
+ const struct shaping_features *features)
+{
+}
+
+const struct shaper arabic_shaper =
+{
+ arabic_collect_features,
+ arabic_setup_masks,
+};
--
2.29.2
More information about the wine-devel
mailing list