Mozilla2:GFXTextRun
From MozillaWiki
Class gfxTextRun
/** * A class representing a single span of text with a uniform style. * It treats the text is laid out along a straight horizontal line * with the glyphs oriented normally with respect to the baseline. Of course, * the text can be rotated or otherwise transformed by imposing a * transformation in the drawing context before drawing. * * When determining glyph geometry, the text should be hinted * assuming it will be drawn with the current transformation in the * referenceContext used to construct the gfxTextRun. The caller guarantees not * to change the state of referenceContext during the lifetime of the * gfxTextRun object. * The actual transformation or even context used in Draw() or AddToPath() * may be different. * * "Character" below refers to the PRUnichar or char elements of the input * string. The input string boundaries must align with Unicode character * boundaries, i.e., the string cannot start or end in the middle of a * surrogate pair. */ class gfxTextRun { // these constructors do not copy the text. it is the caller's // responsibility to keep the text alive during the lifetime of the text run. // ASCII must be genuine ASCII text, i.e., all values less than 128. gfxTextRun(const char* ASCII, int length, nsFontMetrics* font, PRBool RTL, nsIAtom* language, gfxContext* referenceContext); gfxTextRun(const PRUnichar* unicode, int length, nsFontMetrics* font, PRBool RTL, nsIAtom* language, gfxContext* referenceContext); enum { ClusterStart = 0x1 } CharFlags; // ClusterStart: character is the first character of a cluster // Get the flags for each character in a substring. 'flags' is an array // of length 'len' void GetCharacterFlags(int pos, int len, CharFlags* flags); struct RunFlags { PRPackedBool startsWord; PRPackedBool endsWord; PRPackedBool startsLine; PRPackedBool endsLine; }; // Set whether or not this text run starts/ends a word. // This must NOT change the character flags but it can change the geometry. void SetRunFlags(RunFlags flags); RunFlags GetRunFlags(); // Set the spacing between clusters. For each character index i that is // the start of a cluster, spacingArray[i] is the amount of space to insert // before that cluster (possibly negative) (i.e. between this cluster // and the cluster containing the previous character in the string). // For each character index i that is not the start of a cluster, // spacingArray[i] must be zero. spacingArray[0] must be zero. // This must NOT change the character flags but it can change the geometry. void SetSpacing(gfxFloat* spacingArray); // The substring must not contain any partial clusters. The // baseline of the visually left edge of the visually leftmost cluster // is drawn at the context's current point. (That is, the substring's // xOffset is NOT used.) void Draw(gfxContext* ctx, int pos, int len); // The substring must not contain any partial clusters. The // baseline of the visually left edge of the visually leftmost cluster // is drawn at the context's current point. (That is, the substring's // xOffset is NOT used.) // The outlines of the characters are added to the current path. void AddToPath(gfxContext* ctx, int pos, int len); struct Dimensions { // left-to-right advance of substring start from the origin of the whole // string, always non-negative regardless of RTL. If 'pos' is zero then // xOffset is zero. gfxFloat xOffset; // left-to-right advance width of the substring, always non-negative // regardless of RTL gfxFloat advanceWidth; // font ascent and descent for this substring, both always positive gfxFloat ascent, descent; // the bounding box of area actually rendered by the glyphs in the // substring, relative to the left end of the baseline of the whole string; // if this can't be accurately determined, then at least this must contain // the true bounding box. This box encodes left and right bearing // information. gfxRect boundingBox; }; // The substring must not contain any partial clusters. Dimensions MeasureText(int pos, int len); // Compute how many characters from this string starting at // character 'pos' and up to length 'len' fit // into the given width. 'breaks' is an array of length len. // A break is allowed before character i wherever breaks[i] is nonzero, // i.e., if the result of GetCharsFit is i then breaks[i] is nonzero. // If none of the chars fit then this will return zero, so breaks[0] must be // nonzero. If all of the chars fit, return 'len'. Breaks are only allowed // at cluster boundaries so if character i is not the start of a cluster, // then breaks[i] must be zero. // We will usually want to call MeasureText right afterwards, // the implementor could optimize for that. // The substring must not contain any partial clusters. int GetCharsFit(int pos, int len, gfxFloat width, PRUint8* breaks); // Return the index of the character selected if the user clicks the // mouse at point pt. If the point is exactly between two characters, // if preferLeft is true then return the character visually to the left // (as if pt.x had been smaller) if there is one, otherwise return the // character visually to the right. If the point is before the start of // the string, return -1. If the point is beyond the end of the string, // return the full string length. Apart from those cases, the character // returned will always be the first character of a cluster. // pt is relative to the left end of the baseline of the whole string. int GetPositionInString(gfxPoint& pt, PRBool preferLeft); };