summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp')
-rw-r--r--Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp1029
1 files changed, 0 insertions, 1029 deletions
diff --git a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp b/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
deleted file mode 100644
index 9ca0aca41e4..00000000000
--- a/Build/source/texk/web2c/xetexdir/XeTeXLayoutInterface.cpp
+++ /dev/null
@@ -1,1029 +0,0 @@
-/****************************************************************************\
- Part of the XeTeX typesetting system
- Copyright (c) 1994-2008 by SIL International
- Copyright (c) 2009-2012 by Jonathan Kew
- Copyright (c) 2012-2019 by Khaled Hosny
-
- SIL Author(s): Jonathan Kew
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
-FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the copyright holders
-shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in this Software without prior written
-authorization from the copyright holders.
-\****************************************************************************/
-
-#include <w2c/config.h>
-
-#include <unicode/platform.h> // We need this first
-#include <unicode/ubidi.h>
-#include <unicode/utext.h>
-
-#include <graphite2/Font.h>
-#include <graphite2/Segment.h>
-#include <hb.h>
-#include <hb-graphite2.h>
-#if !HB_VERSION_ATLEAST(2,5,0)
-#include <hb-icu.h>
-#endif
-#include <hb-ot.h>
-
-#include "XeTeX_web.h"
-
-#include "XeTeXLayoutInterface.h"
-#include "XeTeXFontInst.h"
-#ifdef XETEX_MAC
-#include "XeTeXFontInst_Mac.h"
-#endif
-#include "XeTeXFontMgr.h"
-
-struct XeTeXLayoutEngine_rec
-{
- XeTeXFontInst* font;
- PlatformFontRef fontRef;
- hb_tag_t script;
- hb_language_t language;
- hb_feature_t* features;
- char** ShaperList; // the requested shapers
- char* shaper; // the actually used shaper
- int nFeatures;
- uint32_t rgbValue;
- float extend;
- float slant;
- float embolden;
- hb_buffer_t* hbBuffer;
-};
-
-/*******************************************************************/
-/* Glyph bounding box cache to speed up \XeTeXuseglyphmetrics mode */
-/*******************************************************************/
-#include <map>
-
-// key is combined value representing (font_id << 16) + glyph
-// value is glyph bounding box in TeX points
-static std::map<uint32_t,GlyphBBox> sGlyphBoxes;
-
-int
-getCachedGlyphBBox(uint16_t fontID, uint16_t glyphID, GlyphBBox* bbox)
-{
- uint32_t key = ((uint32_t)fontID << 16) + glyphID;
- std::map<uint32_t,GlyphBBox>::const_iterator i = sGlyphBoxes.find(key);
- if (i == sGlyphBoxes.end()) {
- return 0;
- }
- *bbox = i->second;
- return 1;
-}
-
-void
-cacheGlyphBBox(uint16_t fontID, uint16_t glyphID, const GlyphBBox* bbox)
-{
- uint32_t key = ((uint32_t)fontID << 16) + glyphID;
- sGlyphBoxes[key] = *bbox;
-}
-/*******************************************************************/
-
-void
-terminatefontmanager()
-{
- XeTeXFontMgr::Terminate();
-}
-
-XeTeXFont
-createFont(PlatformFontRef fontRef, Fixed pointSize)
-{
- int status = 0;
-#ifdef XETEX_MAC
- XeTeXFontInst* font = new XeTeXFontInst_Mac(fontRef, Fix2D(pointSize), status);
-#else
- FcChar8* pathname = 0;
- FcPatternGetString(fontRef, FC_FILE, 0, &pathname);
- int index;
- FcPatternGetInteger(fontRef, FC_INDEX, 0, &index);
- XeTeXFontInst* font = new XeTeXFontInst((const char*)pathname, index, Fix2D(pointSize), status);
-#endif
- if (status != 0) {
- delete font;
- return NULL;
- }
- return (XeTeXFont)font;
-}
-
-XeTeXFont
-createFontFromFile(const char* filename, int index, Fixed pointSize)
-{
- int status = 0;
- XeTeXFontInst* font = new XeTeXFontInst(filename, index, Fix2D(pointSize), status);
- if (status != 0) {
- delete font;
- return NULL;
- }
- return (XeTeXFont)font;
-}
-
-void
-setFontLayoutDir(XeTeXFont font, int vertical)
-{
- ((XeTeXFontInst*)font)->setLayoutDirVertical(vertical != 0);
-}
-
-PlatformFontRef
-findFontByName(const char* name, char* var, double size)
-{
- return XeTeXFontMgr::GetFontManager()->findFont(name, var, size);
-}
-
-char
-getReqEngine()
-{
- return XeTeXFontMgr::GetFontManager()->getReqEngine();
-}
-
-void
-setReqEngine(char reqEngine)
-{
- XeTeXFontMgr::GetFontManager()->setReqEngine(reqEngine);
-}
-
-const char*
-getFullName(PlatformFontRef fontRef)
-{
- return XeTeXFontMgr::GetFontManager()->getFullName(fontRef);
-}
-
-double
-getDesignSize(XeTeXFont font)
-{
- return XeTeXFontMgr::GetFontManager()->getDesignSize(font);
-}
-
-char*
-getFontFilename(XeTeXLayoutEngine engine, uint32_t* index)
-{
- return xstrdup(engine->font->getFilename(index));
-}
-
-PlatformFontRef
-getFontRef(XeTeXLayoutEngine engine)
-{
- return engine->fontRef;
-}
-
-void
-deleteFont(XeTeXFont font)
-{
- delete (XeTeXFontInst*)font;
-}
-
-void*
-getFontTablePtr(XeTeXFont font, uint32_t tableTag)
-{
- return const_cast<void*>(((XeTeXFontInst*)font)->getFontTable(tableTag));
-}
-
-Fixed
-getSlant(XeTeXFont font)
-{
- float italAngle = ((XeTeXFontInst*)font)->getItalicAngle();
- return D2Fix(tan(-italAngle * M_PI / 180.0));
-}
-
-static unsigned int
-getLargerScriptListTable(XeTeXFont font, hb_tag_t** scriptList)
-{
- unsigned int rval = 0;
-
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
-
- hb_tag_t* scriptListSub = NULL;
- hb_tag_t* scriptListPos = NULL;
-
- unsigned int scriptCountSub = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL);
- scriptListSub = (hb_tag_t*) xcalloc(scriptCountSub, sizeof(hb_tag_t*));
- hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCountSub, scriptListSub);
-
- unsigned int scriptCountPos = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GPOS, 0, NULL, NULL);
- scriptListPos = (hb_tag_t*) xcalloc(scriptCountPos, sizeof(hb_tag_t*));
- hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCountPos, scriptListPos);
-
- if (scriptCountSub > scriptCountPos) {
- if (scriptList != NULL)
- *scriptList = scriptListSub;
- rval = scriptCountSub;
- } else {
- if (scriptList != NULL)
- *scriptList = scriptListPos;
- rval = scriptCountPos;
- }
-
- return rval;
-}
-
-unsigned int
-countScripts(XeTeXFont font)
-{
- return getLargerScriptListTable(font, NULL);
-}
-
-hb_tag_t
-getIndScript(XeTeXFont font, unsigned int index)
-{
- hb_tag_t rval = 0;
-
- hb_tag_t* scriptList;
-
- unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
- if (scriptList != NULL) {
- if (index < scriptCount)
- rval = scriptList[index];
- }
-
- return rval;
-}
-
-unsigned int
-countLanguages(XeTeXFont font, hb_tag_t script)
-{
- unsigned int rval = 0;
-
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
- hb_tag_t* scriptList;
-
- unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
- if (scriptList != NULL) {
- for (int i = 0; i < scriptCount; i++) {
- if (scriptList[i] == script) {
- rval += hb_ot_layout_script_get_language_tags (face, HB_OT_TAG_GSUB, i, 0, NULL, NULL);
- rval += hb_ot_layout_script_get_language_tags (face, HB_OT_TAG_GPOS, i, 0, NULL, NULL);
- break;
- }
- }
- }
-
- return rval;
-}
-
-hb_tag_t
-getIndLanguage(XeTeXFont font, hb_tag_t script, unsigned int index)
-{
- hb_tag_t rval = 0;
-
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
- hb_tag_t* scriptList;
-
- unsigned int scriptCount = getLargerScriptListTable(font, &scriptList);
- if (scriptList != NULL) {
- for (int i = 0; i < scriptCount; i++) {
- if (scriptList[i] == script) {
- unsigned int langCount;
- hb_tag_t* langList;
-
- langCount = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, NULL, NULL);
- langList = (hb_tag_t*) xcalloc(langCount, sizeof(hb_tag_t*));
- hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, &langCount, langList);
-
- if (index < langCount) {
- rval = langList[index];
- break;
- }
-
- free(langList);
-
- langCount = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GPOS, i, 0, NULL, NULL);
- langList = (hb_tag_t*) xcalloc(langCount, sizeof(hb_tag_t*));
- hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GPOS, i, 0, &langCount, langList);
-
- if (index < langCount) {
- rval = langList[index];
- break;
- }
-
- free(langList);
- }
- }
- }
-
- return rval;
-}
-
-unsigned int
-countFeatures(XeTeXFont font, hb_tag_t script, hb_tag_t language)
-{
- unsigned int rval = 0;
-
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
-
- for (int i = 0; i < 2; ++i) {
- unsigned int scriptIndex, langIndex = 0;
- hb_tag_t tableTag = i == 0 ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
- if (hb_ot_layout_table_find_script(face, tableTag, script, &scriptIndex)) {
- if (hb_ot_layout_script_find_language(face, tableTag, scriptIndex, language, &langIndex) || language == 0) {
- rval += hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, NULL, NULL);
- }
- }
- }
-
- return rval;
-}
-
-hb_tag_t
-getIndFeature(XeTeXFont font, hb_tag_t script, hb_tag_t language, unsigned int index)
-{
- hb_tag_t rval = 0;
-
- hb_face_t* face = hb_font_get_face(((XeTeXFontInst*)font)->getHbFont());
-
- for (int i = 0; i < 2; ++i) {
- unsigned int scriptIndex, langIndex = 0;
- hb_tag_t tableTag = i == 0 ? HB_OT_TAG_GSUB : HB_OT_TAG_GPOS;
- if (hb_ot_layout_table_find_script(face, tableTag, script, &scriptIndex)) {
- if (hb_ot_layout_script_find_language(face, tableTag, scriptIndex, language, &langIndex) || language == 0) {
- unsigned int featCount = hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, NULL, NULL);
- hb_tag_t* featList = (hb_tag_t*) xcalloc(featCount, sizeof(hb_tag_t*));
- hb_ot_layout_language_get_feature_tags(face, tableTag, scriptIndex, langIndex, 0, &featCount, featList);
-
- if (index < featCount) {
- rval = featList[index];
- break;
- }
-
- index -= featCount;
- }
- }
- }
-
- return rval;
-}
-
-uint32_t
-countGraphiteFeatures(XeTeXLayoutEngine engine)
-{
- uint32_t rval = 0;
-
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL)
- rval = gr_face_n_fref(grFace);
-
- return rval;
-}
-
-uint32_t
-getGraphiteFeatureCode(XeTeXLayoutEngine engine, uint32_t index)
-{
- uint32_t rval = 0;
-
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_fref(grFace, index);
- rval = gr_fref_id(feature);
- }
-
- return rval;
-}
-
-uint32_t
-countGraphiteFeatureSettings(XeTeXLayoutEngine engine, uint32_t featureID)
-{
- uint32_t rval = 0;
-
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- rval = gr_fref_n_values(feature);
- }
-
- return rval;
-}
-
-uint32_t
-getGraphiteFeatureSettingCode(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t index)
-{
- uint32_t rval = 0;
-
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- rval = gr_fref_value(feature, index);
- }
-
- return rval;
-}
-
-#define tag_from_lang(x) hb_tag_from_string(hb_language_to_string(x), strlen(hb_language_to_string(x)))
-
-uint32_t
-getGraphiteFeatureDefaultSetting(XeTeXLayoutEngine engine, uint32_t featureID)
-{
- uint32_t rval = 0;
-
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- gr_feature_val *featureValues = gr_face_featureval_for_lang (grFace, tag_from_lang(engine->language));
-
- rval = gr_fref_feature_value(feature, featureValues);
- }
-
- return rval;
-}
-
-char *
-getGraphiteFeatureLabel(XeTeXLayoutEngine engine, uint32_t featureID)
-{
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- uint32_t len = 0;
- uint16_t langID = 0x409;
-
- return (char *) gr_fref_label(feature, &langID, gr_utf8, &len);
- }
-
- return NULL;
-}
-
-char *
-getGraphiteFeatureSettingLabel(XeTeXLayoutEngine engine, uint32_t featureID, uint32_t settingID)
-{
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, featureID);
- for (int i = 0; i < gr_fref_n_values(feature); i++) {
- if (settingID == gr_fref_value(feature, i)) {
- uint32_t len = 0;
- uint16_t langID = 0x409;
-
- return (char *) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
- }
- }
- }
-
- return NULL;
-}
-
-bool
-findGraphiteFeature(XeTeXLayoutEngine engine, const char* s, const char* e, hb_tag_t* f, int* v)
- /* s...e is a "feature=setting" string; look for this in the font */
-{
- *f = 0;
- *v = 0;
- while (*s == ' ' || *s == '\t')
- ++s;
- const char* cp = s;
- while (cp < e && *cp != '=')
- ++cp;
-
- *f = findGraphiteFeatureNamed(engine, s, cp - s);
- if (*f == -1)
- return false;
-
- ++cp;
- while (cp < e && (*cp == ' ' || *cp == '\t'))
- ++cp;
-
- if (cp == e)
- /* no setting was specified */
- return false;
-
- *v = findGraphiteFeatureSettingNamed(engine, *f, cp, e - cp);
- if (*v == -1)
- return false;
-
- return true;
-}
-
-long
-findGraphiteFeatureNamed(XeTeXLayoutEngine engine, const char* name, int namelength)
-{
- long rval = -1;
-
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- for (int i = 0; i < gr_face_n_fref(grFace); i++) {
- const gr_feature_ref* feature = gr_face_fref(grFace, i);
- uint32_t len = 0;
- uint16_t langID = 0x409;
-
- // the first call is to get the length of the string
- gr_fref_label(feature, &langID, gr_utf8, &len);
- char* label = (char*) xmalloc(len);
- label = (char*) gr_fref_label(feature, &langID, gr_utf8, &len);
-
- if (strncmp(label, name, namelength) == 0) {
- rval = gr_fref_id(feature);
- gr_label_destroy(label);
- break;
- }
-
- gr_label_destroy(label);
- }
- }
-
- return rval;
-}
-
-long
-findGraphiteFeatureSettingNamed(XeTeXLayoutEngine engine, uint32_t id, const char* name, int namelength)
-{
- long rval = -1;
-
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
-
- if (grFace != NULL) {
- const gr_feature_ref* feature = gr_face_find_fref(grFace, id);
- for (int i = 0; i < gr_fref_n_values(feature); i++) {
- uint32_t len = 0;
- uint16_t langID = 0x409;
-
- // the first call is to get the length of the string
- gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
- char* label = (char*) xmalloc(len);
- label = (char*) gr_fref_value_label(feature, i, &langID, gr_utf8, &len);
-
- if (strncmp(label, name, namelength) == 0) {
- rval = gr_fref_value(feature, i);
- gr_label_destroy(label);
- break;
- }
-
- gr_label_destroy(label);
- }
- }
-
- return rval;
-}
-
-float
-getGlyphWidth(XeTeXFont font, uint32_t gid)
-{
- return ((XeTeXFontInst*)font)->getGlyphWidth(gid);
-}
-
-unsigned int
-countGlyphs(XeTeXFont font)
-{
- return ((XeTeXFontInst*)font)->getNumGlyphs();
-}
-
-XeTeXFont
-getFont(XeTeXLayoutEngine engine)
-{
- return (XeTeXFont)(engine->font);
-}
-
-float
-getExtendFactor(XeTeXLayoutEngine engine)
-{
- return engine->extend;
-}
-
-float
-getSlantFactor(XeTeXLayoutEngine engine)
-{
- return engine->slant;
-}
-
-float
-getEmboldenFactor(XeTeXLayoutEngine engine)
-{
- return engine->embolden;
-}
-
-XeTeXLayoutEngine
-createLayoutEngine(PlatformFontRef fontRef, XeTeXFont font, hb_tag_t script, char *language,
- hb_feature_t* features, int nFeatures, char **shapers, uint32_t rgbValue,
- float extend, float slant, float embolden)
-{
- XeTeXLayoutEngine result = new XeTeXLayoutEngine_rec;
- result->fontRef = fontRef;
- result->font = (XeTeXFontInst*)font;
- result->script = script;
- result->features = features;
- result->ShaperList = shapers;
- result->shaper = NULL;
- result->nFeatures = nFeatures;
- result->rgbValue = rgbValue;
- result->extend = extend;
- result->slant = slant;
- result->embolden = embolden;
- result->hbBuffer = hb_buffer_create();
-
- // For Graphite fonts treat the language as BCP 47 tag, for OpenType we
- // treat it as a OT language tag for backward compatibility with pre-0.9999
- // XeTeX.
- if (getReqEngine() == 'G')
- result->language = hb_language_from_string(language, -1);
- else
- result->language = hb_ot_tag_to_language(hb_tag_from_string(language, -1));
-
- free(language);
-
- return result;
-}
-
-void
-deleteLayoutEngine(XeTeXLayoutEngine engine)
-{
- hb_buffer_destroy(engine->hbBuffer);
- delete engine->font;
- free(engine->shaper);
-}
-
-#if !HB_VERSION_ATLEAST(2,5,0)
-static unsigned int
-_decompose_compat(hb_unicode_funcs_t* ufuncs,
- hb_codepoint_t u,
- hb_codepoint_t* decomposed,
- void* user_data)
-{
- return 0;
-}
-
-static hb_unicode_funcs_t*
-_get_unicode_funcs(void)
-{
- static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
- hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, _decompose_compat, NULL, NULL);
- return ufuncs;
-}
-#endif
-
-int
-layoutChars(XeTeXLayoutEngine engine, uint16_t chars[], int32_t offset, int32_t count, int32_t max,
- bool rightToLeft)
-{
- bool res;
- hb_script_t script = HB_SCRIPT_INVALID;
- hb_direction_t direction = HB_DIRECTION_LTR;
- hb_segment_properties_t segment_props;
- hb_shape_plan_t *shape_plan;
- hb_font_t* hbFont = engine->font->getHbFont();
- hb_face_t* hbFace = hb_font_get_face(hbFont);
-
- if (engine->font->getLayoutDirVertical())
- direction = HB_DIRECTION_TTB;
- else if (rightToLeft)
- direction = HB_DIRECTION_RTL;
-
- script = hb_ot_tag_to_script (engine->script);
-
- hb_buffer_reset(engine->hbBuffer);
-
-#if !HB_VERSION_ATLEAST(2,5,0)
- static hb_unicode_funcs_t* hbUnicodeFuncs = NULL;
- if (hbUnicodeFuncs == NULL)
- hbUnicodeFuncs = _get_unicode_funcs();
- hb_buffer_set_unicode_funcs(engine->hbBuffer, hbUnicodeFuncs);
-#endif
-
- hb_buffer_add_utf16(engine->hbBuffer, chars, max, offset, count);
- hb_buffer_set_direction(engine->hbBuffer, direction);
- hb_buffer_set_script(engine->hbBuffer, script);
- hb_buffer_set_language(engine->hbBuffer, engine->language);
-
- hb_buffer_guess_segment_properties(engine->hbBuffer);
- hb_buffer_get_segment_properties(engine->hbBuffer, &segment_props);
-
- if (engine->ShaperList == NULL) {
- // HarfBuzz gives graphite2 shaper a priority, so that for hybrid
- // Graphite/OpenType fonts, Graphite will be used. However, pre-0.9999
- // XeTeX preferred OpenType over Graphite, so we are doing the same
- // here for sake of backward compatibility. Since "ot" shaper never
- // fails, we set the shaper list to just include it.
- engine->ShaperList = (char**) xcalloc(2, sizeof(char*));
- engine->ShaperList[0] = (char*) "ot";
- engine->ShaperList[1] = NULL;
- }
-
- shape_plan = hb_shape_plan_create_cached(hbFace, &segment_props, engine->features, engine->nFeatures, engine->ShaperList);
- res = hb_shape_plan_execute(shape_plan, hbFont, engine->hbBuffer, engine->features, engine->nFeatures);
-
- if (res) {
- engine->shaper = strdup(hb_shape_plan_get_shaper(shape_plan));
- hb_buffer_set_content_type(engine->hbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
- } else {
- // all selected shapers failed, retrying with default
- // we don't use _cached here as the cached plain will always fail.
- hb_shape_plan_destroy(shape_plan);
- shape_plan = hb_shape_plan_create(hbFace, &segment_props, engine->features, engine->nFeatures, NULL);
- res = hb_shape_plan_execute(shape_plan, hbFont, engine->hbBuffer, engine->features, engine->nFeatures);
-
- if (res) {
- engine->shaper = strdup(hb_shape_plan_get_shaper(shape_plan));
- hb_buffer_set_content_type(engine->hbBuffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
- } else {
- fprintf(stderr, "\nERROR: all shapers failed\n");
- exit(3);
- }
- }
-
- hb_shape_plan_destroy(shape_plan);
-
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
-
-#ifdef DEBUG
- char buf[1024];
- unsigned int consumed;
-
- printf ("shaper: %s\n", engine->shaper);
-
- hb_buffer_serialize_flags_t flags = HB_BUFFER_SERIALIZE_FLAGS_DEFAULT;
- hb_buffer_serialize_format_t format = HB_BUFFER_SERIALIZE_FORMAT_JSON;
-
- hb_buffer_serialize_glyphs (engine->hbBuffer, 0, glyphCount, buf, sizeof(buf), &consumed, hbFont, format, flags);
- if (consumed)
- printf ("buffer glyphs: %s\n", buf);
-#endif
-
- return glyphCount;
-}
-
-void
-getGlyphs(XeTeXLayoutEngine engine, uint32_t glyphs[])
-{
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
- hb_glyph_info_t *hbGlyphs = hb_buffer_get_glyph_infos(engine->hbBuffer, NULL);
-
- for (int i = 0; i < glyphCount; i++)
- glyphs[i] = hbGlyphs[i].codepoint;
-}
-
-void
-getGlyphAdvances(XeTeXLayoutEngine engine, float advances[])
-{
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
- hb_glyph_position_t *hbPositions = hb_buffer_get_glyph_positions(engine->hbBuffer, NULL);
-
- for (int i = 0; i < glyphCount; i++) {
- if (engine->font->getLayoutDirVertical())
- advances[i] = engine->font->unitsToPoints(hbPositions[i].y_advance);
- else
- advances[i] = engine->font->unitsToPoints(hbPositions[i].x_advance);
- }
-}
-
-void
-getGlyphPositions(XeTeXLayoutEngine engine, FloatPoint positions[])
-{
- int glyphCount = hb_buffer_get_length(engine->hbBuffer);
- hb_glyph_position_t *hbPositions = hb_buffer_get_glyph_positions(engine->hbBuffer, NULL);
-
- float x = 0, y = 0;
-
- if (engine->font->getLayoutDirVertical()) {
- for (int i = 0; i < glyphCount; i++) {
- positions[i].x = -engine->font->unitsToPoints(x + hbPositions[i].y_offset); /* negative is forwards */
- positions[i].y = engine->font->unitsToPoints(y - hbPositions[i].x_offset);
- x += hbPositions[i].y_advance;
- y += hbPositions[i].x_advance;
- }
- positions[glyphCount].x = -engine->font->unitsToPoints(x);
- positions[glyphCount].y = engine->font->unitsToPoints(y);
- } else {
- for (int i = 0; i < glyphCount; i++) {
- positions[i].x = engine->font->unitsToPoints(x + hbPositions[i].x_offset);
- positions[i].y = -engine->font->unitsToPoints(y + hbPositions[i].y_offset); /* negative is upwards */
- x += hbPositions[i].x_advance;
- y += hbPositions[i].y_advance;
- }
- positions[glyphCount].x = engine->font->unitsToPoints(x);
- positions[glyphCount].y = -engine->font->unitsToPoints(y);
- }
-
- if (engine->extend != 1.0 || engine->slant != 0.0)
- for (int i = 0; i <= glyphCount; ++i)
- positions[i].x = positions[i].x * engine->extend - positions[i].y * engine->slant;
-}
-
-float
-getPointSize(XeTeXLayoutEngine engine)
-{
- return engine->font->getPointSize();
-}
-
-void
-getAscentAndDescent(XeTeXLayoutEngine engine, float* ascent, float* descent)
-{
- *ascent = engine->font->getAscent();
- *descent = engine->font->getDescent();
-}
-
-void
-getCapAndXHeight(XeTeXLayoutEngine engine, float* capheight, float* xheight)
-{
- *capheight = engine->font->getCapHeight();
- *xheight = engine->font->getXHeight();
-}
-
-int
-getDefaultDirection(XeTeXLayoutEngine engine)
-{
- hb_script_t script = hb_buffer_get_script(engine->hbBuffer);
- if (hb_script_get_horizontal_direction (script) == HB_DIRECTION_RTL)
- return UBIDI_DEFAULT_RTL;
- else
- return UBIDI_DEFAULT_LTR;
-}
-
-uint32_t
-getRgbValue(XeTeXLayoutEngine engine)
-{
- return engine->rgbValue;
-}
-
-void
-getGlyphBounds(XeTeXLayoutEngine engine, uint32_t glyphID, GlyphBBox* bbox)
-{
- engine->font->getGlyphBounds(glyphID, bbox);
- if (engine->extend != 0.0) {
- bbox->xMin *= engine->extend;
- bbox->xMax *= engine->extend;
- }
-}
-
-float
-getGlyphWidthFromEngine(XeTeXLayoutEngine engine, uint32_t glyphID)
-{
- return engine->extend * engine->font->getGlyphWidth(glyphID);
-}
-
-void
-getGlyphHeightDepth(XeTeXLayoutEngine engine, uint32_t glyphID, float* height, float* depth)
-{
- engine->font->getGlyphHeightDepth(glyphID, height, depth);
-}
-
-void
-getGlyphSidebearings(XeTeXLayoutEngine engine, uint32_t glyphID, float* lsb, float* rsb)
-{
- engine->font->getGlyphSidebearings(glyphID, lsb, rsb);
- if (engine->extend != 0.0) {
- *lsb *= engine->extend;
- *rsb *= engine->extend;
- }
-}
-
-float
-getGlyphItalCorr(XeTeXLayoutEngine engine, uint32_t glyphID)
-{
- return engine->extend * engine->font->getGlyphItalCorr(glyphID);
-}
-
-uint32_t
-mapCharToGlyph(XeTeXLayoutEngine engine, uint32_t charCode)
-{
- return engine->font->mapCharToGlyph(charCode);
-}
-
-int
-getFontCharRange(XeTeXLayoutEngine engine, int reqFirst)
-{
- if (reqFirst)
- return engine->font->getFirstCharCode();
- else
- return engine->font->getLastCharCode();
-}
-
-const char*
-getGlyphName(XeTeXFont font, uint16_t gid, int* len)
-{
- return ((XeTeXFontInst*)font)->getGlyphName(gid, *len);
-}
-
-int
-mapGlyphToIndex(XeTeXLayoutEngine engine, const char* glyphName)
-{
- return engine->font->mapGlyphToIndex(glyphName);
-}
-
-static gr_segment* grSegment = NULL;
-static const gr_slot* grPrevSlot = NULL;
-static int grTextLen;
-
-bool
-initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen)
-{
- hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
- gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
- gr_font* grFont = hb_graphite2_font_get_gr_font(engine->font->getHbFont());
- if (grFace != NULL && grFont != NULL) {
- if (grSegment != NULL) {
- gr_seg_destroy(grSegment);
- grSegment = NULL;
- grPrevSlot = NULL;
- }
-
- gr_feature_val *grFeatureValues = gr_face_featureval_for_lang (grFace, tag_from_lang(engine->language));
-
- int nFeatures = engine->nFeatures;
- hb_feature_t *features = engine->features;
- while (nFeatures--) {
- const gr_feature_ref *fref = gr_face_find_fref (grFace, features->tag);
- if (fref)
- gr_fref_set_feature_value (fref, features->value, grFeatureValues);
- features++;
- }
-
- grSegment = gr_make_seg(grFont, grFace, engine->script, grFeatureValues, gr_utf16, txtPtr, txtLen, 0);
- grPrevSlot = gr_seg_first_slot(grSegment);
- grTextLen = txtLen;
-
- return true;
- }
-
- return false;
-}
-
-int
-findNextGraphiteBreak(void)
-{
- int ret = -1;
-
- if (grSegment != NULL) {
- if (grPrevSlot && grPrevSlot != gr_seg_last_slot(grSegment)) {
- for (const gr_slot* s = gr_slot_next_in_segment(grPrevSlot); s != NULL; s = gr_slot_next_in_segment(s)) {
- const gr_char_info* ci = NULL;
- int bw;
-
- ci = gr_seg_cinfo(grSegment, gr_slot_index(s));
- bw = gr_cinfo_break_weight(ci);
- if (bw < gr_breakNone && bw >= gr_breakBeforeWord) {
- grPrevSlot = s;
- ret = gr_cinfo_base(ci);
- } else if (bw > gr_breakNone && bw <= gr_breakWord) {
- grPrevSlot = gr_slot_next_in_segment(s);
- ret = gr_cinfo_base(ci) + 1;
- }
-
- if (ret != -1)
- break;
- }
-
- if (ret == -1) {
- grPrevSlot = gr_seg_last_slot(grSegment);
- ret = grTextLen;
- }
- }
- }
-
- return ret;
-}
-
-bool
-usingGraphite(XeTeXLayoutEngine engine)
-{
- if (engine->shaper != NULL && (strcmp("graphite2", engine->shaper) == 0))
- return true;
- else
- return false;
-}
-
-bool
-usingOpenType(XeTeXLayoutEngine engine)
-{
- if (engine->shaper == NULL || (strcmp("ot", engine->shaper) == 0))
- return true;
- else
- return false;
-}
-
-bool
-isOpenTypeMathFont(XeTeXLayoutEngine engine)
-{
- return hb_ot_math_has_data(hb_font_get_face(engine->font->getHbFont()));
-}