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

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: Adding a Mac rebaseline 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 CodePath Font::codePath(const TextRunPaintInfo& runInfo) const 335 CodePath Font::codePath(const TextRunPaintInfo& runInfo) const
336 { 336 {
337 const TextRun& run = runInfo.run; 337 const TextRun& run = runInfo.run;
338 338
339 if (fontDescription().typesettingFeatures() && (runInfo.from || runInfo.to ! = run.length())) 339 if (fontDescription().typesettingFeatures() && (runInfo.from || runInfo.to ! = run.length()))
340 return ComplexPath; 340 return ComplexPath;
341 341
342 if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings ()->size() > 0 && m_fontDescription.letterSpacing() == 0) 342 if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings ()->size() > 0 && m_fontDescription.letterSpacing() == 0)
343 return ComplexPath; 343 return ComplexPath;
344 344
345 if (m_fontDescription.orientation() == Vertical)
346 return ComplexPath;
347
345 if (m_fontDescription.widthVariant() != RegularWidth) 348 if (m_fontDescription.widthVariant() != RegularWidth)
346 return ComplexPath; 349 return ComplexPath;
347 350
348 if (run.length() > 1 && fontDescription().typesettingFeatures()) 351 if (run.length() > 1 && fontDescription().typesettingFeatures())
349 return ComplexPath; 352 return ComplexPath;
350 353
351 // FIXME: This really shouldn't be needed but for some reason the 354 // FIXME: This really shouldn't be needed but for some reason the
352 // TextRendering setting doesn't propagate to typesettingFeatures in time 355 // TextRendering setting doesn't propagate to typesettingFeatures in time
353 // for the prefs width calculation. 356 // for the prefs width calculation.
354 if (fontDescription().textRendering() == OptimizeLegibility || fontDescripti on().textRendering() == GeometricPrecision) 357 if (fontDescription().textRendering() == OptimizeLegibility || fontDescripti on().textRendering() == GeometricPrecision)
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 SkPaint paint = textFillPaint(gc, font); 784 SkPaint paint = textFillPaint(gc, font);
782 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint); 785 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint);
783 } 786 }
784 787
785 if ((textMode & TextModeStroke) && gc->hasStroke()) { 788 if ((textMode & TextModeStroke) && gc->hasStroke()) {
786 SkPaint paint = textStrokePaint(gc, font, textMode & TextModeFill); 789 SkPaint paint = textStrokePaint(gc, font, textMode & TextModeFill);
787 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint); 790 gc->drawPosTextH(glyphs, numGlyphs * sizeof(Glyph), xpos, constY, textRe ct, paint);
788 } 791 }
789 } 792 }
790 793
791 void Font::paintGlyphsVertical(GraphicsContext* gc, const SimpleFontData* font,
792 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, const Flo atPoint& point,
793 const FloatRect& textRect) const
794 {
795 const OpenTypeVerticalData* verticalData = font->verticalData();
796
797 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
798 SkPoint* pos = storage.get();
799
800 // Bend over backwards to preserve legacy rounding.
801 float initialAdvance = glyphBuffer.xOffsetAt(from);
802 FloatPoint adjustedPoint(point.x() + initialAdvance, point.y());
803
804 AffineTransform savedMatrix = gc->getCTM();
805 gc->concatCTM(AffineTransform(0, -1, 1, 0, adjustedPoint.x(), adjustedPoint. y()));
806 gc->concatCTM(AffineTransform(1, 0, 0, 1, -adjustedPoint.x(), -adjustedPoint .y()));
807
808 const unsigned kMaxBufferLength = 256;
809 Vector<FloatPoint, kMaxBufferLength> translations;
810
811 const FontMetrics& metrics = font->fontMetrics();
812 float verticalOriginX = adjustedPoint.x() + metrics.floatAscent() - metrics. floatAscent(IdeographicBaseline);
813
814 unsigned glyphIndex = 0;
815 while (glyphIndex < numGlyphs) {
816 unsigned chunkLength = std::min(kMaxBufferLength, numGlyphs - glyphIndex );
817
818 const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex);
819
820 translations.resize(chunkLength);
821 verticalData->getVerticalTranslationsForGlyphs(font, glyphs, chunkLength ,
822 reinterpret_cast<float*>(&translations[0]));
823
824 for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) {
825 SkScalar x = verticalOriginX + lroundf(translations[i].x());
826 SkScalar y = adjustedPoint.y() - SkIntToScalar(
827 -lroundf(glyphBuffer.xOffsetAt(from + glyphIndex) - initialAdvan ce - translations[i].y()));
828 pos[i].set(x, y);
829 }
830 paintGlyphs(gc, font, glyphs, chunkLength, pos, textRect);
831 }
832
833 gc->setCTM(savedMatrix);
834 }
835
836 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, 794 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
837 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, 795 const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs,
838 const FloatPoint& point, const FloatRect& textRect) const 796 const FloatPoint& point, const FloatRect& textRect) const
839 { 797 {
840 ASSERT(glyphBuffer.size() >= from + numGlyphs); 798 ASSERT(glyphBuffer.size() >= from + numGlyphs);
841 799
842 if (font->platformData().orientation() == Vertical && font->verticalData()) {
843 paintGlyphsVertical(gc, font, glyphBuffer, from, numGlyphs, point, textR ect);
844 return;
845 }
846
847 if (!glyphBuffer.hasVerticalOffsets()) { 800 if (!glyphBuffer.hasVerticalOffsets()) {
848 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs); 801 SkAutoSTMalloc<64, SkScalar> storage(numGlyphs);
849 SkScalar* xpos = storage.get(); 802 SkScalar* xpos = storage.get();
850 for (unsigned i = 0; i < numGlyphs; i++) 803 for (unsigned i = 0; i < numGlyphs; i++)
851 xpos[i] = SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i )); 804 xpos[i] = SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i ));
852 805
853 paintGlyphsHorizontal(gc, font, glyphBuffer.glyphs(from), numGlyphs, xpo s, 806 paintGlyphsHorizontal(gc, font, glyphBuffer.glyphs(from), numGlyphs, xpo s,
854 SkFloatToScalar(point.y()), textRect); 807 SkFloatToScalar(point.y()), textRect);
855 return; 808 return;
856 } 809 }
857 810
811 bool drawVertically = font->platformData().orientation() == Vertical && font ->verticalData();
812
813 AffineTransform savedMatrix = gc->getCTM();
fs 2014/12/03 09:40:39 In https://codereview.chromium.org/748863004/ this
814 if (drawVertically) {
815 gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
816 gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));
817 }
818
819 const float verticalBaselineXOffset = drawVertically ? SkFloatToScalar(font- >fontMetrics().floatAscent() - font->fontMetrics().floatAscent(IdeographicBaseli ne)) : 0;
820
858 ASSERT(glyphBuffer.hasVerticalOffsets()); 821 ASSERT(glyphBuffer.hasVerticalOffsets());
859 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); 822 SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
860 SkPoint* pos = storage.get(); 823 SkPoint* pos = storage.get();
861 for (unsigned i = 0; i < numGlyphs; i++) { 824 for (unsigned i = 0; i < numGlyphs; i++) {
862 pos[i].set( 825 pos[i].set(
863 SkFloatToScalar(point.x() + glyphBuffer.xOffsetAt(from + i)), 826 SkFloatToScalar(point.x() + verticalBaselineXOffset + glyphBuffer.xO ffsetAt(from + i)),
864 SkFloatToScalar(point.y() + glyphBuffer.yOffsetAt(from + i))); 827 SkFloatToScalar(point.y() + glyphBuffer.yOffsetAt(from + i)));
865 } 828 }
866 829
867 paintGlyphs(gc, font, glyphBuffer.glyphs(from), numGlyphs, pos, textRect); 830 paintGlyphs(gc, font, glyphBuffer.glyphs(from), numGlyphs, pos, textRect);
831
832 if (drawVertically) {
833 gc->setCTM(savedMatrix);
834 }
868 } 835 }
869 836
870 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi nt& origin) const 837 void Font::drawTextBlob(GraphicsContext* gc, const SkTextBlob* blob, const SkPoi nt& origin) const
871 { 838 {
872 ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); 839 ASSERT(RuntimeEnabledFeatures::textBlobEnabled());
873 840
874 TextDrawingModeFlags textMode = gc->textDrawingMode(); 841 TextDrawingModeFlags textMode = gc->textDrawingMode();
875 if (textMode & TextModeFill) 842 if (textMode & TextModeFill)
876 gc->drawTextBlob(blob, origin, gc->fillPaint()); 843 gc->drawTextBlob(blob, origin, gc->fillPaint());
877 844
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 HarfBuzzShaper shaper(this, run); 881 HarfBuzzShaper shaper(this, run);
915 if (!shaper.shape()) 882 if (!shaper.shape())
916 return FloatRect(); 883 return FloatRect();
917 return shaper.selectionRect(point, height, from, to); 884 return shaper.selectionRect(point, height, from, to);
918 } 885 }
919 886
920 void Font::drawGlyphBuffer(GraphicsContext* context, 887 void Font::drawGlyphBuffer(GraphicsContext* context,
921 const TextRunPaintInfo& runInfo, const GlyphBuffer& glyphBuffer, 888 const TextRunPaintInfo& runInfo, const GlyphBuffer& glyphBuffer,
922 const FloatPoint& point) const 889 const FloatPoint& point) const
923 { 890 {
891 if (!glyphBuffer.size())
892 return;
893
924 // Draw each contiguous run of glyphs that use the same font data. 894 // Draw each contiguous run of glyphs that use the same font data.
925 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0); 895 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0);
926 unsigned lastFrom = 0; 896 unsigned lastFrom = 0;
927 unsigned nextGlyph; 897 unsigned nextGlyph;
928 898
929 for (nextGlyph = 0; nextGlyph < glyphBuffer.size(); ++nextGlyph) { 899 for (nextGlyph = 0; nextGlyph < glyphBuffer.size(); ++nextGlyph) {
930 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph); 900 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph);
931 901
932 if (nextFontData != fontData) { 902 if (nextFontData != fontData) {
933 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - las tFrom, point, 903 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - las tFrom, point,
934 runInfo.bounds); 904 runInfo.bounds);
935 905
936 lastFrom = nextGlyph; 906 lastFrom = nextGlyph;
937 fontData = nextFontData; 907 fontData = nextFontData;
938 } 908 }
939 } 909 }
940 910
941 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint, 911 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, p oint,
942 runInfo.bounds); 912 runInfo.bounds);
943 } 913 }
944 914
945 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph) 915 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph, FontOrientation orientation = Horizontal)
946 { 916 {
947 if (fontData->platformData().orientation() == Horizontal) { 917 FloatRect bounds = fontData->boundsForGlyph(glyph);
948 FloatRect bounds = fontData->boundsForGlyph(glyph); 918 if (orientation == Horizontal)
949 return bounds.x() + bounds.width() / 2; 919 return bounds.x() + bounds.width() / 2;
950 } 920 return bounds.y() + bounds.height() / 2;
951 // FIXME: Use glyph bounds once they make sense for vertical fonts.
952 return fontData->widthForGlyph(glyph) / 2;
953 } 921 }
954 922
955 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi nt& point) const 923 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r unInfo, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoi nt& point) const
956 { 924 {
957 FontCachePurgePreventer purgePreventer; 925 FontCachePurgePreventer purgePreventer;
958 926
959 GlyphData markGlyphData; 927 GlyphData markGlyphData;
960 if (!getEmphasisMarkGlyphData(mark, markGlyphData)) 928 if (!getEmphasisMarkGlyphData(mark, markGlyphData))
961 return; 929 return;
962 930
963 const SimpleFontData* markFontData = markGlyphData.fontData; 931 const SimpleFontData* markFontData = markGlyphData.fontData;
964 ASSERT(markFontData); 932 ASSERT(markFontData);
965 if (!markFontData) 933 if (!markFontData)
966 return; 934 return;
967 935
968 GlyphBuffer markBuffer; 936 GlyphBuffer markBuffer;
969 float midMarkOffset = offsetToMiddleOfGlyph(markFontData, markGlyphData.glyp h); 937 bool drawVertically = markFontData->platformData().orientation() == Vertical && markFontData->verticalData();
970 for (unsigned i = 0; i < glyphBuffer.size(); ++i) { 938 for (unsigned i = 0; i < glyphBuffer.size(); ++i) {
971 // Skip marks for suppressed glyphs. 939 // Skip marks for suppressed glyphs.
972 if (!glyphBuffer.glyphAt(i)) 940 if (!glyphBuffer.glyphAt(i))
973 continue; 941 continue;
974 942
975 // We want the middle of the emphasis mark aligned with the middle of th e glyph. 943 // We want the middle of the emphasis mark aligned with the middle of th e glyph.
976 // The input offsets are already adjusted to point to the middle of the glyph, so all 944 // The input offsets are already adjusted to point to the middle of the glyph, so all
977 // is left to do is adjust for 1/2 mark width. 945 // is left to do is adjust for 1/2 mark width.
978 // FIXME: we could avoid this by passing some additional info to the sha per, 946 // FIXME: we could avoid this by passing some additional info to the sha per,
979 // and perform all adjustments at buffer build time. 947 // and perform all adjustments at buffer build time.
980 markBuffer.add(markGlyphData.glyph, markFontData, glyphBuffer.xOffsetAt( i) - midMarkOffset); 948 if (!drawVertically) {
949 markBuffer.add(markGlyphData.glyph, markFontData, glyphBuffer.xOffse tAt(i) - offsetToMiddleOfGlyph(markFontData, markGlyphData.glyph));
950 } else {
951 markBuffer.add(markGlyphData.glyph, markFontData, FloatPoint(- offse tToMiddleOfGlyph(markFontData, markGlyphData.glyph),
952 glyphBuffer.xOffsetAt(i) - offsetToMiddleOfGlyph(markFontData, m arkGlyphData.glyph, Vertical)));
953 }
981 } 954 }
982 955
983 drawGlyphBuffer(context, runInfo, markBuffer, point); 956 drawGlyphBuffer(context, runInfo, markBuffer, point);
984 } 957 }
985 958
986 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectExtent* glyphBounds) const 959 float Font::floatWidthForSimpleText(const TextRun& run, HashSet<const SimpleFont Data*>* fallbackFonts, IntRectExtent* glyphBounds) const
987 { 960 {
988 SimpleShaper::GlyphBounds bounds; 961 SimpleShaper::GlyphBounds bounds;
989 SimpleShaper shaper(this, run, fallbackFonts, glyphBounds ? &bounds : 0); 962 SimpleShaper shaper(this, run, fallbackFonts, glyphBounds ? &bounds : 0);
990 shaper.advance(run.length()); 963 shaper.advance(run.length());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 if (delta <= 0) 1032 if (delta <= 0)
1060 break; 1033 break;
1061 } 1034 }
1062 } 1035 }
1063 } 1036 }
1064 1037
1065 return offset; 1038 return offset;
1066 } 1039 }
1067 1040
1068 } // namespace blink 1041 } // 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