OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. | 5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. |
6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. | 6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 CodePath Font::codePath(const TextRunPaintInfo& runInfo) const | 332 CodePath Font::codePath(const TextRunPaintInfo& runInfo) const |
333 { | 333 { |
334 const TextRun& run = runInfo.run; | 334 const TextRun& run = runInfo.run; |
335 | 335 |
336 if (fontDescription().typesettingFeatures() && (runInfo.from || runInfo.to !
= run.length())) | 336 if (fontDescription().typesettingFeatures() && (runInfo.from || runInfo.to !
= run.length())) |
337 return ComplexPath; | 337 return ComplexPath; |
338 | 338 |
339 if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings
()->size() > 0 && m_fontDescription.letterSpacing() == 0) | 339 if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings
()->size() > 0 && m_fontDescription.letterSpacing() == 0) |
340 return ComplexPath; | 340 return ComplexPath; |
341 | 341 |
342 if (m_fontDescription.orientation() == Vertical) | |
343 return ComplexPath; | |
344 | |
345 if (m_fontDescription.widthVariant() != RegularWidth) | 342 if (m_fontDescription.widthVariant() != RegularWidth) |
346 return ComplexPath; | 343 return ComplexPath; |
347 | 344 |
348 if (run.length() > 1 && fontDescription().typesettingFeatures()) | 345 if (run.length() > 1 && fontDescription().typesettingFeatures()) |
349 return ComplexPath; | 346 return ComplexPath; |
350 | 347 |
351 // FIXME: This really shouldn't be needed but for some reason the | 348 // FIXME: This really shouldn't be needed but for some reason the |
352 // TextRendering setting doesn't propagate to typesettingFeatures in time | 349 // TextRendering setting doesn't propagate to typesettingFeatures in time |
353 // for the prefs width calculation. | 350 // for the prefs width calculation. |
354 if (fontDescription().textRendering() == OptimizeLegibility || fontDescripti
on().textRendering() == GeometricPrecision) | 351 if (fontDescription().textRendering() == OptimizeLegibility || fontDescripti
on().textRendering() == GeometricPrecision) |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe
ct, paint); | 706 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe
ct, paint); |
710 } | 707 } |
711 } | 708 } |
712 | 709 |
713 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, | 710 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, |
714 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, | 711 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, |
715 const FloatPoint& point, const FloatRect& textRect) const | 712 const FloatPoint& point, const FloatRect& textRect) const |
716 { | 713 { |
717 ASSERT(glyphBuffer.size() >= from + numGlyphs); | 714 ASSERT(glyphBuffer.size() >= from + numGlyphs); |
718 | 715 |
719 if (!glyphBuffer.hasVerticalOffsets()) { | 716 bool drawVertically = font->platformData().orientation() == Vertical && font
->verticalData(); |
| 717 if (!glyphBuffer.hasVerticalOffsets() && !drawVertically) { |
720 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs); | 718 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs); |
721 SkScalar* xpos = storage.get(); | 719 SkScalar* xpos = storage.get(); |
722 for (unsigned i = 0; i < numGlyphs; i++) | 720 for (unsigned i = 0; i < numGlyphs; i++) |
723 xpos[i] = SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i
)); | 721 xpos[i] = SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i
)); |
724 | 722 |
725 paintGlyphsHorizontal(gc, font, glyphBuffer.glyphs(from), numGlyphs, xpo
s, | 723 paintGlyphsHorizontal(gc, font, glyphBuffer.glyphs(from), numGlyphs, xpo
s, |
726 SkFloatToScalar(point.y()), textRect); | 724 SkFloatToScalar(point.y()), textRect); |
727 return; | 725 return; |
728 } | 726 } |
729 | 727 |
730 bool drawVertically = font->platformData().orientation() == Vertical && font
->verticalData(); | 728 GraphicsContextStateSaver stateSaver(*gc); |
| 729 if (drawVertically) { |
| 730 const float initialAdvance = glyphBuffer.hasVerticalOffsets() ? 0 : glyp
hBuffer.xOffsetAt(from); |
| 731 const FloatPoint adjustedPoint(point.x() + initialAdvance, point.y()); |
| 732 const float verticalBaselineXOffset = font->fontMetrics().floatAscent()
- font->fontMetrics().floatAscent(IdeographicBaseline); |
| 733 const FloatPoint verticalOrigin(adjustedPoint.x() + verticalBaselineXOff
set, adjustedPoint.y() - initialAdvance); |
731 | 734 |
732 GraphicsContextStateSaver stateSaver(*gc, false); | 735 // Multiple matrices are needed to convert between multiple coordinate s
ystems, so they are pre-concatenated. |
733 if (drawVertically) { | 736 // First, rotate back the rotated baseline in the rendering coordinates
to the glyph baseline: |
734 stateSaver.save(); | 737 // gc->concatCTM(AffineTransform(0, -1, 1, 0, adjustedPoint.x(), adjuste
dPoint.y())); |
735 gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y())); | 738 // gc->concatCTM(AffineTransform(1, 0, 0, 1, -adjustedPoint.x(), -adjust
edPoint.y())); |
736 gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y())); | 739 // then move to the text origin to use the glyph coordinate system. |
| 740 // gc->concatCTM(AffineTransform(1, 0, 0, 1, verticalOrigin.x(), vertica
lOrigin.y())); |
| 741 gc->concatCTM(AffineTransform(0, -1, 1, 0, |
| 742 -adjustedPoint.y() + adjustedPoint.x() + verticalOrigin.y(), |
| 743 adjustedPoint.x() + adjustedPoint.y() - verticalOrigin.x())); |
| 744 } else { |
| 745 gc->concatCTM(AffineTransform::translation(point.x(), point.y())); |
737 } | 746 } |
738 | 747 |
739 const float verticalBaselineXOffset = drawVertically ? SkFloatToScalar(font-
>fontMetrics().floatAscent() - font->fontMetrics().floatAscent(IdeographicBaseli
ne)) : 0; | 748 SkAutoSTMalloc<64, SkPoint> storage(numGlyphs); |
| 749 SkPoint* pos = storage.get(); |
740 | 750 |
741 ASSERT(glyphBuffer.hasVerticalOffsets()); | 751 if (!glyphBuffer.hasVerticalOffsets()) { // Simple path, vertical |
742 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); | 752 ASSERT(drawVertically); |
743 SkPoint* pos = storage.get(); | 753 |
744 for (unsigned i = 0; i < numGlyphs; i++) { | 754 Vector<FloatPoint, 64> translations(numGlyphs); |
745 pos[i].set( | 755 font->verticalData()->getVerticalTranslationsForGlyphs(font, glyphBuffer
.glyphs(from), numGlyphs, reinterpret_cast<float*>(&translations[0])); |
746 SkFloatToScalar(point.x() + verticalBaselineXOffset + glyphBuffer.xO
ffsetAt(from + i)), | 756 |
747 SkFloatToScalar(point.y() + glyphBuffer.yOffsetAt(from + i))); | 757 for (unsigned i = 0; i < numGlyphs; ++i) |
| 758 pos[i].set(SkFloatToScalar(translations[i].x()), SkFloatToScalar(gly
phBuffer.xOffsetAt(from + i) - translations[i].y())); |
| 759 } else { // Complex path, either horizontal or vertical |
| 760 for (unsigned i = 0; i < numGlyphs; i++) |
| 761 pos[i].set(SkFloatToScalar(glyphBuffer.xOffsetAt(from + i)), SkFloat
ToScalar(glyphBuffer.yOffsetAt(from + i))); |
748 } | 762 } |
749 | 763 |
750 paintGlyphs(gc, font, glyphBuffer.glyphs(from), numGlyphs, pos, textRect); | 764 paintGlyphs(gc, font, glyphBuffer.glyphs(from), numGlyphs, pos, textRect); |
751 } | 765 } |
752 | 766 |
753 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi
nt& origin) const | 767 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi
nt& origin) const |
754 { | 768 { |
755 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); | 769 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); |
756 | 770 |
757 TextDrawingModeFlags textMode = gc->textDrawingMode(); | 771 TextDrawingModeFlags textMode = gc->textDrawingMode(); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 if (delta <= 0) | 963 if (delta <= 0) |
950 break; | 964 break; |
951 } | 965 } |
952 } | 966 } |
953 } | 967 } |
954 | 968 |
955 return offset; | 969 return offset; |
956 } | 970 } |
957 | 971 |
958 } // namespace blink | 972 } // namespace blink |
OLD | NEW |