| Index: Source/platform/fonts/Font.cpp
|
| diff --git a/Source/platform/fonts/Font.cpp b/Source/platform/fonts/Font.cpp
|
| index 4522a7f0389e092064c4132d33e79318e4d3a14c..84a96f1947f76af8719f768af3691b3cb07edb1c 100644
|
| --- a/Source/platform/fonts/Font.cpp
|
| +++ b/Source/platform/fonts/Font.cpp
|
| @@ -339,9 +339,6 @@ CodePath Font::codePath(const TextRunPaintInfo& runInfo) const
|
| if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0 && m_fontDescription.letterSpacing() == 0)
|
| return ComplexPath;
|
|
|
| - if (m_fontDescription.orientation() == Vertical)
|
| - return ComplexPath;
|
| -
|
| if (m_fontDescription.widthVariant() != RegularWidth)
|
| return ComplexPath;
|
|
|
| @@ -716,7 +713,8 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
|
| {
|
| ASSERT(glyphBuffer.size() >= from + numGlyphs);
|
|
|
| - if (!glyphBuffer.hasVerticalOffsets()) {
|
| + bool drawVertically = font->platformData().orientation() == Vertical && font->verticalData();
|
| + if (!glyphBuffer.hasVerticalOffsets() && !drawVertically) {
|
| SkAutoSTMalloc<64, SkScalar> storage(numGlyphs);
|
| SkScalar* xpos = storage.get();
|
| for (unsigned i = 0; i < numGlyphs; i++)
|
| @@ -727,24 +725,40 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
|
| return;
|
| }
|
|
|
| - bool drawVertically = font->platformData().orientation() == Vertical && font->verticalData();
|
| -
|
| - GraphicsContextStateSaver stateSaver(*gc, false);
|
| + GraphicsContextStateSaver stateSaver(*gc);
|
| if (drawVertically) {
|
| - stateSaver.save();
|
| - gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
|
| - gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));
|
| + const float initialAdvance = glyphBuffer.hasVerticalOffsets() ? 0 : glyphBuffer.xOffsetAt(from);
|
| + const FloatPoint adjustedPoint(point.x() + initialAdvance, point.y());
|
| + const float verticalBaselineXOffset = font->fontMetrics().floatAscent() - font->fontMetrics().floatAscent(IdeographicBaseline);
|
| + const FloatPoint verticalOrigin(adjustedPoint.x() + verticalBaselineXOffset, adjustedPoint.y() - initialAdvance);
|
| +
|
| + // Multiple matrices are needed to convert between multiple coordinate systems, so they are pre-concatenated.
|
| + // First, rotate back the rotated baseline in the rendering coordinates to the glyph baseline:
|
| + // gc->concatCTM(AffineTransform(0, -1, 1, 0, adjustedPoint.x(), adjustedPoint.y()));
|
| + // gc->concatCTM(AffineTransform(1, 0, 0, 1, -adjustedPoint.x(), -adjustedPoint.y()));
|
| + // then move to the text origin to use the glyph coordinate system.
|
| + // gc->concatCTM(AffineTransform(1, 0, 0, 1, verticalOrigin.x(), verticalOrigin.y()));
|
| + gc->concatCTM(AffineTransform(0, -1, 1, 0,
|
| + -adjustedPoint.y() + adjustedPoint.x() + verticalOrigin.y(),
|
| + adjustedPoint.x() + adjustedPoint.y() - verticalOrigin.x()));
|
| + } else {
|
| + gc->concatCTM(AffineTransform::translation(point.x(), point.y()));
|
| }
|
|
|
| - const float verticalBaselineXOffset = drawVertically ? SkFloatToScalar(font->fontMetrics().floatAscent() - font->fontMetrics().floatAscent(IdeographicBaseline)) : 0;
|
| -
|
| - ASSERT(glyphBuffer.hasVerticalOffsets());
|
| - SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
|
| + SkAutoSTMalloc<64, SkPoint> storage(numGlyphs);
|
| SkPoint* pos = storage.get();
|
| - for (unsigned i = 0; i < numGlyphs; i++) {
|
| - pos[i].set(
|
| - SkFloatToScalar(point.x() + verticalBaselineXOffset + glyphBuffer.xOffsetAt(from + i)),
|
| - SkFloatToScalar(point.y() + glyphBuffer.yOffsetAt(from + i)));
|
| +
|
| + if (!glyphBuffer.hasVerticalOffsets()) { // Simple path, vertical
|
| + ASSERT(drawVertically);
|
| +
|
| + Vector<FloatPoint, 64> translations(numGlyphs);
|
| + font->verticalData()->getVerticalTranslationsForGlyphs(font, glyphBuffer.glyphs(from), numGlyphs, reinterpret_cast<float*>(&translations[0]));
|
| +
|
| + for (unsigned i = 0; i < numGlyphs; ++i)
|
| + pos[i].set(SkFloatToScalar(translations[i].x()), SkFloatToScalar(glyphBuffer.xOffsetAt(from + i) - translations[i].y()));
|
| + } else { // Complex path, either horizontal or vertical
|
| + for (unsigned i = 0; i < numGlyphs; i++)
|
| + pos[i].set(SkFloatToScalar(glyphBuffer.xOffsetAt(from + i)), SkFloatToScalar(glyphBuffer.yOffsetAt(from + i)));
|
| }
|
|
|
| paintGlyphs(gc, font, glyphBuffer.glyphs(from), numGlyphs, pos, textRect);
|
|
|