| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2008, 2010 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2006 Alexey Proskuryakov | 3 * Copyright (C) 2006 Alexey Proskuryakov |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * | 8 * |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 */ | 28 */ |
| 29 | 29 |
| 30 #include "platform/fonts/SimpleFontData.h" | 30 #include "platform/fonts/SimpleFontData.h" |
| 31 | 31 |
| 32 #include "SkPaint.h" | |
| 33 #include "SkPath.h" | 32 #include "SkPath.h" |
| 34 #include "SkTypeface.h" | 33 #include "SkTypeface.h" |
| 35 #include "SkTypes.h" | 34 #include "SkTypes.h" |
| 36 #include "platform/fonts/FontDescription.h" | 35 #include "platform/fonts/FontDescription.h" |
| 37 #include "platform/fonts/GlyphPage.h" | 36 #include "platform/fonts/GlyphPage.h" |
| 38 #include "platform/fonts/VDMXParser.h" | 37 #include "platform/fonts/VDMXParser.h" |
| 38 #include "platform/fonts/skia/SkiaTextMetrics.h" |
| 39 #include "platform/geometry/FloatRect.h" | 39 #include "platform/geometry/FloatRect.h" |
| 40 #include "wtf/MathExtras.h" | 40 #include "wtf/MathExtras.h" |
| 41 #include "wtf/PtrUtil.h" | 41 #include "wtf/PtrUtil.h" |
| 42 #include "wtf/allocator/Partitions.h" | 42 #include "wtf/allocator/Partitions.h" |
| 43 #include "wtf/text/CharacterNames.h" | 43 #include "wtf/text/CharacterNames.h" |
| 44 #include "wtf/text/Unicode.h" | 44 #include "wtf/text/Unicode.h" |
| 45 #include <memory> | 45 #include <memory> |
| 46 #include <unicode/unorm.h> | 46 #include <unicode/unorm.h> |
| 47 #include <unicode/utf16.h> | 47 #include <unicode/utf16.h> |
| 48 | 48 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 | 84 |
| 85 void SimpleFontData::platformInit() | 85 void SimpleFontData::platformInit() |
| 86 { | 86 { |
| 87 if (!m_platformData.size()) { | 87 if (!m_platformData.size()) { |
| 88 m_fontMetrics.reset(); | 88 m_fontMetrics.reset(); |
| 89 m_avgCharWidth = 0; | 89 m_avgCharWidth = 0; |
| 90 m_maxCharWidth = 0; | 90 m_maxCharWidth = 0; |
| 91 return; | 91 return; |
| 92 } | 92 } |
| 93 | 93 |
| 94 SkPaint paint; | |
| 95 SkPaint::FontMetrics metrics; | 94 SkPaint::FontMetrics metrics; |
| 96 | 95 |
| 97 m_platformData.setupPaint(&paint); | 96 m_platformData.setupPaint(&m_paint); |
| 98 paint.getFontMetrics(&metrics); | 97 m_paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 99 SkTypeface* face = paint.getTypeface(); | 98 m_paint.getFontMetrics(&metrics); |
| 99 SkTypeface* face = m_paint.getTypeface(); |
| 100 ASSERT(face); | 100 ASSERT(face); |
| 101 | 101 |
| 102 int vdmxAscent = 0, vdmxDescent = 0; | 102 int vdmxAscent = 0, vdmxDescent = 0; |
| 103 bool isVDMXValid = false; | 103 bool isVDMXValid = false; |
| 104 | 104 |
| 105 #if OS(LINUX) || OS(ANDROID) | 105 #if OS(LINUX) || OS(ANDROID) |
| 106 // Manually digging up VDMX metrics is only applicable when bytecode hinting
using FreeType. | 106 // Manually digging up VDMX metrics is only applicable when bytecode hinting
using FreeType. |
| 107 // With DirectWrite or CoreText, no bytecode hinting is ever done. | 107 // With DirectWrite or CoreText, no bytecode hinting is ever done. |
| 108 // This code should be pushed into FreeType (hinted font metrics). | 108 // This code should be pushed into FreeType (hinted font metrics). |
| 109 static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X'); | 109 static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X'); |
| 110 int pixelSize = m_platformData.size() + 0.5; | 110 int pixelSize = m_platformData.size() + 0.5; |
| 111 if (!paint.isAutohinted() | 111 if (!m_paint.isAutohinted() |
| 112 && (paint.getHinting() == SkPaint::kFull_Hinting | 112 && (m_paint.getHinting() == SkPaint::kFull_Hinting |
| 113 || paint.getHinting() == SkPaint::kNormal_Hinting)) | 113 || m_paint.getHinting() == SkPaint::kNormal_Hinting)) |
| 114 { | 114 { |
| 115 size_t vdmxSize = face->getTableSize(vdmxTag); | 115 size_t vdmxSize = face->getTableSize(vdmxTag); |
| 116 if (vdmxSize && vdmxSize < maxVDMXTableSize) { | 116 if (vdmxSize && vdmxSize < maxVDMXTableSize) { |
| 117 uint8_t* vdmxTable = (uint8_t*)WTF::Partitions::fastMalloc(vdmxSize,
WTF_HEAP_PROFILER_TYPE_NAME(SimpleFontData)); | 117 uint8_t* vdmxTable = (uint8_t*)WTF::Partitions::fastMalloc(vdmxSize,
WTF_HEAP_PROFILER_TYPE_NAME(SimpleFontData)); |
| 118 if (vdmxTable | 118 if (vdmxTable |
| 119 && face->getTableData(vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSi
ze | 119 && face->getTableData(vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSi
ze |
| 120 && parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pix
elSize)) | 120 && parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pix
elSize)) |
| 121 isVDMXValid = true; | 121 isVDMXValid = true; |
| 122 WTF::Partitions::fastFree(vdmxTable); | 122 WTF::Partitions::fastFree(vdmxTable); |
| 123 } | 123 } |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 if (uprightOrientation) | 364 if (uprightOrientation) |
| 365 GlyphPageTreeNode::pruneTreeCustomFontData(uprightOrientation.get()); | 365 GlyphPageTreeNode::pruneTreeCustomFontData(uprightOrientation.get()); |
| 366 } | 366 } |
| 367 | 367 |
| 368 PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
ption& fontDescription, float scaleFactor) const | 368 PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescri
ption& fontDescription, float scaleFactor) const |
| 369 { | 369 { |
| 370 const float scaledSize = lroundf(fontDescription.computedSize() * scaleFacto
r); | 370 const float scaledSize = lroundf(fontDescription.computedSize() * scaleFacto
r); |
| 371 return SimpleFontData::create(FontPlatformData(m_platformData, scaledSize),
isCustomFont() ? CustomFontData::create() : nullptr); | 371 return SimpleFontData::create(FontPlatformData(m_platformData, scaledSize),
isCustomFont() ? CustomFontData::create() : nullptr); |
| 372 } | 372 } |
| 373 | 373 |
| 374 static inline void getSkiaBoundsForGlyph(SkPaint& paint, Glyph glyph, SkRect& bo
unds) | |
| 375 { | |
| 376 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | |
| 377 | |
| 378 SkPath path; | |
| 379 paint.getTextPath(&glyph, sizeof(glyph), 0, 0, &path); | |
| 380 bounds = path.getBounds(); | |
| 381 | |
| 382 if (!paint.isSubpixelText()) { | |
| 383 SkIRect ir; | |
| 384 bounds.round(&ir); | |
| 385 bounds.set(ir); | |
| 386 } | |
| 387 } | |
| 388 | |
| 389 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const | 374 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const |
| 390 { | 375 { |
| 391 if (!m_platformData.size()) | |
| 392 return FloatRect(); | |
| 393 | |
| 394 SkASSERT(sizeof(glyph) == 2); // compile-time assert | |
| 395 | |
| 396 SkPaint paint; | |
| 397 m_platformData.setupPaint(&paint); | |
| 398 | |
| 399 SkRect bounds; | 376 SkRect bounds; |
| 400 getSkiaBoundsForGlyph(paint, glyph, bounds); | 377 SkiaTextMetrics(&m_paint).getSkiaBoundsForGlyph(glyph, &bounds); |
| 401 return FloatRect(bounds); | 378 return FloatRect(bounds); |
| 402 } | 379 } |
| 403 | 380 |
| 404 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const | 381 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const |
| 405 { | 382 { |
| 406 if (!m_platformData.size()) | 383 return SkiaTextMetrics(&m_paint).getSkiaWidthForGlyph(glyph); |
| 407 return 0; | 384 } |
| 408 | 385 |
| 409 SkASSERT(sizeof(glyph) == 2); // compile-time assert | |
| 410 | |
| 411 SkPaint paint; | |
| 412 | |
| 413 m_platformData.setupPaint(&paint); | |
| 414 | |
| 415 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); | |
| 416 SkScalar width = paint.measureText(&glyph, 2); | |
| 417 if (!paint.isSubpixelText()) | |
| 418 width = SkScalarRoundToInt(width); | |
| 419 return SkScalarToFloat(width); | |
| 420 } | |
| 421 | 386 |
| 422 bool SimpleFontData::fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsig
ned length, UChar* buffer, unsigned bufferLength) const | 387 bool SimpleFontData::fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsig
ned length, UChar* buffer, unsigned bufferLength) const |
| 423 { | 388 { |
| 424 if (U16_IS_LEAD(buffer[bufferLength-1])) { | 389 if (U16_IS_LEAD(buffer[bufferLength-1])) { |
| 425 DLOG(ERROR) << "Last UTF-16 code unit is high-surrogate."; | 390 DLOG(ERROR) << "Last UTF-16 code unit is high-surrogate."; |
| 426 return false; | 391 return false; |
| 427 } | 392 } |
| 428 | 393 |
| 429 SkTypeface* typeface = platformData().typeface(); | 394 SkTypeface* typeface = platformData().typeface(); |
| 430 if (!typeface) { | 395 if (!typeface) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 441 if (glyphs[i]) { | 406 if (glyphs[i]) { |
| 442 pageToFill->setGlyphDataForIndex(offset + i, glyphs[i], this); | 407 pageToFill->setGlyphDataForIndex(offset + i, glyphs[i], this); |
| 443 haveGlyphs = true; | 408 haveGlyphs = true; |
| 444 } | 409 } |
| 445 } | 410 } |
| 446 | 411 |
| 447 return haveGlyphs; | 412 return haveGlyphs; |
| 448 } | 413 } |
| 449 | 414 |
| 450 } // namespace blink | 415 } // namespace blink |
| OLD | NEW |