Bidi support for alternate text: reorder the text correctly, align text and icon to the right when direction is right-to-left, and create a bidi embedding when the alternate text is displayed inline. Bug 345954, r=uriber, sr=bzbarsky

This commit is contained in:
smontagu%smontagu.org 2006-07-31 07:08:45 +00:00
Родитель 13d8a8aafc
Коммит 0a263351b8
3 изменённых файлов: 50 добавлений и 13 удалений

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

@ -102,6 +102,8 @@
#include "nsContentPolicyUtils.h" #include "nsContentPolicyUtils.h"
#include "nsIEventStateManager.h" #include "nsIEventStateManager.h"
#include "nsLayoutErrors.h" #include "nsLayoutErrors.h"
#include "nsBidiUtils.h"
#include "nsBidiPresUtils.h"
#ifdef DEBUG #ifdef DEBUG
#undef NOISY_IMAGE_LOADING #undef NOISY_IMAGE_LOADING
@ -1007,7 +1009,7 @@ nsImageFrame::Reflow(nsPresContext* aPresContext,
// The number of characters that fit within the maximum width are returned in // The number of characters that fit within the maximum width are returned in
// aMaxFit. NOTE: it is assumed that the fontmetrics have already been selected // aMaxFit. NOTE: it is assumed that the fontmetrics have already been selected
// into the rendering context before this is called (for performance). MMP // into the rendering context before this is called (for performance). MMP
void nscoord
nsImageFrame::MeasureString(const PRUnichar* aString, nsImageFrame::MeasureString(const PRUnichar* aString,
PRInt32 aLength, PRInt32 aLength,
nscoord aMaxWidth, nscoord aMaxWidth,
@ -1064,6 +1066,7 @@ nsImageFrame::MeasureString(const PRUnichar* aString,
break; break;
} }
} }
return totalWidth;
} }
// Formats the alt-text to fit within the specified rectangle. Breaks lines // Formats the alt-text to fit within the specified rectangle. Breaks lines
@ -1098,10 +1101,29 @@ nsImageFrame::DisplayAltText(nsPresContext* aPresContext,
while ((strLen > 0) && (firstLine || (y + maxDescent) < aRect.YMost())) { while ((strLen > 0) && (firstLine || (y + maxDescent) < aRect.YMost())) {
// Determine how much of the text to display on this line // Determine how much of the text to display on this line
PRUint32 maxFit; // number of characters that fit PRUint32 maxFit; // number of characters that fit
MeasureString(str, strLen, aRect.width, maxFit, aRenderingContext); nscoord strWidth = MeasureString(str, strLen, aRect.width, maxFit,
aRenderingContext);
// Display the text // Display the text
aRenderingContext.DrawString(str, maxFit, aRect.x, y + maxAscent); nsresult rv = NS_ERROR_FAILURE;
if (aPresContext->BidiEnabled()) {
nsBidiPresUtils* bidiUtils = aPresContext->GetBidiUtils();
if (bidiUtils) {
const nsStyleVisibility* vis = GetStyleVisibility();
if (vis->mDirection == NS_STYLE_DIRECTION_RTL)
rv = bidiUtils->RenderText(str, maxFit, NSBIDI_RTL,
aPresContext, aRenderingContext,
aRect.XMost() - strWidth, y + maxAscent);
else
rv = bidiUtils->RenderText(str, maxFit, NSBIDI_LTR,
aPresContext, aRenderingContext,
aRect.x, y + maxAscent);
}
}
if (NS_FAILED(rv))
aRenderingContext.DrawString(str, maxFit, aRect.x, y + maxAscent);
// Move to the next line // Move to the next line
str += maxFit; str += maxFit;
@ -1175,6 +1197,7 @@ nsImageFrame::DisplayAltFeedback(nsIRenderingContext& aRenderingContext,
// Check if we should display image placeholders // Check if we should display image placeholders
if (dispIcon) { if (dispIcon) {
const nsStyleVisibility* vis = GetStyleVisibility();
PRInt32 size = NSIntPixelsToTwips(ICON_SIZE, p2t); PRInt32 size = NSIntPixelsToTwips(ICON_SIZE, p2t);
PRBool iconUsed = PR_FALSE; PRBool iconUsed = PR_FALSE;
@ -1189,7 +1212,9 @@ nsImageFrame::DisplayAltFeedback(nsIRenderingContext& aRenderingContext,
if (imgCon) { if (imgCon) {
// draw it // draw it
nsRect source(0,0,size,size); nsRect source(0,0,size,size);
nsRect dest(inner.x,inner.y,size,size); nsRect dest((vis->mDirection == NS_STYLE_DIRECTION_RTL) ?
inner.XMost() - size : inner.x,
inner.y, size, size);
aRenderingContext.DrawImage(imgCon, source, dest); aRenderingContext.DrawImage(imgCon, source, dest);
iconUsed = PR_TRUE; iconUsed = PR_TRUE;
} }
@ -1198,10 +1223,12 @@ nsImageFrame::DisplayAltFeedback(nsIRenderingContext& aRenderingContext,
// if we could not draw the image, then just draw some graffiti // if we could not draw the image, then just draw some graffiti
if (!iconUsed) { if (!iconUsed) {
nscolor oldColor; nscolor oldColor;
aRenderingContext.DrawRect(aPt.x, aPt.y,size,size); nscoord iconXPos = (vis->mDirection == NS_STYLE_DIRECTION_RTL) ?
inner.XMost() - size : inner.x;
aRenderingContext.DrawRect(iconXPos, inner.y,size,size);
aRenderingContext.GetColor(oldColor); aRenderingContext.GetColor(oldColor);
aRenderingContext.SetColor(NS_RGB(0xFF,0,0)); aRenderingContext.SetColor(NS_RGB(0xFF,0,0));
aRenderingContext.FillEllipse(NS_STATIC_CAST(int,size/2) + aPt.x,NS_STATIC_CAST(int,size/2) + aPt.y, aRenderingContext.FillEllipse(NS_STATIC_CAST(int,size/2) + iconXPos,NS_STATIC_CAST(int,size/2) + inner.y,
NS_STATIC_CAST(int,(size/2)-(2*p2t)),NS_STATIC_CAST(int,(size/2)-(2*p2t))); NS_STATIC_CAST(int,(size/2)-(2*p2t)),NS_STATIC_CAST(int,(size/2)-(2*p2t)));
aRenderingContext.SetColor(oldColor); aRenderingContext.SetColor(oldColor);
} }
@ -1209,7 +1236,8 @@ nsImageFrame::DisplayAltFeedback(nsIRenderingContext& aRenderingContext,
// Reduce the inner rect by the width of the icon, and leave an // Reduce the inner rect by the width of the icon, and leave an
// additional ICON_PADDING pixels for padding // additional ICON_PADDING pixels for padding
PRInt32 iconWidth = NSIntPixelsToTwips(ICON_SIZE + ICON_PADDING, p2t); PRInt32 iconWidth = NSIntPixelsToTwips(ICON_SIZE + ICON_PADDING, p2t);
inner.x += iconWidth; if (vis->mDirection != NS_STYLE_DIRECTION_RTL)
inner.x += iconWidth;
inner.width -= iconWidth; inner.width -= iconWidth;
} }

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

@ -187,12 +187,20 @@ protected:
PRBool GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget, PRBool GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget,
nsINode** aNode); nsINode** aNode);
/**
void MeasureString(const PRUnichar* aString, * Computes the width of the string that fits into the available space
PRInt32 aLength, *
nscoord aMaxWidth, * @param in aLength total length of the string in PRUnichars
PRUint32& aMaxFit, * @param in aMaxWidth width not to be exceeded
nsIRenderingContext& aContext); * @param out aMaxFit length of the string that fits within aMaxWidth
* in PRUnichars
* @return width of the string that fits within aMaxWidth
*/
nscoord MeasureString(const PRUnichar* aString,
PRInt32 aLength,
nscoord aMaxWidth,
PRUint32& aMaxFit,
nsIRenderingContext& aContext);
void DisplayAltText(nsPresContext* aPresContext, void DisplayAltText(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext, nsIRenderingContext& aRenderingContext,

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

@ -398,6 +398,7 @@ img:-moz-loading::before, input:-moz-loading::before,
applet:-moz-empty-except-children-with-localname(param):-moz-broken::before, applet:-moz-empty-except-children-with-localname(param):-moz-broken::before,
applet:-moz-empty-except-children-with-localname(param):-moz-user-disabled::before { applet:-moz-empty-except-children-with-localname(param):-moz-user-disabled::before {
content: -moz-alt-content !important; content: -moz-alt-content !important;
unicode-bidi: embed;
} }
object:-moz-broken > *|*, applet:-moz-broken > *|* object:-moz-broken > *|*, applet:-moz-broken > *|*