bug 603879 - part 2 - update harfbuzz integration to support arabic etc shaping. r=jdaggett a=blocking2.0

This commit is contained in:
Jonathan Kew 2010-11-20 17:49:12 +00:00
parent f23e23f242
commit d572b7fa06
5 changed files with 57 additions and 32 deletions

View File

@ -205,12 +205,13 @@ struct HMetrics {
};
void
gfxHarfBuzzShaper::GetGlyphMetrics(gfxContext *aContext,
gfxHarfBuzzShaper::GetGlyphAdvance(gfxContext *aContext,
hb_codepoint_t glyph,
hb_glyph_metrics_t *metrics) const
hb_position_t *x_advance,
hb_position_t *y_advance) const
{
if (mUseHintedWidths) {
metrics->x_advance = mFont->GetHintedGlyphWidth(aContext, glyph);
*x_advance = mFont->GetHintedGlyphWidth(aContext, glyph);
return;
}
@ -229,21 +230,20 @@ gfxHarfBuzzShaper::GetGlyphMetrics(gfxContext *aContext,
// to contain mNumLongMetrics records
const HMetrics* hmtx =
reinterpret_cast<const HMetrics*>(hb_blob_lock(mHmtxTable));
metrics->x_advance =
*x_advance =
FloatToFixed(mFont->FUnitsToDevUnitsFactor() *
PRUint16(hmtx->metrics[glyph].advanceWidth));
hb_blob_unlock(mHmtxTable);
// TODO: set additional metrics if/when harfbuzz needs them
}
static void
HBGetGlyphMetrics(hb_font_t *font, hb_face_t *face, const void *user_data,
hb_codepoint_t glyph, hb_glyph_metrics_t *metrics)
HBGetGlyphAdvance(hb_font_t *font, hb_face_t *face, const void *user_data,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance)
{
const FontCallbackData *fcd =
static_cast<const FontCallbackData*>(user_data);
fcd->mShaper->GetGlyphMetrics(fcd->mContext, glyph, metrics);
fcd->mShaper->GetGlyphAdvance(fcd->mContext, glyph, x_advance, y_advance);
}
static hb_bool_t
@ -711,8 +711,8 @@ gfxHarfBuzzShaper::InitTextRun(gfxContext *aContext,
// harfbuzz shaper used
sHBFontFuncs = hb_font_funcs_copy(hb_font_funcs_create());
hb_font_funcs_set_glyph_func(sHBFontFuncs, HBGetGlyph);
hb_font_funcs_set_glyph_metrics_func(sHBFontFuncs,
HBGetGlyphMetrics);
hb_font_funcs_set_glyph_advance_func(sHBFontFuncs,
HBGetGlyphAdvance);
hb_font_funcs_set_contour_point_func(sHBFontFuncs,
HBGetContourPoint);
hb_font_funcs_set_kerning_func(sHBFontFuncs, HBGetKerning);

View File

@ -64,10 +64,11 @@ public:
hb_codepoint_t GetGlyph(hb_codepoint_t unicode,
hb_codepoint_t variation_selector) const;
// get harfbuzz glyph metrics, in font design units
void GetGlyphMetrics(gfxContext *aContext,
// get harfbuzz glyph advance, in font design units
void GetGlyphAdvance(gfxContext *aContext,
hb_codepoint_t glyph,
hb_glyph_metrics_t *metrics) const;
hb_position_t *x_advance,
hb_position_t *y_advance) const;
hb_position_t GetKerning(PRUint16 aFirstGlyph,
PRUint16 aSecondGlyph) const;

View File

@ -193,7 +193,7 @@ struct ScriptRange {
};
const ScriptRange gScriptsThatRequireShaping[] = {
{ eComplexScriptArabic, 0x0600, 0x077F }, // Basic Arabic and Arabic Supplement
{ eComplexScriptArabic, 0x0600, 0x077F }, // Basic Arabic, Syriac, Arabic Supplement
{ eComplexScriptIndic, 0x0900, 0x0D7F }, // Indic scripts - Devanagari, Bengali, ..., Malayalam
{ eComplexScriptTibetan, 0x0F00, 0x0FFF } // Tibetan
// Thai seems to be "renderable" without AAT morphing tables
@ -261,8 +261,10 @@ MacOSFontEntry::ReadCMAP()
} else if (whichScript == eComplexScriptArabic) {
// special-case for Arabic:
// even if there's no morph table, CoreText can shape Arabic
// using OpenType layout
if (hasOTLayout) {
// using OpenType layout; or if it's a downloaded font,
// assume the site knows what it's doing (as harfbuzz will
// be able to shape even though the font itself lacks tables)
if (hasOTLayout || (mIsUserFont && !mIsLocalUserFont)) {
// TODO: to be really thorough, we could check that the
// GSUB table actually supports the 'arab' script tag.
omitRange = PR_FALSE;

View File

@ -152,23 +152,45 @@ gfxUnicodeProperties::GetScriptCode(PRUint32 aCh)
// function, is compared to the gfx.font_rendering.harfbuzz.level
// preference to decide whether to use the harfbuzz shaper.
//
// Currently, we only distinguish "simple" (level 1) scripts
// and "the rest" (level 2), but may subdivide this further in
// the future.
// Currently, we only distinguish "simple" (level 1) scripts,
// Arabic-style cursive scripts (level 2),
// and "Indic or other complex scripts" (level 3),
// but may subdivide this further in the future.
PRInt32
gfxUnicodeProperties::ScriptShapingLevel(PRInt32 aScriptCode)
{
switch (aScriptCode) {
case HB_SCRIPT_LATIN:
case HB_SCRIPT_CYRILLIC:
case HB_SCRIPT_HAN:
case HB_SCRIPT_HIRAGANA:
case HB_SCRIPT_KATAKANA:
case HB_SCRIPT_COMMON:
case HB_SCRIPT_INHERITED:
case HB_SCRIPT_UNKNOWN:
return 1; // level 1: common scripts that can use "generic" shaping
}
default:
return 1; // scripts not explicitly listed here are considered
// level 1: default shaping behavior is adequate
return 2; // all others are considered level 2
case HB_SCRIPT_ARABIC:
case HB_SCRIPT_SYRIAC:
case HB_SCRIPT_NKO:
return 2; // level 2: bidi scripts with Arabic-style shaping
case HB_SCRIPT_HEBREW:
case HB_SCRIPT_HANGUL:
case HB_SCRIPT_BENGALI:
case HB_SCRIPT_DEVANAGARI:
case HB_SCRIPT_GUJARATI:
case HB_SCRIPT_GURMUKHI:
case HB_SCRIPT_KANNADA:
case HB_SCRIPT_MALAYALAM:
case HB_SCRIPT_ORIYA:
case HB_SCRIPT_TAMIL:
case HB_SCRIPT_TELUGU:
case HB_SCRIPT_KHMER:
case HB_SCRIPT_THAI:
case HB_SCRIPT_LAO:
case HB_SCRIPT_TIBETAN:
case HB_SCRIPT_NEW_TAI_LUE:
case HB_SCRIPT_TAI_LE:
case HB_SCRIPT_MONGOLIAN:
case HB_SCRIPT_MYANMAR:
case HB_SCRIPT_PHAGS_PA:
case HB_SCRIPT_BATAK:
case HB_SCRIPT_BRAHMI:
return 3; // scripts that require Indic or other "special" shaping
}
}

View File

@ -199,7 +199,7 @@ pref("gfx.downloadable_fonts.sanitize.preserve_otl_tables", false);
pref("gfx.downloadable_fonts.sanitize.preserve_otl_tables", true);
#endif
pref("gfx.font_rendering.harfbuzz.level", 1);
pref("gfx.font_rendering.harfbuzz.level", 2);
#ifdef XP_WIN
#ifndef WINCE