зеркало из https://github.com/mozilla/pjs.git
b=597147 part 5: move glyph run routines from FontGroup to Font r=jfkthame
--HG-- extra : transplant_source : %3E%9A%B3%994%99%E9%08jQb%3D%08%B1y%C5%A36%C9%89
This commit is contained in:
Родитель
0bdf3e250b
Коммит
e23cb68201
|
@ -108,6 +108,8 @@ static PangoLanguage *GuessPangoLanguage(const nsACString& aLangGroup);
|
|||
static PangoLanguage *GuessPangoLanguage(nsIAtom *aLangGroup);
|
||||
|
||||
static cairo_scaled_font_t *CreateScaledFont(FcPattern *aPattern);
|
||||
static void SetMissingGlyphs(gfxTextRun *aTextRun, const gchar *aUTF8,
|
||||
PRUint32 aUTF8Length, PRUint32 *aUTF16Offset);
|
||||
|
||||
static PangoFontMap *gPangoFontMap;
|
||||
static PangoFontMap *GetPangoFontMap();
|
||||
|
@ -527,6 +529,10 @@ public:
|
|||
virtual ~gfxFcFont ();
|
||||
static already_AddRefed<gfxFcFont> GetOrMakeFont(FcPattern *aPattern);
|
||||
|
||||
#if defined(ENABLE_FAST_PATH_8BIT)
|
||||
nsresult InitGlyphRunFast(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString, PRUint32 aLength);
|
||||
#endif
|
||||
protected:
|
||||
gfxFcFont(cairo_scaled_font_t *aCairoFont,
|
||||
gfxFontEntry *aFontEntry, const gfxFontStyle *aFontStyle);
|
||||
|
@ -2504,20 +2510,9 @@ gfxPangoFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
|
|||
if (!run)
|
||||
return nsnull;
|
||||
|
||||
PRBool isRTL = run->IsRightToLeft();
|
||||
if ((aFlags & TEXT_IS_ASCII) && !isRTL) {
|
||||
// We don't need to send an override character here, the characters must be all LTR
|
||||
const gchar *utf8Chars = reinterpret_cast<const gchar*>(aString);
|
||||
InitTextRun(run, utf8Chars, aLength, 0, PR_TRUE);
|
||||
} else {
|
||||
// this is really gross...
|
||||
const char *chars = reinterpret_cast<const char*>(aString);
|
||||
NS_ConvertASCIItoUTF16 unicodeString(chars, aLength);
|
||||
nsCAutoString utf8;
|
||||
PRInt32 headerLen = AppendDirectionalIndicatorUTF8(isRTL, utf8);
|
||||
AppendUTF16toUTF8(unicodeString, utf8);
|
||||
InitTextRun(run, utf8.get(), utf8.Length(), headerLen, PR_TRUE);
|
||||
}
|
||||
const char *chars = reinterpret_cast<const char*>(aString);
|
||||
NS_ConvertASCIItoUTF16 unicodeString(chars, aLength);
|
||||
InitTextRun(run, unicodeString.get(), unicodeString.Length(), PR_TRUE);
|
||||
run->FetchGlyphExtents(aParams->mContext);
|
||||
return run;
|
||||
}
|
||||
|
@ -2544,11 +2539,7 @@ gfxPangoFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
|
|||
if (!run)
|
||||
return nsnull;
|
||||
|
||||
nsCAutoString utf8;
|
||||
PRInt32 headerLen = AppendDirectionalIndicatorUTF8(run->IsRightToLeft(), utf8);
|
||||
AppendUTF16toUTF8(Substring(aString, aString + aLength), utf8);
|
||||
PRBool is8Bit = PR_FALSE;
|
||||
|
||||
#if defined(ENABLE_FAST_PATH_8BIT)
|
||||
if (CanTakeFastPath(aFlags)) {
|
||||
PRUint32 allBits = 0;
|
||||
|
@ -2559,29 +2550,24 @@ gfxPangoFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
|
|||
is8Bit = (allBits & 0xFF00) == 0;
|
||||
}
|
||||
#endif
|
||||
InitTextRun(run, utf8.get(), utf8.Length(), headerLen, is8Bit);
|
||||
InitTextRun(run, aString, aLength, is8Bit);
|
||||
run->FetchGlyphExtents(aParams->mContext);
|
||||
return run;
|
||||
}
|
||||
|
||||
void
|
||||
gfxPangoFontGroup::InitTextRun(gfxTextRun *aTextRun, const gchar *aUTF8Text,
|
||||
PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
|
||||
PRBool aTake8BitPath)
|
||||
gfxPangoFontGroup::InitTextRun(gfxTextRun *aTextRun, const PRUnichar *aString,
|
||||
PRUint32 aLength, PRBool aTake8BitPath)
|
||||
{
|
||||
#if defined(ENABLE_FAST_PATH_ALWAYS)
|
||||
CreateGlyphRunsFast(aTextRun, aUTF8Text + aUTF8HeaderLength, aUTF8Length - aUTF8HeaderLength);
|
||||
#else
|
||||
#if defined(ENABLE_FAST_PATH_8BIT)
|
||||
if (aTake8BitPath && CanTakeFastPath(aTextRun->GetFlags())) {
|
||||
nsresult rv = CreateGlyphRunsFast(aTextRun, aUTF8Text + aUTF8HeaderLength, aUTF8Length - aUTF8HeaderLength);
|
||||
nsresult rv = CreateGlyphRunsFast(aTextRun, aString, aLength);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateGlyphRunsItemizing(aTextRun, aUTF8Text, aUTF8Length, aUTF8HeaderLength);
|
||||
#endif
|
||||
CreateGlyphRunsItemizing(aTextRun, aString, aLength);
|
||||
}
|
||||
|
||||
static void ReleaseDownloadedFontEntry(void *data)
|
||||
|
@ -2955,12 +2941,10 @@ SetGlyphsForCharacterGroup(const PangoGlyphInfo *aGlyphs, PRUint32 aGlyphCount,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPangoFontGroup::SetGlyphs(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 *aUTF16Offset, PangoGlyphString *aGlyphs,
|
||||
PangoGlyphUnit aOverrideSpaceWidth,
|
||||
PRBool aAbortOnMissingGlyph)
|
||||
static nsresult
|
||||
SetGlyphs(gfxTextRun *aTextRun, const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 *aUTF16Offset, PangoGlyphString *aGlyphs,
|
||||
PangoGlyphUnit aOverrideSpaceWidth)
|
||||
{
|
||||
gint numGlyphs = aGlyphs->num_glyphs;
|
||||
PangoGlyphInfo *glyphs = aGlyphs->glyphs;
|
||||
|
@ -3031,12 +3015,9 @@ gfxPangoFontGroup::SetGlyphs(gfxTextRun *aTextRun,
|
|||
} while (glyphIndex < numGlyphs &&
|
||||
logClusters[glyphIndex] == gint(clusterUTF8Start));
|
||||
|
||||
if (haveMissingGlyph && aAbortOnMissingGlyph)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
if (haveMissingGlyph) {
|
||||
rv = SetMissingGlyphs(aTextRun, clusterUTF8, clusterUTF8Length,
|
||||
SetMissingGlyphs(aTextRun, clusterUTF8, clusterUTF8Length,
|
||||
&utf16Offset);
|
||||
} else {
|
||||
rv = SetGlyphsForCharacterGroup(&glyphs[glyphClusterStart],
|
||||
|
@ -3044,17 +3025,16 @@ gfxPangoFontGroup::SetGlyphs(gfxTextRun *aTextRun,
|
|||
aTextRun,
|
||||
clusterUTF8, clusterUTF8Length,
|
||||
&utf16Offset, aOverrideSpaceWidth);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
*aUTF16Offset = utf16Offset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPangoFontGroup::SetMissingGlyphs(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 *aUTF16Offset)
|
||||
static void
|
||||
SetMissingGlyphs(gfxTextRun *aTextRun, const gchar *aUTF8,
|
||||
PRUint32 aUTF8Length, PRUint32 *aUTF16Offset)
|
||||
{
|
||||
PRUint32 utf16Offset = *aUTF16Offset;
|
||||
PRUint32 textRunLength = aTextRun->GetLength();
|
||||
|
@ -3075,42 +3055,45 @@ gfxPangoFontGroup::SetMissingGlyphs(gfxTextRun *aTextRun,
|
|||
}
|
||||
|
||||
*aUTF16Offset = utf16Offset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FAST_PATH_8BIT) || defined(ENABLE_FAST_PATH_ALWAYS)
|
||||
#if defined(ENABLE_FAST_PATH_8BIT)
|
||||
nsresult
|
||||
gfxPangoFontGroup::CreateGlyphRunsFast(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length)
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
const gchar *p = aUTF8;
|
||||
gfxFcFont *gfxFont = GetBaseFont();
|
||||
PRUint32 utf16Offset = 0;
|
||||
aTextRun->AddGlyphRun(gfxFont, 0);
|
||||
return gfxFont->InitGlyphRunFast(aTextRun, aString, aLength);
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxFcFont::InitGlyphRunFast(gfxTextRun *aTextRun,
|
||||
const PRUnichar *aString, PRUint32 aLength)
|
||||
{
|
||||
gfxTextRun::CompressedGlyph g;
|
||||
const PRUint32 appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
|
||||
|
||||
aTextRun->AddGlyphRun(gfxFont, 0);
|
||||
for (PRUint32 utf16Offset = 0; utf16Offset < aLength; ++utf16Offset) {
|
||||
|
||||
PRUint32 ch = aString[utf16Offset];
|
||||
NS_ASSERTION(!gfxFontGroup::IsInvalidChar(ch), "Invalid char detected");
|
||||
|
||||
while (p < aUTF8 + aUTF8Length) {
|
||||
// glib-2.12.9: "If p does not point to a valid UTF-8 encoded
|
||||
// character, results are undefined." so it is not easy to assert that
|
||||
// aUTF8 in fact points to UTF8 data but asserting
|
||||
// g_unichar_validate(ch) may be mildly useful.
|
||||
gunichar ch = g_utf8_get_char(p);
|
||||
p = g_utf8_next_char(p);
|
||||
|
||||
if (ch == 0) {
|
||||
// treat this null byte as a missing glyph. Pango
|
||||
// doesn't create glyphs for these, not even missing-glyphs.
|
||||
aTextRun->SetMissingGlyph(utf16Offset, 0);
|
||||
} else {
|
||||
NS_ASSERTION(!IsInvalidChar(ch), "Invalid char detected");
|
||||
FT_UInt glyph = gfxFont->GetGlyph(ch);
|
||||
// This code is used for 8-bit text only.
|
||||
NS_ASSERTION(!IS_SURROGATE(ch), "Need to add surrogate support");
|
||||
|
||||
FT_UInt glyph = GetGlyph(ch);
|
||||
if (!glyph) // character not in font,
|
||||
return NS_ERROR_FAILURE; // fallback to CreateGlyphRunsItemizing
|
||||
|
||||
cairo_text_extents_t extents;
|
||||
gfxFont->GetGlyphExtents(glyph, &extents);
|
||||
GetGlyphExtents(glyph, &extents);
|
||||
|
||||
PRInt32 advance = NS_lround(extents.x_advance * appUnitsPerDevUnit);
|
||||
if (advance >= 0 &&
|
||||
|
@ -3129,15 +3112,7 @@ gfxPangoFontGroup::CreateGlyphRunsFast(gfxTextRun *aTextRun,
|
|||
g.SetComplex(aTextRun->IsClusterStart(utf16Offset), PR_TRUE, 1);
|
||||
aTextRun->SetGlyphs(utf16Offset, g, &details);
|
||||
}
|
||||
|
||||
NS_ASSERTION(!IS_SURROGATE(ch), "Surrogates shouldn't appear in UTF8");
|
||||
if (ch >= 0x10000) {
|
||||
// This character is a surrogate pair in UTF16
|
||||
++utf16Offset;
|
||||
}
|
||||
}
|
||||
|
||||
++utf16Offset;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3145,8 +3120,8 @@ gfxPangoFontGroup::CreateGlyphRunsFast(gfxTextRun *aTextRun,
|
|||
|
||||
void
|
||||
gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 aUTF8HeaderLen)
|
||||
const PRUnichar *aString,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
// This font group and gfxPangoFontMap are recorded on the PangoContext
|
||||
// passed to pango_itemize_with_base_dir().
|
||||
|
@ -3168,6 +3143,11 @@ gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
|||
// PangoFont and so can render the same glyphs in the same way as
|
||||
// pango_shape measures.
|
||||
|
||||
nsCAutoString utf8;
|
||||
PRUint32 headerLen =
|
||||
AppendDirectionalIndicatorUTF8(aTextRun->IsRightToLeft(), utf8);
|
||||
AppendUTF16toUTF8(Substring(aString, aString + aLength), utf8);
|
||||
|
||||
PangoContext *context = GetPangoContext();
|
||||
// we should set this to null if we don't have a text language from the page...
|
||||
// except that we almost always have something...
|
||||
|
@ -3175,7 +3155,9 @@ gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
|||
SetFontGroup(context, this);
|
||||
|
||||
PangoDirection dir = aTextRun->IsRightToLeft() ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
|
||||
GList *items = pango_itemize_with_base_dir(context, dir, aUTF8, 0, aUTF8Length, nsnull, nsnull);
|
||||
GList *items =
|
||||
pango_itemize_with_base_dir(context, dir, utf8.get(), 0, utf8.Length(),
|
||||
nsnull, nsnull);
|
||||
|
||||
PRUint32 utf16Offset = 0;
|
||||
#ifdef DEBUG
|
||||
|
@ -3192,12 +3174,12 @@ gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
|||
|
||||
PRUint32 offset = item->offset;
|
||||
PRUint32 length = item->length;
|
||||
if (offset < aUTF8HeaderLen) {
|
||||
if (offset + length <= aUTF8HeaderLen)
|
||||
if (offset < headerLen) {
|
||||
if (offset + length <= headerLen)
|
||||
continue;
|
||||
|
||||
length -= aUTF8HeaderLen - offset;
|
||||
offset = aUTF8HeaderLen;
|
||||
length -= headerLen - offset;
|
||||
offset = headerLen;
|
||||
}
|
||||
|
||||
gfxFcFont *font =
|
||||
|
@ -3212,7 +3194,7 @@ gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
|||
PRUint32 spaceWidth =
|
||||
moz_pango_units_from_double(font->GetMetrics().spaceWidth);
|
||||
|
||||
const gchar *p = aUTF8 + offset;
|
||||
const gchar *p = utf8.get() + offset;
|
||||
const gchar *end = p + length;
|
||||
while (p < end) {
|
||||
if (*p == 0) {
|
||||
|
@ -3232,7 +3214,7 @@ gfxPangoFontGroup::CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
|||
|
||||
pango_shape(text, len, &item->analysis, glyphString);
|
||||
SetupClusterBoundaries(aTextRun, text, len, utf16Offset, &item->analysis);
|
||||
SetGlyphs(aTextRun, text, len, &utf16Offset, glyphString, spaceWidth, PR_FALSE);
|
||||
SetGlyphs(aTextRun, text, len, &utf16Offset, glyphString, spaceWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,9 +53,6 @@
|
|||
// to shape any textruns with non-8bit characters
|
||||
// XXX
|
||||
#define ENABLE_FAST_PATH_8BIT
|
||||
// Enable this to bypass Pango shaping for all textruns. Don't expect
|
||||
// anything other than simple Latin work though!
|
||||
//#define ENABLE_FAST_PATH_ALWAYS
|
||||
|
||||
class gfxFcFontSet;
|
||||
class gfxFcFont;
|
||||
|
@ -133,26 +130,15 @@ private:
|
|||
* (TEXT_IS_8BIT can return false when the characters are all below 0x100
|
||||
* but stored in UTF16 format)
|
||||
*/
|
||||
void InitTextRun(gfxTextRun *aTextRun, const gchar *aUTF8Text,
|
||||
PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
|
||||
PRBool aTake8BitPath);
|
||||
void InitTextRun(gfxTextRun *aTextRun, const PRUnichar *aString,
|
||||
PRUint32 aLength, PRBool aTake8BitPath);
|
||||
|
||||
// Returns NS_ERROR_FAILURE if there's a missing glyph
|
||||
nsresult SetGlyphs(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 *aUTF16Offset, PangoGlyphString *aGlyphs,
|
||||
PangoGlyphUnit aOverrideSpaceWidth,
|
||||
PRBool aAbortOnMissingGlyph);
|
||||
nsresult SetMissingGlyphs(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 *aUTF16Offset);
|
||||
void CreateGlyphRunsItemizing(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length,
|
||||
PRUint32 aUTF8HeaderLength);
|
||||
#if defined(ENABLE_FAST_PATH_8BIT) || defined(ENABLE_FAST_PATH_ALWAYS)
|
||||
const PRUnichar *aString, PRUint32 aLength);
|
||||
#if defined(ENABLE_FAST_PATH_8BIT)
|
||||
PRBool CanTakeFastPath(PRUint32 aFlags);
|
||||
nsresult CreateGlyphRunsFast(gfxTextRun *aTextRun,
|
||||
const gchar *aUTF8, PRUint32 aUTF8Length);
|
||||
const PRUnichar *aString, PRUint32 aLength);
|
||||
#endif
|
||||
|
||||
void GetFcFamilies(nsTArray<nsString> *aFcFamilyList,
|
||||
|
|
Загрузка…
Ссылка в новой задаче