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

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

Issue 1479003002: Remove Simple Text Path (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 1 month 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
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 14 matching lines...) Expand all
25 #include "platform/fonts/Font.h" 25 #include "platform/fonts/Font.h"
26 26
27 #include "platform/LayoutTestSupport.h" 27 #include "platform/LayoutTestSupport.h"
28 #include "platform/LayoutUnit.h" 28 #include "platform/LayoutUnit.h"
29 #include "platform/RuntimeEnabledFeatures.h" 29 #include "platform/RuntimeEnabledFeatures.h"
30 #include "platform/fonts/CharacterRange.h" 30 #include "platform/fonts/CharacterRange.h"
31 #include "platform/fonts/FontCache.h" 31 #include "platform/fonts/FontCache.h"
32 #include "platform/fonts/FontFallbackIterator.h" 32 #include "platform/fonts/FontFallbackIterator.h"
33 #include "platform/fonts/FontFallbackList.h" 33 #include "platform/fonts/FontFallbackList.h"
34 #include "platform/fonts/GlyphBuffer.h" 34 #include "platform/fonts/GlyphBuffer.h"
35 #include "platform/fonts/GlyphPageTreeNode.h"
36 #include "platform/fonts/SimpleFontData.h" 35 #include "platform/fonts/SimpleFontData.h"
37 #include "platform/fonts/shaping/CachingWordShaper.h" 36 #include "platform/fonts/shaping/CachingWordShaper.h"
38 #include "platform/fonts/shaping/SimpleShaper.h"
39 #include "platform/geometry/FloatRect.h" 37 #include "platform/geometry/FloatRect.h"
40 #include "platform/text/BidiResolver.h" 38 #include "platform/text/BidiResolver.h"
41 #include "platform/text/Character.h" 39 #include "platform/text/Character.h"
42 #include "platform/text/TextRun.h" 40 #include "platform/text/TextRun.h"
43 #include "platform/text/TextRunIterator.h" 41 #include "platform/text/TextRunIterator.h"
44 #include "platform/transforms/AffineTransform.h" 42 #include "platform/transforms/AffineTransform.h"
45 #include "third_party/skia/include/core/SkCanvas.h" 43 #include "third_party/skia/include/core/SkCanvas.h"
46 #include "third_party/skia/include/core/SkPaint.h" 44 #include "third_party/skia/include/core/SkPaint.h"
47 #include "third_party/skia/include/core/SkTextBlob.h" 45 #include "third_party/skia/include/core/SkTextBlob.h"
48 #include "wtf/StdLibExtras.h" 46 #include "wtf/StdLibExtras.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // in trouble). Still, this is pretty disgusting, and could eventually be 101 // in trouble). Still, this is pretty disgusting, and could eventually be
104 // rectified by using RefPtrs for Fonts themselves. 102 // rectified by using RefPtrs for Fonts themselves.
105 if (!m_fontFallbackList) 103 if (!m_fontFallbackList)
106 m_fontFallbackList = FontFallbackList::create(); 104 m_fontFallbackList = FontFallbackList::create();
107 m_fontFallbackList->invalidate(fontSelector); 105 m_fontFallbackList->invalidate(fontSelector);
108 } 106 }
109 107
110 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, 108 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo,
111 GlyphBuffer& glyphBuffer, 109 GlyphBuffer& glyphBuffer,
112 const GlyphData* emphasisData) const { 110 const GlyphData* emphasisData) const {
113 if (codePath(runInfo) == ComplexPath) { 111 float width;
114 float width; 112 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
115 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); 113 if (emphasisData) {
116 if (emphasisData) { 114 width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run,
117 width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run, 115 emphasisData, &glyphBuffer,
118 emphasisData, &glyphBuffer, 116 runInfo.from, runInfo.to);
119 runInfo.from, runInfo.to); 117 } else {
120 } else { 118 width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, &glyphBuffer,
121 width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, &glyphBuffer, 119 runInfo.from, runInfo.to);
122 runInfo.from, runInfo.to);
123 }
124
125 return width;
126 } 120 }
127
128 SimpleShaper shaper(this, runInfo.run, emphasisData,
129 nullptr /* fallbackFonts */, nullptr);
130 shaper.advance(runInfo.from);
131 shaper.advance(runInfo.to, &glyphBuffer);
132 float width = shaper.runWidthSoFar();
133
134 if (runInfo.run.rtl()) {
135 // Glyphs are shaped & stored in RTL advance order - reverse them for LTR
136 // drawing.
137 shaper.advance(runInfo.run.length());
138 glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar());
139 }
140
141 return width; 121 return width;
142 } 122 }
143 123
144 bool Font::drawText(SkCanvas* canvas, 124 bool Font::drawText(SkCanvas* canvas,
145 const TextRunPaintInfo& runInfo, 125 const TextRunPaintInfo& runInfo,
146 const FloatPoint& point, 126 const FloatPoint& point,
147 float deviceScaleFactor, 127 float deviceScaleFactor,
148 const SkPaint& paint) const { 128 const SkPaint& paint) const {
149 // Don't draw anything while we are using custom fonts that are in the process 129 // Don't draw anything while we are using custom fonts that are in the process
150 // of loading. 130 // of loading.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 228
249 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, 229 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point,
250 deviceScaleFactor); 230 deviceScaleFactor);
251 } 231 }
252 232
253 float Font::width(const TextRun& run, 233 float Font::width(const TextRun& run,
254 HashSet<const SimpleFontData*>* fallbackFonts, 234 HashSet<const SimpleFontData*>* fallbackFonts,
255 FloatRect* glyphBounds) const { 235 FloatRect* glyphBounds) const {
256 FontCachePurgePreventer purgePreventer; 236 FontCachePurgePreventer purgePreventer;
257 237
258 if (codePath(TextRunPaintInfo(run)) == ComplexPath) 238 return floatWidthForComplexText(run, fallbackFonts, glyphBounds);
259 return floatWidthForComplexText(run, fallbackFonts, glyphBounds);
260 return floatWidthForSimpleText(run, fallbackFonts, glyphBounds);
261 } 239 }
262 240
263 namespace { 241 namespace {
264 242
265 enum BlobRotation { 243 enum BlobRotation {
266 NoRotation, 244 NoRotation,
267 CCWRotation, 245 CCWRotation,
268 }; 246 };
269 247
270 class GlyphBufferBloberizer { 248 class GlyphBufferBloberizer {
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 int to, 470 int to,
493 bool accountForGlyphBounds) const { 471 bool accountForGlyphBounds) const {
494 to = (to == -1 ? run.length() : to); 472 to = (to == -1 ? run.length() : to);
495 473
496 TextRunPaintInfo runInfo(run); 474 TextRunPaintInfo runInfo(run);
497 runInfo.from = from; 475 runInfo.from = from;
498 runInfo.to = to; 476 runInfo.to = to;
499 477
500 FontCachePurgePreventer purgePreventer; 478 FontCachePurgePreventer purgePreventer;
501 479
502 if (codePath(runInfo) != ComplexPath)
503 return pixelSnappedSelectionRect(selectionRectForSimpleText(
504 run, point, h, from, to, accountForGlyphBounds));
505 return pixelSnappedSelectionRect( 480 return pixelSnappedSelectionRect(
506 selectionRectForComplexText(run, point, h, from, to)); 481 selectionRectForComplexText(run, point, h, from, to));
507 } 482 }
508 483
509 int Font::offsetForPosition(const TextRun& run, 484 int Font::offsetForPosition(const TextRun& run,
510 float x, 485 float x,
511 bool includePartialGlyphs) const { 486 bool includePartialGlyphs) const {
512 FontCachePurgePreventer purgePreventer; 487 FontCachePurgePreventer purgePreventer;
513
514 if (codePath(TextRunPaintInfo(run)) != ComplexPath &&
515 !getFontDescription().getTypesettingFeatures())
516 return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
517
518 return offsetForPositionForComplexText(run, x, includePartialGlyphs); 488 return offsetForPositionForComplexText(run, x, includePartialGlyphs);
519 } 489 }
520 490
521 CodePath Font::codePath(const TextRunPaintInfo& runInfo) const {
522 if (RuntimeEnabledFeatures::alwaysUseComplexTextEnabled() ||
523 LayoutTestSupport::alwaysUseComplexTextForTest()) {
524 return ComplexPath;
525 }
526
527 const TextRun& run = runInfo.run;
528
529 if (getFontDescription().getTypesettingFeatures())
530 return ComplexPath;
531
532 if (m_fontDescription.featureSettings() &&
533 m_fontDescription.featureSettings()->size() > 0)
534 return ComplexPath;
535
536 if (m_fontDescription.isVerticalBaseline())
537 return ComplexPath;
538
539 if (m_fontDescription.widthVariant() != RegularWidth)
540 return ComplexPath;
541
542 // FIXME: This really shouldn't be needed but for some reason the
543 // TextRendering setting doesn't propagate to typesettingFeatures in time
544 // for the prefs width calculation.
545 if (getFontDescription().textRendering() == OptimizeLegibility ||
546 getFontDescription().textRendering() == GeometricPrecision)
547 return ComplexPath;
548
549 if (run.is8Bit())
550 return SimplePath;
551
552 // Start from 0 since drawing and highlighting also measure the characters
553 // before run->from.
554 return Character::characterRangeCodePath(run.characters16(), run.length());
555 }
556
557 bool Font::canShapeWordByWord() const { 491 bool Font::canShapeWordByWord() const {
558 if (!m_shapeWordByWordComputed) { 492 if (!m_shapeWordByWordComputed) {
559 m_canShapeWordByWord = computeCanShapeWordByWord(); 493 m_canShapeWordByWord = computeCanShapeWordByWord();
560 m_shapeWordByWordComputed = true; 494 m_shapeWordByWordComputed = true;
561 } 495 }
562 return m_canShapeWordByWord; 496 return m_canShapeWordByWord;
563 }; 497 };
564 498
565 bool Font::computeCanShapeWordByWord() const { 499 bool Font::computeCanShapeWordByWord() const {
566 if (!getFontDescription().getTypesettingFeatures()) 500 if (!getFontDescription().getTypesettingFeatures())
567 return true; 501 return true;
568 502
569 if (!primaryFont()) 503 if (!primaryFont())
570 return false; 504 return false;
571 505
572 const FontPlatformData& platformData = primaryFont()->platformData(); 506 const FontPlatformData& platformData = primaryFont()->platformData();
573 TypesettingFeatures features = getFontDescription().getTypesettingFeatures(); 507 TypesettingFeatures features = getFontDescription().getTypesettingFeatures();
574 return !platformData.hasSpaceInLigaturesOrKerning(features); 508 return !platformData.hasSpaceInLigaturesOrKerning(features);
575 }; 509 };
576 510
577 void Font::willUseFontData(const String& text) const { 511 void Font::willUseFontData(const String& text) const {
578 const FontFamily& family = getFontDescription().family(); 512 const FontFamily& family = getFontDescription().family();
579 if (m_fontFallbackList && m_fontFallbackList->getFontSelector() && 513 if (m_fontFallbackList && m_fontFallbackList->getFontSelector() &&
580 !family.familyIsEmpty()) 514 !family.familyIsEmpty())
581 m_fontFallbackList->getFontSelector()->willUseFontData( 515 m_fontFallbackList->getFontSelector()->willUseFontData(
582 getFontDescription(), family.family(), text); 516 getFontDescription(), family.family(), text);
583 } 517 }
584 518
585 static inline GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(
586 UChar32 character,
587 bool isUpright,
588 GlyphData& data,
589 unsigned pageNumber) {
590 if (isUpright) {
591 RefPtr<SimpleFontData> uprightFontData =
592 data.fontData->uprightOrientationFontData();
593 GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getNormalRootChild(
594 uprightFontData.get(), pageNumber);
595 GlyphPage* uprightPage = uprightNode->page();
596 if (uprightPage) {
597 GlyphData uprightData = uprightPage->glyphDataForCharacter(character);
598 // If the glyphs are the same, then we know we can just use the horizontal
599 // glyph rotated vertically to be upright.
600 if (data.glyph == uprightData.glyph)
601 return data;
602 // The glyphs are distinct, meaning that the font has a vertical-right
603 // glyph baked into it. We can't use that glyph, so we fall back to the
604 // upright data and use the horizontal glyph.
605 if (uprightData.fontData)
606 return uprightData;
607 }
608 } else {
609 RefPtr<SimpleFontData> verticalRightFontData =
610 data.fontData->verticalRightOrientationFontData();
611 GlyphPageTreeNode* verticalRightNode =
612 GlyphPageTreeNode::getNormalRootChild(verticalRightFontData.get(),
613 pageNumber);
614 GlyphPage* verticalRightPage = verticalRightNode->page();
615 if (verticalRightPage) {
616 GlyphData verticalRightData =
617 verticalRightPage->glyphDataForCharacter(character);
618 // If the glyphs are distinct, we will make the assumption that the font
619 // has a vertical-right glyph baked into it.
620 if (data.glyph != verticalRightData.glyph)
621 return data;
622 // The glyphs are identical, meaning that we should just use the
623 // horizontal glyph.
624 if (verticalRightData.fontData)
625 return verticalRightData;
626 }
627 }
628 return data;
629 }
630
631 PassRefPtr<FontFallbackIterator> Font::createFontFallbackIterator( 519 PassRefPtr<FontFallbackIterator> Font::createFontFallbackIterator(
632 FontFallbackPriority fallbackPriority) const { 520 FontFallbackPriority fallbackPriority) const {
633 return FontFallbackIterator::create(m_fontDescription, m_fontFallbackList, 521 return FontFallbackIterator::create(m_fontDescription, m_fontFallbackList,
634 fallbackPriority); 522 fallbackPriority);
635 } 523 }
636 524
637 GlyphData Font::glyphDataForCharacter(UChar32& c,
638 bool mirror,
639 bool normalizeSpace,
640 FontDataVariant variant) const {
641 ASSERT(isMainThread());
642
643 if (variant == AutoVariant) {
644 if (m_fontDescription.variantCaps() == FontDescription::SmallCaps) {
645 UChar32 upperC =
646 toUpper(c, LayoutLocale::localeString(m_fontDescription.locale()));
647 if (upperC != c) {
648 c = upperC;
649 variant = SmallCapsVariant;
650 } else {
651 variant = NormalVariant;
652 }
653 } else {
654 variant = NormalVariant;
655 }
656 }
657
658 if (normalizeSpace && Character::isNormalizedCanvasSpaceCharacter(c))
659 c = spaceCharacter;
660
661 if (mirror)
662 c = mirroredChar(c);
663
664 unsigned pageNumber = (c / GlyphPage::size);
665
666 GlyphPageTreeNodeBase* node = m_fontFallbackList->getPageNode(pageNumber);
667 if (!node) {
668 node = GlyphPageTreeNode::getRootChild(fontDataAt(0), pageNumber);
669 m_fontFallbackList->setPageNode(pageNumber, node);
670 }
671 RELEASE_ASSERT(node); // Diagnosing crbug.com/446566 crash bug.
672
673 GlyphPage* page = 0;
674 if (variant == NormalVariant) {
675 // Fastest loop, for the common case (normal variant).
676 while (true) {
677 page = node->page(m_fontDescription.script());
678 if (page) {
679 GlyphData data = page->glyphDataForCharacter(c);
680 if (data.fontData) {
681 if (!data.fontData->platformData().isVerticalAnyUpright() ||
682 data.fontData->isTextOrientationFallback())
683 return data;
684
685 bool isUpright = m_fontDescription.isVerticalUpright(c);
686 if (!isUpright || !Character::isCJKIdeographOrSymbol(c))
687 return glyphDataForNonCJKCharacterWithGlyphOrientation(
688 c, isUpright, data, pageNumber);
689
690 return data;
691 }
692
693 if (node->isSystemFallback())
694 break;
695 }
696
697 // Proceed with the fallback list.
698 node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()),
699 pageNumber);
700 m_fontFallbackList->setPageNode(pageNumber, node);
701 }
702 }
703 if (variant != NormalVariant) {
704 while (true) {
705 page = node->page(m_fontDescription.script());
706 if (page) {
707 GlyphData data = page->glyphDataForCharacter(c);
708 if (data.fontData) {
709 // The variantFontData function should not normally return 0.
710 // But if it does, we will just render the capital letter big.
711 RefPtr<SimpleFontData> variantFontData =
712 data.fontData->variantFontData(m_fontDescription, variant);
713 if (!variantFontData)
714 return data;
715
716 GlyphPageTreeNode* variantNode =
717 GlyphPageTreeNode::getNormalRootChild(variantFontData.get(),
718 pageNumber);
719 GlyphPage* variantPage = variantNode->page();
720 if (variantPage) {
721 GlyphData data = variantPage->glyphDataForCharacter(c);
722 if (data.fontData)
723 return data;
724 }
725
726 // Do not attempt system fallback off the variantFontData. This is the
727 // very unlikely case that a font has the lowercase character but the
728 // small caps font does not have its uppercase version.
729 return variantFontData->missingGlyphData();
730 }
731
732 if (node->isSystemFallback())
733 break;
734 }
735
736 // Proceed with the fallback list.
737 node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()),
738 pageNumber);
739 m_fontFallbackList->setPageNode(pageNumber, node);
740 }
741 }
742
743 ASSERT(page);
744 ASSERT(node->isSystemFallback());
745
746 // System fallback is character-dependent. When we get here, we
747 // know that the character in question isn't in the system fallback
748 // font's glyph page. Try to lazily create it here.
749
750 // FIXME: Unclear if this should normalizeSpaces above 0xFFFF.
751 // Doing so changes fast/text/international/plane2-diffs.html
752 UChar32 characterToRender = c;
753 if (characterToRender <= 0xFFFF)
754 characterToRender = Character::normalizeSpaces(characterToRender);
755
756 const FontData* fontData = fontDataAt(0);
757 if (fontData) {
758 const SimpleFontData* fontDataToSubstitute =
759 fontData->fontDataForCharacter(characterToRender);
760 RefPtr<SimpleFontData> characterFontData =
761 FontCache::fontCache()->fallbackFontForCharacter(
762 m_fontDescription, characterToRender, fontDataToSubstitute);
763 if (characterFontData && variant != NormalVariant) {
764 characterFontData =
765 characterFontData->variantFontData(m_fontDescription, variant);
766 }
767 if (characterFontData) {
768 // Got the fallback glyph and font.
769 unsigned pageNumberForRendering = characterToRender / GlyphPage::size;
770 GlyphPage* fallbackPage =
771 GlyphPageTreeNode::getRootChild(characterFontData.get(),
772 pageNumberForRendering)
773 ->page();
774 GlyphData data =
775 fallbackPage && fallbackPage->glyphForCharacter(characterToRender)
776 ? fallbackPage->glyphDataForCharacter(characterToRender)
777 : characterFontData->missingGlyphData();
778 // Cache it so we don't have to do system fallback again next time.
779 if (variant == NormalVariant) {
780 page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
781 data.fontData->setMaxGlyphPageTreeLevel(
782 std::max(data.fontData->maxGlyphPageTreeLevel(), node->level()));
783 if (data.fontData->platformData().isVerticalAnyUpright() &&
784 !data.fontData->isTextOrientationFallback() &&
785 !Character::isCJKIdeographOrSymbol(characterToRender))
786 return glyphDataForNonCJKCharacterWithGlyphOrientation(
787 characterToRender,
788 m_fontDescription.isVerticalUpright(characterToRender), data,
789 pageNumberForRendering);
790 }
791 return data;
792 }
793 }
794
795 // Even system fallback can fail; use the missing glyph in that case.
796 // FIXME: It would be nicer to use the missing glyph from the last resort font
797 // instead.
798 DCHECK(primaryFont());
799 if (!primaryFont())
800 return GlyphData();
801 GlyphData data = primaryFont()->missingGlyphData();
802 if (variant == NormalVariant) {
803 page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
804 data.fontData->setMaxGlyphPageTreeLevel(
805 std::max(data.fontData->maxGlyphPageTreeLevel(), node->level()));
806 }
807 return data;
808 }
809
810 bool Font::getEmphasisMarkGlyphData(const AtomicString& mark, 525 bool Font::getEmphasisMarkGlyphData(const AtomicString& mark,
811 GlyphData& glyphData) const { 526 GlyphData& glyphData) const {
812 if (mark.isEmpty()) 527 if (mark.isEmpty())
813 return false; 528 return false;
814 529
815 TextRun emphasisMarkRun(mark, mark.length()); 530 TextRun emphasisMarkRun(mark, mark.length());
816 TextRunPaintInfo emphasisPaintInfo(emphasisMarkRun); 531 TextRunPaintInfo emphasisPaintInfo(emphasisMarkRun);
817 GlyphBuffer glyphBuffer; 532 GlyphBuffer glyphBuffer;
818 buildGlyphBuffer(emphasisPaintInfo, glyphBuffer); 533 buildGlyphBuffer(emphasisPaintInfo, glyphBuffer);
819 534
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); 636 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
922 auto ranges = shaper.individualCharacterRanges(this, run); 637 auto ranges = shaper.individualCharacterRanges(this, run);
923 // The shaper should return ranges.size == run.length but on some platforms 638 // The shaper should return ranges.size == run.length but on some platforms
924 // (OSX10.9.5) we are seeing cases in the upper end of the unicode range 639 // (OSX10.9.5) we are seeing cases in the upper end of the unicode range
925 // where this is not true (see: crbug.com/620952). To catch these cases on 640 // where this is not true (see: crbug.com/620952). To catch these cases on
926 // more popular platforms, and to protect users, we are using a CHECK here. 641 // more popular platforms, and to protect users, we are using a CHECK here.
927 CHECK_EQ(ranges.size(), run.length()); 642 CHECK_EQ(ranges.size(), run.length());
928 return ranges; 643 return ranges;
929 } 644 }
930 645
931 float Font::floatWidthForSimpleText(
932 const TextRun& run,
933 HashSet<const SimpleFontData*>* fallbackFonts,
934 FloatRect* glyphBounds) const {
935 SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds);
936 shaper.advance(run.length());
937 return shaper.runWidthSoFar();
938 }
939
940 FloatRect Font::selectionRectForSimpleText(const TextRun& run,
941 const FloatPoint& point,
942 int h,
943 int from,
944 int to,
945 bool accountForGlyphBounds) const {
946 FloatRect bounds;
947 SimpleShaper shaper(this, run, nullptr, nullptr,
948 accountForGlyphBounds ? &bounds : nullptr);
949 shaper.advance(from);
950 float fromX = shaper.runWidthSoFar();
951 shaper.advance(to);
952 float toX = shaper.runWidthSoFar();
953
954 if (run.rtl()) {
955 shaper.advance(run.length());
956 float totalWidth = shaper.runWidthSoFar();
957 float beforeWidth = fromX;
958 float afterWidth = toX;
959 fromX = totalWidth - afterWidth;
960 toX = totalWidth - beforeWidth;
961 }
962
963 return FloatRect(point.x() + fromX,
964 accountForGlyphBounds ? bounds.y() : point.y(), toX - fromX,
965 accountForGlyphBounds ? bounds.maxY() - bounds.y() : h);
966 }
967
968 int Font::offsetForPositionForSimpleText(const TextRun& run,
969 float x,
970 bool includePartialGlyphs) const {
971 float delta = x;
972
973 SimpleShaper shaper(this, run);
974 unsigned offset;
975 if (run.rtl()) {
976 delta -= floatWidthForSimpleText(run);
977 while (1) {
978 offset = shaper.currentOffset();
979 float w;
980 if (!shaper.advanceOneCharacter(w))
981 break;
982 delta += w;
983 if (includePartialGlyphs) {
984 if (delta - w / 2 >= 0)
985 break;
986 } else {
987 if (delta >= 0)
988 break;
989 }
990 }
991 } else {
992 while (1) {
993 offset = shaper.currentOffset();
994 float w;
995 if (!shaper.advanceOneCharacter(w))
996 break;
997 delta -= w;
998 if (includePartialGlyphs) {
999 if (delta + w / 2 <= 0)
1000 break;
1001 } else {
1002 if (delta <= 0)
1003 break;
1004 }
1005 }
1006 }
1007
1008 return offset;
1009 }
1010
1011 bool Font::loadingCustomFonts() const { 646 bool Font::loadingCustomFonts() const {
1012 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); 647 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
1013 } 648 }
1014 649
1015 bool Font::isFallbackValid() const { 650 bool Font::isFallbackValid() const {
1016 return !m_fontFallbackList || m_fontFallbackList->isValid(); 651 return !m_fontFallbackList || m_fontFallbackList->isValid();
1017 } 652 }
1018 653
1019 } // namespace blink 654 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/fonts/Font.h ('k') | third_party/WebKit/Source/platform/fonts/GlyphBufferTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698