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 17 matching lines...) Expand all Loading... | |
28 #include "platform/LayoutUnit.h" | 28 #include "platform/LayoutUnit.h" |
29 #include "platform/RuntimeEnabledFeatures.h" | 29 #include "platform/RuntimeEnabledFeatures.h" |
30 #include "platform/fonts/CharacterRange.h" | 30 #include "platform/fonts/CharacterRange.h" |
31 #include "platform/fonts/FontCache.h" | 31 #include "platform/fonts/FontCache.h" |
32 #include "platform/fonts/FontFallbackIterator.h" | 32 #include "platform/fonts/FontFallbackIterator.h" |
33 #include "platform/fonts/FontFallbackList.h" | 33 #include "platform/fonts/FontFallbackList.h" |
34 #include "platform/fonts/GlyphBuffer.h" | 34 #include "platform/fonts/GlyphBuffer.h" |
35 #include "platform/fonts/SimpleFontData.h" | 35 #include "platform/fonts/SimpleFontData.h" |
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/graphics/paint/PaintCanvas.h" | |
39 #include "platform/graphics/paint/PaintFlags.h" | |
38 #include "platform/text/BidiResolver.h" | 40 #include "platform/text/BidiResolver.h" |
39 #include "platform/text/Character.h" | 41 #include "platform/text/Character.h" |
40 #include "platform/text/TextRun.h" | 42 #include "platform/text/TextRun.h" |
41 #include "platform/text/TextRunIterator.h" | 43 #include "platform/text/TextRunIterator.h" |
42 #include "platform/transforms/AffineTransform.h" | 44 #include "platform/transforms/AffineTransform.h" |
43 #include "third_party/skia/include/core/SkCanvas.h" | |
44 #include "third_party/skia/include/core/SkPaint.h" | 45 #include "third_party/skia/include/core/SkPaint.h" |
45 #include "third_party/skia/include/core/SkTextBlob.h" | 46 #include "third_party/skia/include/core/SkTextBlob.h" |
46 #include "wtf/StdLibExtras.h" | 47 #include "wtf/StdLibExtras.h" |
47 #include "wtf/text/CharacterNames.h" | 48 #include "wtf/text/CharacterNames.h" |
48 #include "wtf/text/Unicode.h" | 49 #include "wtf/text/Unicode.h" |
49 | 50 |
50 using namespace WTF; | 51 using namespace WTF; |
51 using namespace Unicode; | 52 using namespace Unicode; |
52 | 53 |
53 namespace blink { | 54 namespace blink { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run, | 115 width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run, |
115 emphasisData, &glyphBuffer, | 116 emphasisData, &glyphBuffer, |
116 runInfo.from, runInfo.to); | 117 runInfo.from, runInfo.to); |
117 } else { | 118 } else { |
118 width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, &glyphBuffer, | 119 width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, &glyphBuffer, |
119 runInfo.from, runInfo.to); | 120 runInfo.from, runInfo.to); |
120 } | 121 } |
121 return width; | 122 return width; |
122 } | 123 } |
123 | 124 |
124 bool Font::drawText(SkCanvas* canvas, | 125 bool Font::drawText(PaintCanvas* canvas, |
125 const TextRunPaintInfo& runInfo, | 126 const TextRunPaintInfo& runInfo, |
126 const FloatPoint& point, | 127 const FloatPoint& point, |
127 float deviceScaleFactor, | 128 float deviceScaleFactor, |
128 const SkPaint& paint) const { | 129 const PaintFlags& paint) const { |
129 // Don't draw anything while we are using custom fonts that are in the process | 130 // Don't draw anything while we are using custom fonts that are in the process |
130 // of loading. | 131 // of loading. |
131 if (shouldSkipDrawing()) | 132 if (shouldSkipDrawing()) |
132 return false; | 133 return false; |
133 | 134 |
134 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { | 135 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { |
135 // we have a pre-cached blob -- happy joy! | 136 // we have a pre-cached blob -- happy joy! |
136 canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(), | 137 canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(), |
137 paint); | 138 paint); |
138 return true; | 139 return true; |
139 } | 140 } |
140 | 141 |
141 GlyphBuffer glyphBuffer; | 142 GlyphBuffer glyphBuffer; |
142 buildGlyphBuffer(runInfo, glyphBuffer); | 143 buildGlyphBuffer(runInfo, glyphBuffer); |
143 | 144 |
144 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, | 145 drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point, |
145 deviceScaleFactor); | 146 deviceScaleFactor); |
146 return true; | 147 return true; |
147 } | 148 } |
148 | 149 |
149 bool Font::drawBidiText(SkCanvas* canvas, | 150 bool Font::drawBidiText(PaintCanvas* canvas, |
150 const TextRunPaintInfo& runInfo, | 151 const TextRunPaintInfo& runInfo, |
151 const FloatPoint& point, | 152 const FloatPoint& point, |
152 CustomFontNotReadyAction customFontNotReadyAction, | 153 CustomFontNotReadyAction customFontNotReadyAction, |
153 float deviceScaleFactor, | 154 float deviceScaleFactor, |
154 const SkPaint& paint) const { | 155 const PaintFlags& paint) const { |
155 // Don't draw anything while we are using custom fonts that are in the process | 156 // 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 | 157 // of loading, except if the 'force' argument is set to true (in which case it |
157 // will use a fallback font). | 158 // will use a fallback font). |
158 if (shouldSkipDrawing() && | 159 if (shouldSkipDrawing() && |
159 customFontNotReadyAction == DoNotPaintIfFontNotReady) | 160 customFontNotReadyAction == DoNotPaintIfFontNotReady) |
160 return false; | 161 return false; |
161 | 162 |
162 // sub-run painting is not supported for Bidi text. | 163 // sub-run painting is not supported for Bidi text. |
163 const TextRun& run = runInfo.run; | 164 const TextRun& run = runInfo.run; |
164 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); | 165 ASSERT((runInfo.from == 0) && (runInfo.to == run.length())); |
(...skipping 29 matching lines...) Expand all Loading... | |
194 deviceScaleFactor); | 195 deviceScaleFactor); |
195 | 196 |
196 bidiRun = bidiRun->next(); | 197 bidiRun = bidiRun->next(); |
197 currPoint.move(runWidth, 0); | 198 currPoint.move(runWidth, 0); |
198 } | 199 } |
199 | 200 |
200 bidiRuns.deleteRuns(); | 201 bidiRuns.deleteRuns(); |
201 return true; | 202 return true; |
202 } | 203 } |
203 | 204 |
204 void Font::drawEmphasisMarks(SkCanvas* canvas, | 205 void Font::drawEmphasisMarks(PaintCanvas* canvas, |
205 const TextRunPaintInfo& runInfo, | 206 const TextRunPaintInfo& runInfo, |
206 const AtomicString& mark, | 207 const AtomicString& mark, |
207 const FloatPoint& point, | 208 const FloatPoint& point, |
208 float deviceScaleFactor, | 209 float deviceScaleFactor, |
209 const SkPaint& paint) const { | 210 const PaintFlags& paint) const { |
210 if (shouldSkipDrawing()) | 211 if (shouldSkipDrawing()) |
211 return; | 212 return; |
212 | 213 |
213 FontCachePurgePreventer purgePreventer; | 214 FontCachePurgePreventer purgePreventer; |
214 | 215 |
215 GlyphData emphasisGlyphData; | 216 GlyphData emphasisGlyphData; |
216 if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData)) | 217 if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData)) |
217 return; | 218 return; |
218 | 219 |
219 ASSERT(emphasisGlyphData.fontData); | 220 ASSERT(emphasisGlyphData.fontData); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
354 | 355 |
355 SkTextBlobBuilder m_builder; | 356 SkTextBlobBuilder m_builder; |
356 unsigned m_index; | 357 unsigned m_index; |
357 unsigned m_endIndex; | 358 unsigned m_endIndex; |
358 unsigned m_blobCount; | 359 unsigned m_blobCount; |
359 BlobRotation m_rotation; | 360 BlobRotation m_rotation; |
360 }; | 361 }; |
361 | 362 |
362 } // anonymous namespace | 363 } // anonymous namespace |
363 | 364 |
364 void Font::drawGlyphBuffer(SkCanvas* canvas, | 365 void Font::drawGlyphBuffer(PaintCanvas* canvas, |
365 const SkPaint& paint, | 366 const PaintFlags& paint, |
366 const TextRunPaintInfo& runInfo, | 367 const TextRunPaintInfo& runInfo, |
367 const GlyphBuffer& glyphBuffer, | 368 const GlyphBuffer& glyphBuffer, |
368 const FloatPoint& point, | 369 const FloatPoint& point, |
369 float deviceScaleFactor) const { | 370 float deviceScaleFactor) const { |
370 GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor); | 371 GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor); |
371 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; | 372 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; |
372 | 373 |
373 while (!bloberizer.done()) { | 374 while (!bloberizer.done()) { |
374 blob = bloberizer.next(); | 375 blob = bloberizer.next(); |
375 ASSERT(blob.first); | 376 ASSERT(blob.first); |
376 | 377 |
377 SkAutoCanvasRestore autoRestore(canvas, false); | 378 PaintCanvasAutoRestore autoRestore(canvas, false); |
378 if (blob.second == CCWRotation) { | 379 if (blob.second == CCWRotation) { |
379 canvas->save(); | 380 canvas->save(); |
380 | 381 |
381 SkMatrix m; | 382 SkMatrix m; |
382 m.setSinCos(-1, 0, point.x(), point.y()); | 383 m.setSinCos(-1, 0, point.x(), point.y()); |
383 canvas->concat(m); | 384 canvas->concat(m); |
384 } | 385 } |
385 | 386 |
386 canvas->drawTextBlob(blob.first, point.x(), point.y(), paint); | 387 canvas->drawTextBlob(blob.first, point.x(), point.y(), paint); |
387 } | 388 } |
388 | 389 |
389 // Cache results when | 390 // Cache results when |
390 // 1) requested by clients, and | 391 // 1) requested by clients, and |
391 // 2) the glyph buffer is encoded as a single blob, and | 392 // 2) the glyph buffer is encoded as a single blob, and |
392 // 3) the blob is not upright/rotated | 393 // 3) the blob is not upright/rotated |
393 if (runInfo.cachedTextBlob && bloberizer.blobCount() == 1 && | 394 if (runInfo.cachedTextBlob && bloberizer.blobCount() == 1 && |
394 blob.second == NoRotation) { | 395 blob.second == NoRotation) { |
395 ASSERT(!*runInfo.cachedTextBlob); | 396 ASSERT(!*runInfo.cachedTextBlob); |
396 *runInfo.cachedTextBlob = std::move(blob.first); | 397 *runInfo.cachedTextBlob = std::move(blob.first); |
397 ASSERT(*runInfo.cachedTextBlob); | 398 ASSERT(*runInfo.cachedTextBlob); |
398 } | 399 } |
399 } | 400 } |
400 | 401 |
401 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer, | 402 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer, |
402 const Font* font, | 403 const Font* font, |
403 const SkPaint& paint, | 404 const PaintFlags& paint, |
404 float deviceScaleFactor, | 405 float deviceScaleFactor, |
405 const std::tuple<float, float>& bounds, | 406 const std::tuple<float, float>& bounds, |
406 SkScalar* interceptsBuffer) { | 407 SkScalar* interceptsBuffer) { |
407 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; | 408 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; |
408 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor); | 409 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor); |
409 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; | 410 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; |
410 | 411 |
412 SkPaint skPaint = ToSkPaint(paint); | |
danakj
2017/01/20 23:34:14
Why do you wanna SkPaint?
enne (OOO)
2017/01/24 01:51:28
See my comments in comment #1. I'll just remove t
| |
411 int numIntervals = 0; | 413 int numIntervals = 0; |
412 while (!bloberizer.done()) { | 414 while (!bloberizer.done()) { |
413 blob = bloberizer.next(); | 415 blob = bloberizer.next(); |
414 DCHECK(blob.first); | 416 DCHECK(blob.first); |
415 | 417 |
416 // GlyphBufferBloberizer splits for a new blob rotation, but does not split | 418 // GlyphBufferBloberizer splits for a new blob rotation, but does not split |
417 // for a change in font. A TextBlob can contain runs with differing fonts | 419 // for a change in font. A TextBlob can contain runs with differing fonts |
418 // and the getTextBlobIntercepts method handles multiple fonts for us. For | 420 // and the getTextBlobIntercepts method handles multiple fonts for us. For |
419 // upright in vertical blobs we currently have to bail, see crbug.com/655154 | 421 // upright in vertical blobs we currently have to bail, see crbug.com/655154 |
420 if (blob.second == BlobRotation::CCWRotation) | 422 if (blob.second == BlobRotation::CCWRotation) |
421 continue; | 423 continue; |
422 | 424 |
423 SkScalar* offsetInterceptsBuffer = nullptr; | 425 SkScalar* offsetInterceptsBuffer = nullptr; |
424 if (interceptsBuffer) | 426 if (interceptsBuffer) |
425 offsetInterceptsBuffer = &interceptsBuffer[numIntervals]; | 427 offsetInterceptsBuffer = &interceptsBuffer[numIntervals]; |
426 numIntervals += paint.getTextBlobIntercepts(blob.first.get(), boundsArray, | 428 numIntervals += skPaint.getTextBlobIntercepts(blob.first.get(), boundsArray, |
427 offsetInterceptsBuffer); | 429 offsetInterceptsBuffer); |
428 } | 430 } |
429 return numIntervals; | 431 return numIntervals; |
430 } | 432 } |
431 | 433 |
432 void Font::getTextIntercepts(const TextRunPaintInfo& runInfo, | 434 void Font::getTextIntercepts(const TextRunPaintInfo& runInfo, |
433 float deviceScaleFactor, | 435 float deviceScaleFactor, |
434 const SkPaint& paint, | 436 const PaintFlags& paint, |
435 const std::tuple<float, float>& bounds, | 437 const std::tuple<float, float>& bounds, |
436 Vector<TextIntercept>& intercepts) const { | 438 Vector<TextIntercept>& intercepts) const { |
437 if (shouldSkipDrawing()) | 439 if (shouldSkipDrawing()) |
438 return; | 440 return; |
439 | 441 |
442 SkPaint skPaint = ToSkPaint(paint); | |
440 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { | 443 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) { |
441 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; | 444 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; |
442 int numIntervals = paint.getTextBlobIntercepts( | 445 int numIntervals = skPaint.getTextBlobIntercepts( |
443 runInfo.cachedTextBlob->get(), boundsArray, nullptr); | 446 runInfo.cachedTextBlob->get(), boundsArray, nullptr); |
444 if (!numIntervals) | 447 if (!numIntervals) |
445 return; | 448 return; |
446 DCHECK_EQ(numIntervals % 2, 0); | 449 DCHECK_EQ(numIntervals % 2, 0); |
447 intercepts.resize(numIntervals / 2); | 450 intercepts.resize(numIntervals / 2); |
448 paint.getTextBlobIntercepts(runInfo.cachedTextBlob->get(), boundsArray, | 451 skPaint.getTextBlobIntercepts( |
449 reinterpret_cast<SkScalar*>(intercepts.data())); | 452 runInfo.cachedTextBlob->get(), boundsArray, |
453 reinterpret_cast<SkScalar*>(intercepts.data())); | |
450 return; | 454 return; |
451 } | 455 } |
452 | 456 |
453 GlyphBuffer glyphBuffer; | 457 GlyphBuffer glyphBuffer; |
454 // Compute skip-ink exceptions in the GlyphBuffer. | 458 // Compute skip-ink exceptions in the GlyphBuffer. |
455 // Skip the computation if 8Bit(), no such characters in Latin-1. | 459 // Skip the computation if 8Bit(), no such characters in Latin-1. |
456 if (!runInfo.run.is8Bit()) | 460 if (!runInfo.run.is8Bit()) |
457 glyphBuffer.saveSkipInkExceptions(); | 461 glyphBuffer.saveSkipInkExceptions(); |
458 buildGlyphBuffer(runInfo, glyphBuffer); | 462 buildGlyphBuffer(runInfo, glyphBuffer); |
459 | 463 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
636 | 640 |
637 bool Font::loadingCustomFonts() const { | 641 bool Font::loadingCustomFonts() const { |
638 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); | 642 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); |
639 } | 643 } |
640 | 644 |
641 bool Font::isFallbackValid() const { | 645 bool Font::isFallbackValid() const { |
642 return !m_fontFallbackList || m_fontFallbackList->isValid(); | 646 return !m_fontFallbackList || m_fontFallbackList->isValid(); |
643 } | 647 } |
644 | 648 |
645 } // namespace blink | 649 } // namespace blink |
OLD | NEW |