NS_IMETHODIMP
nsThebesRenderingContext::GetWidth(const PRUnichar *aString,
                                   PRUint32 aLength,
                                   nscoord &aWidth,
                                   PRInt32 *aFontID)
{
    PRUint32 maxChunkLength = GetMaxChunkLength(this);
    aWidth = 0;

    if (aFontID) {
        *aFontID = 0;
    }

    while (aLength > 0) {
        PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength);
        nscoord width;
        nsresult rv = GetWidthInternal(aString, len, width);
        if (NS_FAILED(rv))
            return rv;
        aWidth += width;
        aLength -= len;
        aString += len;
    }
    return NS_OK;
}
NS_IMETHODIMP
nsThebesRenderingContext::GetTextDimensions(const PRUnichar* aString,
                                            PRUint32 aLength,
                                            nsTextDimensions& aDimensions,
                                            PRInt32* aFontID)
{
    PRUint32 maxChunkLength = GetMaxChunkLength(this);
    if (aLength <= maxChunkLength)
        return GetTextDimensionsInternal(aString, aLength, aDimensions);

    if (aFontID) {
        *aFontID = nsnull;
    }

    PRBool firstIteration = PR_TRUE;
    while (aLength > 0) {
        PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength);
        nsTextDimensions dimensions;
        nsresult rv = GetTextDimensionsInternal(aString, len, dimensions);
        if (NS_FAILED(rv))
            return rv;
        if (firstIteration) {
            // Instead of combining with a Clear()ed nsTextDimensions, we
            // assign directly in the first iteration. This ensures that
            // negative ascent/ descent can be returned.
            aDimensions = dimensions;
        } else {
            aDimensions.Combine(dimensions);
        }
        aLength -= len;
        aString += len;
        firstIteration = PR_FALSE;
    }
    return NS_OK;
}
Пример #3
0
void
nsRenderingContext::DrawString(const PRUnichar *aString, PRUint32 aLength,
                               nscoord aX, nscoord aY)
{
    PRUint32 maxChunkLength = GetMaxChunkLength();
    if (aLength <= maxChunkLength) {
        mFontMetrics->DrawString(aString, aLength, aX, aY, this, this);
        return;
    }

    PRBool isRTL = mFontMetrics->GetTextRunRTL();

    // If we're drawing right to left, we must start at the end.
    if (isRTL) {
        aX += GetWidth(aString, aLength);
    }

    while (aLength > 0) {
        PRInt32 len = FindSafeLength(aString, aLength, maxChunkLength);
        nscoord width = mFontMetrics->GetWidth(aString, len, this);
        if (isRTL) {
            aX -= width;
        }
        mFontMetrics->DrawString(aString, len, aX, aY, this, this);
        if (!isRTL) {
            aX += width;
        }
        aLength -= len;
        aString += len;
    }
}
NS_IMETHODIMP
nsThebesRenderingContext::GetBoundingMetrics(const char*        aString,
                                             PRUint32           aLength,
                                             nsBoundingMetrics& aBoundingMetrics)
{
    PRUint32 maxChunkLength = GetMaxChunkLength(this);
    if (aLength <= maxChunkLength)
        return GetBoundingMetricsInternal(aString, aLength, aBoundingMetrics);

    PRBool firstIteration = PR_TRUE;
    while (aLength > 0) {
        PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength);
        nsBoundingMetrics metrics;
        nsresult rv = GetBoundingMetricsInternal(aString, len, metrics);
        if (NS_FAILED(rv))
            return rv;
        if (firstIteration) {
            // Instead of combining with a Clear()ed nsBoundingMetrics, we
            // assign directly in the first iteration. This ensures that
            // negative ascent/ descent can be returned and the left bearing
            // is properly initialized.
            aBoundingMetrics = metrics;
        } else {
            aBoundingMetrics += metrics;
        }
        aLength -= len;
        aString += len;
        firstIteration = PR_FALSE;
    }
    return NS_OK;
}
NS_IMETHODIMP
nsThebesRenderingContext::DrawString(const PRUnichar *aString, PRUint32 aLength,
                                   nscoord aX, nscoord aY,
                                   PRInt32 aFontID,
                                   const nscoord* aSpacing)
{
    PRUint32 maxChunkLength = GetMaxChunkLength(this);
    if (aLength <= maxChunkLength) {
        return DrawStringInternal(aString, aLength, aX, aY, aFontID, aSpacing);
    }

    PRBool isRTL = PR_FALSE;
    GetRightToLeftText(&isRTL);

    if (isRTL) {
        nscoord totalWidth = 0;
        if (aSpacing) {
            for (PRUint32 i = 0; i < aLength; ++i) {
                totalWidth += aSpacing[i];
            }
        } else {
            nsresult rv = GetWidth(aString, aLength, totalWidth);
            if (NS_FAILED(rv))
                return rv;
        }
        aX += totalWidth;
    }

    while (aLength > 0) {
        PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength);
        nscoord width = 0;
        if (aSpacing) {
            for (PRInt32 i = 0; i < len; ++i) {
                width += aSpacing[i];
            }
        } else {
            nsresult rv = GetWidthInternal(aString, len, width);
            if (NS_FAILED(rv))
                return rv;
        }

        if (isRTL) {
            aX -= width;
        }
        nsresult rv = DrawStringInternal(aString, len, aX, aY, aFontID, aSpacing);
        if (NS_FAILED(rv))
            return rv;
        aLength -= len;
        if (!isRTL) {
            aX += width;
        }
        aString += len;
        if (aSpacing) {
            aSpacing += len;
        }
    }
    return NS_OK;
}
NS_IMETHODIMP
nsThebesRenderingContext::GetTextDimensions(const char*       aString,
                                            PRInt32           aLength,
                                            PRInt32           aAvailWidth,
                                            PRInt32*          aBreaks,
                                            PRInt32           aNumBreaks,
                                            nsTextDimensions& aDimensions,
                                            PRInt32&          aNumCharsFit,
                                            nsTextDimensions& aLastWordDimensions,
                                            PRInt32*          aFontID)
{
    PRUint32 maxChunkLength = GetMaxChunkLength(this);
    if (aLength <= PRInt32(maxChunkLength))
        return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks, aNumBreaks,
                                         aDimensions, aNumCharsFit, aLastWordDimensions, aFontID);

    if (aFontID) {
        *aFontID = 0;
    }

    // Do a naive implementation based on 3-arg GetTextDimensions
    PRInt32 x = 0;
    PRInt32 wordCount;
    for (wordCount = 0; wordCount < aNumBreaks; ++wordCount) {
        PRInt32 lastBreak = wordCount > 0 ? aBreaks[wordCount - 1] : 0;
        nsTextDimensions dimensions;

        NS_ASSERTION(aBreaks[wordCount] > lastBreak, "Breaks must be monotonically increasing");
        NS_ASSERTION(aBreaks[wordCount] <= aLength, "Breaks can't exceed string length");

         // Call safe method

        nsresult rv =
            GetTextDimensions(aString + lastBreak, aBreaks[wordCount] - lastBreak,
                            dimensions);
        if (NS_FAILED(rv))
            return rv;
        x += dimensions.width;
        // The first word always "fits"
        if (x > aAvailWidth && wordCount > 0)
            break;
        // aDimensions ascent/descent should exclude the last word (unless there
        // is only one word) so we let it run one word behind
        if (wordCount == 0) {
            aDimensions = dimensions;
        } else {
            aDimensions.Combine(aLastWordDimensions);
        }
        aNumCharsFit = aBreaks[wordCount];
        aLastWordDimensions = dimensions;
    }
    // aDimensions width should include all the text
    aDimensions.width = x;
    return NS_OK;
}
Пример #7
0
nscoord
nsRenderingContext::GetWidth(const PRUnichar *aString, PRUint32 aLength)
{
    PRUint32 maxChunkLength = GetMaxChunkLength();
    nscoord width = 0;
    while (aLength > 0) {
        PRInt32 len = FindSafeLength(aString, aLength, maxChunkLength);
        width += mFontMetrics->GetWidth(aString, len, this);
        aLength -= len;
        aString += len;
    }
    return width;
}
Пример #8
0
nscoord
nsRenderingContext::GetWidth(const char16_t *aString, uint32_t aLength)
{
    uint32_t maxChunkLength = GetMaxChunkLength();
    nscoord width = 0;
    while (aLength > 0) {
        int32_t len = FindSafeLength(aString, aLength, maxChunkLength);
        width += mFontMetrics->GetWidth(aString, len, this);
        aLength -= len;
        aString += len;
    }
    return width;
}
Пример #9
0
void
nsRenderingContext::DrawString(const char *aString, PRUint32 aLength,
                               nscoord aX, nscoord aY)
{
    PRUint32 maxChunkLength = GetMaxChunkLength();
    while (aLength > 0) {
        PRInt32 len = FindSafeLength(aString, aLength, maxChunkLength);
        mFontMetrics->DrawString(aString, len, aX, aY, this);
        aLength -= len;

        if (aLength > 0) {
            nscoord width = mFontMetrics->GetWidth(aString, len, this);
            aX += width;
            aString += len;
        }
    }
}
NS_IMETHODIMP
nsThebesRenderingContext::DrawString(const char *aString, PRUint32 aLength,
                                   nscoord aX, nscoord aY,
                                   const nscoord* aSpacing)
{
    PRUint32 maxChunkLength = GetMaxChunkLength(this);
    while (aLength > 0) {
        PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength);
        nsresult rv = DrawStringInternal(aString, len, aX, aY);
        if (NS_FAILED(rv))
            return rv;
        aLength -= len;

        if (aLength > 0) {
            nscoord width;
            rv = GetWidthInternal(aString, len, width);
            if (NS_FAILED(rv))
                return rv;
            aX += width;
            aString += len;
        }
    }
    return NS_OK;
}
Пример #11
0
nsBoundingMetrics
nsRenderingContext::GetBoundingMetrics(const PRUnichar* aString,
                                       PRUint32 aLength)
{
    PRUint32 maxChunkLength = GetMaxChunkLength();
    PRInt32 len = FindSafeLength(aString, aLength, maxChunkLength);
    // Assign directly in the first iteration. This ensures that
    // negative ascent/descent can be returned and the left bearing
    // is properly initialized.
    nsBoundingMetrics totalMetrics
        = mFontMetrics->GetBoundingMetrics(aString, len, this);
    aLength -= len;
    aString += len;

    while (aLength > 0) {
        len = FindSafeLength(aString, aLength, maxChunkLength);
        nsBoundingMetrics metrics
            = mFontMetrics->GetBoundingMetrics(aString, len, this);
        totalMetrics += metrics;
        aLength -= len;
        aString += len;
    }
    return totalMetrics;
}