Bug 1148660 - Correct the handling of glyph positioning offsets in vertical-upright mode. r=jdaggett
authorJonathan Kew <jkew@mozilla.com>
Mon, 01 Jun 2015 09:12:46 +0100
changeset 246482 a2297f8ea6693375ac6b25593df30f95bc77cc7b
parent 246481 ae6329a95ed12e0ce605e3f53d62bd1239fc0374
child 246483 c7b9b0f97e3d7a033c86494b380b60226ba24c28
push id28830
push usercbook@mozilla.com
push dateMon, 01 Jun 2015 13:02:44 +0000
treeherdermozilla-central@39c85ec2d644 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdaggett
bugs1148660
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1148660 - Correct the handling of glyph positioning offsets in vertical-upright mode. r=jdaggett
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxHarfBuzzShaper.cpp
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2244,17 +2244,17 @@ gfxFont::Measure(gfxTextRun *aTextRun,
             x += direction*advance;
         } else {
             allGlyphsInvisible = false;
             uint32_t glyphCount = glyphData->GetGlyphCount();
             if (glyphCount > 0) {
                 const gfxTextRun::DetailedGlyph *details =
                     aTextRun->GetDetailedGlyphs(i);
                 NS_ASSERTION(details != nullptr,
-                             "detaiedGlyph record should not be missing!");
+                             "detailedGlyph record should not be missing!");
                 uint32_t j;
                 for (j = 0; j < glyphCount; ++j, ++details) {
                     uint32_t glyphIndex = details->mGlyphID;
                     gfxPoint glyphPt(x + details->mXOffset, details->mYOffset);
                     double advance = details->mAdvance;
                     gfxRect glyphRect;
                     if (glyphData->IsMissing() || !extents ||
                         !extents->GetTightGlyphExtentsAppUnits(this,
--- a/gfx/thebes/gfxHarfBuzzShaper.cpp
+++ b/gfx/thebes/gfxHarfBuzzShaper.cpp
@@ -1786,20 +1786,28 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxC
             gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
             charGlyphs[baseCharIndex].IsClusterStart() &&
             iOffset == 0 && b_offset == 0 &&
             b_advance == 0 && bPos == 0)
         {
             charGlyphs[baseCharIndex].SetSimpleGlyph(advance,
                                                      ginfo[glyphStart].codepoint);
         } else {
-            // collect all glyphs in a list to be assigned to the first char;
+            // Collect all glyphs in a list to be assigned to the first char;
             // there must be at least one in the clump, and we already measured
             // its advance, hence the placement of the loop-exit test and the
-            // measurement of the next glyph
+            // measurement of the next glyph.
+            // For vertical orientation, we add a "base offset" to compensate
+            // for the positioning within the cluster being based on horizontal
+            // glyph origin/offset.
+            hb_position_t baseIOffset, baseBOffset;
+            if (aVertical) {
+                baseIOffset = 2 * (i_offset - i_advance);
+                baseBOffset = GetGlyphHAdvance(ginfo[glyphStart].codepoint);
+            }
             while (1) {
                 gfxTextRun::DetailedGlyph* details =
                     detailedGlyphs.AppendElement();
                 details->mGlyphID = ginfo[glyphStart].codepoint;
 
                 details->mXOffset = iOffset;
                 details->mAdvance = advance;
 
@@ -1812,19 +1820,19 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxC
                         roundB ? appUnitsPerDevUnit * FixedToIntRound(b_advance)
                         : floor(hb2appUnits * b_advance + 0.5);
                 }
                 if (++glyphStart >= glyphEnd) {
                     break;
                 }
 
                 if (aVertical) {
-                    i_offset = posInfo[glyphStart].y_offset;
+                    i_offset = baseIOffset - posInfo[glyphStart].y_offset;
                     i_advance = posInfo[glyphStart].y_advance;
-                    b_offset = posInfo[glyphStart].x_offset;
+                    b_offset = baseBOffset - posInfo[glyphStart].x_offset;
                     b_advance = posInfo[glyphStart].x_advance;
                 } else {
                     i_offset = posInfo[glyphStart].x_offset;
                     i_advance = posInfo[glyphStart].x_advance;
                     b_offset = posInfo[glyphStart].y_offset;
                     b_advance = posInfo[glyphStart].y_advance;
                 }