Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: Source/platform/fonts/Font.cpp

Issue 617103003: Replace ENABLE_OPENTYPE_VERTICAL implementation with HarfBuzz (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@removeOpenTypeVertical
Patch Set: Additional TestExpectations tweaking for Mac Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/build/features.gypi ('k') | Source/platform/fonts/FontCache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 CodePath Font::codePath(const TextRunPaintInfo& runInfo) const 336 CodePath Font::codePath(const TextRunPaintInfo& runInfo) const
337 { 337 {
338 const TextRun& run = runInfo.run; 338 const TextRun& run = runInfo.run;
339 339
340 if (fontDescription().typesettingFeatures() && (runInfo.from || runInfo.to ! = run.length())) 340 if (fontDescription().typesettingFeatures() && (runInfo.from || runInfo.to ! = run.length()))
341 return ComplexPath; 341 return ComplexPath;
342 342
343 if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings ()->size() > 0 && m_fontDescription.letterSpacing() == 0) 343 if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings ()->size() > 0 && m_fontDescription.letterSpacing() == 0)
344 return ComplexPath; 344 return ComplexPath;
345 345
346 if (m_fontDescription.orientation() == Vertical)
347 return ComplexPath;
348
346 if (m_fontDescription.widthVariant() != RegularWidth) 349 if (m_fontDescription.widthVariant() != RegularWidth)
347 return ComplexPath; 350 return ComplexPath;
348 351
349 if (run.length() > 1 && fontDescription().typesettingFeatures()) 352 if (run.length() > 1 && fontDescription().typesettingFeatures())
350 return ComplexPath; 353 return ComplexPath;
351 354
352 // FIXME: This really shouldn't be needed but for some reason the 355 // FIXME: This really shouldn't be needed but for some reason the
353 // TextRendering setting doesn't propagate to typesettingFeatures in time 356 // TextRendering setting doesn't propagate to typesettingFeatures in time
354 // for the prefs width calculation. 357 // for the prefs width calculation.
355 if (fontDescription().textRendering() == OptimizeLegibility || fontDescripti on().textRendering() == GeometricPrecision) 358 if (fontDescription().textRendering() == OptimizeLegibility || fontDescripti on().textRendering() == GeometricPrecision)
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 SkPaint paint = textFillPaint(gc, font); 701 SkPaint paint = textFillPaint(gc, font);
699 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint); 702 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint);
700 } 703 }
701 704
702 if ((textMode & TextModeStroke) && gc->hasStroke()) { 705 if ((textMode & TextModeStroke) && gc->hasStroke()) {
703 SkPaint paint = textStrokePaint(gc, font, textMode & TextModeFill); 706 SkPaint paint = textStrokePaint(gc, font, textMode & TextModeFill);
704 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint); 707 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint);
705 } 708 }
706 } 709 }
707 710
708 void Font::paintGlyphsVertical(GraphicsContext* gc, const SimpleFontData* font,
709 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, const Flo atPoint& point,
710 const FloatRect& textRect) const
711 {
712 const OpenTypeVerticalData* verticalData = font->verticalData();
713
714 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
715 SkPoint* pos = storage.get();
716
717 // Bend over backwards to preserve legacy rounding.
718 float initialAdvance = glyphBuffer.xOffsetAt(from);
719 FloatPoint adjustedPoint(point.x() + initialAdvance, point.y());
720
721 GraphicsContextStateSaver stateSaver(*gc);
722 gc->concatCTM(AffineTransform(0, -1, 1, 0, adjustedPoint.x(), adjustedPoint. y()));
723 gc->concatCTM(AffineTransform(1, 0, 0, 1, -adjustedPoint.x(), -adjustedPoint .y()));
724
725 const unsigned kMaxBufferLength = 256;
726 Vector<FloatPoint, kMaxBufferLength> translations;
727
728 const FontMetrics& metrics = font->fontMetrics();
729 float verticalOriginX = adjustedPoint.x() + metrics.floatAscent() - metrics. floatAscent(IdeographicBaseline);
730
731 unsigned glyphIndex = 0;
732 while (glyphIndex < numGlyphs) {
733 unsigned chunkLength = std::min(kMaxBufferLength, numGlyphs - glyphIndex );
734
735 const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex);
736
737 translations.resize(chunkLength);
738 verticalData->getVerticalTranslationsForGlyphs(font, glyphs, chunkLength ,
739 reinterpret_cast<float*>(&translations[0]));
740
741 for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) {
742 SkScalar x = verticalOriginX + lroundf(translations[i].x());
743 SkScalar y = adjustedPoint.y() - SkIntToScalar(
744 -lroundf(glyphBuffer.xOffsetAt(from + glyphIndex) - initialAdvan ce - translations[i].y()));
745 pos[i].set(x, y);
746 }
747 paintGlyphs(gc, font, glyphs, chunkLength, pos, textRect);
748 }
749 }
750
751 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, 711 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
752 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, 712 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs,
753 const FloatPoint& point, const FloatRect& textRect) const 713 const FloatPoint& point, const FloatRect& textRect) const
754 { 714 {
755 ASSERT(glyphBuffer.size() >= from + numGlyphs); 715 ASSERT(glyphBuffer.size() >= from + numGlyphs);
756 716
757 if (font->platformData().orientation() == Vertical && font->verticalData()) {
758 paintGlyphsVertical(gc, font, glyphBuffer, from, numGlyphs, point, textR ect);
759 return;
760 }
761
762 if (!glyphBuffer.hasVerticalOffsets()) { 717 if (!glyphBuffer.hasVerticalOffsets()) {
763 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs); 718 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs);
764 SkScalar* xpos = storage.get(); 719 SkScalar* xpos = storage.get();
765 for (unsigned i = 0; i < numGlyphs; i++) 720 for (unsigned i = 0; i < numGlyphs; i++)
766 xpos[i] = SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i )); 721 xpos[i] = SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i ));
767 722
768 paintGlyphsHorizontal(gc, font, glyphBuffer.glyphs(from), numGlyphs, xpo s, 723 paintGlyphsHorizontal(gc, font, glyphBuffer.glyphs(from), numGlyphs, xpo s,
769 SkFloatToScalar(point.y()), textRect); 724 SkFloatToScalar(point.y()), textRect);
770 return; 725 return;
771 } 726 }
772 727
728 bool drawVertically = font->platformData().orientation() == Vertical && font ->verticalData();
729
730 GraphicsContextStateSaver stateSaver(*gc, false);
731 if (drawVertically) {
732 stateSaver.save();
733 gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
734 gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));
735 }
736
737 const float verticalBaselineXOffset = drawVertically ? SkFloatToScalar(font- >fontMetrics().floatAscent() - font->fontMetrics().floatAscent(IdeographicBaseli ne)) : 0;
738
773 ASSERT(glyphBuffer.hasVerticalOffsets()); 739 ASSERT(glyphBuffer.hasVerticalOffsets());
774 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); 740 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
775 SkPoint* pos = storage.get(); 741 SkPoint* pos = storage.get();
776 for (unsigned i = 0; i < numGlyphs; i++) { 742 for (unsigned i = 0; i < numGlyphs; i++) {
777 pos[i].set( 743 pos[i].set(
778 SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i)), 744 SkFloatToScalar(point.x() + verticalBaselineXOffset + glyphBuffer.xO ffsetAt(from + i)),
779 SkFloatToScalar(point.y() + glyphBuffer.yOffsetAt(from + i))); 745 SkFloatToScalar(point.y() + glyphBuffer.yOffsetAt(from + i)));
780 } 746 }
781 747
782 paintGlyphs(gc, font, glyphBuffer.glyphs(from), numGlyphs, pos, textRect); 748 paintGlyphs(gc, font, glyphBuffer.glyphs(from), numGlyphs, pos, textRect);
783 } 749 }
784 750
785 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi nt& origin) const 751 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi nt& origin) const
786 { 752 {
787 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); 753 ASSERT(RuntimeEnabledFeatures::textBlobEnabled());
788 754
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 HarfBuzzShaper shaper(this, run); 795 HarfBuzzShaper shaper(this, run);
830 if (!shaper.shape()) 796 if (!shaper.shape())
831 return FloatRect(); 797 return FloatRect();
832 return shaper.selectionRect(point, height, from, to); 798 return shaper.selectionRect(point, height, from, to);
833 } 799 }
834 800
835 void Font::drawGlyphBuffer(GraphicsContext* context, 801 void Font::drawGlyphBuffer(GraphicsContext* context,
836 const TextRunPaintInfo& runInfo, const GlyphBuffer& glyphBuffer, 802 const TextRunPaintInfo& runInfo, const GlyphBuffer& glyphBuffer,
837 const FloatPoint& point) const 803 const FloatPoint& point) const
838 { 804 {
805 if (!glyphBuffer.size())
806 return;
807
839 // Draw each contiguous run of glyphs that use the same font data. 808 // Draw each contiguous run of glyphs that use the same font data.
840 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0); 809 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0);
841 unsigned lastFrom = 0; 810 unsigned lastFrom = 0;
842 unsigned nextGlyph; 811 unsigned nextGlyph;
843 812
844 for (nextGlyph = 0; nextGlyph < glyphBuffer.size(); ++nextGlyph) { 813 for (nextGlyph = 0; nextGlyph < glyphBuffer.size(); ++nextGlyph) {
845 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph); 814 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph);
846 815
847 if (nextFontData != fontData) { 816 if (nextFontData != fontData) {
848 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - las tFrom, point, 817 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - las tFrom, point,
849 runInfo.bounds); 818 runInfo.bounds);
850 819
851 lastFrom = nextGlyph; 820 lastFrom = nextGlyph;
852 fontData = nextFontData; 821 fontData = nextFontData;
853 } 822 }
854 } 823 }
855 824
856 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint, 825 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint,
857 runInfo.bounds); 826 runInfo.bounds);
858 } 827 }
859 828
860 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph) 829 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph, FontOrientation orientation = Horizontal)
861 { 830 {
862 if (fontData->platformData().orientation() == Horizontal) { 831 FloatRect bounds = fontData->boundsForGlyph(glyph);
863 FloatRect bounds = fontData->boundsForGlyph(glyph); 832 if (orientation == Horizontal)
864 return bounds.x() + bounds.width() / 2; 833 return bounds.x() + bounds.width() / 2;
865 } 834 return bounds.y() + bounds.height() / 2;
866 // FIXME: Use glyph bounds once they make sense for vertical fonts.
867 return fontData->widthForGlyph(glyph) / 2;
868 } 835 }
869 836
870 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi nt& point) const 837 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi nt& point) const
871 { 838 {
872 FontCachePurgePreventer purgePreventer; 839 FontCachePurgePreventer purgePreventer;
873 840
874 GlyphData markGlyphData; 841 GlyphData markGlyphData;
875 if (!getEmphasisMarkGlyphData(mark, markGlyphData)) 842 if (!getEmphasisMarkGlyphData(mark, markGlyphData))
876 return; 843 return;
877 844
878 const SimpleFontData* markFontData = markGlyphData.fontData; 845 const SimpleFontData* markFontData = markGlyphData.fontData;
879 ASSERT(markFontData); 846 ASSERT(markFontData);
880 if (!markFontData) 847 if (!markFontData)
881 return; 848 return;
882 849
883 GlyphBuffer markBuffer; 850 GlyphBuffer markBuffer;
884 float midMarkOffset = offsetToMiddleOfGlyph(markFontData, markGlyphData.glyp h); 851 bool drawVertically = markFontData->platformData().orientation() == Vertical && markFontData->verticalData();
885 for (unsigned i = 0; i < glyphBuffer.size(); ++i) { 852 for (unsigned i = 0; i < glyphBuffer.size(); ++i) {
886 // Skip marks for suppressed glyphs. 853 // Skip marks for suppressed glyphs.
887 if (!glyphBuffer.glyphAt(i)) 854 if (!glyphBuffer.glyphAt(i))
888 continue; 855 continue;
889 856
890 // We want the middle of the emphasis mark aligned with the middle of th e glyph. 857 // We want the middle of the emphasis mark aligned with the middle of th e glyph.
891 // The input offsets are already adjusted to point to the middle of the glyph, so all 858 // The input offsets are already adjusted to point to the middle of the glyph, so all
892 // is left to do is adjust for 1/2 mark width. 859 // is left to do is adjust for 1/2 mark width.
893 // FIXME: we could avoid this by passing some additional info to the sha per, 860 // FIXME: we could avoid this by passing some additional info to the sha per,
894 // and perform all adjustments at buffer build time. 861 // and perform all adjustments at buffer build time.
895 markBuffer.add(markGlyphData.glyph, markFontData, glyphBuffer.xOffsetAt( i) - midMarkOffset); 862 if (!drawVertically) {
863 markBuffer.add(markGlyphData.glyph, markFontData, glyphBuffer.xOffse tAt(i) - offsetToMiddleOfGlyph(markFontData, markGlyphData.glyph));
864 } else {
865 markBuffer.add(markGlyphData.glyph, markFontData, FloatPoint(- offse tToMiddleOfGlyph(markFontData, markGlyphData.glyph),
866 glyphBuffer.xOffsetAt(i) - offsetToMiddleOfGlyph(markFontData, m arkGlyphData.glyph, Vertical)));
867 }
896 } 868 }
897 869
898 drawGlyphBuffer(context, runInfo, markBuffer, point); 870 drawGlyphBuffer(context, runInfo, markBuffer, point);
899 } 871 }
900 872
901 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectExtent* glyphBounds) const 873 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectExtent* glyphBounds) const
902 { 874 {
903 SimpleShaper::GlyphBounds bounds; 875 SimpleShaper::GlyphBounds bounds;
904 SimpleShaper shaper(this, run, fallbackFonts, glyphBounds ? &bounds : 0); 876 SimpleShaper shaper(this, run, fallbackFonts, glyphBounds ? &bounds : 0);
905 shaper.advance(run.length()); 877 shaper.advance(run.length());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 if (delta <= 0) 946 if (delta <= 0)
975 break; 947 break;
976 } 948 }
977 } 949 }
978 } 950 }
979 951
980 return offset; 952 return offset;
981 } 953 }
982 954
983 } // namespace blink 955 } // namespace blink
OLDNEW
« no previous file with comments | « Source/build/features.gypi ('k') | Source/platform/fonts/FontCache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698