| 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 17 matching lines...) Expand all  Loading... | 
| 28 #include "SkPaint.h" | 28 #include "SkPaint.h" | 
| 29 #include "SkTemplates.h" | 29 #include "SkTemplates.h" | 
| 30 #include "platform/LayoutUnit.h" | 30 #include "platform/LayoutUnit.h" | 
| 31 #include "platform/RuntimeEnabledFeatures.h" | 31 #include "platform/RuntimeEnabledFeatures.h" | 
| 32 #include "platform/fonts/Character.h" | 32 #include "platform/fonts/Character.h" | 
| 33 #include "platform/fonts/FontCache.h" | 33 #include "platform/fonts/FontCache.h" | 
| 34 #include "platform/fonts/FontFallbackList.h" | 34 #include "platform/fonts/FontFallbackList.h" | 
| 35 #include "platform/fonts/GlyphBuffer.h" | 35 #include "platform/fonts/GlyphBuffer.h" | 
| 36 #include "platform/fonts/GlyphPageTreeNode.h" | 36 #include "platform/fonts/GlyphPageTreeNode.h" | 
| 37 #include "platform/fonts/SimpleFontData.h" | 37 #include "platform/fonts/SimpleFontData.h" | 
|  | 38 #include "platform/fonts/shaping/HarfBuzzFace.h" | 
| 38 #include "platform/fonts/shaping/HarfBuzzShaper.h" | 39 #include "platform/fonts/shaping/HarfBuzzShaper.h" | 
| 39 #include "platform/fonts/shaping/SimpleShaper.h" | 40 #include "platform/fonts/shaping/SimpleShaper.h" | 
| 40 #include "platform/geometry/FloatRect.h" | 41 #include "platform/geometry/FloatRect.h" | 
| 41 #include "platform/graphics/skia/SkiaUtils.h" | 42 #include "platform/graphics/skia/SkiaUtils.h" | 
| 42 #include "platform/text/BidiResolver.h" | 43 #include "platform/text/BidiResolver.h" | 
| 43 #include "platform/text/TextRun.h" | 44 #include "platform/text/TextRun.h" | 
| 44 #include "platform/text/TextRunIterator.h" | 45 #include "platform/text/TextRunIterator.h" | 
| 45 #include "platform/transforms/AffineTransform.h" | 46 #include "platform/transforms/AffineTransform.h" | 
| 46 #include "third_party/skia/include/core/SkCanvas.h" | 47 #include "third_party/skia/include/core/SkCanvas.h" | 
| 47 #include "wtf/MainThread.h" | 48 #include "wtf/MainThread.h" | 
| 48 #include "wtf/StdLibExtras.h" | 49 #include "wtf/StdLibExtras.h" | 
| 49 #include "wtf/unicode/CharacterNames.h" | 50 #include "wtf/unicode/CharacterNames.h" | 
| 50 #include "wtf/unicode/Unicode.h" | 51 #include "wtf/unicode/Unicode.h" | 
| 51 | 52 | 
| 52 using namespace WTF; | 53 using namespace WTF; | 
| 53 using namespace Unicode; | 54 using namespace Unicode; | 
| 54 | 55 | 
| 55 namespace blink { | 56 namespace blink { | 
| 56 | 57 | 
| 57 Font::Font() | 58 Font::Font() | 
| 58 { | 59 { | 
| 59 } | 60 } | 
| 60 | 61 | 
| 61 Font::Font(const FontDescription& fd) | 62 Font::Font(const FontDescription& fd) | 
| 62     : m_fontDescription(fd) | 63     : m_fontDescription(fd) | 
|  | 64     , m_canShapeWordByWord(0) | 
|  | 65     , m_shapeWordByWordComputed(0) | 
| 63 { | 66 { | 
| 64 } | 67 } | 
| 65 | 68 | 
| 66 Font::Font(const Font& other) | 69 Font::Font(const Font& other) | 
| 67     : m_fontDescription(other.m_fontDescription) | 70     : m_fontDescription(other.m_fontDescription) | 
| 68     , m_fontFallbackList(other.m_fontFallbackList) | 71     , m_fontFallbackList(other.m_fontFallbackList) | 
|  | 72     , m_canShapeWordByWord(0) | 
|  | 73     , m_shapeWordByWordComputed(0) | 
| 69 { | 74 { | 
| 70 } | 75 } | 
| 71 | 76 | 
| 72 Font& Font::operator=(const Font& other) | 77 Font& Font::operator=(const Font& other) | 
| 73 { | 78 { | 
| 74     m_fontDescription = other.m_fontDescription; | 79     m_fontDescription = other.m_fontDescription; | 
| 75     m_fontFallbackList = other.m_fontFallbackList; | 80     m_fontFallbackList = other.m_fontFallbackList; | 
|  | 81     m_canShapeWordByWord = other.m_canShapeWordByWord; | 
|  | 82     m_shapeWordByWordComputed = other.m_shapeWordByWordComputed; | 
| 76     return *this; | 83     return *this; | 
| 77 } | 84 } | 
| 78 | 85 | 
| 79 bool Font::operator==(const Font& other) const | 86 bool Font::operator==(const Font& other) const | 
| 80 { | 87 { | 
| 81     FontSelector* first = m_fontFallbackList ? m_fontFallbackList->fontSelector(
     ) : 0; | 88     FontSelector* first = m_fontFallbackList ? m_fontFallbackList->fontSelector(
     ) : 0; | 
| 82     FontSelector* second = other.m_fontFallbackList ? other.m_fontFallbackList->
     fontSelector() : 0; | 89     FontSelector* second = other.m_fontFallbackList ? other.m_fontFallbackList->
     fontSelector() : 0; | 
| 83 | 90 | 
| 84     return first == second | 91     return first == second | 
| 85         && m_fontDescription == other.m_fontDescription | 92         && m_fontDescription == other.m_fontDescription | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 96     // and could eventually be rectified by using RefPtrs for Fonts themselves. | 103     // and could eventually be rectified by using RefPtrs for Fonts themselves. | 
| 97     if (!m_fontFallbackList) | 104     if (!m_fontFallbackList) | 
| 98         m_fontFallbackList = FontFallbackList::create(); | 105         m_fontFallbackList = FontFallbackList::create(); | 
| 99     m_fontFallbackList->invalidate(fontSelector); | 106     m_fontFallbackList->invalidate(fontSelector); | 
| 100 } | 107 } | 
| 101 | 108 | 
| 102 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph
     Buffer, | 109 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph
     Buffer, | 
| 103     const GlyphData* emphasisData) const | 110     const GlyphData* emphasisData) const | 
| 104 { | 111 { | 
| 105     if (codePath(runInfo) == ComplexPath) { | 112     if (codePath(runInfo) == ComplexPath) { | 
| 106         HarfBuzzShaper shaper(this, runInfo.run, emphasisData); | 113         float width; | 
| 107         shaper.setDrawRange(runInfo.from, runInfo.to); | 114         CachingWordShaper& shaper = m_fontFallbackList->cachingWordShaper(); | 
| 108         shaper.shape(&glyphBuffer); | 115         if (emphasisData) { | 
| 109         return shaper.totalWidth(); | 116             width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run, | 
|  | 117                 emphasisData, &glyphBuffer, runInfo.from, runInfo.to); | 
|  | 118         } else { | 
|  | 119             width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, | 
|  | 120                 &glyphBuffer, runInfo.from, runInfo.to); | 
|  | 121         } | 
|  | 122 | 
|  | 123         return width; | 
| 110     } | 124     } | 
| 111 | 125 | 
| 112     SimpleShaper shaper(this, runInfo.run, emphasisData, nullptr /* fallbackFont
     s */, nullptr); | 126     SimpleShaper shaper(this, runInfo.run, emphasisData, nullptr /* fallbackFont
     s */, nullptr); | 
