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 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr,
but it ends up | 96 // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr,
but it ends up |
97 // being reasonably safe (because inherited fonts in the render tree pick up
the new | 97 // being reasonably safe (because inherited fonts in the render tree pick up
the new |
98 // style anyway. Other copies are transient, e.g., the state in the Graphics
Context, and | 98 // style anyway. Other copies are transient, e.g., the state in the Graphics
Context, and |
99 // won't stick around long enough to get you in trouble). Still, this is pre
tty disgusting, | 99 // won't stick around long enough to get you in trouble). Still, this is pre
tty disgusting, |
100 // and could eventually be rectified by using RefPtrs for Fonts themselves. | 100 // and could eventually be rectified by using RefPtrs for Fonts themselves. |
101 if (!m_fontFallbackList) | 101 if (!m_fontFallbackList) |
102 m_fontFallbackList = FontFallbackList::create(); | 102 m_fontFallbackList = FontFallbackList::create(); |
103 m_fontFallbackList->invalidate(fontSelector); | 103 m_fontFallbackList->invalidate(fontSelector); |
104 } | 104 } |
105 | 105 |
106 void Font::drawText(GraphicsContext* context, const TextRunPaintInfo& runInfo, c
onst FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction) const | 106 float Font::drawText(GraphicsContext* context, const TextRunPaintInfo& runInfo,
const FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction) cons
t |
107 { | 107 { |
108 // Don't draw anything while we are using custom fonts that are in the proce
ss of loading, | 108 // Don't draw anything while we are using custom fonts that are in the proce
ss of loading, |
109 // except if the 'force' argument is set to true (in which case it will use
a fallback | 109 // except if the 'force' argument is set to true (in which case it will use
a fallback |
110 // font). | 110 // font). |
111 if (shouldSkipDrawing() && customFontNotReadyAction == DoNotPaintIfFontNotRe
ady) | 111 if (shouldSkipDrawing() && customFontNotReadyAction == DoNotPaintIfFontNotRe
ady) |
112 return; | 112 return 0; |
113 | 113 |
114 CodePath codePathToUse = codePath(runInfo.run); | 114 CodePath codePathToUse = codePath(runInfo.run); |
115 // FIXME: Use the fast code path once it handles partial runs with kerning a
nd ligatures. See http://webkit.org/b/100050 | 115 // FIXME: Use the fast code path once it handles partial runs with kerning a
nd ligatures. See http://webkit.org/b/100050 |
116 if (codePathToUse != ComplexPath && fontDescription().typesettingFeatures()
&& (runInfo.from || runInfo.to != runInfo.run.length())) | 116 if (codePathToUse != ComplexPath && fontDescription().typesettingFeatures()
&& (runInfo.from || runInfo.to != runInfo.run.length())) |
117 codePathToUse = ComplexPath; | 117 codePathToUse = ComplexPath; |
118 | 118 |
119 if (codePathToUse != ComplexPath) { | 119 if (codePathToUse != ComplexPath) |
120 drawSimpleText(context, runInfo, point); | 120 return drawSimpleText(context, runInfo, point); |
121 } else { | 121 |
122 drawComplexText(context, runInfo, point); | 122 return drawComplexText(context, runInfo, point); |
123 } | |
124 } | 123 } |
125 | 124 |
126 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r
unInfo, const AtomicString& mark, const FloatPoint& point) const | 125 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRunPaintInfo& r
unInfo, const AtomicString& mark, const FloatPoint& point) const |
127 { | 126 { |
128 if (shouldSkipDrawing()) | 127 if (shouldSkipDrawing()) |
129 return; | 128 return; |
130 | 129 |
131 CodePath codePathToUse = codePath(runInfo.run); | 130 CodePath codePathToUse = codePath(runInfo.run); |
132 // FIXME: Use the fast code path once it handles partial runs with kerning a
nd ligatures. See http://webkit.org/b/100050 | 131 // FIXME: Use the fast code path once it handles partial runs with kerning a
nd ligatures. See http://webkit.org/b/100050 |
133 if (codePathToUse != ComplexPath && fontDescription().typesettingFeatures()
&& (runInfo.from || runInfo.to != runInfo.run.length())) | 132 if (codePathToUse != ComplexPath && fontDescription().typesettingFeatures()
&& (runInfo.from || runInfo.to != runInfo.run.length())) |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 it.advance(runInfo.run.length()); | 636 it.advance(runInfo.run.length()); |
638 initialAdvance = it.m_runWidthSoFar - afterWidth; | 637 initialAdvance = it.m_runWidthSoFar - afterWidth; |
639 glyphBuffer.reverse(); | 638 glyphBuffer.reverse(); |
640 } else { | 639 } else { |
641 initialAdvance = beforeWidth; | 640 initialAdvance = beforeWidth; |
642 } | 641 } |
643 | 642 |
644 return initialAdvance; | 643 return initialAdvance; |
645 } | 644 } |
646 | 645 |
647 void Font::drawSimpleText(GraphicsContext* context, const TextRunPaintInfo& runI
nfo, const FloatPoint& point) const | 646 float Font::drawSimpleText(GraphicsContext* context, const TextRunPaintInfo& run
Info, const FloatPoint& point) const |
648 { | 647 { |
649 // This glyph buffer holds our glyphs+advances+font data for each glyph. | 648 // This glyph buffer holds our glyphs+advances+font data for each glyph. |
650 GlyphBuffer glyphBuffer; | 649 GlyphBuffer glyphBuffer; |
651 float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffe
r); | 650 float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffe
r); |
652 ASSERT(!glyphBuffer.hasVerticalAdvances()); | 651 ASSERT(!glyphBuffer.hasVerticalAdvances()); |
653 | 652 |
654 if (glyphBuffer.isEmpty()) | 653 if (glyphBuffer.isEmpty()) |
655 return; | 654 return 0; |
656 | 655 |
657 TextBlobPtr textBlob; | 656 TextBlobPtr textBlob; |
| 657 float advance = 0; |
658 if (RuntimeEnabledFeatures::textBlobEnabled()) { | 658 if (RuntimeEnabledFeatures::textBlobEnabled()) { |
659 // Using text blob causes a small difference in how gradients and | 659 // Using text blob causes a small difference in how gradients and |
660 // patterns are rendered. | 660 // patterns are rendered. |
661 // FIXME: Fix this, most likely in Skia. | 661 // FIXME: Fix this, most likely in Skia. |
662 if (!context->strokeGradient() && !context->strokePattern() && !context-
>fillGradient() && !context->fillPattern()) { | 662 if (!context->strokeGradient() && !context->strokePattern() && !context-
>fillGradient() && !context->fillPattern()) { |
663 FloatRect blobBounds = runInfo.bounds; | 663 FloatRect blobBounds = runInfo.bounds; |
664 blobBounds.moveBy(-point); | 664 blobBounds.moveBy(-point); |
665 textBlob = buildTextBlob(glyphBuffer, initialAdvance, blobBounds); | 665 textBlob = buildTextBlob(glyphBuffer, initialAdvance, blobBounds, ad
vance); |
666 } | 666 } |
667 } | 667 } |
668 | 668 |
669 if (textBlob) { | 669 if (textBlob) { |
670 drawTextBlob(context, textBlob.get(), point.data()); | 670 drawTextBlob(context, textBlob.get(), point.data()); |
671 } else { | 671 return advance; |
672 FloatPoint startPoint(point.x() + initialAdvance, point.y()); | |
673 drawGlyphBuffer(context, runInfo, glyphBuffer, startPoint); | |
674 } | 672 } |
| 673 |
| 674 FloatPoint startPoint(point.x() + initialAdvance, point.y()); |
| 675 return drawGlyphBuffer(context, runInfo, glyphBuffer, startPoint); |
675 } | 676 } |
676 | 677 |
677 void Font::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRu
nPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const | 678 void Font::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRu
nPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const |
678 { | 679 { |
679 GlyphBuffer glyphBuffer; | 680 GlyphBuffer glyphBuffer; |
680 float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffe
r, ForTextEmphasis); | 681 float initialAdvance = getGlyphsAndAdvancesForSimpleText(runInfo, glyphBuffe
r, ForTextEmphasis); |
681 | 682 |
682 if (glyphBuffer.isEmpty()) | 683 if (glyphBuffer.isEmpty()) |
683 return; | 684 return; |
684 | 685 |
685 drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x()
+ initialAdvance, point.y())); | 686 drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x()
+ initialAdvance, point.y())); |
686 } | 687 } |
687 | 688 |
688 void Font::drawGlyphBuffer(GraphicsContext* context, const TextRunPaintInfo& run
Info, const GlyphBuffer& glyphBuffer, const FloatPoint& point) const | 689 float Font::drawGlyphBuffer(GraphicsContext* context, const TextRunPaintInfo& ru
nInfo, const GlyphBuffer& glyphBuffer, const FloatPoint& point) const |
689 { | 690 { |
690 // Draw each contiguous run of glyphs that use the same font data. | 691 // Draw each contiguous run of glyphs that use the same font data. |
691 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0); | 692 const SimpleFontData* fontData = glyphBuffer.fontDataAt(0); |
692 FloatPoint startPoint(point); | 693 FloatPoint startPoint(point); |
693 FloatPoint nextPoint = startPoint + glyphBuffer.advanceAt(0); | 694 FloatPoint nextPoint = startPoint + glyphBuffer.advanceAt(0); |
694 unsigned lastFrom = 0; | 695 unsigned lastFrom = 0; |
695 unsigned nextGlyph = 1; | 696 unsigned nextGlyph = 1; |
696 #if ENABLE(SVG_FONTS) | 697 #if ENABLE(SVG_FONTS) |
697 TextRun::RenderingContext* renderingContext = runInfo.run.renderingContext()
; | 698 TextRun::RenderingContext* renderingContext = runInfo.run.renderingContext()
; |
698 #endif | 699 #endif |
| 700 |
| 701 float widthSoFar = 0; |
| 702 widthSoFar += glyphBuffer.advanceAt(0).width(); |
699 while (nextGlyph < glyphBuffer.size()) { | 703 while (nextGlyph < glyphBuffer.size()) { |
700 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph); | 704 const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph); |
701 | 705 |
702 if (nextFontData != fontData) { | 706 if (nextFontData != fontData) { |
703 #if ENABLE(SVG_FONTS) | 707 #if ENABLE(SVG_FONTS) |
704 if (renderingContext && fontData->isSVGFont()) | 708 if (renderingContext && fontData->isSVGFont()) |
705 renderingContext->drawSVGGlyphs(context, runInfo.run, fontData,
glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint); | 709 renderingContext->drawSVGGlyphs(context, runInfo.run, fontData,
glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint); |
706 else | 710 else |
707 #endif | 711 #endif |
708 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph -
lastFrom, startPoint, runInfo.bounds); | 712 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph -
lastFrom, startPoint, runInfo.bounds); |
709 | 713 |
710 lastFrom = nextGlyph; | 714 lastFrom = nextGlyph; |
711 fontData = nextFontData; | 715 fontData = nextFontData; |
712 startPoint = nextPoint; | 716 startPoint = nextPoint; |
713 } | 717 } |
714 nextPoint += glyphBuffer.advanceAt(nextGlyph); | 718 nextPoint += glyphBuffer.advanceAt(nextGlyph); |
| 719 widthSoFar += glyphBuffer.advanceAt(nextGlyph).width(); |
715 nextGlyph++; | 720 nextGlyph++; |
716 } | 721 } |
717 | 722 |
718 #if ENABLE(SVG_FONTS) | 723 #if ENABLE(SVG_FONTS) |
719 if (renderingContext && fontData->isSVGFont()) | 724 if (renderingContext && fontData->isSVGFont()) |
720 renderingContext->drawSVGGlyphs(context, runInfo.run, fontData, glyphBuf
fer, lastFrom, nextGlyph - lastFrom, startPoint); | 725 renderingContext->drawSVGGlyphs(context, runInfo.run, fontData, glyphBuf
fer, lastFrom, nextGlyph - lastFrom, startPoint); |
721 else | 726 else |
722 #endif | 727 #endif |
723 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFro
m, startPoint, runInfo.bounds); | 728 drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFro
m, startPoint, runInfo.bounds); |
| 729 return widthSoFar; |
724 } | 730 } |
725 | 731 |
726 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph
glyph) | 732 inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph
glyph) |
727 { | 733 { |
728 if (fontData->platformData().orientation() == Horizontal) { | 734 if (fontData->platformData().orientation() == Horizontal) { |
729 FloatRect bounds = fontData->boundsForGlyph(glyph); | 735 FloatRect bounds = fontData->boundsForGlyph(glyph); |
730 return bounds.x() + bounds.width() / 2; | 736 return bounds.x() + bounds.width() / 2; |
731 } | 737 } |
732 // FIXME: Use glyph bounds once they make sense for vertical fonts. | 738 // FIXME: Use glyph bounds once they make sense for vertical fonts. |
733 return fontData->widthForGlyph(glyph) / 2; | 739 return fontData->widthForGlyph(glyph) / 2; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 if (delta <= 0) | 856 if (delta <= 0) |
851 break; | 857 break; |
852 } | 858 } |
853 } | 859 } |
854 } | 860 } |
855 | 861 |
856 return offset; | 862 return offset; |
857 } | 863 } |
858 | 864 |
859 } // namespace blink | 865 } // namespace blink |
OLD | NEW |