mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 761442 - don't use per-word shaping with fonts that use <space> in opentype lookups. r=jdaggett
This commit is contained in:
parent
b6e9bb11be
commit
64b1171f3c
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user