| 113     shaper.advance(runInfo.from); | 127     shaper.advance(runInfo.from); | 
| 114     shaper.advance(runInfo.to, &glyphBuffer); | 128     shaper.advance(runInfo.to, &glyphBuffer); | 
| 115     float width = shaper.runWidthSoFar(); | 129     float width = shaper.runWidthSoFar(); | 
| 116 | 130 | 
| 117     if (runInfo.run.rtl()) { | 131     if (runInfo.run.rtl()) { | 
| 118         // Glyphs are shaped & stored in RTL advance order - reverse them for LT
     R drawing. | 132         // Glyphs are shaped & stored in RTL advance order - reverse them for LT
     R drawing. | 
| 119         shaper.advance(runInfo.run.length()); | 133         shaper.advance(runInfo.run.length()); | 
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 330     if (run.codePath() == TextRun::ForceSimple) | 344     if (run.codePath() == TextRun::ForceSimple) | 
| 331         return SimplePath; | 345         return SimplePath; | 
| 332 | 346 | 
| 333     if (run.is8Bit()) | 347     if (run.is8Bit()) | 
| 334         return SimplePath; | 348         return SimplePath; | 
| 335 | 349 | 
| 336     // Start from 0 since drawing and highlighting also measure the characters b
     efore run->from. | 350     // Start from 0 since drawing and highlighting also measure the characters b
     efore run->from. | 
| 337     return Character::characterRangeCodePath(run.characters16(), run.length()); | 351     return Character::characterRangeCodePath(run.characters16(), run.length()); | 
| 338 } | 352 } | 
| 339 | 353 | 
|  | 354 bool Font::canShapeWordByWord() const | 
|  | 355 { | 
|  | 356     if (!m_shapeWordByWordComputed) { | 
|  | 357         m_canShapeWordByWord = computeCanShapeWordByWord(); | 
|  | 358         m_shapeWordByWordComputed = true; | 
|  | 359     } | 
|  | 360     return m_canShapeWordByWord; | 
|  | 361 }; | 
|  | 362 | 
|  | 363 bool Font::computeCanShapeWordByWord() const | 
|  | 364 { | 
|  | 365     if (!fontDescription().typesettingFeatures()) | 
|  | 366         return true; | 
|  | 367 | 
|  | 368     const FontPlatformData& platformData = primaryFont()->platformData(); | 
|  | 369     return !platformData.hasSpaceInLigaturesOrKerning(); | 
|  | 370 }; | 
|  | 371 | 
| 340 void Font::willUseFontData(UChar32 character) const | 372 void Font::willUseFontData(UChar32 character) const | 
| 341 { | 373 { | 
| 342     const FontFamily& family = fontDescription().family(); | 374     const FontFamily& family = fontDescription().family(); | 
| 343     if (m_fontFallbackList && m_fontFallbackList->fontSelector() && !family.fami
     lyIsEmpty()) | 375     if (m_fontFallbackList && m_fontFallbackList->fontSelector() && !family.fami
     lyIsEmpty()) | 
| 344         m_fontFallbackList->fontSelector()->willUseFontData(fontDescription(), f
     amily.family(), character); | 376         m_fontFallbackList->fontSelector()->willUseFontData(fontDescription(), f
     amily.family(), character); | 
| 345 } | 377 } | 
| 346 | 378 | 
| 347 static inline GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(UChar32 
     character, FontOrientation orientation, GlyphData& data, unsigned pageNumber) | 379 static inline GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(UChar32 
     character, FontOrientation orientation, GlyphData& data, unsigned pageNumber) | 
