mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
b=597147 part 15: set up PangoAnalysis for Pango shaping r=jfkthame
--HG-- extra : rebase_source : 89c6d15adbf7d82672939889aad64a80a36f945a
This commit is contained in:
parent
eb96d52f43
commit
f4f708456a
@ -552,9 +552,7 @@ OSUtils.h
|
||||
Packages.h
|
||||
Palettes.h
|
||||
PALM_CMN.H
|
||||
pango-engine.h
|
||||
pango-glyph.h
|
||||
pango-modules.h
|
||||
pango/pango-modules.h
|
||||
pango/pangocairo.h
|
||||
pango/pangofc-decoder.h
|
||||
pango/pangofc-font.h
|
||||
@ -564,7 +562,6 @@ pango/pango-fontmap.h
|
||||
pango/pango.h
|
||||
pango/pangoxft.h
|
||||
pango/pango-utils.h
|
||||
pango-types.h
|
||||
pascal.h
|
||||
Patches.h
|
||||
Path.h
|
||||
|
@ -43,6 +43,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#define PANGO_ENABLE_BACKEND
|
||||
#define PANGO_ENABLE_ENGINE
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "prlink.h"
|
||||
@ -62,6 +63,7 @@
|
||||
#include "gfxFT2FontBase.h"
|
||||
#include "gfxFT2Utils.h"
|
||||
#include "harfbuzz/hb-unicode.h"
|
||||
#include "harfbuzz/hb-ot-tag.h"
|
||||
#include "gfxUnicodeProperties.h"
|
||||
#include "gfxFontconfigUtils.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
@ -74,6 +76,7 @@
|
||||
|
||||
#include <fontconfig/fcfreetype.h>
|
||||
#include <pango/pango.h>
|
||||
#include <pango/pango-modules.h>
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
@ -535,6 +538,11 @@ public:
|
||||
nsresult InitGlyphRunFast(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString, PRUint32 aLength);
|
||||
#endif
|
||||
PRBool InitGlyphRunWithPango(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart, PRUint32 aRunLength,
|
||||
PangoScript aScript);
|
||||
|
||||
// The PangoFont returned is owned by the gfxFcFont
|
||||
PangoFont *GetPangoFont() {
|
||||
if (!mPangoFont) {
|
||||
@ -3199,11 +3207,11 @@ SetMissingGlyphs(gfxTextRun *aTextRun, const gchar *aUTF8,
|
||||
}
|
||||
|
||||
static void
|
||||
InitGlyphRunWithPango(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 *aUTF16Offset,
|
||||
PangoAnalysis *aAnalysis,
|
||||
PangoGlyphUnit aOverrideSpaceWidth)
|
||||
InitGlyphRunWithPangoAnalysis(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 *aUTF16Offset,
|
||||
PangoAnalysis *aAnalysis,
|
||||
PangoGlyphUnit aOverrideSpaceWidth)
|
||||
{
|
||||
PRUint32 utf16Offset = *aUTF16Offset;
|
||||
PangoGlyphString *glyphString = pango_glyph_string_new();
|
||||
@ -3236,6 +3244,165 @@ InitGlyphRunWithPango(gfxTextRun *aTextRun,
|
||||
*aUTF16Offset = utf16Offset;
|
||||
}
|
||||
|
||||
// PangoAnalysis is part of Pango's ABI but over time extra fields have been
|
||||
// inserted into padding. This union is used so that the code here can be
|
||||
// compiled against older Pango versions but run against newer versions.
|
||||
typedef union {
|
||||
PangoAnalysis pango;
|
||||
// This struct matches PangoAnalysis from Pango version
|
||||
// 1.16.5 to 1.28.1 (at least).
|
||||
struct {
|
||||
PangoEngineShape *shape_engine;
|
||||
PangoEngineLang *lang_engine;
|
||||
PangoFont *font;
|
||||
guint8 level;
|
||||
guint8 gravity; /* PangoGravity */
|
||||
guint8 flags;
|
||||
guint8 script; /* PangoScript */
|
||||
PangoLanguage *language;
|
||||
GSList *extra_attrs;
|
||||
} local;
|
||||
} PangoAnalysisUnion;
|
||||
|
||||
PRBool
|
||||
gfxFcFont::InitGlyphRunWithPango(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aRunStart, PRUint32 aRunLength,
|
||||
PangoScript aScript)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 utf8(aString + aRunStart, aRunLength);
|
||||
|
||||
PangoFont *font = GetPangoFont();
|
||||
gfxPangoFontGroup *fontGroup =
|
||||
static_cast<gfxPangoFontGroup*>(aTextRun->GetFontGroup());
|
||||
|
||||
hb_language_t languageOverride = NULL;
|
||||
if (fontGroup->GetStyle()->languageOverride) {
|
||||
languageOverride =
|
||||
hb_ot_tag_to_language(fontGroup->GetStyle()->languageOverride);
|
||||
} else if (GetFontEntry()->mLanguageOverride) {
|
||||
languageOverride =
|
||||
hb_ot_tag_to_language(GetFontEntry()->mLanguageOverride);
|
||||
}
|
||||
|
||||
PangoLanguage *language;
|
||||
if (languageOverride) {
|
||||
language =
|
||||
pango_language_from_string(hb_language_to_string(languageOverride));
|
||||
} else {
|
||||
language = fontGroup->GetPangoLanguage();
|
||||
// The language that we have here is often not as good an indicator for
|
||||
// the run as the script. This is not so important for the PangoMaps
|
||||
// here as all the default Pango shape and lang engines are selected
|
||||
// by script only (not language) anyway, but may be important in the
|
||||
// PangoAnalysis as the shaper sometimes accesses language-specific
|
||||
// tables.
|
||||
const PangoScript script = static_cast<PangoScript>(aScript);
|
||||
PangoLanguage *scriptLang;
|
||||
if ((!language ||
|
||||
!pango_language_includes_script(language, script)) &&
|
||||
(scriptLang = pango_script_get_sample_language(script))) {
|
||||
language = scriptLang;
|
||||
}
|
||||
}
|
||||
|
||||
static GQuark engineLangId =
|
||||
g_quark_from_static_string(PANGO_ENGINE_TYPE_LANG);
|
||||
static GQuark renderNoneId =
|
||||
g_quark_from_static_string(PANGO_RENDER_TYPE_NONE);
|
||||
PangoMap *langMap = pango_find_map(language, engineLangId, renderNoneId);
|
||||
|
||||
static GQuark engineShapeId =
|
||||
g_quark_from_static_string(PANGO_ENGINE_TYPE_SHAPE);
|
||||
static GQuark renderFcId =
|
||||
g_quark_from_static_string(PANGO_RENDER_TYPE_FC);
|
||||
PangoMap *shapeMap = pango_find_map(language, engineShapeId, renderFcId);
|
||||
if (!shapeMap) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// The preferred shape engine for language and script
|
||||
PangoEngineShape *shapeEngine =
|
||||
PANGO_ENGINE_SHAPE(pango_map_get_engine(shapeMap, aScript));
|
||||
if (!shapeEngine) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PangoEngineShapeClass *shapeClass = static_cast<PangoEngineShapeClass*>
|
||||
(g_type_class_peek(PANGO_TYPE_ENGINE_SHAPE));
|
||||
|
||||
// The |covers| method in the PangoEngineShape base class, which is the
|
||||
// method used by Pango shapers, merely copies the fontconfig coverage map
|
||||
// to a PangoCoverage and checks that the character is supported. We've
|
||||
// already checked for character support, so we can avoid this copy for
|
||||
// these shapers.
|
||||
//
|
||||
// With SIL Graphite shapers, however, |covers| also checks that the font
|
||||
// is a Graphite font. (bug 397860)
|
||||
if (!shapeClass ||
|
||||
PANGO_ENGINE_SHAPE_GET_CLASS(shapeEngine)->covers != shapeClass->covers)
|
||||
{
|
||||
GSList *exact_engines;
|
||||
GSList *fallback_engines;
|
||||
pango_map_get_engines(shapeMap, aScript,
|
||||
&exact_engines, &fallback_engines);
|
||||
|
||||
GSList *engines = g_slist_concat(exact_engines, fallback_engines);
|
||||
for (GSList *link = engines; link; link = link->next) {
|
||||
PangoEngineShape *engine = PANGO_ENGINE_SHAPE(link->data);
|
||||
PangoCoverageLevel (*covers)(PangoEngineShape*, PangoFont*,
|
||||
PangoLanguage*, gunichar) =
|
||||
PANGO_ENGINE_SHAPE_GET_CLASS(shapeEngine)->covers;
|
||||
|
||||
if ((shapeClass && covers == shapeClass->covers) ||
|
||||
covers(engine, font, language, ' ') != PANGO_COVERAGE_NONE)
|
||||
{
|
||||
shapeEngine = engine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_slist_free(engines); // Frees exact and fallback links
|
||||
}
|
||||
|
||||
PangoAnalysisUnion analysis;
|
||||
memset(&analysis, 0, sizeof(analysis));
|
||||
|
||||
// For pango_shape
|
||||
analysis.local.shape_engine = shapeEngine;
|
||||
// For pango_break
|
||||
analysis.local.lang_engine =
|
||||
PANGO_ENGINE_LANG(pango_map_get_engine(langMap, aScript));
|
||||
|
||||
analysis.local.font = font;
|
||||
analysis.local.level = aTextRun->IsRightToLeft() ? 1 : 0;
|
||||
// gravity and flags are used in Pango 1.14.10 and newer.
|
||||
//
|
||||
// PANGO_GRAVITY_SOUTH is what we want for upright horizontal text. The
|
||||
// constant is not available when compiling with older Pango versions, but
|
||||
// is zero so the zero memset initialization is sufficient.
|
||||
//
|
||||
// Pango uses non-zero flags for vertical gravities only
|
||||
// (up to version 1.28 at least), so using zero is fine for flags too.
|
||||
#if 0
|
||||
analysis.local.gravity = PANGO_GRAVITY_SOUTH;
|
||||
analysis.local.flags = 0;
|
||||
#endif
|
||||
// Only used in Pango 1.16.5 and newer.
|
||||
analysis.local.script = aScript;
|
||||
|
||||
analysis.local.language = language;
|
||||
// Non-font attributes. Not used here.
|
||||
analysis.local.extra_attrs = NULL;
|
||||
|
||||
PangoGlyphUnit spaceWidth =
|
||||
moz_pango_units_from_double(GetMetrics().spaceWidth);
|
||||
|
||||
PRUint32 utf16Offset = aRunStart;
|
||||
InitGlyphRunWithPangoAnalysis(aTextRun, utf8.get(), utf8.Length(),
|
||||
&utf16Offset, &analysis.pango, spaceWidth);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FAST_PATH_8BIT)
|
||||
nsresult
|
||||
gfxPangoFontGroup::CreateGlyphRunsFast(gfxTextRun *aTextRun,
|
||||
@ -3368,8 +3535,9 @@ gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
||||
PRUint32 spaceWidth =
|
||||
moz_pango_units_from_double(font->GetMetrics().spaceWidth);
|
||||
|
||||
InitGlyphRunWithPango(aTextRun, utf8.get() + offset, length,
|
||||
&utf16Offset, &item->analysis, spaceWidth);
|
||||
InitGlyphRunWithPangoAnalysis(aTextRun, utf8.get() + offset, length,
|
||||
&utf16Offset, &item->analysis,
|
||||
spaceWidth);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -552,9 +552,7 @@ OSUtils.h
|
||||
Packages.h
|
||||
Palettes.h
|
||||
PALM_CMN.H
|
||||
pango-engine.h
|
||||
pango-glyph.h
|
||||
pango-modules.h
|
||||
pango/pango-modules.h
|
||||
pango/pangocairo.h
|
||||
pango/pangofc-decoder.h
|
||||
pango/pangofc-font.h
|
||||
@ -564,7 +562,6 @@ pango/pango-fontmap.h
|
||||
pango/pango.h
|
||||
pango/pangoxft.h
|
||||
pango/pango-utils.h
|
||||
pango-types.h
|
||||
pascal.h
|
||||
Patches.h
|
||||
Path.h
|
||||
|
Loading…
Reference in New Issue
Block a user