summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/tt_gsub.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm-x/tt_gsub.c')
-rw-r--r--Build/source/texk/dvipdfm-x/tt_gsub.c175
1 files changed, 171 insertions, 4 deletions
diff --git a/Build/source/texk/dvipdfm-x/tt_gsub.c b/Build/source/texk/dvipdfm-x/tt_gsub.c
index 3151e9ed9f7..86d5e8c0e5e 100644
--- a/Build/source/texk/dvipdfm-x/tt_gsub.c
+++ b/Build/source/texk/dvipdfm-x/tt_gsub.c
@@ -1269,10 +1269,16 @@ otl_gsub_apply_ligature (struct otl_gsub_subtab *subtab,
}
#define GSUB_LIST_MAX 32
+struct gsub_entry {
+ int index;
+ struct gsub_entry *next;
+};
+
struct otl_gsub
{
int num_gsubs;
int select;
+ struct gsub_entry *first;
struct otl_gsub_tab gsubs[GSUB_LIST_MAX];
};
@@ -1284,10 +1290,21 @@ otl_gsub_new (void)
gsub_list = NEW(1, struct otl_gsub);
gsub_list->num_gsubs = 0;
gsub_list->select = -1;
+ gsub_list->first = NULL;
return (otl_gsub *) gsub_list;
}
+static void
+clear_chain (otl_gsub *gsub_list) {
+ struct gsub_entry *entry, *next;
+ for (entry = gsub_list->first; entry != NULL; entry = next) {
+ next = entry->next;
+ RELEASE(entry);
+ }
+ gsub_list->first = NULL;
+}
+
int
otl_gsub_add_feat (otl_gsub *gsub_list,
const char *script,
@@ -1342,6 +1359,56 @@ otl_gsub_add_feat (otl_gsub *gsub_list,
return retval;
}
+static const char *
+scan_otl_tag (const char *otl_tags, const char *endptr,
+ char *script, char *language, char *feature)
+{
+ const char *p, *period;
+
+ ASSERT(script && language && feature);
+ ASSERT(otl_tags < endptr);
+
+ if (!otl_tags)
+ return NULL;
+
+ memset(script, ' ', 4); script[4] = 0;
+ memset(language, ' ', 4); language[4] = 0;
+ memset(feature, ' ', 4); feature[4] = 0;
+
+ /* First parse otl_tags variable */
+ p = otl_tags;
+ period = strchr(p, '.');
+ if (period && period < endptr) {
+ /* Format scrp.lang.feat */
+ if (period < p + 5) {
+ strncpy(script, p, period - p);
+ } else {
+ WARN("Invalid OTL script tag found: %s", p);
+ }
+ p = period + 1;
+ period = strchr(p, '.');
+ if (period && period < endptr) {
+ /* Now lang part */
+ if (period < p + 5) {
+ strncpy(language, p, period - p);
+ } else {
+ WARN("Invalid OTL lanuage tag found: %s", p);
+ }
+ p = period + 1;
+ }
+ } else {
+ strcpy(script, "*");
+ strcpy(language, "*");
+ }
+ /* Finally feature */
+ if (p < endptr) {
+ strncpy(feature, p, endptr - p);
+ p = endptr;
+ }
+
+ return p;
+}
+
void
otl_gsub_release (otl_gsub *gsub_list)
{
@@ -1381,7 +1448,7 @@ otl_gsub_release (otl_gsub *gsub_list)
}
RELEASE(gsub->subtables);
}
-
+ clear_chain(gsub_list);
RELEASE(gsub_list);
}
@@ -1487,7 +1554,7 @@ otl_gsub_apply_lig (otl_gsub *gsub_list,
}
int
-otl_gsub_select (otl_gsub *gsub_list,
+gsub_find (otl_gsub *gsub_list,
const char *script,
const char *language,
const char *feature)
@@ -1500,14 +1567,114 @@ otl_gsub_select (otl_gsub *gsub_list,
if (!strcmp(gsub->script, script) &&
!strcmp(gsub->language, language) &&
!strcmp(gsub->feature, feature)) {
- gsub_list->select = i;
return i;
}
}
- gsub_list->select = -1;
+ return -1;
+}
+
+int
+otl_gsub_select (otl_gsub *gsub_list,
+ const char *script,
+ const char *language,
+ const char *feature)
+{
+ gsub_list->select = gsub_find(gsub_list, script, language, feature);
+ return gsub_list->select;
+}
+
+int
+otl_gsub_set_chain (otl_gsub *gsub_list, const char *otl_tags) {
+ struct gsub_entry *prev = NULL;
+ const char *p, *nextptr, *endptr;
+ char script[5], language[5], feature[5];
+ int idx;
+
+ clear_chain(gsub_list);
+
+ endptr = otl_tags + strlen(otl_tags);
+ for (p = otl_tags; p < endptr; p = nextptr) {
+ nextptr = strchr(p, ':');
+ if (!nextptr)
+ nextptr = endptr;
+ scan_otl_tag(p, nextptr, script, language, feature);
+ idx = gsub_find(gsub_list, script, language, feature);
+ if (idx >= 0 && idx <= gsub_list->num_gsubs) {
+ struct gsub_entry *entry;
+ entry = NEW(1, struct gsub_entry);
+ if (prev)
+ prev->next = entry;
+ entry->index = idx;
+ prev = entry;
+ }
+ nextptr++;
+ }
+ if (prev)
+ prev->next = NULL;
+ gsub_list->first = prev;
+
+ return 0;
+}
+
+int
+otl_gsub_add_feat_list (otl_gsub *gsub_list, const char *otl_tags, sfnt *sfont)
+{
+ const char *p, *nextptr, *endptr;
+ char script[5], language[5], feature[5];
+ int idx;
+ if (!gsub_list || !otl_tags || !sfont)
return -1;
+
+ clear_chain(gsub_list);
+ endptr = otl_tags + strlen(otl_tags);
+ for (p = otl_tags; p < endptr; p = nextptr) {
+ nextptr = strchr(p, ':');
+ if (!nextptr)
+ nextptr = endptr;
+ scan_otl_tag(p, nextptr, script, language, feature);
+ idx = gsub_find(gsub_list, script, language, feature);
+ if (idx < 0) {
+ otl_gsub_add_feat(gsub_list, script, language, feature, sfont);
+ }
+ nextptr++;
+ }
+
+ return 0;
+}
+
+int
+otl_gsub_apply_chain (otl_gsub *gsub_list, USHORT *gid) {
+ int retval = -1;
+ struct otl_gsub_tab *gsub;
+ struct otl_gsub_subtab *subtab;
+ struct gsub_entry *entry;
+ int i, idx;
+
+ if (!gsub_list || !gid)
+ return retval;
+
+ for (entry = gsub_list->first;
+ entry != NULL; entry = entry->next) {
+ idx = entry->index;
+ if (idx < 0 || idx >= gsub_list->num_gsubs)
+ continue;
+ gsub = &(gsub_list->gsubs[idx]);
+ for (i = 0, retval = -1;
+ retval < 0 && i < gsub->num_subtables; i++) {
+ subtab = &(gsub->subtables[i]);
+ switch ((int) subtab->LookupType){
+ case OTL_GSUB_TYPE_SINGLE:
+ retval = otl_gsub_apply_single(subtab, gid);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return retval;
}
#if 0