| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef ShapeResultSpacing_h | 5 #ifndef ShapeResultSpacing_h |
| 6 #define ShapeResultSpacing_h | 6 #define ShapeResultSpacing_h |
| 7 | 7 |
| 8 #include "platform/PlatformExport.h" | 8 #include "platform/PlatformExport.h" |
| 9 #include "platform/text/Character.h" | 9 #include "platform/text/Character.h" |
| 10 | 10 |
| 11 namespace blink { | 11 namespace blink { |
| 12 | 12 |
| 13 class FontDescription; | 13 class FontDescription; |
| 14 class ShapeResult; | 14 class ShapeResult; |
| 15 class TextRun; | 15 class TextRun; |
| 16 | 16 |
| 17 class PLATFORM_EXPORT ShapeResultSpacing final { | 17 class PLATFORM_EXPORT ShapeResultSpacing final { |
| 18 public: | 18 public: |
| 19 ShapeResultSpacing(const TextRun&, const FontDescription&); | 19 ShapeResultSpacing(const TextRun&, const FontDescription&); |
| 20 | 20 |
| 21 float letterSpacing() const { return m_letterSpacing; } | 21 float letterSpacing() const { return m_letterSpacing; } |
| 22 bool hasSpacing() const { return m_hasSpacing; } | 22 bool hasSpacing() const { return m_hasSpacing; } |
| 23 bool isVerticalOffset() const { return m_isVerticalOffset; } | 23 bool isVerticalOffset() const { return m_isVerticalOffset; } |
| 24 | 24 |
| 25 float computeSpacing(const TextRun&, size_t, float& offset); | 25 float computeSpacing(const TextRun&, size_t, float& offset); |
| 26 | 26 |
| 27 private: | 27 private: |
| 28 bool hasExpansion() const { return m_expansionOpportunityCount; } | 28 bool hasExpansion() const { return m_expansionOpportunityCount; } |
| 29 bool isAfterExpansion() const { return m_isAfterExpansion; } | 29 bool isAfterExpansion() const { return m_isAfterExpansion; } |
| 30 template <typename CharType> | 30 bool isFirstRun(const TextRun&) const; |
| 31 bool isFirstRun(const CharType*) const; | |
| 32 | 31 |
| 33 float nextExpansion(); | 32 float nextExpansion(); |
| 34 | 33 |
| 35 template <typename CharType> | |
| 36 float computeSpacing(const CharType*, size_t, size_t index, float& offset); | |
| 37 | |
| 38 const TextRun& m_textRun; | 34 const TextRun& m_textRun; |
| 39 float m_letterSpacing; | 35 float m_letterSpacing; |
| 40 float m_wordSpacing; | 36 float m_wordSpacing; |
| 41 float m_expansion; | 37 float m_expansion; |
| 42 float m_expansionPerOpportunity; | 38 float m_expansionPerOpportunity; |
| 43 unsigned m_expansionOpportunityCount; | 39 unsigned m_expansionOpportunityCount; |
| 44 TextJustify m_textJustify; | 40 TextJustify m_textJustify; |
| 45 bool m_hasSpacing; | 41 bool m_hasSpacing; |
| 46 bool m_normalizeSpace; | 42 bool m_normalizeSpace; |
| 47 bool m_allowTabs; | 43 bool m_allowTabs; |
| 48 bool m_isAfterExpansion; | 44 bool m_isAfterExpansion; |
| 49 bool m_isVerticalOffset; | 45 bool m_isVerticalOffset; |
| 50 }; | 46 }; |
| 51 | 47 |
| 52 template <> | |
| 53 inline bool ShapeResultSpacing::isFirstRun(const LChar* p) const | |
| 54 { | |
| 55 return p == m_textRun.characters8(); | |
| 56 } | |
| 57 | |
| 58 template <> | |
| 59 inline bool ShapeResultSpacing::isFirstRun(const UChar* p) const | |
| 60 { | |
| 61 return p == m_textRun.characters16(); | |
| 62 } | |
| 63 | |
| 64 template <typename CharType> | |
| 65 float ShapeResultSpacing::computeSpacing(const CharType* characters, | |
| 66 size_t size, size_t index, float& offset) | |
| 67 { | |
| 68 characters += index; | |
| 69 UChar32 character = characters[0]; | |
| 70 bool treatAsSpace = (Character::treatAsSpace(character) | |
| 71 || (m_normalizeSpace && Character::isNormalizedCanvasSpaceCharacter(char
acter))) | |
| 72 && (character != '\t' || !m_allowTabs); | |
| 73 if (treatAsSpace && character != noBreakSpaceCharacter) | |
| 74 character = spaceCharacter; | |
| 75 | |
| 76 float spacing = 0; | |
| 77 if (m_letterSpacing && !Character::treatAsZeroWidthSpace(character)) | |
| 78 spacing += m_letterSpacing; | |
| 79 | |
| 80 if (treatAsSpace && (index || !isFirstRun(characters) || character == noBrea
kSpaceCharacter)) | |
| 81 spacing += m_wordSpacing; | |
| 82 | |
| 83 if (!hasExpansion()) | |
| 84 return spacing; | |
| 85 | |
| 86 if (treatAsSpace) | |
| 87 return spacing + nextExpansion(); | |
| 88 | |
| 89 if (sizeof(CharType) == sizeof(LChar) | |
| 90 || m_textJustify != TextJustify::TextJustifyAuto) { | |
| 91 return spacing; | |
| 92 } | |
| 93 | |
| 94 // isCJKIdeographOrSymbol() has expansion opportunities both before and | |
| 95 // after each character. | |
| 96 // http://www.w3.org/TR/jlreq/#line_adjustment | |
| 97 if (U16_IS_LEAD(character) && index + 1 < size && U16_IS_TRAIL(characters[1]
)) | |
| 98 character = U16_GET_SUPPLEMENTARY(character, characters[1]); | |
| 99 if (!Character::isCJKIdeographOrSymbol(character)) { | |
| 100 m_isAfterExpansion = false; | |
| 101 return spacing; | |
| 102 } | |
| 103 | |
| 104 if (!m_isAfterExpansion) { | |
| 105 // Take the expansion opportunity before this ideograph. | |
| 106 float expandBefore = nextExpansion(); | |
| 107 if (expandBefore) { | |
| 108 offset += expandBefore; | |
| 109 spacing += expandBefore; | |
| 110 } | |
| 111 if (!hasExpansion()) | |
| 112 return spacing; | |
| 113 } | |
| 114 | |
| 115 return spacing + nextExpansion(); | |
| 116 } | |
| 117 | |
| 118 } // namespace blink | 48 } // namespace blink |
| 119 | 49 |
| 120 #endif | 50 #endif |
| OLD | NEW |