Source/WebCore/ChangeLog

 12012-07-26 Kenichi Ishibashi <bashi@chromium.org>
 2
 3 [Chromium] HarfBuzzShaper can't handle segmented text run
 4 https://bugs.webkit.org/show_bug.cgi?id=92445
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Pass the range to be displayed to HarfBuzzShaper. The shaper calculates positions and advances of each glyph
 9 regardless of the range, but only add glyphs which are in the range.
 10
 11 No new tests. platform/chromium-linux/fast/text/international/draw-complex-text-from-to.html should
 12 work as expected once we move to use harfbuzz-ng on linux. Note that the current expectation will need to be rebaselined
 13 because the old hb shaper (ComplexTextController) mishandles the range. |to| should be exclusive. I'll rebaseline
 14 the expectation later.
 15
 16 * platform/graphics/harfbuzz/FontHarfBuzz.cpp:
 17 (WebCore::Font::drawComplexText): Call shaper.setDrawRange().
 18 * platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp:
 19 (WebCore::HarfBuzzShaper::HarfBuzzShaper):
 20 (WebCore::HarfBuzzShaper::setDrawRange): Added.
 21 (WebCore):
 22 (WebCore::HarfBuzzShaper::shouldDrawCharacter): Added.
 23 (WebCore::HarfBuzzShaper::shapeHarfBuzzRuns): Added variables that hold pending advances.
 24 (WebCore::HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun): Add only glyphs which are in the given range to glyphBuffer.
 25 * platform/graphics/harfbuzz/ng/HarfBuzzShaper.h:
 26 (HarfBuzzShaper):
 27 * platform/graphics/mac/FontComplexTextMac.cpp:
 28 (WebCore::Font::drawComplexText): Call shaper.setDrawRange().
 29
1302012-07-26 Chang Shu <cshu@webkit.org>
231
332 Support constructor-type static readonly attribute for CodeGenerator.

Source/WebCore/platform/graphics/harfbuzz/FontHarfBuzz.cpp

