| 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 25 matching lines...) Expand all Loading... |
| 36 #include "platform/fonts/shaping/CachingWordShaper.h" | 36 #include "platform/fonts/shaping/CachingWordShaper.h" |
| 37 #include "platform/geometry/FloatRect.h" | 37 #include "platform/geometry/FloatRect.h" |
| 38 #include "platform/text/BidiResolver.h" | 38 #include "platform/text/BidiResolver.h" |
| 39 #include "platform/text/Character.h" | 39 #include "platform/text/Character.h" |
| 40 #include "platform/text/TextRun.h" | 40 #include "platform/text/TextRun.h" |
| 41 #include "platform/text/TextRunIterator.h" | 41 #include "platform/text/TextRunIterator.h" |
| 42 #include "platform/transforms/AffineTransform.h" | 42 #include "platform/transforms/AffineTransform.h" |
| 43 #include "third_party/skia/include/core/SkCanvas.h" | 43 #include "third_party/skia/include/core/SkCanvas.h" |
| 44 #include "third_party/skia/include/core/SkPaint.h" | 44 #include "third_party/skia/include/core/SkPaint.h" |
| 45 #include "third_party/skia/include/core/SkTextBlob.h" | 45 #include "third_party/skia/include/core/SkTextBlob.h" |
| 46 #include "skia/ext/cdl_canvas.h" |
| 47 #include "skia/ext/cdl_paint.h" |
| 46 #include "wtf/StdLibExtras.h" | 48 #include "wtf/StdLibExtras.h" |
| 47 #include "wtf/text/CharacterNames.h" | 49 #include "wtf/text/CharacterNames.h" |
| 48 #include "wtf/text/Unicode.h" | 50 #include "wtf/text/Unicode.h" |
| 49 | 51 |
| 50 using namespace WTF; | 52 using namespace WTF; |
| 51 using namespace Unicode; | 53 using namespace Unicode; |
| 52 | 54 |
| 53 namespace blink { | 55 namespace blink { |
| 54 | 56 |
| 55 Font::Font() : m_canShapeWordByWord(0), m_shapeWordByWordComputed(0) {} | 57 Font::Font() : m_canShapeWordByWord(0), m_shapeWordByWordComputed(0) {} |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run, | 116 width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run, |
| 115 emphasisData, &glyphBuffer, | 117 emphasisData, &glyphBuffer, |
| 116 runInfo.from, runInfo.to); | 118 runInfo.from, runInfo.to); |
| 117 } else { | 119 } else { |
| 118 width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, &glyphBuffer, | 120 width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, &glyphBuffer, |
| 119 runInfo.from, runInfo.to); | 121 runInfo.from, runInfo.to); |
| 120 } | 122 } |
| 121 return width; | 123 return width; |
| 122 } | 124 } |
| 123 | 125 |
| 124 bool Font::drawText(SkCanvas* canvas, | 126 bool Font::drawText(CdlCanvas* canvas, |
| 125 const TextRunPaintInfo& runInfo, | 127 const TextRunPaintInfo& runInfo, |
| 126 const FloatPoint& point, | 128 const FloatPoint& point, |
| 127 float deviceScaleFactor, | 129 float deviceScaleFactor, |
| 128 const SkPaint& paint) const { | 130 const CdlPaint& paint) const { |
| 129 // Don't draw anything while we are using custom fonts that are in the process | 131 // Don't draw anything while we are using custom fonts that are in the process |
| 130 // of loading. | 132 // of loading. |
| 131 if (shouldSkipDrawing()) | 133 if (shouldSkipDrawing()) |
| 132 return false; | 134 return false; |
| 133 | 135 |
| 134 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { | 136 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { |
| 135 // we have a pre-cached blob -- happy joy! | 137 // we have a pre-cached blob -- happy joy! |
| 136 canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(), | 138 canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(), |
| 137 paint); | 139 paint); |
| 138 return true; | 140 return true; |
| 139 } | 141 } |
| 140 | 142 |
| 141 GlyphBuffer glyphBuffer; | 143 GlyphBuffer glyphBuffer; |
| 142 buildGlyphBuffer(runInfo, glyphBuffer); | 144 buildGlyphBuffer(runInfo, glyphBuffer); |
| 143 | 145 |
| 144 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, | 146 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, |
| 145 deviceScaleFactor); | 147 deviceScaleFactor); |
| 146 return true; | 148 return true; |
| 147 } | 149 } |
| 148 | 150 |
| 149 bool Font::drawBidiText(SkCanvas* canvas, | 151 bool Font::drawBidiText(CdlCanvas* canvas, |
| 150 const TextRunPaintInfo& runInfo, | 152 const TextRunPaintInfo& runInfo, |
| 151 const FloatPoint& point, | 153 const FloatPoint& point, |
| 152 CustomFontNotReadyAction customFontNotReadyAction, | 154 CustomFontNotReadyAction customFontNotReadyAction, |
| 153 float deviceScaleFactor, | 155 float deviceScaleFactor, |
| 154 const SkPaint& paint) const { | 156 const CdlPaint& paint) const { |
| 155 // Don't draw anything while we are using custom fonts that are in the process | 157 // Don't draw anything while we are using custom fonts that are in the process |
| 156 // of loading, except if the 'force' argument is set to true (in which case it | 158 // of loading, except if the 'force' argument is set to true (in which case it |
| 157 // will use a fallback font). | 159 // will use a fallback font). |
| 158 if (shouldSkipDrawing() && | 160 if (shouldSkipDrawing() && |
| 159 customFontNotReadyAction == DoNotPaintIfFontNotReady) | 161 customFontNotReadyAction == DoNotPaintIfFontNotReady) |
| 160 return false; | 162 return false; |
| 161 | 163 |
| 162 // sub-run painting is not supported for Bidi text. | 164 // sub-run painting is not supported for Bidi text. |
| 163 const TextRun& run = runInfo.run; | 165 const TextRun& run = runInfo.run; |
| 164 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); | 166 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 194 deviceScaleFactor); | 196 deviceScaleFactor); |
| 195 | 197 |
| 196 bidiRun = bidiRun->next(); | 198 bidiRun = bidiRun->next(); |
| 197 currPoint.move(runWidth, 0); | 199 currPoint.move(runWidth, 0); |
| 198 } | 200 } |
| 199 | 201 |
| 200 bidiRuns.deleteRuns(); | 202 bidiRuns.deleteRuns(); |
| 201 return true; | 203 return true; |
| 202 } | 204 } |
| 203 | 205 |
| 204 void Font::drawEmphasisMarks(SkCanvas* canvas, | 206 void Font::drawEmphasisMarks(CdlCanvas* canvas, |
| 205 const TextRunPaintInfo& runInfo, | 207 const TextRunPaintInfo& runInfo, |
| 206 const AtomicString& mark, | 208 const AtomicString& mark, |
| 207 const FloatPoint& point, | 209 const FloatPoint& point, |
| 208 float deviceScaleFactor, | 210 float deviceScaleFactor, |
| 209 const SkPaint& paint) const { | 211 const CdlPaint& paint) const { |
| 210 if (shouldSkipDrawing()) | 212 if (shouldSkipDrawing()) |
| 211 return; | 213 return; |
| 212 | 214 |
| 213 FontCachePurgePreventer purgePreventer; | 215 FontCachePurgePreventer purgePreventer; |
| 214 | 216 |
| 215 GlyphData emphasisGlyphData; | 217 GlyphData emphasisGlyphData; |
| 216 if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData)) | 218 if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData)) |
| 217 return; | 219 return; |
| 218 | 220 |
| 219 ASSERT(emphasisGlyphData.fontData); | 221 ASSERT(emphasisGlyphData.fontData); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 const bool m_hasVerticalOffsets; | 344 const bool m_hasVerticalOffsets; |
| 343 | 345 |
| 344 SkTextBlobBuilder m_builder; | 346 SkTextBlobBuilder m_builder; |
| 345 unsigned m_index; | 347 unsigned m_index; |
| 346 unsigned m_blobCount; | 348 unsigned m_blobCount; |
| 347 BlobRotation m_rotation; | 349 BlobRotation m_rotation; |
| 348 }; | 350 }; |
| 349 | 351 |
| 350 } // anonymous namespace | 352 } // anonymous namespace |
| 351 | 353 |
| 352 void Font::drawGlyphBuffer(SkCanvas* canvas, | 354 void Font::drawGlyphBuffer(CdlCanvas* canvas, |
| 353 const SkPaint& paint, | 355 const CdlPaint& paint, |
| 354 const TextRunPaintInfo& runInfo, | 356 const TextRunPaintInfo& runInfo, |
| 355 const GlyphBuffer& glyphBuffer, | 357 const GlyphBuffer& glyphBuffer, |
| 356 const FloatPoint& point, | 358 const FloatPoint& point, |
| 357 float deviceScaleFactor) const { | 359 float deviceScaleFactor) const { |
| 358 GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor); | 360 GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor); |
| 359 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; | 361 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; |
| 360 | 362 |
| 361 while (!bloberizer.done()) { | 363 while (!bloberizer.done()) { |
| 362 blob = bloberizer.next(); | 364 blob = bloberizer.next(); |
| 363 ASSERT(blob.first); | 365 ASSERT(blob.first); |
| 364 | 366 |
| 365 SkAutoCanvasRestore autoRestore(canvas, false); | 367 CdlAutoCanvasRestore autoRestore(canvas, false); |
| 366 if (blob.second == CCWRotation) { | 368 if (blob.second == CCWRotation) { |
| 367 canvas->save(); | 369 canvas->save(); |
| 368 | 370 |
| 369 SkMatrix m; | 371 SkMatrix m; |
| 370 m.setSinCos(-1, 0, point.x(), point.y()); | 372 m.setSinCos(-1, 0, point.x(), point.y()); |
| 371 canvas->concat(m); | 373 canvas->concat(m); |
| 372 } | 374 } |
| 373 | 375 |
| 374 canvas->drawTextBlob(blob.first, point.x(), point.y(), paint); | 376 canvas->drawTextBlob(blob.first, point.x(), point.y(), paint); |
| 375 } | 377 } |
| 376 | 378 |
| 377 // Cache results when | 379 // Cache results when |
| 378 // 1) requested by clients, and | 380 // 1) requested by clients, and |
| 379 // 2) the glyph buffer is encoded as a single blob, and | 381 // 2) the glyph buffer is encoded as a single blob, and |
| 380 // 3) the blob is not upright/rotated | 382 // 3) the blob is not upright/rotated |
| 381 if (runInfo.cachedTextBlob && bloberizer.blobCount() == 1 && | 383 if (runInfo.cachedTextBlob && bloberizer.blobCount() == 1 && |
| 382 blob.second == NoRotation) { | 384 blob.second == NoRotation) { |
| 383 ASSERT(!*runInfo.cachedTextBlob); | 385 ASSERT(!*runInfo.cachedTextBlob); |
| 384 *runInfo.cachedTextBlob = std::move(blob.first); | 386 *runInfo.cachedTextBlob = std::move(blob.first); |
| 385 ASSERT(*runInfo.cachedTextBlob); | 387 ASSERT(*runInfo.cachedTextBlob); |
| 386 } | 388 } |
| 387 } | 389 } |
| 388 | 390 |
| 389 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer, | 391 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer, |
| 390 const Font* font, | 392 const Font* font, |
| 391 const SkPaint& paint, | 393 const CdlPaint& paint, |
| 392 float deviceScaleFactor, | 394 float deviceScaleFactor, |
| 393 const std::tuple<float, float>& bounds, | 395 const std::tuple<float, float>& bounds, |
| 394 SkScalar* interceptsBuffer) { | 396 SkScalar* interceptsBuffer) { |
| 395 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; | 397 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; |
| 396 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor); | 398 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor); |
| 397 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; | 399 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; |
| 398 | 400 |
| 401 SkPaint skPaint = ToSkPaint(paint); |
| 399 int numIntervals = 0; | 402 int numIntervals = 0; |
| 400 while (!bloberizer.done()) { | 403 while (!bloberizer.done()) { |
| 401 blob = bloberizer.next(); | 404 blob = bloberizer.next(); |
| 402 DCHECK(blob.first); | 405 DCHECK(blob.first); |
| 403 | 406 |
| 404 // GlyphBufferBloberizer splits for a new blob rotation, but does not split | 407 // GlyphBufferBloberizer splits for a new blob rotation, but does not split |
| 405 // for a change in font. A TextBlob can contain runs with differing fonts | 408 // for a change in font. A TextBlob can contain runs with differing fonts |
| 406 // and the getTextBlobIntercepts method handles multiple fonts for us. For | 409 // and the getTextBlobIntercepts method handles multiple fonts for us. For |
| 407 // upright in vertical blobs we currently have to bail, see crbug.com/655154 | 410 // upright in vertical blobs we currently have to bail, see crbug.com/655154 |
| 408 if (blob.second == BlobRotation::CCWRotation) | 411 if (blob.second == BlobRotation::CCWRotation) |
| 409 continue; | 412 continue; |
| 410 | 413 |
| 411 SkScalar* offsetInterceptsBuffer = nullptr; | 414 SkScalar* offsetInterceptsBuffer = nullptr; |
| 412 if (interceptsBuffer) | 415 if (interceptsBuffer) |
| 413 offsetInterceptsBuffer = &interceptsBuffer[numIntervals]; | 416 offsetInterceptsBuffer = &interceptsBuffer[numIntervals]; |
| 414 numIntervals += paint.getTextBlobIntercepts(blob.first.get(), boundsArray, | 417 numIntervals += skPaint.getTextBlobIntercepts(blob.first.get(), boundsArray, |
| 415 offsetInterceptsBuffer); | 418 offsetInterceptsBuffer); |
| 416 } | 419 } |
| 417 return numIntervals; | 420 return numIntervals; |
| 418 } | 421 } |
| 419 | 422 |
| 420 void Font::getTextIntercepts(const TextRunPaintInfo& runInfo, | 423 void Font::getTextIntercepts(const TextRunPaintInfo& runInfo, |
| 421 float deviceScaleFactor, | 424 float deviceScaleFactor, |
| 422 const SkPaint& paint, | 425 const CdlPaint& paint, |
| 423 const std::tuple<float, float>& bounds, | 426 const std::tuple<float, float>& bounds, |
| 424 Vector<TextIntercept>& intercepts) const { | 427 Vector<TextIntercept>& intercepts) const { |
| 425 if (shouldSkipDrawing()) | 428 if (shouldSkipDrawing()) |
| 426 return; | 429 return; |
| 427 | 430 |
| 431 SkPaint skPaint = ToSkPaint(paint); |
| 428 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { | 432 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { |
| 429 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; | 433 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; |
| 430 int numIntervals = paint.getTextBlobIntercepts( | 434 int numIntervals = skPaint.getTextBlobIntercepts( |
| 431 runInfo.cachedTextBlob->get(), boundsArray, nullptr); | 435 runInfo.cachedTextBlob->get(), boundsArray, nullptr); |
| 432 if (!numIntervals) | 436 if (!numIntervals) |
| 433 return; | 437 return; |
| 434 DCHECK_EQ(numIntervals % 2, 0); | 438 DCHECK_EQ(numIntervals % 2, 0); |
| 435 intercepts.resize(numIntervals / 2); | 439 intercepts.resize(numIntervals / 2); |
| 436 paint.getTextBlobIntercepts(runInfo.cachedTextBlob->get(), boundsArray, | 440 skPaint.getTextBlobIntercepts( |
| 437 reinterpret_cast<SkScalar*>(intercepts.data())); | 441 runInfo.cachedTextBlob->get(), boundsArray, |
| 442 reinterpret_cast<SkScalar*>(intercepts.data())); |
| 438 return; | 443 return; |
| 439 } | 444 } |
| 440 | 445 |
| 441 GlyphBuffer glyphBuffer; | 446 GlyphBuffer glyphBuffer; |
| 442 buildGlyphBuffer(runInfo, glyphBuffer); | 447 buildGlyphBuffer(runInfo, glyphBuffer); |
| 443 | 448 |
| 444 // Get the number of intervals, without copying the actual values by | 449 // Get the number of intervals, without copying the actual values by |
| 445 // specifying nullptr for the buffer, following the Skia allocation model for | 450 // specifying nullptr for the buffer, following the Skia allocation model for |
| 446 // retrieving text intercepts. | 451 // retrieving text intercepts. |
| 447 int numIntervals = getInterceptsFromBloberizer( | 452 int numIntervals = getInterceptsFromBloberizer( |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 | 625 |
| 621 bool Font::loadingCustomFonts() const { | 626 bool Font::loadingCustomFonts() const { |
| 622 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); | 627 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); |
| 623 } | 628 } |
| 624 | 629 |
| 625 bool Font::isFallbackValid() const { | 630 bool Font::isFallbackValid() const { |
| 626 return !m_fontFallbackList || m_fontFallbackList->isValid(); | 631 return !m_fontFallbackList || m_fontFallbackList->isValid(); |
| 627 } | 632 } |
| 628 | 633 |
| 629 } // namespace blink | 634 } // namespace blink |
| OLD | NEW |