Chromium Code Reviews| 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 (m_fontFallbackList ? m_fontFallbackList->fontSelectorVersion() : 0) == | 92 (m_fontFallbackList ? m_fontFallbackList->fontSelectorVersion() : 0) == |
| 93 (other.m_fontFallbackList | 93 (other.m_fontFallbackList |
| 94 ? other.m_fontFallbackList->fontSelectorVersion() | 94 ? other.m_fontFallbackList->fontSelectorVersion() |
| 95 : 0) && | 95 : 0) && |
| 96 (m_fontFallbackList ? m_fontFallbackList->generation() : 0) == | 96 (m_fontFallbackList ? m_fontFallbackList->generation() : 0) == |
| 97 (other.m_fontFallbackList ? other.m_fontFallbackList->generation() | 97 (other.m_fontFallbackList ? other.m_fontFallbackList->generation() |
| 98 : 0); | 98 : 0); |
| 99 } | 99 } |
| 100 | 100 |
| 101 void Font::update(FontSelector* fontSelector) const { | 101 void Font::update(FontSelector* fontSelector) const { |
| 102 // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr, b ut it ends up | 102 // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr, |
| 103 // being reasonably safe (because inherited fonts in the render tree pick up t he new | 103 // but it ends up being reasonably safe (because inherited fonts in the render |
| 104 // style anyway. Other copies are transient, e.g., the state in the GraphicsCo ntext, and | 104 // tree pick up the new style anyway. Other copies are transient, e.g., the |
| 105 // won't stick around long enough to get you in trouble). Still, this is prett y disgusting, | 105 // state in the GraphicsContext, and won't stick around long enough to get you |
| 106 // and could eventually be rectified by using RefPtrs for Fonts themselves. | 106 // in trouble). Still, this is pretty disgusting, and could eventually be |
| 107 // rectified by using RefPtrs for Fonts themselves. | |
| 107 if (!m_fontFallbackList) | 108 if (!m_fontFallbackList) |
| 108 m_fontFallbackList = FontFallbackList::create(); | 109 m_fontFallbackList = FontFallbackList::create(); |
| 109 m_fontFallbackList->invalidate(fontSelector); | 110 m_fontFallbackList->invalidate(fontSelector); |
| 110 } | 111 } |
| 111 | 112 |
| 112 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, | 113 float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, |
| 113 GlyphBuffer& glyphBuffer, | 114 GlyphBuffer& glyphBuffer, |
| 114 const GlyphData* emphasisData) const { | 115 const GlyphData* emphasisData) const { |
| 115 if (codePath(runInfo) == ComplexPath) { | 116 if (codePath(runInfo) == ComplexPath) { |
| 116 float width; | 117 float width; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 127 return width; | 128 return width; |
| 128 } | 129 } |
| 129 | 130 |
| 130 SimpleShaper shaper(this, runInfo.run, emphasisData, | 131 SimpleShaper shaper(this, runInfo.run, emphasisData, |
| 131 nullptr /* fallbackFonts */, nullptr); | 132 nullptr /* fallbackFonts */, nullptr); |
| 132 shaper.advance(runInfo.from); | 133 shaper.advance(runInfo.from); |
| 133 shaper.advance(runInfo.to, &glyphBuffer); | 134 shaper.advance(runInfo.to, &glyphBuffer); |
| 134 float width = shaper.runWidthSoFar(); | 135 float width = shaper.runWidthSoFar(); |
| 135 | 136 |
| 136 if (runInfo.run.rtl()) { | 137 if (runInfo.run.rtl()) { |
| 137 // Glyphs are shaped & stored in RTL advance order - reverse them for LTR dr awing. | 138 // Glyphs are shaped & stored in RTL advance order - reverse them for LTR |
| 139 // drawing. | |
| 138 shaper.advance(runInfo.run.length()); | 140 shaper.advance(runInfo.run.length()); |
| 139 glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar()); | 141 glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar()); |
| 140 } | 142 } |
| 141 | 143 |
| 142 return width; | 144 return width; |
| 143 } | 145 } |
| 144 | 146 |
| 145 bool Font::drawText(SkCanvas* canvas, | 147 bool Font::drawText(SkCanvas* canvas, |
| 146 const TextRunPaintInfo& runInfo, | 148 const TextRunPaintInfo& runInfo, |
| 147 const FloatPoint& point, | 149 const FloatPoint& point, |
| 148 float deviceScaleFactor, | 150 float deviceScaleFactor, |
| 149 const SkPaint& paint) const { | 151 const SkPaint& paint) const { |
| 150 // Don't draw anything while we are using custom fonts that are in the process of loading. | 152 // Don't draw anything while we are using custom fonts that are in the process |
| 153 // of loading. | |
| 151 if (shouldSkipDrawing()) | 154 if (shouldSkipDrawing()) |
| 152 return false; | 155 return false; |
| 153 | 156 |
| 154 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { | 157 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { |
| 155 // we have a pre-cached blob -- happy joy! | 158 // we have a pre-cached blob -- happy joy! |
| 156 canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(), | 159 canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(), |
| 157 paint); | 160 paint); |
| 158 return true; | 161 return true; |
| 159 } | 162 } |
| 160 | 163 |
| 161 GlyphBuffer glyphBuffer; | 164 GlyphBuffer glyphBuffer; |
| 162 buildGlyphBuffer(runInfo, glyphBuffer); | 165 buildGlyphBuffer(runInfo, glyphBuffer); |
| 163 | 166 |
| 164 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, | 167 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, |
| 165 deviceScaleFactor); | 168 deviceScaleFactor); |
| 166 return true; | 169 return true; |
| 167 } | 170 } |
| 168 | 171 |
| 169 bool Font::drawBidiText(SkCanvas* canvas, | 172 bool Font::drawBidiText(SkCanvas* canvas, |
| 170 const TextRunPaintInfo& runInfo, | 173 const TextRunPaintInfo& runInfo, |
| 171 const FloatPoint& point, | 174 const FloatPoint& point, |
| 172 CustomFontNotReadyAction customFontNotReadyAction, | 175 CustomFontNotReadyAction customFontNotReadyAction, |
| 173 float deviceScaleFactor, | 176 float deviceScaleFactor, |
| 174 const SkPaint& paint) const { | 177 const SkPaint& paint) const { |
| 175 // Don't draw anything while we are using custom fonts that are in the process of loading, | 178 // Don't draw anything while we are using custom fonts that are in the process |
| 176 // except if the 'force' argument is set to true (in which case it will use a fallback | 179 // of loading, except if the 'force' argument is set to true (in which case it |
| 177 // font). | 180 // will use a fallback font). |
| 178 if (shouldSkipDrawing() && | 181 if (shouldSkipDrawing() && |
| 179 customFontNotReadyAction == DoNotPaintIfFontNotReady) | 182 customFontNotReadyAction == DoNotPaintIfFontNotReady) |
| 180 return false; | 183 return false; |
| 181 | 184 |
| 182 // sub-run painting is not supported for Bidi text. | 185 // sub-run painting is not supported for Bidi text. |
| 183 const TextRun& run = runInfo.run; | 186 const TextRun& run = runInfo.run; |
| 184 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); | 187 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); |
| 185 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; | 188 BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; |
| 186 bidiResolver.setStatus( | 189 bidiResolver.setStatus( |
| 187 BidiStatus(run.direction(), run.directionalOverride())); | 190 BidiStatus(run.direction(), run.directionalOverride())); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 ASSERT(!done()); | 292 ASSERT(!done()); |
| 290 const BlobRotation currentRotation = m_rotation; | 293 const BlobRotation currentRotation = m_rotation; |
| 291 | 294 |
| 292 while (m_index < m_buffer.size()) { | 295 while (m_index < m_buffer.size()) { |
| 293 const SimpleFontData* fontData = m_buffer.fontDataAt(m_index); | 296 const SimpleFontData* fontData = m_buffer.fontDataAt(m_index); |
| 294 ASSERT(fontData); | 297 ASSERT(fontData); |
| 295 | 298 |
| 296 const BlobRotation newRotation = computeBlobRotation(fontData); | 299 const BlobRotation newRotation = computeBlobRotation(fontData); |
| 297 if (newRotation != m_rotation) { | 300 if (newRotation != m_rotation) { |
| 298 // We're switching to an orientation which requires a different rotation | 301 // We're switching to an orientation which requires a different rotation |
| 299 // => emit the pending blob (and start a new one with the new rotation ). | 302 // => emit the pending blob (and start a new one with the new |
| 303 // rotation). | |
|
dcheng
2016/10/03 20:41:17
Nit: perhaps indent a bit more so it's lined up wi
Nico
2016/10/03 20:46:56
Done.
| |
| 300 m_rotation = newRotation; | 304 m_rotation = newRotation; |
| 301 break; | 305 break; |
| 302 } | 306 } |
| 303 | 307 |
| 304 const unsigned start = m_index++; | 308 const unsigned start = m_index++; |
| 305 while (m_index < m_buffer.size() && | 309 while (m_index < m_buffer.size() && |
| 306 m_buffer.fontDataAt(m_index) == fontData) | 310 m_buffer.fontDataAt(m_index) == fontData) |
| 307 m_index++; | 311 m_index++; |
| 308 | 312 |
| 309 appendRun(start, m_index - start, fontData); | 313 appendRun(start, m_index - start, fontData); |
| 310 } | 314 } |
| 311 | 315 |
| 312 m_blobCount++; | 316 m_blobCount++; |
| 313 return std::make_pair(m_builder.make(), currentRotation); | 317 return std::make_pair(m_builder.make(), currentRotation); |
| 314 } | 318 } |
| 315 | 319 |
| 316 private: | 320 private: |
| 317 static BlobRotation computeBlobRotation(const SimpleFontData* font) { | 321 static BlobRotation computeBlobRotation(const SimpleFontData* font) { |
| 318 // For vertical upright text we need to compensate the inherited 90deg CW ro tation | 322 // For vertical upright text we need to compensate the inherited 90deg CW |
| 319 // (using a 90deg CCW rotation). | 323 // rotation (using a 90deg CCW rotation). |
| 320 return (font->platformData().isVerticalAnyUpright() && font->verticalData()) | 324 return (font->platformData().isVerticalAnyUpright() && font->verticalData()) |
| 321 ? CCWRotation | 325 ? CCWRotation |
| 322 : NoRotation; | 326 : NoRotation; |
| 323 } | 327 } |
| 324 | 328 |
| 325 void appendRun(unsigned start, | 329 void appendRun(unsigned start, |
| 326 unsigned count, | 330 unsigned count, |
| 327 const SimpleFontData* fontData) { | 331 const SimpleFontData* fontData) { |
| 328 SkPaint paint; | 332 SkPaint paint; |
| 329 fontData->platformData().setupPaint(&paint, m_deviceScaleFactor, m_font); | 333 fontData->platformData().setupPaint(&paint, m_deviceScaleFactor, m_font); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 340 if (m_rotation == NoRotation) { | 344 if (m_rotation == NoRotation) { |
| 341 std::copy(offsets, offsets + (m_hasVerticalOffsets ? 2 * count : count), | 345 std::copy(offsets, offsets + (m_hasVerticalOffsets ? 2 * count : count), |
| 342 buffer.pos); | 346 buffer.pos); |
| 343 } else { | 347 } else { |
| 344 ASSERT(m_hasVerticalOffsets); | 348 ASSERT(m_hasVerticalOffsets); |
| 345 | 349 |
| 346 const float verticalBaselineXOffset = | 350 const float verticalBaselineXOffset = |
| 347 fontData->getFontMetrics().floatAscent() - | 351 fontData->getFontMetrics().floatAscent() - |
| 348 fontData->getFontMetrics().floatAscent(IdeographicBaseline); | 352 fontData->getFontMetrics().floatAscent(IdeographicBaseline); |
| 349 | 353 |
| 350 // TODO(fmalita): why don't we apply this adjustment when building the gly ph buffer? | 354 // TODO(fmalita): why don't we apply this adjustment when building the |
| 355 // glyph buffer? | |
| 351 for (unsigned i = 0; i < 2 * count; i += 2) { | 356 for (unsigned i = 0; i < 2 * count; i += 2) { |
| 352 buffer.pos[i] = SkFloatToScalar(offsets[i] + verticalBaselineXOffset); | 357 buffer.pos[i] = SkFloatToScalar(offsets[i] + verticalBaselineXOffset); |
| 353 buffer.pos[i + 1] = SkFloatToScalar(offsets[i + 1]); | 358 buffer.pos[i + 1] = SkFloatToScalar(offsets[i + 1]); |
| 354 } | 359 } |
| 355 } | 360 } |
| 356 } | 361 } |
| 357 | 362 |
| 358 const GlyphBuffer& m_buffer; | 363 const GlyphBuffer& m_buffer; |
| 359 const Font* m_font; | 364 const Font* m_font; |
| 360 const float m_deviceScaleFactor; | 365 const float m_deviceScaleFactor; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 // FIXME: This really shouldn't be needed but for some reason the | 475 // FIXME: This really shouldn't be needed but for some reason the |
| 471 // TextRendering setting doesn't propagate to typesettingFeatures in time | 476 // TextRendering setting doesn't propagate to typesettingFeatures in time |
| 472 // for the prefs width calculation. | 477 // for the prefs width calculation. |
| 473 if (getFontDescription().textRendering() == OptimizeLegibility || | 478 if (getFontDescription().textRendering() == OptimizeLegibility || |
| 474 getFontDescription().textRendering() == GeometricPrecision) | 479 getFontDescription().textRendering() == GeometricPrecision) |
| 475 return ComplexPath; | 480 return ComplexPath; |
| 476 | 481 |
| 477 if (run.is8Bit()) | 482 if (run.is8Bit()) |
| 478 return SimplePath; | 483 return SimplePath; |
| 479 | 484 |
| 480 // Start from 0 since drawing and highlighting also measure the characters bef ore run->from. | 485 // Start from 0 since drawing and highlighting also measure the characters |
| 486 // before run->from. | |
| 481 return Character::characterRangeCodePath(run.characters16(), run.length()); | 487 return Character::characterRangeCodePath(run.characters16(), run.length()); |
| 482 } | 488 } |
| 483 | 489 |
| 484 bool Font::canShapeWordByWord() const { | 490 bool Font::canShapeWordByWord() const { |
| 485 if (!m_shapeWordByWordComputed) { | 491 if (!m_shapeWordByWordComputed) { |
| 486 m_canShapeWordByWord = computeCanShapeWordByWord(); | 492 m_canShapeWordByWord = computeCanShapeWordByWord(); |
| 487 m_shapeWordByWordComputed = true; | 493 m_shapeWordByWordComputed = true; |
| 488 } | 494 } |
| 489 return m_canShapeWordByWord; | 495 return m_canShapeWordByWord; |
| 490 }; | 496 }; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 515 GlyphData& data, | 521 GlyphData& data, |
| 516 unsigned pageNumber) { | 522 unsigned pageNumber) { |
| 517 if (isUpright) { | 523 if (isUpright) { |
| 518 RefPtr<SimpleFontData> uprightFontData = | 524 RefPtr<SimpleFontData> uprightFontData = |
| 519 data.fontData->uprightOrientationFontData(); | 525 data.fontData->uprightOrientationFontData(); |
| 520 GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getNormalRootChild( | 526 GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getNormalRootChild( |
| 521 uprightFontData.get(), pageNumber); | 527 uprightFontData.get(), pageNumber); |
| 522 GlyphPage* uprightPage = uprightNode->page(); | 528 GlyphPage* uprightPage = uprightNode->page(); |
| 523 if (uprightPage) { | 529 if (uprightPage) { |
| 524 GlyphData uprightData = uprightPage->glyphDataForCharacter(character); | 530 GlyphData uprightData = uprightPage->glyphDataForCharacter(character); |
| 525 // If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright. | 531 // If the glyphs are the same, then we know we can just use the horizontal |
| 532 // glyph rotated vertically to be upright. | |
| 526 if (data.glyph == uprightData.glyph) | 533 if (data.glyph == uprightData.glyph) |
| 527 return data; | 534 return data; |
| 528 // The glyphs are distinct, meaning that the font has a vertical-right gly ph baked into it. We can't use that | 535 // The glyphs are distinct, meaning that the font has a vertical-right |
| 529 // glyph, so we fall back to the upright data and use the horizontal glyph . | 536 // glyph baked into it. We can't use that glyph, so we fall back to the |
| 537 // upright data and use the horizontal glyph. | |
| 530 if (uprightData.fontData) | 538 if (uprightData.fontData) |
| 531 return uprightData; | 539 return uprightData; |
| 532 } | 540 } |
| 533 } else { | 541 } else { |
| 534 RefPtr<SimpleFontData> verticalRightFontData = | 542 RefPtr<SimpleFontData> verticalRightFontData = |
| 535 data.fontData->verticalRightOrientationFontData(); | 543 data.fontData->verticalRightOrientationFontData(); |
| 536 GlyphPageTreeNode* verticalRightNode = | 544 GlyphPageTreeNode* verticalRightNode = |
| 537 GlyphPageTreeNode::getNormalRootChild(verticalRightFontData.get(), | 545 GlyphPageTreeNode::getNormalRootChild(verticalRightFontData.get(), |
| 538 pageNumber); | 546 pageNumber); |
| 539 GlyphPage* verticalRightPage = verticalRightNode->page(); | 547 GlyphPage* verticalRightPage = verticalRightNode->page(); |
| 540 if (verticalRightPage) { | 548 if (verticalRightPage) { |
| 541 GlyphData verticalRightData = | 549 GlyphData verticalRightData = |
| 542 verticalRightPage->glyphDataForCharacter(character); | 550 verticalRightPage->glyphDataForCharacter(character); |
| 543 // If the glyphs are distinct, we will make the assumption that the font h as a vertical-right glyph baked | 551 // If the glyphs are distinct, we will make the assumption that the font |
| 552 // has a vertical-right glyph baked | |
| 544 // into it. | 553 // into it. |
|
dcheng
2016/10/03 20:41:17
Nit: merge this into the previous line.
Nico
2016/10/03 20:46:56
Done.
| |
| 545 if (data.glyph != verticalRightData.glyph) | 554 if (data.glyph != verticalRightData.glyph) |
| 546 return data; | 555 return data; |
| 547 // The glyphs are identical, meaning that we should just use the horizonta l glyph. | 556 // The glyphs are identical, meaning that we should just use the |
| 557 // horizontal glyph. | |
| 548 if (verticalRightData.fontData) | 558 if (verticalRightData.fontData) |
| 549 return verticalRightData; | 559 return verticalRightData; |
| 550 } | 560 } |
| 551 } | 561 } |
| 552 return data; | 562 return data; |
| 553 } | 563 } |
| 554 | 564 |
| 555 PassRefPtr<FontFallbackIterator> Font::createFontFallbackIterator( | 565 PassRefPtr<FontFallbackIterator> Font::createFontFallbackIterator( |
| 556 FontFallbackPriority fallbackPriority) const { | 566 FontFallbackPriority fallbackPriority) const { |
| 557 return FontFallbackIterator::create(m_fontDescription, m_fontFallbackList, | 567 return FontFallbackIterator::create(m_fontDescription, m_fontFallbackList, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 GlyphPageTreeNode* variantNode = | 650 GlyphPageTreeNode* variantNode = |
| 641 GlyphPageTreeNode::getNormalRootChild(variantFontData.get(), | 651 GlyphPageTreeNode::getNormalRootChild(variantFontData.get(), |
| 642 pageNumber); | 652 pageNumber); |
| 643 GlyphPage* variantPage = variantNode->page(); | 653 GlyphPage* variantPage = variantNode->page(); |
| 644 if (variantPage) { | 654 if (variantPage) { |
| 645 GlyphData data = variantPage->glyphDataForCharacter(c); | 655 GlyphData data = variantPage->glyphDataForCharacter(c); |
| 646 if (data.fontData) | 656 if (data.fontData) |
| 647 return data; | 657 return data; |
| 648 } | 658 } |
| 649 | 659 |
| 650 // Do not attempt system fallback off the variantFontData. This is the very unlikely case that | 660 // Do not attempt system fallback off the variantFontData. This is the |
| 651 // a font has the lowercase character but the small caps font does not have its uppercase version. | 661 // very unlikely case that a font has the lowercase character but the |
| 662 // small caps font does not have its uppercase version. | |
| 652 return variantFontData->missingGlyphData(); | 663 return variantFontData->missingGlyphData(); |
| 653 } | 664 } |
| 654 | 665 |
| 655 if (node->isSystemFallback()) | 666 if (node->isSystemFallback()) |
| 656 break; | 667 break; |
| 657 } | 668 } |
| 658 | 669 |
| 659 // Proceed with the fallback list. | 670 // Proceed with the fallback list. |
| 660 node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()), | 671 node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()), |
| 661 pageNumber); | 672 pageNumber); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 return glyphDataForNonCJKCharacterWithGlyphOrientation( | 720 return glyphDataForNonCJKCharacterWithGlyphOrientation( |
| 710 characterToRender, | 721 characterToRender, |
| 711 m_fontDescription.isVerticalUpright(characterToRender), data, | 722 m_fontDescription.isVerticalUpright(characterToRender), data, |
| 712 pageNumberForRendering); | 723 pageNumberForRendering); |
| 713 } | 724 } |
| 714 return data; | 725 return data; |
| 715 } | 726 } |
| 716 } | 727 } |
| 717 | 728 |
| 718 // Even system fallback can fail; use the missing glyph in that case. | 729 // Even system fallback can fail; use the missing glyph in that case. |
| 719 // FIXME: It would be nicer to use the missing glyph from the last resort font instead. | 730 // FIXME: It would be nicer to use the missing glyph from the last resort font |
| 731 // instead. | |
| 720 ASSERT(primaryFont()); | 732 ASSERT(primaryFont()); |
| 721 GlyphData data = primaryFont()->missingGlyphData(); | 733 GlyphData data = primaryFont()->missingGlyphData(); |
| 722 if (variant == NormalVariant) { | 734 if (variant == NormalVariant) { |
| 723 page->setGlyphDataForCharacter(c, data.glyph, data.fontData); | 735 page->setGlyphDataForCharacter(c, data.glyph, data.fontData); |
| 724 data.fontData->setMaxGlyphPageTreeLevel( | 736 data.fontData->setMaxGlyphPageTreeLevel( |
| 725 std::max(data.fontData->maxGlyphPageTreeLevel(), node->level())); | 737 std::max(data.fontData->maxGlyphPageTreeLevel(), node->level())); |
| 726 } | 738 } |
| 727 return data; | 739 return data; |
| 728 } | 740 } |
| 729 | 741 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 } | 815 } |
| 804 | 816 |
| 805 // Return the code point index for the given |x| offset into the text run. | 817 // Return the code point index for the given |x| offset into the text run. |
| 806 int Font::offsetForPositionForComplexText(const TextRun& run, | 818 int Font::offsetForPositionForComplexText(const TextRun& run, |
| 807 float xFloat, | 819 float xFloat, |
| 808 bool includePartialGlyphs) const { | 820 bool includePartialGlyphs) const { |
| 809 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); | 821 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); |
| 810 return shaper.offsetForPosition(this, run, xFloat, includePartialGlyphs); | 822 return shaper.offsetForPosition(this, run, xFloat, includePartialGlyphs); |
| 811 } | 823 } |
| 812 | 824 |
| 813 // Return the rectangle for selecting the given range of code-points in the Text Run. | 825 // Return the rectangle for selecting the given range of code-points in the |
| 826 // TextRun. | |
| 814 FloatRect Font::selectionRectForComplexText(const TextRun& run, | 827 FloatRect Font::selectionRectForComplexText(const TextRun& run, |
| 815 const FloatPoint& point, | 828 const FloatPoint& point, |
| 816 int height, | 829 int height, |
| 817 int from, | 830 int from, |
| 818 int to) const { | 831 int to) const { |
| 819 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); | 832 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); |
| 820 CharacterRange range = shaper.getCharacterRange(this, run, from, to); | 833 CharacterRange range = shaper.getCharacterRange(this, run, from, to); |
| 821 return FloatRect(point.x() + range.start, point.y(), range.width(), height); | 834 return FloatRect(point.x() + range.start, point.y(), range.width(), height); |
| 822 } | 835 } |
| 823 | 836 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 929 | 942 |
| 930 bool Font::loadingCustomFonts() const { | 943 bool Font::loadingCustomFonts() const { |
| 931 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); | 944 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); |
| 932 } | 945 } |
| 933 | 946 |
| 934 bool Font::isFallbackValid() const { | 947 bool Font::isFallbackValid() const { |
| 935 return !m_fontFallbackList || m_fontFallbackList->isValid(); | 948 return !m_fontFallbackList || m_fontFallbackList->isValid(); |
| 936 } | 949 } |
| 937 | 950 |
| 938 } // namespace blink | 951 } // namespace blink |
| OLD | NEW |