| Index: ui/gfx/render_text_mac.cc
|
| diff --git a/ui/gfx/render_text_mac.cc b/ui/gfx/render_text_mac.cc
|
| index a6367141fe8fada68628d05355661d717e1fcfaf..af8ea3d8e786247c41bb331e03f3183e513e7756 100644
|
| --- a/ui/gfx/render_text_mac.cc
|
| +++ b/ui/gfx/render_text_mac.cc
|
| @@ -158,7 +158,7 @@ void RenderTextMac::DrawVisualText(Canvas* canvas) {
|
| renderer.DrawPosText(&run.glyph_positions[0], &run.glyphs[0],
|
| run.glyphs.size());
|
| renderer.DrawDecorations(run.origin.x(), run.origin.y(), run.width,
|
| - run.style);
|
| + run.underline, run.strike, run.diagonal_strike);
|
| }
|
| }
|
|
|
| @@ -168,7 +168,10 @@ RenderTextMac::TextRun::TextRun()
|
| width(0),
|
| font_style(Font::NORMAL),
|
| text_size(0),
|
| - foreground(SK_ColorBLACK) {
|
| + foreground(SK_ColorBLACK),
|
| + underline(false),
|
| + strike(false),
|
| + diagonal_strike(false) {
|
| }
|
|
|
| RenderTextMac::TextRun::~TextRun() {
|
| @@ -176,44 +179,69 @@ RenderTextMac::TextRun::~TextRun() {
|
|
|
| void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string,
|
| CTFontRef font) {
|
| - // Clear attributes and reserve space to hold the maximum number of entries,
|
| - // which is at most three per style range per the code below.
|
| - attributes_.reset(CFArrayCreateMutable(NULL, 3 * style_ranges().size(),
|
| + // Adjust the text colors to reflect the selection range.
|
| + std::vector<ColorBreak> adjusted_colors(colors());
|
| + ApplySelectionColor(&adjusted_colors);
|
| +
|
| + // Adjust the underline styling to reflect composition ranges.
|
| + const std::vector<StyleBreak>* adjusted_styles[NUM_TEXT_STYLES];
|
| + for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
|
| + adjusted_styles[i] = &styles(static_cast<TextStyle>(i));
|
| + std::vector<StyleBreak> adjusted_underlines(styles(UNDERLINE));
|
| + ApplyCompositionStyle(&adjusted_underlines);
|
| + adjusted_styles[UNDERLINE] = &adjusted_underlines;
|
| +
|
| + // Track the current color and style with iterators; get the max style count.
|
| + std::vector<ColorBreak>::const_iterator color = adjusted_colors.begin();
|
| + std::vector<StyleBreak>::const_iterator style[NUM_TEXT_STYLES];
|
| + size_t max_style_count = adjusted_colors.size();
|
| + for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) {
|
| + style[i] = adjusted_styles[i]->begin();
|
| + max_style_count += adjusted_styles[i]->size();
|
| + }
|
| + size_t style_end[NUM_TEXT_STYLES];
|
| +
|
| + // Clear attributes and reserve space to hold the maximum number of entries.
|
| + attributes_.reset(CFArrayCreateMutable(NULL, max_style_count,
|
| &kCFTypeArrayCallBacks));
|
|
|
| // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html
|
| - for (size_t i = 0; i < style_ranges().size(); ++i) {
|
| - const StyleRange& style = style_ranges()[i];
|
| - const CFRange range = CFRangeMake(style.range.start(),
|
| - style.range.length());
|
| + for (size_t i = 0, end = 0; i < text().length(); i = end) {
|
| + // Find the end of this ranged style.
|
| + const size_t color_end = TextIndexToLayoutIndex(
|
| + GetBreakEnd(adjusted_colors, color));
|
| + end = color_end;
|
| + for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) {
|
| + style_end[i] = TextIndexToLayoutIndex(
|
| + GetBreakEnd(*adjusted_styles[i], style[i]));
|
| + end = std::min(end, style_end[i]);
|
| + }
|
|
|
| // Note: CFAttributedStringSetAttribute() does not appear to retain the
|
| // values passed in, as can be verified via CFGetRetainCount(). To ensure
|
| // the attribute objects do not leak, they are saved to |attributes_|.
|
|
|
| + const CFRange range = CFRangeMake(i, end - i);
|
| base::mac::ScopedCFTypeRef<CGColorRef> foreground(
|
| - gfx::CGColorCreateFromSkColor(style.foreground));
|
| + gfx::CGColorCreateFromSkColor(color->second));
|
| CFAttributedStringSetAttribute(attr_string, range,
|
| kCTForegroundColorAttributeName,
|
| foreground);
|
| CFArrayAppendValue(attributes_, foreground);
|
|
|
| - if (style.underline) {
|
| + if (style[UNDERLINE]->second) {
|
| CTUnderlineStyle value = kCTUnderlineStyleSingle;
|
| - base::mac::ScopedCFTypeRef<CFNumberRef> underline(
|
| + base::mac::ScopedCFTypeRef<CFNumberRef> underline_value(
|
| CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
|
| CFAttributedStringSetAttribute(attr_string, range,
|
| kCTUnderlineStyleAttributeName,
|
| - underline);
|
| - CFArrayAppendValue(attributes_, underline);
|
| + underline_value);
|
| + CFArrayAppendValue(attributes_, underline_value);
|
| }
|
|
|
| - if (style.font_style & (Font::BOLD | Font::ITALIC)) {
|
| - int traits = 0;
|
| - if (style.font_style & Font::BOLD)
|
| - traits |= kCTFontBoldTrait;
|
| - if (style.font_style & Font::ITALIC)
|
| - traits |= kCTFontItalicTrait;
|
| + const int traits = (style[BOLD]->second ? kCTFontBoldTrait : 0) |
|
| + (style[ITALIC]->second ? kCTFontItalicTrait : 0);
|
| + if (traits != 0) {
|
| base::mac::ScopedCFTypeRef<CTFontRef> styled_font(
|
| CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits));
|
| // TODO(asvitkine): Handle |styled_font| == NULL case better.
|
| @@ -223,6 +251,11 @@ void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string,
|
| CFArrayAppendValue(attributes_, styled_font);
|
| }
|
| }
|
| +
|
| + // Advance the color and style iterators as needed.
|
| + color += color_end == end ? 1 : 0;
|
| + for (size_t i = 0; i < NUM_TEXT_STYLES; ++i)
|
| + style[i] += style_end[i] == end ? 1 : 0;
|
| }
|
| }
|
|
|
| @@ -283,7 +316,7 @@ void RenderTextMac::ComputeRuns() {
|
| }
|
|
|
| // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle
|
| - // this better.
|
| + // this better. Also, support strike and diagonal_strike.
|
| CFDictionaryRef attributes = CTRunGetAttributes(ct_run);
|
| CTFontRef ct_font =
|
| base::mac::GetValueFromDictionary<CTFontRef>(attributes,
|
| @@ -310,7 +343,7 @@ void RenderTextMac::ComputeRuns() {
|
| attributes, kCTUnderlineStyleAttributeName);
|
| CTUnderlineStyle value = kCTUnderlineStyleNone;
|
| if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value))
|
| - run->style.underline = (value == kCTUnderlineStyleSingle);
|
| + run->underline = (value == kCTUnderlineStyleSingle);
|
|
|
| run_origin.offset(run_width, 0);
|
| }
|
|
|