| 348 { | 380 { | 
| 349     if (isVerticalNonCJKUpright(orientation) || Character::shouldIgnoreRotation(
     character)) { | 381     if (isVerticalNonCJKUpright(orientation) || Character::shouldIgnoreRotation(
     character)) { | 
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 666     canvas->restoreToCount(canvasStackLevel); | 698     canvas->restoreToCount(canvasStackLevel); | 
| 667 } | 699 } | 
| 668 | 700 | 
| 669 void Font::drawTextBlob(SkCanvas* canvas, const SkPaint& paint, const SkTextBlob
     * blob, const SkPoint& origin) const | 701 void Font::drawTextBlob(SkCanvas* canvas, const SkPaint& paint, const SkTextBlob
     * blob, const SkPoint& origin) const | 
| 670 { | 702 { | 
| 671     ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); | 703     ASSERT(RuntimeEnabledFeatures::textBlobEnabled()); | 
| 672 | 704 | 
| 673     canvas->drawTextBlob(blob, origin.x(), origin.y(), paint); | 705     canvas->drawTextBlob(blob, origin.x(), origin.y(), paint); | 
| 674 } | 706 } | 
| 675 | 707 | 
| 676 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
     tData*>* fallbackFonts, FloatRect* outGlyphBounds) const | 708 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
     tData*>* fallbackFonts, FloatRect* glyphBounds) const | 
