--- a/gfx/thebes/gfxDWriteFonts.cpp
+++ b/gfx/thebes/gfxDWriteFonts.cpp
@@ -547,21 +547,23 @@ gfxDWriteFont::GetCairoScaledFont()
return mScaledFont;
}
gfxFont::RunMetrics
gfxDWriteFont::Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aRefContext,
- Spacing *aSpacing)
+ Spacing *aSpacing,
+ uint16_t aOrientation)
{
gfxFont::RunMetrics metrics =
gfxFont::Measure(aTextRun, aStart, aEnd,
- aBoundingBoxType, aRefContext, aSpacing);
+ aBoundingBoxType, aRefContext, aSpacing,
+ aOrientation);
// if aBoundingBoxType is LOOSE_INK_EXTENTS
// and the underlying cairo font may be antialiased,
// we can't trust Windows to have considered all the pixels
// so we need to add "padding" to the bounds.
// (see bugs 475968, 439831, compare also bug 445087)
if (aBoundingBoxType == LOOSE_INK_EXTENTS &&
mAntialiasOption != kAntialiasNone &&
--- a/gfx/thebes/gfxDWriteFonts.h
+++ b/gfx/thebes/gfxDWriteFonts.h
@@ -44,17 +44,18 @@ public:
IDWriteFontFace *GetFontFace();
/* override Measure to add padding for antialiasing */
virtual RunMetrics Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aContextForTightBoundingBox,
- Spacing *aSpacing);
+ Spacing *aSpacing,
+ uint16_t aOrientation);
virtual bool ProvidesGlyphWidths() const;
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID);
virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2098,40 +2098,42 @@ NeedsGlyphExtents(gfxFont *aFont, gfxTex
aFont->GetFontEntry()->IsUserFont();
}
gfxFont::RunMetrics
gfxFont::Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aRefContext,
- Spacing *aSpacing)
+ Spacing *aSpacing,
+ uint16_t aOrientation)
{
// If aBoundingBoxType is TIGHT_HINTED_OUTLINE_EXTENTS
// and the underlying cairo font may be antialiased,
// we need to create a copy in order to avoid getting cached extents.
// This is only used by MathML layout at present.
if (aBoundingBoxType == TIGHT_HINTED_OUTLINE_EXTENTS &&
mAntialiasOption != kAntialiasNone) {
if (!mNonAAFont) {
mNonAAFont = CopyWithAntialiasOption(kAntialiasNone);
}
// if font subclass doesn't implement CopyWithAntialiasOption(),
// it will return null and we'll proceed to use the existing font
if (mNonAAFont) {
return mNonAAFont->Measure(aTextRun, aStart, aEnd,
TIGHT_HINTED_OUTLINE_EXTENTS,
- aRefContext, aSpacing);
+ aRefContext, aSpacing, aOrientation);
}
}
const int32_t appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
// Current position in appunits
gfxFont::Orientation orientation =
- aTextRun->IsVertical() ? gfxFont::eVertical : gfxFont::eHorizontal;
+ aOrientation == gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT
+ ? gfxFont::eVertical : gfxFont::eHorizontal;
const gfxFont::Metrics& fontMetrics = GetMetrics(orientation);
RunMetrics metrics;
metrics.mAscent = fontMetrics.maxAscent*appUnitsPerDevUnit;
metrics.mDescent = fontMetrics.maxDescent*appUnitsPerDevUnit;
if (aStart == aEnd) {
// exit now before we look at aSpacing[0], which is undefined
metrics.mBoundingBox = gfxRect(0, -metrics.mAscent, 0, metrics.mAscent + metrics.mDescent);
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -1551,17 +1551,17 @@ public:
* The default implementation just uses font metrics and aTextRun's
* advances, and assumes no characters fall outside the font box. In
* general this is insufficient, because that assumption is not always true.
*/
virtual RunMetrics Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aContextForTightBoundingBox,
- Spacing *aSpacing);
+ Spacing *aSpacing, uint16_t aOrientation);
/**
* 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
*/
bool NotifyLineBreaksChanged(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aLength)
{ return false; }
--- a/gfx/thebes/gfxGDIFont.cpp
+++ b/gfx/thebes/gfxGDIFont.cpp
@@ -140,21 +140,23 @@ gfxGDIFont::SetupCairoFont(gfxContext *a
return true;
}
gfxFont::RunMetrics
gfxGDIFont::Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aRefContext,
- Spacing *aSpacing)
+ Spacing *aSpacing,
+ uint16_t aOrientation)
{
gfxFont::RunMetrics metrics =
gfxFont::Measure(aTextRun, aStart, aEnd,
- aBoundingBoxType, aRefContext, aSpacing);
+ aBoundingBoxType, aRefContext, aSpacing,
+ aOrientation);
// if aBoundingBoxType is LOOSE_INK_EXTENTS
// and the underlying cairo font may be antialiased,
// we can't trust Windows to have considered all the pixels
// so we need to add "padding" to the bounds.
// (see bugs 475968, 439831, compare also bug 445087)
if (aBoundingBoxType == LOOSE_INK_EXTENTS &&
mAntialiasOption != kAntialiasNone &&
--- a/gfx/thebes/gfxGDIFont.h
+++ b/gfx/thebes/gfxGDIFont.h
@@ -38,17 +38,18 @@ public:
virtual bool SetupCairoFont(gfxContext *aContext);
/* override Measure to add padding for antialiasing */
virtual RunMetrics Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aContextForTightBoundingBox,
- Spacing *aSpacing);
+ Spacing *aSpacing,
+ uint16_t aOrientation);
/* required for MathML to suppress effects of ClearType "padding" */
virtual gfxFont* CopyWithAntialiasOption(AntialiasOption anAAOption);
// If the font has a cmap table, we handle it purely with harfbuzz;
// but if not (e.g. .fon fonts), we'll use a GDI callback to get glyphs.
virtual bool ProvidesGetGlyph() const {
return !mFontEntry->HasCmapTable();
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -162,21 +162,23 @@ gfxMacFont::SetupCairoFont(gfxContext *a
return true;
}
gfxFont::RunMetrics
gfxMacFont::Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aRefContext,
- Spacing *aSpacing)
+ Spacing *aSpacing,
+ uint16_t aOrientation)
{
gfxFont::RunMetrics metrics =
gfxFont::Measure(aTextRun, aStart, aEnd,
- aBoundingBoxType, aRefContext, aSpacing);
+ aBoundingBoxType, aRefContext, aSpacing,
+ aOrientation);
// if aBoundingBoxType is not TIGHT_HINTED_OUTLINE_EXTENTS then we need to add
// a pixel column each side of the bounding box in case of antialiasing "bleed"
if (aBoundingBoxType != TIGHT_HINTED_OUTLINE_EXTENTS &&
metrics.mBoundingBox.width > 0) {
metrics.mBoundingBox.x -= aTextRun->GetAppUnitsPerDevUnit();
metrics.mBoundingBox.width += aTextRun->GetAppUnitsPerDevUnit() * 2;
}
--- a/gfx/thebes/gfxMacFont.h
+++ b/gfx/thebes/gfxMacFont.h
@@ -30,17 +30,17 @@ public:
virtual bool SetupCairoFont(gfxContext *aContext);
/* override Measure to add padding for antialiasing */
virtual RunMetrics Measure(gfxTextRun *aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
gfxContext *aContextForTightBoundingBox,
- Spacing *aSpacing);
+ Spacing *aSpacing, uint16_t aOrientation);
virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont> GetScaledFont(mozilla::gfx::DrawTarget *aTarget);
virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
FontCacheSizes* aSizes) const;
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
FontCacheSizes* aSizes) const;
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -685,44 +685,46 @@ gfxTextRun::Draw(gfxContext *aContext, g
void
gfxTextRun::AccumulateMetricsForRun(gfxFont *aFont,
uint32_t aStart, uint32_t aEnd,
gfxFont::BoundingBoxType aBoundingBoxType,
gfxContext *aRefContext,
PropertyProvider *aProvider,
uint32_t aSpacingStart, uint32_t aSpacingEnd,
+ uint16_t aOrientation,
Metrics *aMetrics)
{
nsAutoTArray<PropertyProvider::Spacing,200> spacingBuffer;
bool haveSpacing = GetAdjustedSpacingArray(aStart, aEnd, aProvider,
aSpacingStart, aSpacingEnd, &spacingBuffer);
Metrics metrics = aFont->Measure(this, aStart, aEnd, aBoundingBoxType, aRefContext,
- haveSpacing ? spacingBuffer.Elements() : nullptr);
+ haveSpacing ? spacingBuffer.Elements() : nullptr,
+ aOrientation);
aMetrics->CombineWith(metrics, IsRightToLeft());
}
void
gfxTextRun::AccumulatePartialLigatureMetrics(gfxFont *aFont,
uint32_t aStart, uint32_t aEnd,
gfxFont::BoundingBoxType aBoundingBoxType, gfxContext *aRefContext,
- PropertyProvider *aProvider, Metrics *aMetrics)
+ PropertyProvider *aProvider, uint16_t aOrientation, Metrics *aMetrics)
{
if (aStart >= aEnd)
return;
// Measure partial ligature. We hack this by clipping the metrics in the
// same way we clip the drawing.
LigatureData data = ComputeLigatureData(aStart, aEnd, aProvider);
// First measure the complete ligature
Metrics metrics;
AccumulateMetricsForRun(aFont, data.mLigatureStart, data.mLigatureEnd,
aBoundingBoxType, aRefContext,
- aProvider, aStart, aEnd, &metrics);
+ aProvider, aStart, aEnd, aOrientation, &metrics);
// Clip the bounding box to the ligature part
gfxFloat bboxLeft = metrics.mBoundingBox.X();
gfxFloat bboxRight = metrics.mBoundingBox.XMost();
// Where we are going to start "drawing" relative to our left baseline origin
gfxFloat origin = IsRightToLeft() ? metrics.mAdvanceWidth - data.mPartAdvance : 0;
ClipPartialLigature(this, &bboxLeft, &bboxRight, origin, &data);
metrics.mBoundingBox.x = bboxLeft;
@@ -752,30 +754,32 @@ gfxTextRun::MeasureText(uint32_t aStart,
gfxFont *font = iter.GetGlyphRun()->mFont;
uint32_t start = iter.GetStringStart();
uint32_t end = iter.GetStringEnd();
uint32_t ligatureRunStart = start;
uint32_t ligatureRunEnd = end;
ShrinkToLigatureBoundaries(&ligatureRunStart, &ligatureRunEnd);
AccumulatePartialLigatureMetrics(font, start, ligatureRunStart,
- aBoundingBoxType, aRefContext, aProvider, &accumulatedMetrics);
+ aBoundingBoxType, aRefContext, aProvider,
+ iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
// XXX This sucks. We have to get glyph extents just so we can detect
// glyphs outside the font box, even when aBoundingBoxType is LOOSE,
// even though in almost all cases we could get correct results just
// by getting some ascent/descent from the font and using our stored
// advance widths.
AccumulateMetricsForRun(font,
ligatureRunStart, ligatureRunEnd, aBoundingBoxType,
aRefContext, aProvider, ligatureRunStart, ligatureRunEnd,
- &accumulatedMetrics);
+ iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
AccumulatePartialLigatureMetrics(font, ligatureRunEnd, end,
- aBoundingBoxType, aRefContext, aProvider, &accumulatedMetrics);
+ aBoundingBoxType, aRefContext, aProvider,
+ iter.GetGlyphRun()->mOrientation, &accumulatedMetrics);
}
return accumulatedMetrics;
}
#define MEASUREMENT_BUFFER_SIZE 100
uint32_t
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -679,24 +679,26 @@ private:
void ShrinkToLigatureBoundaries(uint32_t *aStart, uint32_t *aEnd);
// result in appunits
gfxFloat GetPartialLigatureWidth(uint32_t aStart, uint32_t aEnd, PropertyProvider *aProvider);
void AccumulatePartialLigatureMetrics(gfxFont *aFont,
uint32_t aStart, uint32_t aEnd,
gfxFont::BoundingBoxType aBoundingBoxType,
gfxContext *aRefContext,
PropertyProvider *aProvider,
+ uint16_t aOrientation,
Metrics *aMetrics);
// **** measurement helper ****
void AccumulateMetricsForRun(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
gfxFont::BoundingBoxType aBoundingBoxType,
gfxContext *aRefContext,
PropertyProvider *aProvider,
uint32_t aSpacingStart, uint32_t aSpacingEnd,
+ uint16_t aOrientation,
Metrics *aMetrics);
// **** drawing helper ****
void DrawGlyphs(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
gfxPoint *aPt, PropertyProvider *aProvider,
uint32_t aSpacingStart, uint32_t aSpacingEnd,
TextRunDrawParams& aParams, uint16_t aOrientation);
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -7573,17 +7573,23 @@ nsTextFrame::ComputeTightBounds(gfxConte
gfxTextRun::Metrics metrics =
mTextRun->MeasureText(provider.GetStart().GetSkippedOffset(),
ComputeTransformedLength(provider),
gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS,
aContext, &provider);
// mAscent should be the same as metrics.mAscent, but it's what we use to
// paint so that's the one we'll use.
- return RoundOut(metrics.mBoundingBox) + nsPoint(0, mAscent);
+ nsRect boundingBox = RoundOut(metrics.mBoundingBox) + nsPoint(0, mAscent);
+ if (mTextRun->IsVertical()) {
+ // Swap line-relative textMetrics dimensions to physical coordinates.
+ Swap(boundingBox.x, boundingBox.y);
+ Swap(boundingBox.width, boundingBox.height);
+ }
+ return boundingBox;
}
/* virtual */ nsresult
nsTextFrame::GetPrefWidthTightBounds(nsRenderingContext* aContext,
nscoord* aX,
nscoord* aXMost)
{
gfxSkipCharsIterator iter =
@@ -8279,16 +8285,21 @@ nsTextFrame::ReflowText(nsLineLayout& aL
aMetrics.BlockStartAscent() >= 0,
"Negative descent???");
mAscent = aMetrics.BlockStartAscent();
// Handle text that runs outside its normal bounds.
nsRect boundingBox = RoundOut(textMetrics.mBoundingBox) + nsPoint(0, mAscent);
aMetrics.SetOverflowAreasToDesiredBounds();
+ if (mTextRun->IsVertical()) {
+ // Swap line-relative textMetrics dimensions to physical coordinates.
+ Swap(boundingBox.x, boundingBox.y);
+ Swap(boundingBox.width, boundingBox.height);
+ }
aMetrics.VisualOverflow().UnionRect(aMetrics.VisualOverflow(), boundingBox);
// When we have text decorations, we don't need to compute their overflow now
// because we're guaranteed to do it later
// (see nsLineLayout::RelativePositionFrames)
UnionAdditionalOverflow(presContext, aLineLayout.LineContainerRS()->frame,
provider, &aMetrics.VisualOverflow(), false);
@@ -8525,17 +8536,23 @@ nsTextFrame::RecomputeOverflow(const nsH
provider.InitializeForDisplay(true);
gfxTextRun::Metrics textMetrics =
mTextRun->MeasureText(provider.GetStart().GetSkippedOffset(),
ComputeTransformedLength(provider),
gfxFont::LOOSE_INK_EXTENTS, nullptr,
&provider);
nsRect &vis = result.VisualOverflow();
- vis.UnionRect(vis, RoundOut(textMetrics.mBoundingBox) + nsPoint(0, mAscent));
+ nsRect boundingBox = RoundOut(textMetrics.mBoundingBox) + nsPoint(0, mAscent);
+ if (mTextRun->IsVertical()) {
+ // Swap line-relative textMetrics dimensions to physical coordinates.
+ Swap(boundingBox.x, boundingBox.y);
+ Swap(boundingBox.width, boundingBox.height);
+ }
+ vis.UnionRect(vis, boundingBox);
UnionAdditionalOverflow(PresContext(), aBlockReflowState.frame, provider,
&vis, true);
return result;
}
static char16_t TransformChar(const nsStyleText* aStyle, gfxTextRun* aTextRun,
uint32_t aSkippedOffset, char16_t aChar)
{
if (aChar == '\n') {