2 * Glyph shaping support
4 * Copyright 2010 Aric Stewart for CodeWeavers
5 * Copyright 2014 Nikolay Sivov for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "dwrite_private.h"
26 struct scriptshaping_cache
28 IDWriteFontFace
*fontface
;
31 HRESULT
create_scriptshaping_cache(IDWriteFontFace
*fontface
, struct scriptshaping_cache
**cache
)
33 struct scriptshaping_cache
*ret
;
35 ret
= heap_alloc(sizeof(*ret
));
39 ret
->fontface
= fontface
;
40 IDWriteFontFace_AddRef(fontface
);
47 void release_scriptshaping_cache(struct scriptshaping_cache
*cache
)
51 IDWriteFontFace_Release(cache
->fontface
);
55 static void shape_update_clusters_from_glyphprop(UINT32 glyphcount
, UINT32 text_len
, UINT16
*clustermap
, DWRITE_SHAPING_GLYPH_PROPERTIES
*glyph_props
)
59 for (i
= 0; i
< glyphcount
; i
++) {
60 if (!glyph_props
[i
].isClusterStart
) {
63 for (j
= 0; j
< text_len
; j
++) {
64 if (clustermap
[j
] == i
) {
66 while (k
>= 0 && k
< text_len
&& !glyph_props
[clustermap
[k
]].isClusterStart
)
69 if (k
>= 0 && k
< text_len
&& glyph_props
[clustermap
[k
]].isClusterStart
)
70 clustermap
[j
] = clustermap
[k
];
77 static int compare_clustersearch(const void *a
, const void* b
)
79 UINT16 target
= *(UINT16
*)a
;
80 UINT16 index
= *(UINT16
*)b
;
85 else if (target
< index
)
91 /* Maps given glyph position in glyph indices array to text index this glyph represents.
92 Lowest possible index is returned.
94 clustermap [I] Text index to index in glyph indices array map
95 len [I] Clustermap size
96 target [I] Index in glyph indices array to map
98 static INT32
map_glyph_to_text_pos(const UINT16
*clustermap
, UINT32 len
, UINT16 target
)
103 ptr
= bsearch(&target
, clustermap
, len
, sizeof(UINT16
), compare_clustersearch
);
107 /* get to the beginning */
108 for (k
= (ptr
- clustermap
) - 1; k
>= 0 && clustermap
[k
] == target
; k
--)
115 static HRESULT
default_set_text_glyphs_props(struct scriptshaping_context
*context
, UINT16
*clustermap
, UINT16
*glyph_indices
,
116 UINT32 glyphcount
, DWRITE_SHAPING_TEXT_PROPERTIES
*text_props
, DWRITE_SHAPING_GLYPH_PROPERTIES
*glyph_props
)
120 for (i
= 0; i
< glyphcount
; i
++) {
121 UINT32 char_index
[20];
122 UINT32 char_count
= 0;
125 k
= map_glyph_to_text_pos(clustermap
, context
->length
, i
);
127 for (; k
< context
->length
&& clustermap
[k
] == i
; k
++)
128 char_index
[char_count
++] = k
;
134 if (char_count
== 1 && isspaceW(context
->text
[char_index
[0]])) {
135 glyph_props
[i
].justification
= SCRIPT_JUSTIFY_BLANK
;
136 text_props
[char_index
[0]].isShapedAlone
= context
->text
[char_index
[0]] == ' ';
139 glyph_props
[i
].justification
= SCRIPT_JUSTIFY_CHARACTER
;
142 /* FIXME: update properties using GDEF table */
143 shape_update_clusters_from_glyphprop(glyphcount
, context
->length
, clustermap
, glyph_props
);
148 static HRESULT
latn_set_text_glyphs_props(struct scriptshaping_context
*context
, UINT16
*clustermap
, UINT16
*glyph_indices
,
149 UINT32 glyphcount
, DWRITE_SHAPING_TEXT_PROPERTIES
*text_props
, DWRITE_SHAPING_GLYPH_PROPERTIES
*glyph_props
)
154 hr
= default_set_text_glyphs_props(context
, clustermap
, glyph_indices
, glyphcount
, text_props
, glyph_props
);
156 for (i
= 0; i
< glyphcount
; i
++)
157 if (glyph_props
[i
].isZeroWidthSpace
)
158 glyph_props
[i
].justification
= SCRIPT_JUSTIFY_NONE
;
163 const struct scriptshaping_ops latn_shaping_ops
=
166 latn_set_text_glyphs_props
169 const struct scriptshaping_ops default_shaping_ops
=
172 default_set_text_glyphs_props