Commit e03febf2 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Add a stub Arabic shaper.

parent 142c06e5
......@@ -17,4 +17,5 @@ C_SRCS = \
mirror.c \
opentype.c \
scripts.c \
shape.c
shape.c \
shapers/arabic.c
......@@ -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;
......
......@@ -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)
{
......
......@@ -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);
......
/*
* 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,
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment