Bug 368799. Refactor gfxPangoTextRun so that the platform-dependent parts are all in gfxPangoFont/gfxPangoFontGroup. Also, remove special-string APIs, FlushSpacingCache and GetDecorationMetrics APIs from gfxTextRun. This will allow us to merge gfxPangoTextRun up to gfxTextRun and use that code on all platforms. r=pavlov

This commit is contained in:
roc+%cs.cmu.edu 2007-02-09 01:42:29 +00:00
Родитель 13f55f415d
Коммит 8841c2301a
5 изменённых файлов: 556 добавлений и 644 удалений

Просмотреть файл

@ -181,7 +181,9 @@ class THEBES_API gfxTextRunFactory {
THEBES_INLINE_DECL_REFCOUNTING(gfxTextRunFactory)
public:
// Flags >= 0x10000 are reserved for textrun clients
// Flags in the mask 0xFFFF0000 are reserved for textrun clients
// Flags in the mask 0x0000F000 are reserved for per-platform fonts
// Flags in the mask 0x00000FFF are set by the textrun creator.
enum {
/**
* When set, the text string pointer used to create the text run
@ -237,9 +239,11 @@ public:
// The language of the text, or null if not known
nsIAtom *mLangGroup;
// A description of which characters have been stripped from the original
// DOM string to produce the characters in the textrun
// DOM string to produce the characters in the textrun. May be null
// if that information is not relevant.
gfxSkipChars *mSkipChars;
// A list of where linebreaks are currently placed in the textrun
// A list of where linebreaks are currently placed in the textrun. May
// be null if mInitialBreakCount is zero.
PRUint32 *mInitialBreaks;
PRUint32 mInitialBreakCount;
// The ratio to use to convert device pixels to application layout units
@ -312,6 +316,27 @@ public:
const nsString& GetFamilies() { return mFamilies; }
/**
* Special strings are strings that we might need to draw/measure but aren't
* actually substrings of DOM text. They never have extra spacing and
* aren't involved in breaking.
*/
enum SpecialString {
STRING_ELLIPSIS,
STRING_HYPHEN,
STRING_SPACE,
STRING_MAX = STRING_SPACE
};
// Get the textrun for the given special string. Ownership remains
// with this gfxFontGroup. Copy relevant parameters from the template textrun.
// SpecialString textruns do not use spacing and it's fine to pass null
// as the PropertyProvider* in their methods.
// This is stubbed out until we have full textrun support on all platforms.
virtual gfxTextRun *GetSpecialStringTextRun(SpecialString aString,
gfxTextRun *aTemplate)
{ return nsnull; }
protected:
nsString mFamilies;
gfxFontStyle mStyle;
@ -337,12 +362,11 @@ protected:
*
* gfxTextRuns are mostly immutable. The only things that can change are
* inter-cluster spacing and line break placement. Spacing is always obtained
* lazily by methods that need it; cached spacing is flushed via
* FlushSpacingCache(). Line breaks are stored persistently (insofar
* as they affect the shaping of glyphs; gfxTextRun does not actually do anything
* to explicitly account for line breaks). Initially there are no line breaks.
* The textrun can record line breaks before or after any given cluster. (Line
* breaks specified inside clusters are ignored.)
* lazily by methods that need it, it is not cached. Line breaks are stored
* persistently (insofar as they affect the shaping of glyphs; gfxTextRun does
* not actually do anything to explicitly account for line breaks). Initially
* there are no line breaks. The textrun can record line breaks before or after
* any given cluster. (Line breaks specified inside clusters are ignored.)
*
* gfxTextRuns don't need to remember their text ... often it's enough just to
* convert text to glyphs and store glyphs plus some geometry data in packed
@ -510,25 +534,6 @@ public:
PropertyProvider *aBreakProvider,
gfxFloat *aAdvanceWidth) = 0;
/**
* Special strings are strings that we might need to draw/measure but aren't
* actually substrings of the given text. They never have extra spacing and
* aren't involved in breaking.
*/
enum SpecialString {
STRING_ELLIPSIS,
STRING_HYPHEN,
STRING_SPACE,
STRING_MAX = STRING_SPACE
};
/**
* Draw special string.
* The provided point is the baseline origin on the left of the string
* for LTR, on the right of the string for RTL.
*/
virtual void DrawSpecialString(gfxContext *aContext, gfxPoint aPt,
SpecialString aString) = 0;
// Metrics needed by reflow
struct Metrics {
Metrics() {
@ -578,14 +583,6 @@ public:
PRBool aTightBoundingBox,
PropertyProvider *aProvider) = 0;
/**
* Computes the ReflowMetrics for a special string.
* Uses GetSpacing from aBreakProvider.
* @param aTightBoundingBox if true, we make the bounding box tight
*/
virtual Metrics MeasureTextSpecialString(SpecialString aString,
PRBool aTightBoundingBox) = 0;
/**
* Computes just the advance width for a substring.
* Uses GetSpacing from aBreakProvider.
@ -593,18 +590,6 @@ public:
virtual gfxFloat GetAdvanceWidth(PRUint32 aStart, PRUint32 aLength,
PropertyProvider *aProvider) = 0;
/**
* Computes the advance width for a special string.
*/
virtual gfxFloat GetAdvanceWidthSpecialString(SpecialString aString) = 0;
/**
* Get the font metrics that we should use for drawing text decorations.
* Overriden here so that transforming gfxTextRuns such as smallcaps
* can do something special if they want to.
*/
virtual gfxFont::Metrics GetDecorationMetrics() = 0;
/**
* Clear all stored line breaks for the given range (both before and after),
* and then set the line-break state before aStart to aBreakBefore and
@ -691,11 +676,6 @@ public:
*/
virtual void SetContext(gfxContext *aContext) {}
/**
* Flush cached spacing data for the characters at and after aStart.
*/
virtual void FlushSpacingCache(PRUint32 aStart) = 0;
// Utility getters
PRBool IsRightToLeft() const { return (mFlags & gfxTextRunFactory::TEXT_IS_RTL) != 0; }
@ -706,14 +686,13 @@ public:
float GetAppUnitsPerDevUnit() { return mAppUnitsPerDevUnit; }
protected:
gfxTextRun(gfxTextRunFactory::Parameters *aParams, PRBool aIs8Bit)
gfxTextRun(gfxTextRunFactory::Parameters *aParams)
: mUserData(aParams->mUserData),
mAppUnitsPerDevUnit(aParams->mAppUnitsPerDevUnit),
mFlags(aParams->mFlags)
{
mSkipChars.TakeFrom(aParams->mSkipChars);
if (aIs8Bit) {
mFlags |= gfxTextRunFactory::TEXT_IS_8BIT;
if (aParams->mSkipChars) {
mSkipChars.TakeFrom(aParams->mSkipChars);
}
}

Просмотреть файл

@ -57,6 +57,8 @@
class FontSelector;
class gfxPangoTextRun;
class gfxPangoFont : public gfxFont {
public:
gfxPangoFont (const nsAString& aName,
@ -75,11 +77,64 @@ public:
XftFont *GetXftFont () { RealizeXftFont (); return mXftFont; }
gfxFloat GetAdjustedSize() { RealizeFont(); return mAdjustedSize; }
// These APIs need to be moved up to gfxFont with gfxPangoTextRun switched
// to gfxTextRun
/**
* Draw a series of glyphs to aContext. The direction of aTextRun must
* be honoured.
* @param aStart the first character to draw
* @param aEnd draw characters up to here
* @param aBaselineOrigin the baseline origin; the left end of the baseline
* for LTR textruns, the right end of the baseline for RTL textruns. On return,
* this should be updated to the other end of the baseline. In application units.
* @param aSpacing spacing to insert before and after characters (for RTL
* glyphs, before-spacing is inserted to the right of characters). There
* are aEnd - aStart elements in this array, unless it's null to indicate
* that there is no spacing.
* @param aDrawToPath when true, add the glyph outlines to the current path
* instead of drawing the glyphs
*
* Callers guarantee:
* -- aStart and aEnd are aligned to cluster and ligature boundaries
* -- all glyphs use this font
*/
void Draw(gfxPangoTextRun *aTextRun, PRUint32 aStart, PRUint32 aEnd,
gfxContext *aContext, PRBool aDrawToPath, gfxPoint *aBaselineOrigin,
gfxTextRun::PropertyProvider::Spacing *aSpacing);
/**
* Measure a run of characters. See gfxTextRun::Metrics.
* @param aTight if false, then return the union of the glyph extents
* with the font-box for the characters (the rectangle with x=0,width=
* the advance width for the character run,y=-(font ascent), and height=
* font ascent + font descent). Otherwise, we must return as tight as possible
* an approximation to the area actually painted by glyphs.
* @param aSpacing spacing to insert before and after glyphs. The bounding box
* need not include the spacing itself, but the spacing affects the glyph
* positions. null if there is no spacing.
*
* Callers guarantee:
* -- aStart and aEnd are aligned to cluster and ligature boundaries
* -- all glyphs use this font
*/
gfxTextRun::Metrics Measure(gfxPangoTextRun *aTextRun,
PRUint32 aStart, PRUint32 aEnd,
PRBool aTightBoundingBox,
gfxTextRun::PropertyProvider::Spacing *aSpacing);
/**
* Line breaks have been changed at the beginning and/or end of a substring
* of the text. Reshaping may be required; glyph updating is permitted.
* @return true if anything was changed, false otherwise
*/
PRBool NotifyLineBreaksChanged(gfxPangoTextRun *aTextRun,
PRUint32 aStart, PRUint32 aLength)
{ return PR_FALSE; }
protected:
PangoFontDescription *mPangoFontDesc;
PangoContext *mPangoCtx;
XftFont *mXftFont;
cairo_scaled_font_t *mCairoFont;
PRBool mHasMetrics;
Metrics mMetrics;
@ -88,8 +143,11 @@ protected:
void RealizeFont(PRBool force = PR_FALSE);
void RealizeXftFont(PRBool force = PR_FALSE);
void GetSize(const char *aString, PRUint32 aLength, gfxSize& inkSize, gfxSize& logSize);
void SetupCairoFont(cairo_t *aCR);
};
class FontSelector;
class THEBES_API gfxPangoFontGroup : public gfxFontGroup {
public:
gfxPangoFontGroup (const nsAString& families,
@ -98,6 +156,7 @@ public:
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
// Create and initialize a textrun using Pango (or Xft)
virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
Parameters *aParams);
virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
@ -119,16 +178,40 @@ public:
mFontCache.Put(aName, aFont);
}
struct SpecialStringData {
PangoGlyphString* mGlyphs;
gfxFloat mAdvance;
SpecialStringData() { mGlyphs = nsnull; }
~SpecialStringData() { if (mGlyphs) pango_glyph_string_free(mGlyphs); }
};
SpecialStringData mSpecialStrings[gfxTextRun::STRING_MAX + 1];
virtual gfxTextRun *GetSpecialStringTextRun(SpecialString aString,
gfxTextRun *aTemplate);
protected:
friend class FontSelector;
// ****** Textrun glyph conversion helpers ******
// If aUTF16Text is null, then the string contains no characters >= 0x100
void InitTextRun(gfxPangoTextRun *aTextRun, const gchar *aUTF8Text,
PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
const PRUnichar *aUTF16Text, PRUint32 aUTF16Length);
// Returns NS_ERROR_FAILURE if there's a missing glyph
nsresult SetGlyphs(gfxPangoTextRun *aTextRun, const gchar *aUTF8,
PRUint32 aUTF8Length,
PRUint32 *aUTF16Offset, PangoGlyphString *aGlyphs,
PangoGlyphUnit aOverrideSpaceWidth,
PRBool aAbortOnMissingGlyph);
// If aUTF16Text is null, then the string contains no characters >= 0x100.
// Returns NS_ERROR_FAILURE if we require the itemizing path
nsresult CreateGlyphRunsFast(gfxPangoTextRun *aTextRun,
const gchar *aUTF8, PRUint32 aUTF8Length,
const PRUnichar *aUTF16Text, PRUint32 aUTF16Length);
void CreateGlyphRunsItemizing(gfxPangoTextRun *aTextRun,
const gchar *aUTF8, PRUint32 aUTF8Length,
PRUint32 aUTF8HeaderLength);
#if defined(ENABLE_XFT_FAST_PATH_8BIT) || defined(ENABLE_XFT_FAST_PATH_ALWAYS)
void CreateGlyphRunsXft(gfxPangoTextRun *aTextRun,
const gchar *aUTF8, PRUint32 aUTF8Length);
#endif
void SetupClusterBoundaries(gfxPangoTextRun *aTextRun,
const gchar *aUTF8, PRUint32 aUTF8Length,
PRUint32 aUTF16Offset, PangoAnalysis *aAnalysis);
static PRBool FontCallback (const nsAString& fontName,
const nsACString& genericName,
void *closure);
@ -136,20 +219,21 @@ protected:
private:
nsDataHashtable<nsStringHashKey, nsRefPtr<gfxPangoFont> > mFontCache;
nsTArray<gfxFontStyle> mAdditionalStyles;
nsAutoPtr<gfxTextRun> mSpecialStrings[STRING_MAX + 1];
};
struct TextSegment;
/**
* This is not really Pango-specific anymore. We'll merge this into gfxTextRun
* soon. At that point uses of gfxPangoFontGroup, gfxPangoFont and gfxPangoTextRun
* will be converted to use the cross-platform superclasses.
*/
class THEBES_API gfxPangoTextRun : public gfxTextRun {
public:
gfxPangoTextRun(gfxPangoFontGroup *aGroup,
const PRUint8 *aString, PRUint32 aLength,
gfxTextRunFactory::Parameters *aParams);
gfxPangoTextRun(gfxPangoFontGroup *aGroup,
const PRUnichar *aString, PRUint32 aLength,
gfxTextRunFactory::Parameters *aParams);
~gfxPangoTextRun();
gfxPangoTextRun(gfxTextRunFactory::Parameters *aParams, PRUint32 aLength);
// The caller is responsible for initializing our glyphs. Initially
// all glyphs are such that GetCharacterGlyphs()[i].IsMissing() is true.
// gfxTextRun public API
virtual void GetCharFlags(PRUint32 aStart, PRUint32 aLength,
PRUint8 *aFlags);
virtual PRUint8 GetCharFlags(PRUint32 aOffset);
@ -165,8 +249,6 @@ public:
PRUint32 aStart, PRUint32 aLength,
PropertyProvider *aBreakProvider,
gfxFloat *aAdvanceWidth);
virtual void DrawSpecialString(gfxContext *aContext, gfxPoint aPt,
SpecialString aString);
virtual Metrics MeasureText(PRUint32 aStart, PRUint32 aLength,
PRBool aTightBoundingBox,
PropertyProvider *aBreakProvider);
@ -174,12 +256,8 @@ public:
PRBool aLineBreakBefore, PRBool aLineBreakAfter,
TextProvider *aProvider,
gfxFloat *aAdvanceWidthDelta);
virtual Metrics MeasureTextSpecialString(SpecialString aString,
PRBool aTightBoundingBox);
virtual gfxFloat GetAdvanceWidth(PRUint32 aStart, PRUint32 aLength,
PropertyProvider *aBreakProvider);
virtual gfxFloat GetAdvanceWidthSpecialString(SpecialString aString);
virtual gfxFont::Metrics GetDecorationMetrics();
virtual PRUint32 BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
PRBool aLineBreakBefore, gfxFloat aWidth,
PropertyProvider *aBreakProvider,
@ -187,7 +265,6 @@ public:
Metrics *aMetrics, PRBool aTightBoundingBox,
PRBool *aUsedHyphenation,
PRUint32 *aLastBreak);
virtual void FlushSpacingCache(PRUint32 aStart);
/**
* This class records the information associated with a character in the
@ -217,15 +294,19 @@ public:
// Non-simple glyphs have the following tags
TAG_MASK = 0x000000FFU,
// Indicates that this character corresponds to a missing glyph
// and should be skipped (or possibly, render the character
// Unicode value in some special way)
TAG_MISSING = 0x00U,
// Indicates that a cluster starts at this character and is rendered
// using one or more glyphs which cannot be represented here.
// Look up the DetailedGlyph table instead.
TAG_COMPLEX_CLUSTER = 0x00U,
TAG_COMPLEX_CLUSTER = 0x01U,
// Indicates that a cluster starts at this character but is rendered
// as part of a ligature starting in a previous cluster.
// NOTE: we divide up the ligature's width by the number of clusters
// to get the width assigned to each cluster.
TAG_LIGATURE_CONTINUATION = 0x01U,
TAG_LIGATURE_CONTINUATION = 0x21U,
// Values where the upper 28 bits equal 0x80 are reserved for
// non-cluster-start characters (see IsClusterStart below)
@ -239,28 +320,34 @@ public:
TAG_CLUSTER_CONTINUATION = 0x81U
};
// "Simple glyphs" have a simple glyph ID, simple advance and their
// x and y offsets are zero. These cases are optimized to avoid storing
// DetailedGlyphs.
// Returns true if the glyph ID aGlyph fits into the compressed representation
static PRBool IsSimpleGlyphID(PRUint32 aGlyph) {
return (aGlyph & GLYPH_MASK) == aGlyph;
}
// Returns true if the advance aAdvance fits into the compressed representation
static PRBool IsSimpleAdvance(PRUint32 aAdvance) {
// Returns true if the advance aAdvance fits into the compressed representation.
// aAdvance is in pixels.
static PRBool IsSimpleAdvancePixels(PRUint32 aAdvance) {
return (aAdvance & (ADVANCE_MASK >> ADVANCE_SHIFT)) == aAdvance;
}
PRBool IsSimpleGlyph() { return (mValue & FLAG_IS_SIMPLE_GLYPH) != 0; }
PRBool IsComplex(PRUint32 aTag) { return (mValue & (FLAG_IS_SIMPLE_GLYPH|TAG_MASK)) == aTag; }
PRBool IsComplexCluster() { return IsComplex(TAG_COMPLEX_CLUSTER); }
PRBool IsLigatureContinuation() { return IsComplex(TAG_LIGATURE_CONTINUATION); }
PRBool IsLowSurrogate() { return IsComplex(TAG_LOW_SURROGATE); }
PRBool IsClusterStart() { return (mValue & (FLAG_IS_SIMPLE_GLYPH|0x80U)) != 0x80U; }
PRBool IsSimpleGlyph() const { return (mValue & FLAG_IS_SIMPLE_GLYPH) != 0; }
PRBool IsComplex(PRUint32 aTag) const { return (mValue & (FLAG_IS_SIMPLE_GLYPH|TAG_MASK)) == aTag; }
PRBool IsMissing() const { return IsComplex(TAG_MISSING); }
PRBool IsComplexCluster() const { return IsComplex(TAG_COMPLEX_CLUSTER); }
PRBool IsLigatureContinuation() const { return IsComplex(TAG_LIGATURE_CONTINUATION); }
PRBool IsLowSurrogate() const { return IsComplex(TAG_LOW_SURROGATE); }
PRBool IsClusterStart() const { return (mValue & (FLAG_IS_SIMPLE_GLYPH|0x80U)) != 0x80U; }
PRUint32 GetSimpleAdvance() { return (mValue & ADVANCE_MASK) >> ADVANCE_SHIFT; }
PRUint32 GetSimpleGlyph() { return mValue & GLYPH_MASK; }
PRUint32 GetSimpleAdvance() const { return (mValue & ADVANCE_MASK) >> ADVANCE_SHIFT; }
PRUint32 GetSimpleGlyph() const { return mValue & GLYPH_MASK; }
PRUint32 GetComplexTag() { return mValue & TAG_MASK; }
PRUint32 GetComplexTag() const { return mValue & TAG_MASK; }
PRBool CanBreakBefore() { return (mValue & FLAG_CAN_BREAK_BEFORE) != 0; }
PRBool CanBreakBefore() const { return (mValue & FLAG_CAN_BREAK_BEFORE) != 0; }
// Returns FLAG_CAN_BREAK_BEFORE if the setting changed, 0 otherwise
PRUint32 SetCanBreakBefore(PRBool aCanBreakBefore) {
PRUint32 breakMask = aCanBreakBefore*FLAG_CAN_BREAK_BEFORE;
@ -269,46 +356,34 @@ public:
return toggle;
}
void SetSimpleGlyph(PRUint32 aAdvance, PRUint32 aGlyph) {
NS_ASSERTION(IsSimpleAdvance(aAdvance), "Advance overflow");
CompressedGlyph& SetSimpleGlyph(PRUint32 aAdvancePixels, PRUint32 aGlyph) {
NS_ASSERTION(IsSimpleAdvancePixels(aAdvancePixels), "Advance overflow");
NS_ASSERTION(IsSimpleGlyphID(aGlyph), "Glyph overflow");
mValue = (mValue & FLAG_CAN_BREAK_BEFORE) | FLAG_IS_SIMPLE_GLYPH |
(aAdvance << ADVANCE_SHIFT) | aGlyph;
(aAdvancePixels << ADVANCE_SHIFT) | aGlyph;
return *this;
}
void SetComplex(PRUint32 aTag) { mValue = (mValue & FLAG_CAN_BREAK_BEFORE) | aTag; }
void SetComplexCluster() { SetComplex(TAG_COMPLEX_CLUSTER); }
void SetLowSurrogate() { SetComplex(TAG_LOW_SURROGATE); }
void SetLigatureContinuation() { SetComplex(TAG_LIGATURE_CONTINUATION); }
void SetClusterContinuation() { SetComplex(TAG_CLUSTER_CONTINUATION); }
CompressedGlyph& SetComplex(PRUint32 aTag) {
mValue = (mValue & FLAG_CAN_BREAK_BEFORE) | aTag;
return *this;
}
CompressedGlyph& SetMissing() { return SetComplex(TAG_MISSING); }
CompressedGlyph& SetComplexCluster() { return SetComplex(TAG_COMPLEX_CLUSTER); }
CompressedGlyph& SetLowSurrogate() { return SetComplex(TAG_LOW_SURROGATE); }
CompressedGlyph& SetLigatureContinuation() { return SetComplex(TAG_LIGATURE_CONTINUATION); }
CompressedGlyph& SetClusterContinuation() { return SetComplex(TAG_CLUSTER_CONTINUATION); }
private:
PRUint32 mValue;
};
struct DetailedGlyph {
PRUint32 mIsLastGlyph:1;
// mGlyphID == 2^31 means "missing glyph"
PRUint32 mGlyphID:31;
float mAdvance, mXOffset, mYOffset;
// This is the ID of a missing glyph in a details record. All "missing" glyphs
// are converted to a detailed glyph record with this glyph ID.
enum {
DETAILED_MISSING_GLYPH = 1U << 30
};
};
// The text is divided into GlyphRuns at Pango item and text segment boundaries
struct GlyphRun {
PangoFont *mPangoFont; // strong ref; can't be null
cairo_scaled_font_t *mCairoFont; // could be null
PRUint32 mCharacterOffset; // into original UTF16 string
~GlyphRun() {
if (mCairoFont) {
cairo_scaled_font_destroy(mCairoFont);
}
if (mPangoFont) {
g_object_unref(mPangoFont);
}
}
nsRefPtr<gfxPangoFont> mFont; // never null
PRUint32 mCharacterOffset; // into original UTF16 string
};
class GlyphRunIterator {
@ -334,35 +409,48 @@ public:
friend class GlyphRunIterator;
friend class FontSelector;
// **** Initialization helpers ****
// API for setting up the textrun glyphs
/**
* We've found a run of text that should use a particular font. Call this
* only during initialization when font substitution has been computed.
*/
nsresult AddGlyphRun(gfxPangoFont *aFont, PRUint32 aStartCharIndex);
// Call the following glyph-setters during initialization or during reshaping
// only. It is OK to overwrite existing data for a character.
/**
* Set the glyph for a character. Also allows you to set low surrogates,
* cluster and ligature continuations.
*/
void SetCharacterGlyph(PRUint32 aCharIndex, CompressedGlyph aGlyph) {
if (mCharacterGlyphs) {
mCharacterGlyphs[aCharIndex] = aGlyph;
}
if (mDetailedGlyphs) {
mDetailedGlyphs[aCharIndex] = nsnull;
}
}
/**
* Set some detailed glyphs for a character. The data is copied from aGlyphs,
* the caller retains ownership.
*/
void SetDetailedGlyphs(PRUint32 aCharIndex, DetailedGlyph *aGlyphs,
PRUint32 aNumGlyphs);
// API for access to the raw glyph data, needed by gfxPangoFont::Draw
// and gfxPangoFont::GetBoundingBox
const CompressedGlyph *GetCharacterGlyphs() { return mCharacterGlyphs; }
const DetailedGlyph *GetDetailedGlyphs(PRUint32 aCharIndex) {
NS_ASSERTION(mDetailedGlyphs && mDetailedGlyphs[aCharIndex],
"Requested detailed glyphs when there aren't any, "
"I think I'll go and have a lie down...");
return mDetailedGlyphs[aCharIndex];
}
PRUint32 CountMissingGlyphs();
private:
// If aUTF16Text is null, then the string contains no characters >= 0x100
void Init(gfxTextRunFactory::Parameters *aParams, const gchar *aUTF8Text,
PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength, const PRUnichar *aUTF16Text,
PRUint32 aUTF16Length);
void SetupClusterBoundaries(const gchar *aUTF8, PRUint32 aUTF8Length,
PRUint32 aUTF16Offset, PangoAnalysis *aAnalysis);
nsresult AddGlyphRun(PangoFont *aFont, PRUint32 aUTF16Offset);
DetailedGlyph *AllocateDetailedGlyphs(PRUint32 aIndex, PRUint32 aCount);
// Returns NS_ERROR_FAILURE if there's a missing glyph
nsresult SetGlyphs(const gchar *aUTF8, PRUint32 aUTF8Length,
PRUint32 *aUTF16Offset, PangoGlyphString *aGlyphs,
PangoGlyphUnit aOverrideSpaceWidth,
PRBool aAbortOnMissingGlyph);
// If aUTF16Text is null, then the string contains no characters >= 0x100.
// Returns NS_ERROR_FAILURE if we require the itemizing path
nsresult CreateGlyphRunsFast(const gchar *aUTF8, PRUint32 aUTF8Length,
const PRUnichar *aUTF16Text, PRUint32 aUTF16Length);
void CreateGlyphRunsItemizing(const gchar *aUTF8, PRUint32 aUTF8Length,
PRUint32 aUTF8HeaderLength);
#if defined(ENABLE_XFT_FAST_PATH_8BIT) || defined(ENABLE_XFT_FAST_PATH_ALWAYS)
void CreateGlyphRunsXft(const gchar *aUTF8, PRUint32 aUTF8Length);
#endif
// **** general helpers ****
void SetupPangoContextDirection();
static void SetupCairoFont(cairo_t *aCR, GlyphRun *aGlyphRun);
// Returns the index of the GlyphRun containing the given offset.
// Returns mGlyphRuns.Length() when aOffset is mCharacterCount.
PRUint32 FindFirstGlyphRunContaining(PRUint32 aOffset);
@ -371,7 +459,7 @@ private:
gfxFloat ComputeClusterAdvance(PRUint32 aClusterOffset);
// **** ligature helpers ****
// (Pango does the actual ligaturization, but we need to do a bunch of stuff
// (Platforms do the actual ligaturization, but we need to do a bunch of stuff
// to handle requests that begin or end inside a ligature)
struct LigatureData {
@ -390,38 +478,33 @@ private:
PRBool GetAdjustedSpacingArray(PRUint32 aStart, PRUint32 aEnd,
PropertyProvider *aProvider,
nsTArray<PropertyProvider::Spacing> *aSpacing);
void DrawPartialLigature(gfxContext *aCtx, PRUint32 aOffset,
void DrawPartialLigature(gfxPangoFont *aFont, gfxContext *aCtx, PRUint32 aOffset,
const gfxRect *aDirtyRect, gfxPoint *aPt,
PropertyProvider *aProvider);
// result in appunits
void ShrinkToLigatureBoundaries(PRUint32 *aStart, PRUint32 *aEnd);
gfxFloat GetPartialLigatureWidth(PRUint32 aStart, PRUint32 aEnd, PropertyProvider *aProvider);
void AccumulatePartialLigatureMetrics(PangoFont *aPangoFont,
PRUint32 aOffset, PropertyProvider *aProvider,
void AccumulatePartialLigatureMetrics(gfxPangoFont *aFont,
PRUint32 aOffset, PRBool aTight,
PropertyProvider *aProvider,
Metrics *aMetrics);
// **** measurement helper ****
void AccumulatePangoMetricsForRun(PangoFont *aPangoFont, PRUint32 aStart,
PRUint32 aEnd, PropertyProvider *aProvider,
Metrics *aMetrics);
void AccumulateMetricsForRun(gfxPangoFont *aFont, PRUint32 aStart,
PRUint32 aEnd, PRBool aTight,
PropertyProvider *aProvider,
Metrics *aMetrics);
// **** drawing helpers ****
// **** drawing helper ****
void DrawGlyphs(gfxPangoFont *aFont, gfxContext *aContext, PRBool aDrawToPath,
gfxPoint *aPt, PRUint32 aStart, PRUint32 aEnd,
PropertyProvider *aProvider);
typedef void (* CairoGlyphProcessorCallback)
(void *aClosure, cairo_glyph_t *aGlyphs, int aNumGlyphs);
void ProcessCairoGlyphsWithSpacing(CairoGlyphProcessorCallback aCB, void *aClosure,
gfxPoint *aPt, PRUint32 aStart, PRUint32 aEnd,
PropertyProvider::Spacing *aSpacing);
void ProcessCairoGlyphs(CairoGlyphProcessorCallback aCB, void *aClosure,
gfxPoint *aPt, PRUint32 aStart, PRUint32 aEnd,
PropertyProvider *aProvider);
static void CairoShowGlyphs(void *aClosure, cairo_glyph_t *aGlyphs, int aNumGlyphs);
static void CairoGlyphsToPath(void *aClosure, cairo_glyph_t *aGlyphs, int aNumGlyphs);
nsRefPtr<gfxPangoFontGroup> mFontGroup;
// All our glyph data is in logical order, not visual
nsAutoArrayPtr<CompressedGlyph> mCharacterGlyphs;
nsAutoArrayPtr<nsAutoArrayPtr<DetailedGlyph> > mDetailedGlyphs; // only non-null if needed
// XXX this should be changed to a GlyphRun plus a maybe-null GlyphRun*,
// for smaller size especially in the super-common one-glyphrun case
nsAutoTArray<GlyphRun,1> mGlyphRuns;
PRUint32 mCharacterCount;
};

Просмотреть файл

@ -379,20 +379,10 @@ public:
PropertyProvider* aBreakProvider,
gfxFloat* aAdvanceWidth)
{ NS_ERROR("NOT IMPLEMENTED"); }
virtual void DrawSpecialString(gfxContext* aContext, gfxPoint aPt,
SpecialString aString)
{ NS_ERROR("NOT IMPLEMENTED"); }
virtual Metrics MeasureText(PRUint32 aStart, PRUint32 aLength,
PRBool aTightBoundingBox,
PropertyProvider* aBreakProvider)
{ NS_ERROR("NOT IMPLEMENTED"); return Metrics(); }
virtual Metrics MeasureTextSpecialString(SpecialString aString,
PRBool aTightBoundingBox)
{ NS_ERROR("NOT IMPLEMENTED"); return Metrics(); }
virtual gfxFloat GetAdvanceWidthSpecialString(SpecialString aString)
{ NS_ERROR("NOT IMPLEMENTED"); return 0; }
virtual gfxFont::Metrics GetDecorationMetrics()
{ NS_ERROR("NOT IMPLEMENTED"); return gfxFont::Metrics(); }
virtual void SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRBool aLineBreakBefore, PRBool aLineBreakAfter,
TextProvider* aProvider,
@ -406,8 +396,6 @@ public:
PRBool* aUsedHyphenation,
PRUint32* aLastBreak)
{ NS_ERROR("NOT IMPLEMENTED"); return 0; }
virtual void FlushSpacingCache(PRUint32 aStart)
{ NS_ERROR("NOT IMPLEMENTED"); }
virtual void Draw(gfxContext *aContext, gfxPoint aPt,
PRUint32 aStart, PRUint32 aLength,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -559,20 +559,10 @@ public:
PropertyProvider* aBreakProvider,
gfxFloat* aAdvanceWidth)
{ NS_ERROR("NOT IMPLEMENTED"); }
virtual void DrawSpecialString(gfxContext* aContext, gfxPoint aPt,
SpecialString aString)
{ NS_ERROR("NOT IMPLEMENTED"); }
virtual Metrics MeasureText(PRUint32 aStart, PRUint32 aLength,
PRBool aTightBoundingBox,
PropertyProvider* aBreakProvider)
{ NS_ERROR("NOT IMPLEMENTED"); for (;;) ; }
virtual Metrics MeasureTextSpecialString(SpecialString aString,
PRBool aTightBoundingBox)
{ NS_ERROR("NOT IMPLEMENTED"); for (;;) ; }
virtual gfxFloat GetAdvanceWidthSpecialString(SpecialString aString)
{ NS_ERROR("NOT IMPLEMENTED"); for (;;) ; }
virtual gfxFont::Metrics GetDecorationMetrics()
{ NS_ERROR("NOT IMPLEMENTED"); for (;;) ; }
virtual void SetLineBreaks(PRUint32 aStart, PRUint32 aLength,
PRBool aLineBreakBefore, PRBool aLineBreakAfter,
TextProvider* aProvider,
@ -586,8 +576,6 @@ public:
PRBool* aUsedHyphenation,
PRUint32* aLastBreak)
{ NS_ERROR("NOT IMPLEMENTED"); for (;;) ; }
virtual void FlushSpacingCache(PRUint32 aStart)
{ NS_ERROR("NOT IMPLEMENTED"); }
virtual void Draw(gfxContext *aContext, gfxPoint aPt,
PRUint32 aStart, PRUint32 aLength,