Bug 381127. Add whitespace trimming capability to BreakAndMeasureText. r=pavlov

This commit is contained in:
roc+@cs.cmu.edu 2007-05-22 16:40:07 -07:00
Родитель a5fcb937f0
Коммит 0b1d94265f
2 изменённых файлов: 34 добавлений и 9 удалений

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

@ -729,6 +729,12 @@ public:
* linebreak before aStart. If false, then we will check the internal
* line break opportunity state before deciding whether to return 0 as the
* character to break before.
* @param aTrimWhitespace if non-null, then we allow a trailing run of
* spaces to be trimmed; the width of the space(s) will not be included in
* the measured string width for comparison with the limit aWidth, and
* trimmed spaces will not be included in returned metrics. The width
* of the trimmed spaces will be returned in aTrimWhitespace.
* Trimmed spaces are still counted in the "characters fit" result.
* @param aMetrics if non-null, we fill this in for the returned substring.
* If a hyphenation break was used, the hyphen is NOT included in the returned metrics.
* @param aTightBoundingBox if true, we make the bounding box in aMetrics tight
@ -748,6 +754,7 @@ public:
PRBool aLineBreakBefore, gfxFloat aWidth,
PropertyProvider *aProvider,
PRBool aSuppressInitialBreak,
gfxFloat *aTrimWhitespace,
Metrics *aMetrics, PRBool aTightBoundingBox,
PRBool *aUsedHyphenation,
PRUint32 *aLastBreak);

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

@ -1228,6 +1228,7 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
PRBool aLineBreakBefore, gfxFloat aWidth,
PropertyProvider *aProvider,
PRBool aSuppressInitialBreak,
gfxFloat *aTrimWhitespace,
Metrics *aMetrics, PRBool aTightBoundingBox,
PRBool *aUsedHyphenation,
PRUint32 *aLastBreak)
@ -1260,6 +1261,8 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
gfxFloat width = 0;
gfxFloat advance = 0;
gfxFloat trimmableAdvance = 0;
PRUint32 trimmableChars = 0;
PRInt32 lastBreak = -1;
PRBool aborted = PR_FALSE;
PRUint32 end = aStart + aMaxLength;
@ -1294,7 +1297,7 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
hyphenatedAdvance += aProvider->GetHyphenWidth();
}
if (lastBreak < 0 || width + hyphenatedAdvance <= aWidth) {
if (lastBreak < 0 || width + hyphenatedAdvance - trimmableAdvance <= aWidth) {
// We can break here.
lastBreak = i;
lastBreakUsedHyphenation = hyphenation;
@ -1302,22 +1305,23 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
width += advance;
advance = 0;
if (width > aWidth) {
if (width - trimmableAdvance > aWidth) {
// No more text fits. Abort
aborted = PR_TRUE;
break;
}
}
gfxFloat charAdvance = 0;
if (i >= ligatureRunStart && i < ligatureRunEnd) {
CompressedGlyph *glyphData = &charGlyphs[i];
if (glyphData->IsSimpleGlyph()) {
advance += glyphData->GetSimpleAdvance();
charAdvance = glyphData->GetSimpleAdvance();
} else if (glyphData->IsComplexOrMissing()) {
const DetailedGlyph *details = GetDetailedGlyphs(i);
if (details) {
while (1) {
advance += details->mAdvance;
charAdvance += details->mAdvance;
if (details->mIsLastGlyph)
break;
++details;
@ -1326,10 +1330,21 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
}
if (haveSpacing) {
PropertyProvider::Spacing *space = &spacingBuffer[i - bufferStart];
advance += space->mBefore + space->mAfter;
charAdvance += space->mBefore + space->mAfter;
}
} else {
advance += GetPartialLigatureWidth(i, i + 1, aProvider);
charAdvance += GetPartialLigatureWidth(i, i + 1, aProvider);
}
advance += charAdvance;
if (aTrimWhitespace) {
if (GetChar(i) == ' ') {
++trimmableChars;
trimmableAdvance += charAdvance;
} else {
trimmableAdvance = 0;
trimmableChars = 0;
}
}
}
@ -1342,7 +1357,7 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
// 2) some of the text fit up to a break opportunity (width > aWidth && lastBreak >= 0)
// 3) none of the text fits before a break opportunity (width > aWidth && lastBreak < 0)
PRUint32 charsFit;
if (width <= aWidth) {
if (width - trimmableAdvance <= aWidth) {
charsFit = aMaxLength;
} else if (lastBreak >= 0) {
charsFit = lastBreak - aStart;
@ -1351,7 +1366,10 @@ gfxTextRun::BreakAndMeasureText(PRUint32 aStart, PRUint32 aMaxLength,
}
if (aMetrics) {
*aMetrics = MeasureText(aStart, charsFit, aTightBoundingBox, aProvider);
*aMetrics = MeasureText(aStart, charsFit - trimmableChars, aTightBoundingBox, aProvider);
}
if (aTrimWhitespace) {
*aTrimWhitespace = trimmableAdvance;
}
if (aUsedHyphenation) {
*aUsedHyphenation = lastBreakUsedHyphenation;