| 677 { | 709 { | 
| 678     bool hasWordSpacingOrLetterSpacing = fontDescription().wordSpacing() | 710     CachingWordShaper& shaper = m_fontFallbackList->cachingWordShaper(); | 
| 679         || fontDescription().letterSpacing(); | 711     float width = shaper.width(this, run, fallbackFonts, glyphBounds); | 
| 680     // Word spacing and letter spacing can change the width of a word. | 712     return width; | 
| 681     // If a tab occurs inside a word, the width of the word varies based on its |  | 
| 682     // position on the line. |  | 
| 683     bool isCacheable = !hasWordSpacingOrLetterSpacing && !run.allowTabs(); |  | 
| 684 |  | 
| 685     WidthCacheEntry* cacheEntry = isCacheable |  | 
| 686         ? m_fontFallbackList->widthCache().add(run, WidthCacheEntry()) |  | 
| 687         : 0; |  | 
| 688     if (cacheEntry && cacheEntry->isValid()) { |  | 
| 689         if (outGlyphBounds) |  | 
| 690             *outGlyphBounds = cacheEntry->glyphBounds; |  | 
| 691         return cacheEntry->width; |  | 
| 692     } |  | 
| 693 |  | 
| 694     FloatRect glyphBounds; |  | 
| 695     HarfBuzzShaper shaper(this, run, nullptr, fallbackFonts, &glyphBounds); |  | 
| 696     if (!shaper.shape()) |  | 
| 697         return 0; |  | 
| 698 |  | 
| 699     float result = shaper.totalWidth(); |  | 
| 700 |  | 
| 701     if (cacheEntry && (!fallbackFonts || fallbackFonts->isEmpty())) { |  | 
| 702         cacheEntry->glyphBounds = glyphBounds; |  | 
| 703         cacheEntry->width = result; |  | 
| 704     } |  | 
| 705 |  | 
| 706     if (outGlyphBounds) |  | 
| 707         *outGlyphBounds = glyphBounds; |  | 
| 708     return result; |  | 
| 709 } | 713 } | 
| 710 | 714 | 
| 711 // Return the code point index for the given |x| offset into the text run. | 715 // Return the code point index for the given |x| offset into the text run. | 
| 712 int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, | 716 int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, | 
| 713     bool includePartialGlyphs) const | 717     bool includePartialGlyphs) const | 
| 714 { | 718 { | 
| 715     HarfBuzzShaper shaper(this, run); | 719     HarfBuzzShaper shaper(this, run); | 
| 716     if (!shaper.shape()) | 720     RefPtr<ShapeResult> shapeResult = shaper.shapeResult(); | 
|  | 721     if (!shapeResult) | 
| 717         return 0; | 722         return 0; | 
| 718     return shaper.offsetForPosition(xFloat); | 723     return shapeResult->offsetForPosition(xFloat); | 
| 719 } | 724 } | 
| 720 | 725 | 
| 721 // Return the rectangle for selecting the given range of code-points in the Text
     Run. | 726 // Return the rectangle for selecting the given range of code-points in the Text
     Run. | 
| 722 FloatRect Font::selectionRectForComplexText(const TextRun& run, | 727 FloatRect Font::selectionRectForComplexText(const TextRun& run, | 
| 723     const FloatPoint& point, int height, int from, int to) const | 728     const FloatPoint& point, int height, int from, int to) const | 
| 724 { | 729 { | 
| 725     HarfBuzzShaper shaper(this, run); | 730     CachingWordShaper& shaper = m_fontFallbackList->cachingWordShaper(); | 
| 726     if (!shaper.shape()) | 731     return shaper.selectionRect(this, run, point, height, from, to); | 
| 727         return FloatRect(); |  | 
| 728     return shaper.selectionRect(point, height, from, to); |  | 
| 729 } | 732 } | 
| 730 | 733 | 
| 731 void Font::drawGlyphBuffer(SkCanvas* canvas, const SkPaint& paint, const TextRun
     PaintInfo& runInfo, const GlyphBuffer& glyphBuffer, const FloatPoint& point, flo
     at deviceScaleFactor) const | 734 void Font::drawGlyphBuffer(SkCanvas* canvas, const SkPaint& paint, const TextRun
     PaintInfo& runInfo, const GlyphBuffer& glyphBuffer, const FloatPoint& point, flo
     at deviceScaleFactor) const | 
| 732 { | 735 { | 
| 733     if (glyphBuffer.isEmpty()) | 736     if (glyphBuffer.isEmpty()) | 
| 734         return; | 737         return; | 
| 735 | 738 | 
| 736     if (RuntimeEnabledFeatures::textBlobEnabled()) { | 739     if (RuntimeEnabledFeatures::textBlobEnabled()) { | 
| 737         // Enabling text-blobs forces the blob rendering path even for uncacheab
     le blobs. | 740         // Enabling text-blobs forces the blob rendering path even for uncacheab
     le blobs. | 
| 738         TextBlobPtr uncacheableTextBlob; | 741         TextBlobPtr uncacheableTextBlob; | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 840 { | 843 { | 
| 841     return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); | 844     return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); | 
| 842 } | 845 } | 
| 843 | 846 | 
| 844 bool Font::isFallbackValid() const | 847 bool Font::isFallbackValid() const | 
| 845 { | 848 { | 
| 846     return !m_fontFallbackList || m_fontFallbackList->isValid(); | 849     return !m_fontFallbackList || m_fontFallbackList->isValid(); | 
| 847 } | 850 } | 
| 848 | 851 | 
| 849 } // namespace blink | 852 } // namespace blink | 
| OLD | NEW | 
|---|