@@void Font::drawComplexText(GraphicsContext* gc, const TextRun& run,
185185#if USE(HARFBUZZ_NG)
186186 GlyphBuffer glyphBuffer;
187187 HarfBuzzShaper shaper(this, run);
 188 shaper.setDrawRange(from, to);
188189 if (!shaper.shape(&glyphBuffer))
189190 return;
190191 FloatPoint adjustedPoint = shaper.adjustStartPoint(point);

Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp

@@static void normalizeCharacters(const UChar* source, UChar* destination, int len
167167
168168HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run)
169169 : HarfBuzzShaperBase(font, run)
 170 , m_fromIndex(0)
 171 , m_toIndex(m_run.length())
170172{
171173 m_normalizedBuffer = adoptArrayPtr(new UChar[m_run.length() + 1]);
172174 m_normalizedBufferLength = m_run.length();

@@HarfBuzzShaper::~HarfBuzzShaper()
179181{
180182}
181183
 184void HarfBuzzShaper::setDrawRange(int from, int to)
 185{
 186 ASSERT(from >= 0);
 187 ASSERT(to <= m_run.length());
 188 m_fromIndex = from;
 189 m_toIndex = to;
 190}
 191
 192bool HarfBuzzShaper::shouldDrawCharacter(int index)
 193{
 194 return index >= m_fromIndex && index < m_toIndex;
 195}
 196
182197void HarfBuzzShaper::setFontFeatures()
183198{
184199 FontFeatureSettings* settings = m_font->fontDescription().featureSettings();

@@bool HarfBuzzShaper::collectHarfBuzzRuns()
254269bool HarfBuzzShaper::shapeHarfBuzzRuns(GlyphBuffer* glyphBuffer)
255270{
256271 HarfBuzzScopedPtr<hb_buffer_t> harfbuzzBuffer(hb_buffer_create(), hb_buffer_destroy);
 272 float pendingGlyphAdvanceX = 0;
 273 float pendingGlyphAdvanceY = 0;
 274
257275 hb_buffer_set_unicode_funcs(harfbuzzBuffer.get(), hb_icu_get_unicode_funcs());
258276 if (m_run.directionalOverride())
259277 hb_buffer_set_direction(harfbuzzBuffer.get(), m_run.rtl() ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);

@@bool HarfBuzzShaper::shapeHarfBuzzRuns(GlyphBuffer* glyphBuffer)
279297 hb_shape(harfbuzzFont.get(), harfbuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size());
280298
281299 currentRun->applyShapeResult(harfbuzzBuffer.get());
282  setGlyphPositionsForHarfBuzzRun(currentRun, i, harfbuzzBuffer.get(), glyphBuffer);
 300 setGlyphPositionsForHarfBuzzRun(currentRun, i, harfbuzzBuffer.get(), glyphBuffer, pendingGlyphAdvanceX, pendingGlyphAdvanceY);
283301
284302 hb_buffer_reset(harfbuzzBuffer.get());
285303 if (m_run.directionalOverride())

@@bool HarfBuzzShaper::shapeHarfBuzzRuns(GlyphBuffer* glyphBuffer)
288306 return true;
289307}
290308
291 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, unsigned runIndexInVisualOrder, hb_buffer_t* harfbuzzBuffer, GlyphBuffer* glyphBuffer)
 309void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, unsigned runIndexInVisualOrder, hb_buffer_t* harfbuzzBuffer, GlyphBuffer* glyphBuffer, float& pendingGlyphAdvanceX, float& pendingGlyphAdvanceY)
292310{
293311 const SimpleFontData* currentFontData = currentRun->fontData();
294312 hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(harfbuzzBuffer, 0);

@@void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, un
317335
318336 if (currentFontData->isZeroWidthSpaceGlyph(glyph)) {
319337 currentRun->setGlyphAndAdvance(i, glyph, 0);
320  if (glyphBuffer)
 338 if (glyphBuffer && shouldDrawCharacter(currentCharacterIndex))
321339 glyphBuffer->add(glyph, currentFontData, createGlyphBufferAdvance(0, 0));
322340 continue;
323341 }

@@void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, un
330348 m_startOffset.set(offsetX, offsetY);
331349 float glyphAdvanceX = advance + nextOffsetX - offsetX;
332350 float glyphAdvanceY = nextOffsetY - offsetY;
333  glyphBuffer->add(glyph, currentFontData, createGlyphBufferAdvance(glyphAdvanceX, glyphAdvanceY));
 351 if (shouldDrawCharacter(currentCharacterIndex)) {
 352 glyphAdvanceX += pendingGlyphAdvanceX;
 353 glyphAdvanceY += pendingGlyphAdvanceY;
 354 pendingGlyphAdvanceX = 0;
 355 pendingGlyphAdvanceY = 0;
 356 glyphBuffer->add(glyph, currentFontData, createGlyphBufferAdvance(glyphAdvanceX, glyphAdvanceY));
 357 } else {
 358 pendingGlyphAdvanceX += glyphAdvanceX;
 359 pendingGlyphAdvanceY += glyphAdvanceY;
 360 }
334361 }
335362
336363 totalAdvance += advance;

Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.h

@@public:
5151 HarfBuzzShaper(const Font*, const TextRun&);
5252 virtual ~HarfBuzzShaper();
5353
 54 void setDrawRange(int from, int to);
5455 bool shape(GlyphBuffer* = 0);
5556 FloatPoint adjustStartPoint(const FloatPoint&);
5657 float totalWidth() { return m_totalWidth; }

@@private:
9697 float m_width;
9798 };
9899
 100 bool shouldDrawCharacter(int index);
99101 void setFontFeatures();
100102
101103 bool collectHarfBuzzRuns();
102104 bool shapeHarfBuzzRuns(GlyphBuffer*);
103  void setGlyphPositionsForHarfBuzzRun(HarfBuzzRun*, unsigned runIndexInVisualOrder, hb_buffer_t*, GlyphBuffer*);
 105 void setGlyphPositionsForHarfBuzzRun(HarfBuzzRun*, unsigned runIndexInVisualOrder, hb_buffer_t*, GlyphBuffer*, float& pendingGlyphAdvanceX, float& pendingGlyphAdvanceY);
104106
105107 GlyphBufferAdvance createGlyphBufferAdvance(float, float);
106108

@@private:
109111
110112 FloatPoint m_startOffset;
111113
 114 int m_fromIndex;
 115 int m_toIndex;
 116
112117 float m_totalWidth;
113118};
114119

Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp

@@void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
105105 if (preferHarfBuzz(this)) {
106106 GlyphBuffer glyphBuffer;
107107 HarfBuzzShaper shaper(this, run);
 108 shaper.setDrawRange(from, to);
108109 if (shaper.shape(&glyphBuffer)) {
109110 drawGlyphBuffer(context, run, glyphBuffer, point);
110111 return;