1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "third_party/blink/renderer/core/layout/text_run_constructor.h"
32 
33 #include "third_party/blink/renderer/core/layout/api/line_layout_item.h"
34 #include "third_party/blink/renderer/core/layout/api/line_layout_text.h"
35 #include "third_party/blink/renderer/core/layout/layout_text.h"
36 #include "third_party/blink/renderer/platform/text/bidi_text_run.h"
37 
38 namespace blink {
39 
40 template <typename CharacterType>
ConstructTextRunInternal(const Font & font,const CharacterType * characters,int length,const ComputedStyle & style,TextDirection direction)41 static inline TextRun ConstructTextRunInternal(const Font& font,
42                                                const CharacterType* characters,
43                                                int length,
44                                                const ComputedStyle& style,
45                                                TextDirection direction) {
46   TextRun::ExpansionBehavior expansion =
47       TextRun::kAllowTrailingExpansion | TextRun::kForbidLeadingExpansion;
48   bool directional_override = style.RtlOrdering() == EOrder::kVisual;
49   TextRun run(characters, length, 0, 0, expansion, direction,
50               directional_override);
51   return run;
52 }
53 
54 template <typename CharacterType>
ConstructTextRunInternal(const Font & font,const CharacterType * characters,int length,const ComputedStyle & style,TextDirection direction,TextRunFlags flags)55 static inline TextRun ConstructTextRunInternal(const Font& font,
56                                                const CharacterType* characters,
57                                                int length,
58                                                const ComputedStyle& style,
59                                                TextDirection direction,
60                                                TextRunFlags flags) {
61   TextDirection text_direction = direction;
62   bool directional_override = style.RtlOrdering() == EOrder::kVisual;
63   if (flags != kDefaultTextRunFlags) {
64     if (flags & kRespectDirection)
65       text_direction = style.Direction();
66     if (flags & kRespectDirectionOverride)
67       directional_override |= IsOverride(style.GetUnicodeBidi());
68   }
69 
70   TextRun::ExpansionBehavior expansion =
71       TextRun::kAllowTrailingExpansion | TextRun::kForbidLeadingExpansion;
72   TextRun run(characters, length, 0, 0, expansion, text_direction,
73               directional_override);
74   return run;
75 }
76 
ConstructTextRun(const Font & font,const LChar * characters,int length,const ComputedStyle & style,TextDirection direction)77 TextRun ConstructTextRun(const Font& font,
78                          const LChar* characters,
79                          int length,
80                          const ComputedStyle& style,
81                          TextDirection direction) {
82   return ConstructTextRunInternal(font, characters, length, style, direction);
83 }
84 
ConstructTextRun(const Font & font,const UChar * characters,int length,const ComputedStyle & style,TextDirection direction)85 TextRun ConstructTextRun(const Font& font,
86                          const UChar* characters,
87                          int length,
88                          const ComputedStyle& style,
89                          TextDirection direction) {
90   return ConstructTextRunInternal(font, characters, length, style, direction);
91 }
92 
ConstructTextRun(const Font & font,const LayoutText * text,unsigned offset,unsigned length,const ComputedStyle & style,TextDirection direction)93 TextRun ConstructTextRun(const Font& font,
94                          const LayoutText* text,
95                          unsigned offset,
96                          unsigned length,
97                          const ComputedStyle& style,
98                          TextDirection direction) {
99   DCHECK_LE(offset + length, text->TextLength());
100   if (text->HasEmptyText())
101     return ConstructTextRunInternal(font, static_cast<const LChar*>(nullptr), 0,
102                                     style, direction);
103   if (text->Is8Bit())
104     return ConstructTextRunInternal(font, text->Characters8() + offset, length,
105                                     style, direction);
106   return ConstructTextRunInternal(font, text->Characters16() + offset, length,
107                                   style, direction);
108 }
109 
ConstructTextRun(const Font & font,const String & string,const ComputedStyle & style,TextDirection direction,TextRunFlags flags)110 TextRun ConstructTextRun(const Font& font,
111                          const String& string,
112                          const ComputedStyle& style,
113                          TextDirection direction,
114                          TextRunFlags flags) {
115   unsigned length = string.length();
116   if (!length)
117     return ConstructTextRunInternal(font, static_cast<const LChar*>(nullptr),
118                                     length, style, direction, flags);
119   if (string.Is8Bit())
120     return ConstructTextRunInternal(font, string.Characters8(), length, style,
121                                     direction, flags);
122   return ConstructTextRunInternal(font, string.Characters16(), length, style,
123                                   direction, flags);
124 }
125 
ConstructTextRun(const Font & font,const String & string,const ComputedStyle & style,TextRunFlags flags)126 TextRun ConstructTextRun(const Font& font,
127                          const String& string,
128                          const ComputedStyle& style,
129                          TextRunFlags flags) {
130   return ConstructTextRun(font, string, style,
131                           string.IsEmpty() || string.Is8Bit()
132                               ? TextDirection::kLtr
133                               : DetermineDirectionality(string),
134                           flags);
135 }
136 
ConstructTextRun(const Font & font,const LineLayoutText text,unsigned offset,unsigned length,const ComputedStyle & style)137 TextRun ConstructTextRun(const Font& font,
138                          const LineLayoutText text,
139                          unsigned offset,
140                          unsigned length,
141                          const ComputedStyle& style) {
142   SECURITY_DCHECK(offset + length <= text.TextLength());
143   if (text.HasEmptyText()) {
144     return ConstructTextRunInternal(font, static_cast<const LChar*>(nullptr), 0,
145                                     style, TextDirection::kLtr);
146   }
147   if (text.Is8Bit()) {
148     return ConstructTextRunInternal(font, text.Characters8() + offset, length,
149                                     style, TextDirection::kLtr);
150   }
151 
152   TextRun run = ConstructTextRunInternal(font, text.Characters16() + offset,
153                                          length, style, TextDirection::kLtr);
154   run.SetDirection(DirectionForRun(run));
155   return run;
156 }
157 
158 }  // namespace blink
159