Bug 761442 - don't use per-word shaping with fonts that use <space> in opentype lookups. r=jdaggett

This commit is contained in:
Jonathan Kew 2013-01-08 14:38:48 +00:00
parent b6e9bb11be
commit 64b1171f3c
3 changed files with 93 additions and 3 deletions

View File

@ -44,6 +44,7 @@
#include "gfxFontTest.h"
#include "harfbuzz/hb.h"
#include "harfbuzz/hb-ot.h"
#include "nsCRT.h"
#include "GeckoProfiler.h"
@ -1492,6 +1493,54 @@ gfxFont::GetFontTable(uint32_t aTag) {
haveTable ? &buffer : nullptr);
}
static hb_blob_t *
HBGetTable(hb_face_t *face, hb_tag_t aTag, void *aUserData)
{
gfxFont* font = static_cast<gfxFont*>(aUserData);
return font->GetFontTable(aTag);
}
static bool
HasLayoutFeatureInvolving(hb_face_t *aFace, hb_tag_t aTag, uint16_t aGlyph)
{
hb_set_t *lookups = hb_set_create();
hb_set_t *glyphs = hb_set_create();
hb_ot_layout_collect_lookups(aFace, aTag, nullptr, nullptr, nullptr,
lookups);
hb_codepoint_t index = -1;
while (hb_set_next(lookups, &index)) {
hb_ot_layout_lookup_collect_glyphs(aFace, aTag, index,
glyphs, glyphs, glyphs,
glyphs);
}
bool result = hb_set_has(glyphs, aGlyph);
hb_set_destroy(glyphs);
hb_set_destroy(lookups);
return result;
}
bool
gfxFont::CheckForFeaturesInvolvingSpace()
{
hb_face_t *face = hb_face_create_for_tables(HBGetTable, this, nullptr);
bool result = (hb_ot_layout_has_substitution(face) &&
HasLayoutFeatureInvolving(face, HB_OT_TAG_GSUB,
GetSpaceGlyph())) ||
(hb_ot_layout_has_positioning(face) &&
HasLayoutFeatureInvolving(face, HB_OT_TAG_GPOS,
GetSpaceGlyph()));
hb_face_destroy(face);
return result;
}
/**
* A helper function in case we need to do any rounding or other
* processing here.
@ -2710,12 +2759,18 @@ gfxFont::SplitAndInitTextRun(gfxContext *aContext,
return true;
}
uint32_t flags = aTextRun->GetFlags();
if (BypassShapedWordCache(flags)) {
return ShapeTextWithoutWordCache(aContext, aString + aRunStart,
aRunStart, aRunLength, aRunScript,
aTextRun);
}
InitWordCache();
// the only flags we care about for ShapedWord construction/caching
uint32_t flags = aTextRun->GetFlags() &
(gfxTextRunFactory::TEXT_IS_RTL |
gfxTextRunFactory::TEXT_DISABLE_OPTIONAL_LIGATURES);
flags &= (gfxTextRunFactory::TEXT_IS_RTL |
gfxTextRunFactory::TEXT_DISABLE_OPTIONAL_LIGATURES);
if (sizeof(T) == sizeof(uint8_t)) {
flags |= gfxTextRunFactory::TEXT_IS_8BIT;
}

View File

@ -216,6 +216,7 @@ public:
mIgnoreGSUB(false),
mSVGInitialized(false),
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
mHasSpaceFeaturesInitialized(false),
mCheckedForGraphiteTables(false),
mHasCmapTable(false),
mUVSOffset(0), mUVSData(nullptr),
@ -348,6 +349,9 @@ public:
uint16_t mWeight;
int16_t mStretch;
bool mHasSpaceFeatures;
bool mHasSpaceFeaturesInitialized;
bool mHasGraphiteTables;
bool mCheckedForGraphiteTables;
bool mHasCmapTable;
@ -379,6 +383,7 @@ protected:
mIgnoreGSUB(false),
mSVGInitialized(false),
mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
mHasSpaceFeaturesInitialized(false),
mCheckedForGraphiteTables(false),
mHasCmapTable(false),
mUVSOffset(0), mUVSData(nullptr),
@ -1561,6 +1566,26 @@ public:
{ return gfxPlatform::GetPlatform()->GetScaledFontForFont(aTarget, this); }
protected:
bool BypassShapedWordCache(uint32_t aRunFlags) {
// When creating a textrun in optimizeSpeed mode, we always use the
// word cache (which means we do not support features that span
// inter-word spaces)
if (aRunFlags & gfxTextRunFactory::TEXT_OPTIMIZE_SPEED) {
return false;
}
// We record the presence of space-dependent features in the font entry
// so that subsequent instantiations for the same font face won't
// require us to re-check the tables; however, the actual check is done
// by gfxFont because not all font entry subclasses know how to create
// a harfbuzz face for introspection.
gfxFontEntry *fe = GetFontEntry();
if (!fe->mHasSpaceFeaturesInitialized) {
fe->mHasSpaceFeaturesInitialized = true;
fe->mHasSpaceFeatures = CheckForFeaturesInvolvingSpace();
}
return fe->mHasSpaceFeatures;
}
// For 8-bit text, expand to 16-bit and then call the following method.
bool ShapeText(gfxContext *aContext,
const uint8_t *aText,
@ -1617,6 +1642,8 @@ protected:
int32_t aScript,
gfxTextRun *aTextRun);
bool CheckForFeaturesInvolvingSpace();
nsRefPtr<gfxFontEntry> mFontEntry;
struct CacheHashKey {

View File

@ -544,7 +544,15 @@ hb_font_set_funcs
hb_font_set_ppem
hb_font_set_scale
hb_language_from_string
hb_ot_layout_collect_lookups
hb_ot_layout_has_positioning
hb_ot_layout_has_substitution
hb_ot_layout_lookup_collect_glyphs
hb_ot_tag_to_language
hb_set_create
hb_set_destroy
hb_set_has
hb_set_next
hb_shape
hb_unicode_funcs_create
hb_unicode_funcs_get_empty