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

Side by Side Diff: Source/platform/fonts/mac/FontComplexTextMac.cpp

Issue 175253002: Switch to HarfBuzz on Mac and remove CoreText shaper (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fighting trunk TestExpectation changes Created 6 years, 2 months 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
(Empty)
1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN Y
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN Y
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O N
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include "config.h"
26 #include "platform/fonts/Font.h"
27
28 #include "platform/fonts/Character.h"
29 #include "platform/fonts/FontFallbackList.h"
30 #include "platform/fonts/GlyphBuffer.h"
31 #include "platform/fonts/SimpleFontData.h"
32 #include "platform/fonts/harfbuzz/HarfBuzzShaper.h"
33 #include "platform/fonts/mac/ComplexTextController.h"
34 #include "platform/geometry/IntRect.h"
35 #include "platform/graphics/GraphicsContext.h"
36 #include "platform/text/TextRun.h"
37 #include "wtf/MathExtras.h"
38
39 namespace blink {
40
41 static bool preferHarfBuzz(const Font* font)
42 {
43 const FontDescription& description = font->fontDescription();
44 return description.featureSettings() && description.featureSettings()->size( ) > 0;
45 }
46
47 FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint & point, int h,
48 int from, int to) const
49 {
50 if (preferHarfBuzz(this)) {
51 HarfBuzzShaper shaper(this, run);
52 if (shaper.shape())
53 return shaper.selectionRect(point, h, from, to);
54 }
55 ComplexTextController controller(this, run);
56 controller.advance(from);
57 float beforeWidth = controller.runWidthSoFar();
58 controller.advance(to);
59 float afterWidth = controller.runWidthSoFar();
60
61 // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning
62 if (run.rtl()) {
63 float totalWidth = controller.totalWidth();
64 return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h);
65 }
66
67 return FloatRect(floorf(point.x() + beforeWidth), point.y(), roundf(point.x( ) + afterWidth) - floorf(point.x() + beforeWidth), h);
68 }
69
70 float Font::getGlyphsAndAdvancesForComplexText(const TextRunPaintInfo& runInfo, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
71 {
72 float initialAdvance;
73
74 ComplexTextController controller(this, runInfo.run, false, 0, forTextEmphasi s);
75 controller.advance(runInfo.from);
76 float beforeWidth = controller.runWidthSoFar();
77 controller.advance(runInfo.to, &glyphBuffer);
78
79 if (glyphBuffer.isEmpty())
80 return 0;
81
82 float afterWidth = controller.runWidthSoFar();
83
84 if (runInfo.run.rtl()) {
85 initialAdvance = controller.totalWidth() - afterWidth;
86 glyphBuffer.reverse();
87 } else
88 initialAdvance = beforeWidth;
89
90 return initialAdvance;
91 }
92
93 float Font::drawComplexText(GraphicsContext* context, const TextRunPaintInfo& ru nInfo, const FloatPoint& point) const
94 {
95 if (preferHarfBuzz(this)) {
96 GlyphBuffer glyphBuffer;
97 HarfBuzzShaper shaper(this, runInfo.run);
98 shaper.setDrawRange(runInfo.from, runInfo.to);
99 if (shaper.shape(&glyphBuffer)) {
100 return drawGlyphBuffer(context, runInfo, glyphBuffer, point);
101 }
102 }
103 // This glyph buffer holds our glyphs + advances + font data for each glyph.
104 GlyphBuffer glyphBuffer;
105
106 float startX = point.x() + getGlyphsAndAdvancesForComplexText(runInfo, glyph Buffer);
107
108 // We couldn't generate any glyphs for the run. Give up.
109 if (glyphBuffer.isEmpty())
110 return 0;
111
112 // Draw the glyph buffer now at the starting point returned in startX.
113 FloatPoint startPoint(startX, point.y());
114 return drawGlyphBuffer(context, runInfo, glyphBuffer, startPoint);
115 }
116
117 void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextR unPaintInfo& runInfo, const AtomicString& mark, const FloatPoint& point) const
118 {
119 GlyphBuffer glyphBuffer;
120 float initialAdvance = getGlyphsAndAdvancesForComplexText(runInfo, glyphBuff er, ForTextEmphasis);
121
122 if (glyphBuffer.isEmpty())
123 return;
124
125 drawEmphasisMarks(context, runInfo, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
126 }
127
128 float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon tData*>* fallbackFonts, IntRectExtent* glyphBounds) const
129 {
130 if (preferHarfBuzz(this)) {
131 HarfBuzzShaper shaper(this, run);
132 if (shaper.shape())
133 return shaper.totalWidth();
134 }
135 ComplexTextController controller(this, run, true, fallbackFonts);
136 glyphBounds->setTop(floorf(-controller.minGlyphBoundingBoxY()));
137 glyphBounds->setBottom(ceilf(controller.maxGlyphBoundingBoxY()));
138 glyphBounds->setLeft(std::max<int>(0, floorf(-controller.minGlyphBoundingBox X())));
139 glyphBounds->setRight(std::max<int>(0, ceilf(controller.maxGlyphBoundingBoxX () - controller.totalWidth())));
140
141 return controller.totalWidth();
142 }
143
144 int Font::offsetForPositionForComplexText(const TextRun& run, float x, bool incl udePartialGlyphs) const
145 {
146 if (preferHarfBuzz(this)) {
147 HarfBuzzShaper shaper(this, run);
148 if (shaper.shape())
149 return shaper.offsetForPosition(x);
150 }
151 ComplexTextController controller(this, run);
152 return controller.offsetForPosition(x, includePartialGlyphs);
153 }
154
155 const SimpleFontData* Font::fontDataForCombiningCharacterSequence(const UChar* c haracters, size_t length, FontDataVariant variant) const
156 {
157 UChar32 baseCharacter;
158 size_t baseCharacterLength = 0;
159 U16_NEXT(characters, baseCharacterLength, length, baseCharacter);
160
161 GlyphData baseCharacterGlyphData = glyphDataForCharacter(baseCharacter, fals e, false, variant);
162
163 if (!baseCharacterGlyphData.glyph)
164 return 0;
165
166 if (length == baseCharacterLength)
167 return baseCharacterGlyphData.fontData;
168
169 bool triedBaseCharacterFontData = false;
170
171 unsigned i = 0;
172 for (const FontData* fontData = fontDataAt(0); fontData; fontData = fontData At(++i)) {
173 const SimpleFontData* simpleFontData = fontData->fontDataForCharacter(ba seCharacter);
174 if (variant == NormalVariant) {
175 if (simpleFontData->platformData().orientation() == Vertical) {
176 if (Character::isCJKIdeographOrSymbol(baseCharacter) && !simpleF ontData->hasVerticalGlyphs()) {
177 variant = BrokenIdeographVariant;
178 simpleFontData = simpleFontData->brokenIdeographFontData().g et();
179 } else if (m_fontDescription.nonCJKGlyphOrientation() == NonCJKG lyphOrientationVerticalRight) {
180 SimpleFontData* verticalRightFontData = simpleFontData->vert icalRightOrientationFontData().get();
181 Glyph verticalRightGlyph = verticalRightFontData->glyphForCh aracter(baseCharacter);
182 if (verticalRightGlyph == baseCharacterGlyphData.glyph)
183 simpleFontData = verticalRightFontData;
184 } else {
185 SimpleFontData* uprightFontData = simpleFontData->uprightOri entationFontData().get();
186 Glyph uprightGlyph = uprightFontData->glyphForCharacter(base Character);
187 if (uprightGlyph != baseCharacterGlyphData.glyph)
188 simpleFontData = uprightFontData;
189 }
190 }
191 } else {
192 if (const SimpleFontData* variantFontData = simpleFontData->variantF ontData(m_fontDescription, variant).get())
193 simpleFontData = variantFontData;
194 }
195
196 if (simpleFontData == baseCharacterGlyphData.fontData)
197 triedBaseCharacterFontData = true;
198
199 if (simpleFontData->canRenderCombiningCharacterSequence(characters, leng th))
200 return simpleFontData;
201 }
202
203 if (!triedBaseCharacterFontData && baseCharacterGlyphData.fontData && baseCh aracterGlyphData.fontData->canRenderCombiningCharacterSequence(characters, lengt h))
204 return baseCharacterGlyphData.fontData;
205
206 return SimpleFontData::systemFallback();
207 }
208
209 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/fonts/mac/ComplexTextControllerCoreText.mm ('k') | Source/platform/fonts/mac/FontMac.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698