// static
std::map<std::string, Font> RenderTextWin::successful_substitute_fonts_;
-RenderTextWin::RenderTextWin()
- : RenderText(),
- needs_layout_(false) {
+RenderTextWin::RenderTextWin() : RenderText(), needs_layout_(false) {
set_truncate_length(kMaxUniscribeTextLength);
-
memset(&script_control_, 0, sizeof(script_control_));
memset(&script_state_, 0, sizeof(script_state_));
-
MoveCursorTo(EdgeSelectionModel(CURSOR_LEFT));
}
-RenderTextWin::~RenderTextWin() {
-}
+RenderTextWin::~RenderTextWin() {}
Size RenderTextWin::GetStringSize() {
EnsureLayout();
size_t RenderTextWin::TextIndexToLayoutIndex(size_t index) const {
DCHECK_LE(index, text().length());
- ptrdiff_t i = obscured() ? gfx::UTF16IndexToOffset(text(), 0, index) : index;
+ ptrdiff_t i = obscured() ? UTF16IndexToOffset(text(), 0, index) : index;
CHECK_GE(i, 0);
// Clamp layout indices to the length of the text actually used for layout.
return std::min<size_t>(GetLayoutText().length(), i);
return index;
DCHECK_LE(index, GetLayoutText().length());
- const size_t text_index = gfx::UTF16OffsetToIndex(text(), 0, index);
+ const size_t text_index = UTF16OffsetToIndex(text(), 0, index);
DCHECK_LE(text_index, text().length());
return text_index;
}
-bool RenderTextWin::IsCursorablePosition(size_t position) {
- if (position == 0 || position == text().length())
+bool RenderTextWin::IsValidCursorIndex(size_t index) {
+ if (index == 0 || index == text().length())
return true;
+ if (!IsValidLogicalIndex(index))
+ return false;
EnsureLayout();
-
- // Check that the index is at a valid code point (not mid-surrgate-pair),
- // that it is not truncated from layout text (its glyph is shown on screen),
- // and that its glyph has distinct bounds (not mid-multi-character-grapheme).
- // An example of a multi-character-grapheme that is not a surrogate-pair is:
- // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
- return gfx::IsValidCodePointIndex(text(), position) &&
- position < LayoutIndexToTextIndex(GetLayoutText().length()) &&
- GetGlyphBounds(position) != GetGlyphBounds(position - 1);
+ // Disallow indices amid multi-character graphemes by checking glyph bounds.
+ // These characters are not surrogate-pairs, but may yield a single glyph:
+ // \x0915\x093f - (ki) - one of many Devanagari biconsonantal conjuncts.
+ // \x0e08\x0e33 - (cho chan + sara am) - a Thai consonant and vowel pair.
+ return GetGlyphBounds(index) != GetGlyphBounds(index - 1);
}
void RenderTextWin::ResetLayout() {
for (size_t k = glyph_range.start(); k < glyph_range.end(); ++k) {
pos[k - glyph_range.start()].set(
SkIntToScalar(text_offset.x() + run->offsets[k].du + segment_x),
- SkIntToScalar(text_offset.y() + run->offsets[k].dv));
+ SkIntToScalar(text_offset.y() - run->offsets[k].dv));
segment_x += run->advance_widths[k];
}
pos.back().set(SkIntToScalar(text_offset.x() + segment_x),
const Range intersection =
colors().GetRange(it).Intersect(segment->char_range);
const Range colored_glyphs = CharRangeToGlyphRange(*run, intersection);
+ // The range may be empty if a portion of a multi-character grapheme is
+ // selected, yielding two colors for a single glyph. For now, this just
+ // paints the glyph with a single style, but it should paint it twice,
+ // clipped according to selection bounds. See http://crbug.com/366786
+ if (colored_glyphs.is_empty())
+ continue;
DCHECK(glyph_range.Contains(colored_glyphs));
- DCHECK(!colored_glyphs.is_empty());
const SkPoint& start_pos =
pos[colored_glyphs.start() - glyph_range.start()];
const SkPoint& end_pos =
if (run->glyph_count > 0) {
run->advance_widths.reset(new int[run->glyph_count]);
- // TODO(asvitkine): Temporary instrumentation to debug a double-free
- // crash where we're seeing these two being equal inexplicably. Hitting
- // this implies that the malloc book-keeping is corrupt and it returned
- // the same pointer for two different allocs, which we can debug further.
- // http://crbug.com/348103
- CHECK_NE(static_cast<void*>(run->logical_clusters.get()),
- static_cast<void*>(run->advance_widths.get()));
run->offsets.reset(new GOFFSET[run->glyph_count]);
hr = ScriptPlace(cached_hdc_,
&run->script_cache,