mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 619521 - Part 1: Send a notification of any scripts for which font coverage is lacking. r=jdaggett
This commit is contained in:
parent
1d3e35e67b
commit
65c4ca0e3f
@ -3252,6 +3252,22 @@ CanvasRenderingContext2D::GetHitRegionRect(Element* aElement, nsRect& aRect)
|
|||||||
*/
|
*/
|
||||||
struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcessor
|
struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcessor
|
||||||
{
|
{
|
||||||
|
CanvasBidiProcessor()
|
||||||
|
: nsBidiPresUtils::BidiProcessor()
|
||||||
|
{
|
||||||
|
if (Preferences::GetBool(GFX_MISSING_FONTS_NOTIFY_PREF)) {
|
||||||
|
mMissingFonts = new gfxMissingFontRecorder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~CanvasBidiProcessor()
|
||||||
|
{
|
||||||
|
// notify front-end code if we encountered missing glyphs in any script
|
||||||
|
if (mMissingFonts) {
|
||||||
|
mMissingFonts->Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef CanvasRenderingContext2D::ContextState ContextState;
|
typedef CanvasRenderingContext2D::ContextState ContextState;
|
||||||
|
|
||||||
virtual void SetText(const char16_t* text, int32_t length, nsBidiDirection direction)
|
virtual void SetText(const char16_t* text, int32_t length, nsBidiDirection direction)
|
||||||
@ -3268,7 +3284,8 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
|||||||
length,
|
length,
|
||||||
mThebes,
|
mThebes,
|
||||||
mAppUnitsPerDevPixel,
|
mAppUnitsPerDevPixel,
|
||||||
flags);
|
flags,
|
||||||
|
mMissingFonts);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual nscoord GetWidth()
|
virtual nscoord GetWidth()
|
||||||
@ -3514,6 +3531,10 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
|||||||
// current font
|
// current font
|
||||||
gfxFontGroup* mFontgrp;
|
gfxFontGroup* mFontgrp;
|
||||||
|
|
||||||
|
// to record any unsupported characters found in the text,
|
||||||
|
// and notify front-end if it is interested
|
||||||
|
nsAutoPtr<gfxMissingFontRecorder> mMissingFonts;
|
||||||
|
|
||||||
// dev pixel conversion factor
|
// dev pixel conversion factor
|
||||||
int32_t mAppUnitsPerDevPixel;
|
int32_t mAppUnitsPerDevPixel;
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ public:
|
|||||||
reinterpret_cast<const uint8_t*>(aString), aLength,
|
reinterpret_cast<const uint8_t*>(aString), aLength,
|
||||||
aRC->ThebesContext(),
|
aRC->ThebesContext(),
|
||||||
aMetrics->AppUnitsPerDevPixel(),
|
aMetrics->AppUnitsPerDevPixel(),
|
||||||
ComputeFlags(aMetrics));
|
ComputeFlags(aMetrics),
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoTextRun(nsFontMetrics* aMetrics, nsRenderingContext* aRC,
|
AutoTextRun(nsFontMetrics* aMetrics, nsRenderingContext* aRC,
|
||||||
@ -43,7 +44,8 @@ public:
|
|||||||
aString, aLength,
|
aString, aLength,
|
||||||
aRC->ThebesContext(),
|
aRC->ThebesContext(),
|
||||||
aMetrics->AppUnitsPerDevPixel(),
|
aMetrics->AppUnitsPerDevPixel(),
|
||||||
ComputeFlags(aMetrics));
|
ComputeFlags(aMetrics),
|
||||||
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxTextRun *get() { return mTextRun; }
|
gfxTextRun *get() { return mTextRun; }
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
using namespace mozilla::unicode;
|
using namespace mozilla::unicode;
|
||||||
|
using mozilla::services::GetObserverService;
|
||||||
|
|
||||||
static const char16_t kEllipsisChar[] = { 0x2026, 0x0 };
|
static const char16_t kEllipsisChar[] = { 0x2026, 0x0 };
|
||||||
static const char16_t kASCIIPeriodsChar[] = { '.', '.', '.', 0x0 };
|
static const char16_t kASCIIPeriodsChar[] = { '.', '.', '.', 0x0 };
|
||||||
@ -2039,12 +2040,12 @@ gfxFontGroup::MakeHyphenTextRun(gfxContext *aCtx, uint32_t aAppUnitsPerDevUnit)
|
|||||||
gfxFont *font = GetFirstValidFont(uint32_t(hyphen));
|
gfxFont *font = GetFirstValidFont(uint32_t(hyphen));
|
||||||
if (font->HasCharacter(hyphen)) {
|
if (font->HasCharacter(hyphen)) {
|
||||||
return MakeTextRun(&hyphen, 1, aCtx, aAppUnitsPerDevUnit,
|
return MakeTextRun(&hyphen, 1, aCtx, aAppUnitsPerDevUnit,
|
||||||
gfxFontGroup::TEXT_IS_PERSISTENT);
|
gfxFontGroup::TEXT_IS_PERSISTENT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t dash = '-';
|
static const uint8_t dash = '-';
|
||||||
return MakeTextRun(&dash, 1, aCtx, aAppUnitsPerDevUnit,
|
return MakeTextRun(&dash, 1, aCtx, aAppUnitsPerDevUnit,
|
||||||
gfxFontGroup::TEXT_IS_PERSISTENT);
|
gfxFontGroup::TEXT_IS_PERSISTENT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFloat
|
gfxFloat
|
||||||
@ -2065,7 +2066,8 @@ gfxFontGroup::GetHyphenWidth(gfxTextRun::PropertyProvider *aProvider)
|
|||||||
|
|
||||||
gfxTextRun *
|
gfxTextRun *
|
||||||
gfxFontGroup::MakeTextRun(const uint8_t *aString, uint32_t aLength,
|
gfxFontGroup::MakeTextRun(const uint8_t *aString, uint32_t aLength,
|
||||||
const Parameters *aParams, uint32_t aFlags)
|
const Parameters *aParams, uint32_t aFlags,
|
||||||
|
gfxMissingFontRecorder *aMFR)
|
||||||
{
|
{
|
||||||
if (aLength == 0) {
|
if (aLength == 0) {
|
||||||
return MakeEmptyTextRun(aParams, aFlags);
|
return MakeEmptyTextRun(aParams, aFlags);
|
||||||
@ -2089,7 +2091,7 @@ gfxFontGroup::MakeTextRun(const uint8_t *aString, uint32_t aLength,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitTextRun(aParams->mContext, textRun, aString, aLength);
|
InitTextRun(aParams->mContext, textRun, aString, aLength, aMFR);
|
||||||
|
|
||||||
textRun->FetchGlyphExtents(aParams->mContext);
|
textRun->FetchGlyphExtents(aParams->mContext);
|
||||||
|
|
||||||
@ -2098,7 +2100,8 @@ gfxFontGroup::MakeTextRun(const uint8_t *aString, uint32_t aLength,
|
|||||||
|
|
||||||
gfxTextRun *
|
gfxTextRun *
|
||||||
gfxFontGroup::MakeTextRun(const char16_t *aString, uint32_t aLength,
|
gfxFontGroup::MakeTextRun(const char16_t *aString, uint32_t aLength,
|
||||||
const Parameters *aParams, uint32_t aFlags)
|
const Parameters *aParams, uint32_t aFlags,
|
||||||
|
gfxMissingFontRecorder *aMFR)
|
||||||
{
|
{
|
||||||
if (aLength == 0) {
|
if (aLength == 0) {
|
||||||
return MakeEmptyTextRun(aParams, aFlags);
|
return MakeEmptyTextRun(aParams, aFlags);
|
||||||
@ -2116,7 +2119,7 @@ gfxFontGroup::MakeTextRun(const char16_t *aString, uint32_t aLength,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitTextRun(aParams->mContext, textRun, aString, aLength);
|
InitTextRun(aParams->mContext, textRun, aString, aLength, aMFR);
|
||||||
|
|
||||||
textRun->FetchGlyphExtents(aParams->mContext);
|
textRun->FetchGlyphExtents(aParams->mContext);
|
||||||
|
|
||||||
@ -2128,7 +2131,8 @@ void
|
|||||||
gfxFontGroup::InitTextRun(gfxContext *aContext,
|
gfxFontGroup::InitTextRun(gfxContext *aContext,
|
||||||
gfxTextRun *aTextRun,
|
gfxTextRun *aTextRun,
|
||||||
const T *aString,
|
const T *aString,
|
||||||
uint32_t aLength)
|
uint32_t aLength,
|
||||||
|
gfxMissingFontRecorder *aMFR)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aLength > 0, "don't call InitTextRun for a zero-length run");
|
NS_ASSERTION(aLength > 0, "don't call InitTextRun for a zero-length run");
|
||||||
|
|
||||||
@ -2208,7 +2212,7 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
|||||||
// the text is still purely 8-bit; bypass the script-run itemizer
|
// the text is still purely 8-bit; bypass the script-run itemizer
|
||||||
// and treat it as a single Latin run
|
// and treat it as a single Latin run
|
||||||
InitScriptRun(aContext, aTextRun, aString,
|
InitScriptRun(aContext, aTextRun, aString,
|
||||||
0, aLength, MOZ_SCRIPT_LATIN);
|
0, aLength, MOZ_SCRIPT_LATIN, aMFR);
|
||||||
} else {
|
} else {
|
||||||
const char16_t *textPtr;
|
const char16_t *textPtr;
|
||||||
if (transformedString) {
|
if (transformedString) {
|
||||||
@ -2256,7 +2260,7 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
InitScriptRun(aContext, aTextRun, textPtr + runStart,
|
InitScriptRun(aContext, aTextRun, textPtr + runStart,
|
||||||
runStart, runLimit - runStart, runScript);
|
runStart, runLimit - runStart, runScript, aMFR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2292,6 +2296,14 @@ gfxFontGroup::InitTextRun(gfxContext *aContext,
|
|||||||
aTextRun->SortGlyphRuns();
|
aTextRun->SortGlyphRuns();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
IsPUA(uint32_t aUSV)
|
||||||
|
{
|
||||||
|
// We could look up the General Category of the codepoint here,
|
||||||
|
// but it's simpler to check PUA codepoint ranges.
|
||||||
|
return (aUSV >= 0xE000 && aUSV <= 0xF8FF) || (aUSV >= 0xF0000);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void
|
void
|
||||||
gfxFontGroup::InitScriptRun(gfxContext *aContext,
|
gfxFontGroup::InitScriptRun(gfxContext *aContext,
|
||||||
@ -2301,7 +2313,8 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
|
|||||||
uint32_t aOffset, // position of the script run
|
uint32_t aOffset, // position of the script run
|
||||||
// within the textrun
|
// within the textrun
|
||||||
uint32_t aLength, // length of the script run
|
uint32_t aLength, // length of the script run
|
||||||
int32_t aRunScript)
|
int32_t aRunScript,
|
||||||
|
gfxMissingFontRecorder *aMFR)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aLength > 0, "don't call InitScriptRun for a 0-length run");
|
NS_ASSERTION(aLength > 0, "don't call InitScriptRun for a 0-length run");
|
||||||
NS_ASSERTION(aTextRun->GetShapingState() != gfxTextRun::eShapingState_Aborted,
|
NS_ASSERTION(aTextRun->GetShapingState() != gfxTextRun::eShapingState_Aborted,
|
||||||
@ -2322,6 +2335,7 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
|
|||||||
ComputeRanges(fontRanges, aString, aLength, aRunScript,
|
ComputeRanges(fontRanges, aString, aLength, aRunScript,
|
||||||
aTextRun->GetFlags() & gfxTextRunFactory::TEXT_ORIENT_MASK);
|
aTextRun->GetFlags() & gfxTextRunFactory::TEXT_ORIENT_MASK);
|
||||||
uint32_t numRanges = fontRanges.Length();
|
uint32_t numRanges = fontRanges.Length();
|
||||||
|
bool missingChars = false;
|
||||||
|
|
||||||
for (uint32_t r = 0; r < numRanges; r++) {
|
for (uint32_t r = 0; r < numRanges; r++) {
|
||||||
const gfxTextRange& range = fontRanges[r];
|
const gfxTextRange& range = fontRanges[r];
|
||||||
@ -2468,11 +2482,15 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
|
|||||||
index + 1 < aLength &&
|
index + 1 < aLength &&
|
||||||
NS_IS_LOW_SURROGATE(aString[index + 1]))
|
NS_IS_LOW_SURROGATE(aString[index + 1]))
|
||||||
{
|
{
|
||||||
|
uint32_t usv =
|
||||||
|
SURROGATE_TO_UCS4(ch, aString[index + 1]);
|
||||||
aTextRun->SetMissingGlyph(aOffset + index,
|
aTextRun->SetMissingGlyph(aOffset + index,
|
||||||
SURROGATE_TO_UCS4(ch,
|
usv,
|
||||||
aString[index + 1]),
|
|
||||||
mainFont);
|
mainFont);
|
||||||
index++;
|
index++;
|
||||||
|
if (!mSkipDrawing && !IsPUA(usv)) {
|
||||||
|
missingChars = true;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2507,11 +2525,18 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
|
|||||||
|
|
||||||
// record char code so we can draw a box with the Unicode value
|
// record char code so we can draw a box with the Unicode value
|
||||||
aTextRun->SetMissingGlyph(aOffset + index, ch, mainFont);
|
aTextRun->SetMissingGlyph(aOffset + index, ch, mainFont);
|
||||||
|
if (!mSkipDrawing && !IsPUA(ch)) {
|
||||||
|
missingChars = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runStart += matchedLength;
|
runStart += matchedLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aMFR && missingChars) {
|
||||||
|
aMFR->RecordScript(aRunScript);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxTextRun *
|
gfxTextRun *
|
||||||
@ -2537,7 +2562,8 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
|
|||||||
refCtx, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel
|
refCtx, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel
|
||||||
};
|
};
|
||||||
gfxTextRun* textRun =
|
gfxTextRun* textRun =
|
||||||
MakeTextRun(ellipsis.get(), ellipsis.Length(), ¶ms, TEXT_IS_PERSISTENT);
|
MakeTextRun(ellipsis.get(), ellipsis.Length(), ¶ms,
|
||||||
|
TEXT_IS_PERSISTENT, nullptr);
|
||||||
if (!textRun) {
|
if (!textRun) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -3109,3 +3135,41 @@ gfxFontGroup::Shutdown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsILanguageAtomService* gfxFontGroup::gLangService = nullptr;
|
nsILanguageAtomService* gfxFontGroup::gLangService = nullptr;
|
||||||
|
|
||||||
|
void
|
||||||
|
gfxMissingFontRecorder::Flush()
|
||||||
|
{
|
||||||
|
static bool mNotifiedFontsInitialized = false;
|
||||||
|
static uint32_t mNotifiedFonts[gfxMissingFontRecorder::kNumScriptBitsWords];
|
||||||
|
if (!mNotifiedFontsInitialized) {
|
||||||
|
memset(&mNotifiedFonts, 0, sizeof(mNotifiedFonts));
|
||||||
|
mNotifiedFontsInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString fontNeeded;
|
||||||
|
for (uint32_t i = 0; i < kNumScriptBitsWords; ++i) {
|
||||||
|
mMissingFonts[i] &= ~mNotifiedFonts[i];
|
||||||
|
if (!mMissingFonts[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (uint32_t j = 0; j < 32; ++j) {
|
||||||
|
if (!(mMissingFonts[i] & (1 << j))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mNotifiedFonts[i] |= (1 << j);
|
||||||
|
if (!fontNeeded.IsEmpty()) {
|
||||||
|
fontNeeded.Append(PRUnichar(','));
|
||||||
|
}
|
||||||
|
uint32_t tag = GetScriptTagForCode(i * 32 + j);
|
||||||
|
fontNeeded.Append(char16_t(tag >> 24));
|
||||||
|
fontNeeded.Append(char16_t((tag >> 16) & 0xff));
|
||||||
|
fontNeeded.Append(char16_t((tag >> 8) & 0xff));
|
||||||
|
fontNeeded.Append(char16_t(tag & 0xff));
|
||||||
|
}
|
||||||
|
mMissingFonts[i] = 0;
|
||||||
|
}
|
||||||
|
if (!fontNeeded.IsEmpty()) {
|
||||||
|
nsCOMPtr<nsIObserverService> service = GetObserverService();
|
||||||
|
service->NotifyObservers(nullptr, "font-needed", fontNeeded.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "DrawMode.h"
|
#include "DrawMode.h"
|
||||||
#include "harfbuzz/hb.h"
|
#include "harfbuzz/hb.h"
|
||||||
|
#include "nsUnicodeScriptCodes.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -27,6 +28,7 @@ class gfxUserFontSet;
|
|||||||
class gfxTextContextPaint;
|
class gfxTextContextPaint;
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
class nsILanguageAtomService;
|
class nsILanguageAtomService;
|
||||||
|
class gfxMissingFontRecorder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for Draw() to use when drawing text with mode
|
* Callback for Draw() to use when drawing text with mode
|
||||||
@ -769,7 +771,8 @@ public:
|
|||||||
* This calls FetchGlyphExtents on the textrun.
|
* This calls FetchGlyphExtents on the textrun.
|
||||||
*/
|
*/
|
||||||
virtual gfxTextRun *MakeTextRun(const char16_t *aString, uint32_t aLength,
|
virtual gfxTextRun *MakeTextRun(const char16_t *aString, uint32_t aLength,
|
||||||
const Parameters *aParams, uint32_t aFlags);
|
const Parameters *aParams, uint32_t aFlags,
|
||||||
|
gfxMissingFontRecorder *aMFR);
|
||||||
/**
|
/**
|
||||||
* Make a textrun for a given string.
|
* Make a textrun for a given string.
|
||||||
* If aText is not persistent (aFlags & TEXT_IS_PERSISTENT), the
|
* If aText is not persistent (aFlags & TEXT_IS_PERSISTENT), the
|
||||||
@ -777,7 +780,8 @@ public:
|
|||||||
* This calls FetchGlyphExtents on the textrun.
|
* This calls FetchGlyphExtents on the textrun.
|
||||||
*/
|
*/
|
||||||
virtual gfxTextRun *MakeTextRun(const uint8_t *aString, uint32_t aLength,
|
virtual gfxTextRun *MakeTextRun(const uint8_t *aString, uint32_t aLength,
|
||||||
const Parameters *aParams, uint32_t aFlags);
|
const Parameters *aParams, uint32_t aFlags,
|
||||||
|
gfxMissingFontRecorder *aMFR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Textrun creation helper for clients that don't want to pass
|
* Textrun creation helper for clients that don't want to pass
|
||||||
@ -787,12 +791,13 @@ public:
|
|||||||
gfxTextRun *MakeTextRun(const T *aString, uint32_t aLength,
|
gfxTextRun *MakeTextRun(const T *aString, uint32_t aLength,
|
||||||
gfxContext *aRefContext,
|
gfxContext *aRefContext,
|
||||||
int32_t aAppUnitsPerDevUnit,
|
int32_t aAppUnitsPerDevUnit,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags,
|
||||||
|
gfxMissingFontRecorder *aMFR)
|
||||||
{
|
{
|
||||||
gfxTextRunFactory::Parameters params = {
|
gfxTextRunFactory::Parameters params = {
|
||||||
aRefContext, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevUnit
|
aRefContext, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevUnit
|
||||||
};
|
};
|
||||||
return MakeTextRun(aString, aLength, ¶ms, aFlags);
|
return MakeTextRun(aString, aLength, ¶ms, aFlags, aMFR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1088,7 +1093,8 @@ protected:
|
|||||||
void InitTextRun(gfxContext *aContext,
|
void InitTextRun(gfxContext *aContext,
|
||||||
gfxTextRun *aTextRun,
|
gfxTextRun *aTextRun,
|
||||||
const T *aString,
|
const T *aString,
|
||||||
uint32_t aLength);
|
uint32_t aLength,
|
||||||
|
gfxMissingFontRecorder *aMFR);
|
||||||
|
|
||||||
// InitTextRun helper to handle a single script run, by finding font ranges
|
// InitTextRun helper to handle a single script run, by finding font ranges
|
||||||
// and calling each font's InitTextRun() as appropriate
|
// and calling each font's InitTextRun() as appropriate
|
||||||
@ -1098,7 +1104,8 @@ protected:
|
|||||||
const T *aString,
|
const T *aString,
|
||||||
uint32_t aScriptRunStart,
|
uint32_t aScriptRunStart,
|
||||||
uint32_t aScriptRunEnd,
|
uint32_t aScriptRunEnd,
|
||||||
int32_t aRunScript);
|
int32_t aRunScript,
|
||||||
|
gfxMissingFontRecorder *aMFR);
|
||||||
|
|
||||||
// Helper for font-matching:
|
// Helper for font-matching:
|
||||||
// When matching the italic case, allow use of the regular face
|
// When matching the italic case, allow use of the regular face
|
||||||
@ -1124,4 +1131,56 @@ protected:
|
|||||||
|
|
||||||
static nsILanguageAtomService* gLangService;
|
static nsILanguageAtomService* gLangService;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A "missing font recorder" is to be used during text-run creation to keep
|
||||||
|
// a record of any scripts encountered for which font coverage was lacking;
|
||||||
|
// when Flush() is called, it sends a notification that front-end code can use
|
||||||
|
// to download fonts on demand (or whatever else it wants to do).
|
||||||
|
|
||||||
|
#define GFX_MISSING_FONTS_NOTIFY_PREF "gfx.missing_fonts.notify"
|
||||||
|
|
||||||
|
class gfxMissingFontRecorder {
|
||||||
|
public:
|
||||||
|
gfxMissingFontRecorder()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(gfxMissingFontRecorder);
|
||||||
|
memset(&mMissingFonts, 0, sizeof(mMissingFonts));
|
||||||
|
}
|
||||||
|
|
||||||
|
~gfxMissingFontRecorder()
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
for (uint32_t i = 0; i < kNumScriptBitsWords; i++) {
|
||||||
|
NS_ASSERTION(mMissingFonts[i] == 0,
|
||||||
|
"failed to flush the missing-font recorder");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
MOZ_COUNT_DTOR(gfxMissingFontRecorder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// record this script code in our mMissingFonts bitset
|
||||||
|
void RecordScript(int32_t aScriptCode)
|
||||||
|
{
|
||||||
|
mMissingFonts[uint32_t(aScriptCode) >> 5] |=
|
||||||
|
(1 << (uint32_t(aScriptCode) & 0x1f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// send a notification of any missing-scripts that have been
|
||||||
|
// recorded, and clear the mMissingFonts set for re-use
|
||||||
|
void Flush();
|
||||||
|
|
||||||
|
// forget any missing-scripts that have been recorded up to now;
|
||||||
|
// called before discarding a recorder we no longer care about
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
memset(&mMissingFonts, 0, sizeof(mMissingFonts));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Number of 32-bit words needed for the missing-script flags
|
||||||
|
static const uint32_t kNumScriptBitsWords =
|
||||||
|
((MOZ_NUM_SCRIPT_CODES + 31) / 32);
|
||||||
|
uint32_t mMissingFonts[kNumScriptBitsWords];
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsPIWindowRoot.h"
|
#include "nsPIWindowRoot.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "gfxTextRun.h"
|
||||||
|
|
||||||
// Needed for Start/Stop of Image Animation
|
// Needed for Start/Stop of Image Animation
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
@ -249,6 +250,10 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
|
|||||||
if (log && log->level >= PR_LOG_WARNING) {
|
if (log && log->level >= PR_LOG_WARNING) {
|
||||||
mTextPerf = new gfxTextPerfMetrics();
|
mTextPerf = new gfxTextPerfMetrics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Preferences::GetBool(GFX_MISSING_FONTS_NOTIFY_PREF)) {
|
||||||
|
mMissingFonts = new gfxMissingFontRecorder();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -341,6 +346,9 @@ nsPresContext::LastRelease()
|
|||||||
if (IsRoot()) {
|
if (IsRoot()) {
|
||||||
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimer();
|
static_cast<nsRootPresContext*>(this)->CancelDidPaintTimer();
|
||||||
}
|
}
|
||||||
|
if (mMissingFonts) {
|
||||||
|
mMissingFonts->Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPresContext)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPresContext)
|
||||||
@ -873,6 +881,20 @@ nsPresContext::PreferenceChanged(const char* aPrefName)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (prefName.EqualsLiteral(GFX_MISSING_FONTS_NOTIFY_PREF)) {
|
||||||
|
if (Preferences::GetBool(GFX_MISSING_FONTS_NOTIFY_PREF)) {
|
||||||
|
if (!mMissingFonts) {
|
||||||
|
mMissingFonts = new gfxMissingFontRecorder();
|
||||||
|
// trigger reflow to detect missing fonts on the current page
|
||||||
|
mPrefChangePendingNeedsReflow = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mMissingFonts) {
|
||||||
|
mMissingFonts->Clear();
|
||||||
|
}
|
||||||
|
mMissingFonts = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (StringBeginsWith(prefName, NS_LITERAL_CSTRING("font."))) {
|
if (StringBeginsWith(prefName, NS_LITERAL_CSTRING("font."))) {
|
||||||
// Changes to font family preferences don't change anything in the
|
// Changes to font family preferences don't change anything in the
|
||||||
// computed style data, so the style system won't generate a reflow
|
// computed style data, so the style system won't generate a reflow
|
||||||
@ -2194,6 +2216,14 @@ nsPresContext::RebuildCounterStyles()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsPresContext::NotifyMissingFonts()
|
||||||
|
{
|
||||||
|
if (mMissingFonts) {
|
||||||
|
mMissingFonts->Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPresContext::EnsureSafeToHandOutCSSRules()
|
nsPresContext::EnsureSafeToHandOutCSSRules()
|
||||||
{
|
{
|
||||||
|
@ -65,6 +65,7 @@ class nsAnimationManager;
|
|||||||
class nsRefreshDriver;
|
class nsRefreshDriver;
|
||||||
class nsIWidget;
|
class nsIWidget;
|
||||||
class nsDeviceContext;
|
class nsDeviceContext;
|
||||||
|
class gfxMissingFontRecorder;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class EventStateManager;
|
class EventStateManager;
|
||||||
@ -876,6 +877,9 @@ public:
|
|||||||
// user font set is changed and fonts become unavailable).
|
// user font set is changed and fonts become unavailable).
|
||||||
void UserFontSetUpdated();
|
void UserFontSetUpdated();
|
||||||
|
|
||||||
|
gfxMissingFontRecorder *MissingFontRecorder() { return mMissingFonts; }
|
||||||
|
void NotifyMissingFonts();
|
||||||
|
|
||||||
mozilla::dom::FontFaceSet* Fonts();
|
mozilla::dom::FontFaceSet* Fonts();
|
||||||
|
|
||||||
void FlushCounterStyles();
|
void FlushCounterStyles();
|
||||||
@ -1251,6 +1255,8 @@ protected:
|
|||||||
// text performance metrics
|
// text performance metrics
|
||||||
nsAutoPtr<gfxTextPerfMetrics> mTextPerf;
|
nsAutoPtr<gfxTextPerfMetrics> mTextPerf;
|
||||||
|
|
||||||
|
nsAutoPtr<gfxMissingFontRecorder> mMissingFonts;
|
||||||
|
|
||||||
nsRect mVisibleArea;
|
nsRect mVisibleArea;
|
||||||
nsSize mPageSize;
|
nsSize mPageSize;
|
||||||
float mPageScale;
|
float mPageScale;
|
||||||
|
@ -9119,6 +9119,8 @@ PresShell::DidDoReflow(bool aInterruptible, bool aWasInterrupted)
|
|||||||
mTouchCaret->UpdatePositionIfNeeded();
|
mTouchCaret->UpdatePositionIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPresContext->NotifyMissingFonts();
|
||||||
|
|
||||||
if (!aWasInterrupted) {
|
if (!aWasInterrupted) {
|
||||||
ClearReflowOnZoomPending();
|
ClearReflowOnZoomPending();
|
||||||
}
|
}
|
||||||
|
@ -529,7 +529,8 @@ MathVariant(uint32_t aCh, uint8_t aMathVar)
|
|||||||
|
|
||||||
void
|
void
|
||||||
MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||||
gfxContext* aRefContext)
|
gfxContext* aRefContext,
|
||||||
|
gfxMissingFontRecorder* aMFR)
|
||||||
{
|
{
|
||||||
gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
|
gfxFontGroup* fontGroup = aTextRun->GetFontGroup();
|
||||||
|
|
||||||
@ -766,7 +767,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||||||
} else {
|
} else {
|
||||||
cachedChild = newFontGroup->MakeTextRun(
|
cachedChild = newFontGroup->MakeTextRun(
|
||||||
convertedString.BeginReading(), convertedString.Length(),
|
convertedString.BeginReading(), convertedString.Length(),
|
||||||
&innerParams, flags);
|
&innerParams, flags, aMFR);
|
||||||
child = cachedChild.get();
|
child = cachedChild.get();
|
||||||
}
|
}
|
||||||
if (!child)
|
if (!child)
|
||||||
@ -778,7 +779,7 @@ MathMLTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||||||
child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(),
|
child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(),
|
||||||
canBreakBeforeArray.Elements(), aRefContext);
|
canBreakBeforeArray.Elements(), aRefContext);
|
||||||
if (transformedChild) {
|
if (transformedChild) {
|
||||||
transformedChild->FinishSettingProperties(aRefContext);
|
transformedChild->FinishSettingProperties(aRefContext, aMFR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mergeNeeded) {
|
if (mergeNeeded) {
|
||||||
|
@ -22,7 +22,8 @@ public:
|
|||||||
mSSTYScriptLevel(aSSTYScriptLevel) {}
|
mSSTYScriptLevel(aSSTYScriptLevel) {}
|
||||||
|
|
||||||
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun,
|
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||||
gfxContext* aRefContext) MOZ_OVERRIDE;
|
gfxContext* aRefContext,
|
||||||
|
gfxMissingFontRecorder* aMFR) MOZ_OVERRIDE;
|
||||||
enum {
|
enum {
|
||||||
// Style effects which may override single character <mi> behaviour
|
// Style effects which may override single character <mi> behaviour
|
||||||
MATH_FONT_STYLING_NORMAL = 0x1, // fontstyle="normal" has been set.
|
MATH_FONT_STYLING_NORMAL = 0x1, // fontstyle="normal" has been set.
|
||||||
|
@ -561,10 +561,11 @@ template<typename T>
|
|||||||
gfxTextRun *
|
gfxTextRun *
|
||||||
MakeTextRun(const T *aText, uint32_t aLength,
|
MakeTextRun(const T *aText, uint32_t aLength,
|
||||||
gfxFontGroup *aFontGroup, const gfxFontGroup::Parameters* aParams,
|
gfxFontGroup *aFontGroup, const gfxFontGroup::Parameters* aParams,
|
||||||
uint32_t aFlags)
|
uint32_t aFlags, gfxMissingFontRecorder *aMFR)
|
||||||
{
|
{
|
||||||
nsAutoPtr<gfxTextRun> textRun(aFontGroup->MakeTextRun(aText, aLength,
|
nsAutoPtr<gfxTextRun> textRun(aFontGroup->MakeTextRun(aText, aLength,
|
||||||
aParams, aFlags));
|
aParams, aFlags,
|
||||||
|
aMFR));
|
||||||
if (!textRun) {
|
if (!textRun) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -842,6 +843,7 @@ public:
|
|||||||
mCurrentFramesAllSameTextRun(nullptr),
|
mCurrentFramesAllSameTextRun(nullptr),
|
||||||
mContext(aContext),
|
mContext(aContext),
|
||||||
mLineContainer(aLineContainer),
|
mLineContainer(aLineContainer),
|
||||||
|
mMissingFonts(aPresContext->MissingFontRecorder()),
|
||||||
mBidiEnabled(aPresContext->BidiEnabled()),
|
mBidiEnabled(aPresContext->BidiEnabled()),
|
||||||
mSkipIncompleteTextRuns(false),
|
mSkipIncompleteTextRuns(false),
|
||||||
mWhichTextRun(aWhichTextRun),
|
mWhichTextRun(aWhichTextRun),
|
||||||
@ -971,7 +973,7 @@ public:
|
|||||||
aCapitalize, mContext);
|
aCapitalize, mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Finish() {
|
void Finish(gfxMissingFontRecorder* aMFR) {
|
||||||
NS_ASSERTION(!(mTextRun->GetFlags() &
|
NS_ASSERTION(!(mTextRun->GetFlags() &
|
||||||
(gfxTextRunFactory::TEXT_UNUSED_FLAGS |
|
(gfxTextRunFactory::TEXT_UNUSED_FLAGS |
|
||||||
nsTextFrameUtils::TEXT_UNUSED_FLAG)),
|
nsTextFrameUtils::TEXT_UNUSED_FLAG)),
|
||||||
@ -979,7 +981,7 @@ public:
|
|||||||
if (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_IS_TRANSFORMED) {
|
if (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_IS_TRANSFORMED) {
|
||||||
nsTransformedTextRun* transformedTextRun =
|
nsTransformedTextRun* transformedTextRun =
|
||||||
static_cast<nsTransformedTextRun*>(mTextRun);
|
static_cast<nsTransformedTextRun*>(mTextRun);
|
||||||
transformedTextRun->FinishSettingProperties(mContext);
|
transformedTextRun->FinishSettingProperties(mContext, aMFR);
|
||||||
}
|
}
|
||||||
// The way nsTransformedTextRun is implemented, its glyph runs aren't
|
// The way nsTransformedTextRun is implemented, its glyph runs aren't
|
||||||
// available until after nsTransformedTextRun::FinishSettingProperties()
|
// available until after nsTransformedTextRun::FinishSettingProperties()
|
||||||
@ -1007,6 +1009,7 @@ private:
|
|||||||
// The common ancestor of the current frame and the previous leaf frame
|
// The common ancestor of the current frame and the previous leaf frame
|
||||||
// on the line, or null if there was no previous leaf frame.
|
// on the line, or null if there was no previous leaf frame.
|
||||||
nsIFrame* mCommonAncestorWithLastFrame;
|
nsIFrame* mCommonAncestorWithLastFrame;
|
||||||
|
gfxMissingFontRecorder* mMissingFonts;
|
||||||
// mMaxTextLength is an upper bound on the size of the text in all mapped frames
|
// mMaxTextLength is an upper bound on the size of the text in all mapped frames
|
||||||
// The value UINT32_MAX represents overflow; text will be discarded
|
// The value UINT32_MAX represents overflow; text will be discarded
|
||||||
uint32_t mMaxTextLength;
|
uint32_t mMaxTextLength;
|
||||||
@ -1506,7 +1509,7 @@ void BuildTextRunsScanner::FlushLineBreaks(gfxTextRun* aTrailingTextRun)
|
|||||||
// TODO cause frames associated with the textrun to be reflowed, if they
|
// TODO cause frames associated with the textrun to be reflowed, if they
|
||||||
// aren't being reflowed already!
|
// aren't being reflowed already!
|
||||||
}
|
}
|
||||||
mBreakSinks[i]->Finish();
|
mBreakSinks[i]->Finish(mMissingFonts);
|
||||||
}
|
}
|
||||||
mBreakSinks.Clear();
|
mBreakSinks.Clear();
|
||||||
|
|
||||||
@ -2138,27 +2141,31 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
|
|||||||
if (mDoubleByteText) {
|
if (mDoubleByteText) {
|
||||||
const char16_t* text = static_cast<const char16_t*>(textPtr);
|
const char16_t* text = static_cast<const char16_t*>(textPtr);
|
||||||
if (transformingFactory) {
|
if (transformingFactory) {
|
||||||
textRun = transformingFactory->MakeTextRun(text, transformedLength, ¶ms,
|
textRun = transformingFactory->MakeTextRun(text, transformedLength,
|
||||||
fontGroup, textFlags, styles.Elements());
|
¶ms, fontGroup, textFlags,
|
||||||
|
styles.Elements(), true);
|
||||||
if (textRun) {
|
if (textRun) {
|
||||||
// ownership of the factory has passed to the textrun
|
// ownership of the factory has passed to the textrun
|
||||||
transformingFactory.forget();
|
transformingFactory.forget();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
textRun = MakeTextRun(text, transformedLength, fontGroup, ¶ms, textFlags);
|
textRun = MakeTextRun(text, transformedLength, fontGroup, ¶ms,
|
||||||
|
textFlags, mMissingFonts);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const uint8_t* text = static_cast<const uint8_t*>(textPtr);
|
const uint8_t* text = static_cast<const uint8_t*>(textPtr);
|
||||||
textFlags |= gfxFontGroup::TEXT_IS_8BIT;
|
textFlags |= gfxFontGroup::TEXT_IS_8BIT;
|
||||||
if (transformingFactory) {
|
if (transformingFactory) {
|
||||||
textRun = transformingFactory->MakeTextRun(text, transformedLength, ¶ms,
|
textRun = transformingFactory->MakeTextRun(text, transformedLength,
|
||||||
fontGroup, textFlags, styles.Elements());
|
¶ms, fontGroup, textFlags,
|
||||||
|
styles.Elements(), true);
|
||||||
if (textRun) {
|
if (textRun) {
|
||||||
// ownership of the factory has passed to the textrun
|
// ownership of the factory has passed to the textrun
|
||||||
transformingFactory.forget();
|
transformingFactory.forget();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
textRun = MakeTextRun(text, transformedLength, fontGroup, ¶ms, textFlags);
|
textRun = MakeTextRun(text, transformedLength, fontGroup, ¶ms,
|
||||||
|
textFlags, mMissingFonts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!textRun) {
|
if (!textRun) {
|
||||||
|
@ -596,7 +596,7 @@ nsCaseTransformTextRunFactory::TransformString(
|
|||||||
|
|
||||||
void
|
void
|
||||||
nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||||
gfxContext* aRefContext)
|
gfxContext* aRefContext, gfxMissingFontRecorder *aMFR)
|
||||||
{
|
{
|
||||||
nsAutoString convertedString;
|
nsAutoString convertedString;
|
||||||
nsAutoTArray<bool,50> charsToMergeArray;
|
nsAutoTArray<bool,50> charsToMergeArray;
|
||||||
@ -631,7 +631,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||||||
} else {
|
} else {
|
||||||
cachedChild = fontGroup->MakeTextRun(
|
cachedChild = fontGroup->MakeTextRun(
|
||||||
convertedString.BeginReading(), convertedString.Length(),
|
convertedString.BeginReading(), convertedString.Length(),
|
||||||
&innerParams, flags);
|
&innerParams, flags, aMFR);
|
||||||
child = cachedChild.get();
|
child = cachedChild.get();
|
||||||
}
|
}
|
||||||
if (!child)
|
if (!child)
|
||||||
@ -643,7 +643,7 @@ nsCaseTransformTextRunFactory::RebuildTextRun(nsTransformedTextRun* aTextRun,
|
|||||||
child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(),
|
child->SetPotentialLineBreaks(0, canBreakBeforeArray.Length(),
|
||||||
canBreakBeforeArray.Elements(), aRefContext);
|
canBreakBeforeArray.Elements(), aRefContext);
|
||||||
if (transformedChild) {
|
if (transformedChild) {
|
||||||
transformedChild->FinishSettingProperties(aRefContext);
|
transformedChild->FinishSettingProperties(aRefContext, aMFR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mergeNeeded) {
|
if (mergeNeeded) {
|
||||||
|
@ -21,13 +21,17 @@ public:
|
|||||||
nsTransformedTextRun* MakeTextRun(const uint8_t* aString, uint32_t aLength,
|
nsTransformedTextRun* MakeTextRun(const uint8_t* aString, uint32_t aLength,
|
||||||
const gfxFontGroup::Parameters* aParams,
|
const gfxFontGroup::Parameters* aParams,
|
||||||
gfxFontGroup* aFontGroup, uint32_t aFlags,
|
gfxFontGroup* aFontGroup, uint32_t aFlags,
|
||||||
nsStyleContext** aStyles, bool aOwnsFactory = true);
|
nsStyleContext** aStyles,
|
||||||
|
bool aOwnsFactory);
|
||||||
nsTransformedTextRun* MakeTextRun(const char16_t* aString, uint32_t aLength,
|
nsTransformedTextRun* MakeTextRun(const char16_t* aString, uint32_t aLength,
|
||||||
const gfxFontGroup::Parameters* aParams,
|
const gfxFontGroup::Parameters* aParams,
|
||||||
gfxFontGroup* aFontGroup, uint32_t aFlags,
|
gfxFontGroup* aFontGroup, uint32_t aFlags,
|
||||||
nsStyleContext** aStyles, bool aOwnsFactory = true);
|
nsStyleContext** aStyles,
|
||||||
|
bool aOwnsFactory);
|
||||||
|
|
||||||
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext) = 0;
|
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||||
|
gfxContext* aRefContext,
|
||||||
|
gfxMissingFontRecorder* aMFR) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +52,9 @@ public:
|
|||||||
: mInnerTransformingTextRunFactory(aInnerTransformingTextRunFactory),
|
: mInnerTransformingTextRunFactory(aInnerTransformingTextRunFactory),
|
||||||
mAllUppercase(aAllUppercase) {}
|
mAllUppercase(aAllUppercase) {}
|
||||||
|
|
||||||
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun, gfxContext* aRefContext) MOZ_OVERRIDE;
|
virtual void RebuildTextRun(nsTransformedTextRun* aTextRun,
|
||||||
|
gfxContext* aRefContext,
|
||||||
|
gfxMissingFontRecorder* aMFR) MOZ_OVERRIDE;
|
||||||
|
|
||||||
// Perform a transformation on the given string, writing the result into
|
// Perform a transformation on the given string, writing the result into
|
||||||
// aConvertedString. If aAllUppercase is true, the transform is (global)
|
// aConvertedString. If aAllUppercase is true, the transform is (global)
|
||||||
@ -105,11 +111,12 @@ public:
|
|||||||
* are done and before we request any data from the textrun. Also always
|
* are done and before we request any data from the textrun. Also always
|
||||||
* called after a Create.
|
* called after a Create.
|
||||||
*/
|
*/
|
||||||
void FinishSettingProperties(gfxContext* aRefContext)
|
void FinishSettingProperties(gfxContext* aRefContext,
|
||||||
|
gfxMissingFontRecorder* aMFR)
|
||||||
{
|
{
|
||||||
if (mNeedsRebuild) {
|
if (mNeedsRebuild) {
|
||||||
mNeedsRebuild = false;
|
mNeedsRebuild = false;
|
||||||
mFactory->RebuildTextRun(this, aRefContext);
|
mFactory->RebuildTextRun(this, aRefContext, aMFR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ nsPropertiesTable::MakeTextRun(gfxContext* aThebesContext,
|
|||||||
"nsPropertiesTable can only access glyphs by code point");
|
"nsPropertiesTable can only access glyphs by code point");
|
||||||
return aFontGroup->
|
return aFontGroup->
|
||||||
MakeTextRun(aGlyph.code, aGlyph.Length(), aThebesContext,
|
MakeTextRun(aGlyph.code, aGlyph.Length(), aThebesContext,
|
||||||
aAppUnitsPerDevPixel, 0);
|
aAppUnitsPerDevPixel, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// An instance of nsOpenTypeTable is associated with one gfxFontEntry that
|
// An instance of nsOpenTypeTable is associated with one gfxFontEntry that
|
||||||
@ -470,7 +470,7 @@ nsOpenTypeTable::UpdateCache(gfxContext* aThebesContext,
|
|||||||
if (mCharCache != aChar) {
|
if (mCharCache != aChar) {
|
||||||
nsAutoPtr<gfxTextRun> textRun;
|
nsAutoPtr<gfxTextRun> textRun;
|
||||||
textRun = aFontGroup->
|
textRun = aFontGroup->
|
||||||
MakeTextRun(&aChar, 1, aThebesContext, aAppUnitsPerDevPixel, 0);
|
MakeTextRun(&aChar, 1, aThebesContext, aAppUnitsPerDevPixel, 0, nullptr);
|
||||||
const gfxTextRun::CompressedGlyph& data = textRun->GetCharacterGlyphs()[0];
|
const gfxTextRun::CompressedGlyph& data = textRun->GetCharacterGlyphs()[0];
|
||||||
if (data.IsSimpleGlyph()) {
|
if (data.IsSimpleGlyph()) {
|
||||||
mGlyphID = data.GetSimpleGlyph();
|
mGlyphID = data.GetSimpleGlyph();
|
||||||
@ -1553,7 +1553,8 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
|
|||||||
nsAutoPtr<gfxTextRun> textRun;
|
nsAutoPtr<gfxTextRun> textRun;
|
||||||
textRun = fm->GetThebesFontGroup()->
|
textRun = fm->GetThebesFontGroup()->
|
||||||
MakeTextRun(static_cast<const char16_t*>(mData.get()), len, aThebesContext,
|
MakeTextRun(static_cast<const char16_t*>(mData.get()), len, aThebesContext,
|
||||||
aPresContext->AppUnitsPerDevPixel(), 0);
|
aPresContext->AppUnitsPerDevPixel(), 0,
|
||||||
|
aPresContext->MissingFontRecorder());
|
||||||
aDesiredStretchSize = MeasureTextRun(aThebesContext, textRun);
|
aDesiredStretchSize = MeasureTextRun(aThebesContext, textRun);
|
||||||
mGlyphs[0] = textRun;
|
mGlyphs[0] = textRun;
|
||||||
|
|
||||||
|
@ -592,6 +592,10 @@ pref("gfx.bundled_fonts.enabled", true);
|
|||||||
pref("gfx.bundled_fonts.force-enabled", false);
|
pref("gfx.bundled_fonts.force-enabled", false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Do we fire a notification about missing fonts, so the front-end can decide
|
||||||
|
// whether to try and do something about it (e.g. download additional fonts)?
|
||||||
|
pref("gfx.missing_fonts.notify", false);
|
||||||
|
|
||||||
pref("gfx.filter.nearest.force-enabled", false);
|
pref("gfx.filter.nearest.force-enabled", false);
|
||||||
|
|
||||||
// prefs controlling the font (name/cmap) loader that runs shortly after startup
|
// prefs controlling the font (name/cmap) loader that runs shortly after startup
|
||||||
|
Loading…
Reference in New Issue
Block a user