Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "ui/gfx/render_text_linux.h" | 5 #include "ui/gfx/render_text_linux.h" |
| 6 | 6 |
| 7 #include <fontconfig/fontconfig.h> | 7 #include <fontconfig/fontconfig.h> |
| 8 #include <pango/pangocairo.h> | 8 #include <pango/pangocairo.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 int fc_rgba = FC_RGBA_RGB; | 63 int fc_rgba = FC_RGBA_RGB; |
| 64 FcPatternGetInteger(match, FC_RGBA, 0, &fc_rgba); | 64 FcPatternGetInteger(match, FC_RGBA, 0, &fc_rgba); |
| 65 FcPatternDestroy(pattern); | 65 FcPatternDestroy(pattern); |
| 66 FcPatternDestroy(match); | 66 FcPatternDestroy(match); |
| 67 | 67 |
| 68 already_queried = true; | 68 already_queried = true; |
| 69 subpixel_enabled = (fc_rgba != FC_RGBA_NONE); | 69 subpixel_enabled = (fc_rgba != FC_RGBA_NONE); |
| 70 return subpixel_enabled; | 70 return subpixel_enabled; |
| 71 } | 71 } |
| 72 | 72 |
| 73 // Sets underline metrics on |renderer| according to Pango font |desc|. | |
| 74 void SetPangoUnderlineMetrics(PangoFontDescription *desc, | |
| 75 internal::SkiaTextRenderer* renderer) { | |
| 76 PangoFontMetrics* metrics = GetPangoFontMetrics(desc); | |
| 77 int thickness = pango_font_metrics_get_underline_thickness(metrics); | |
| 78 // Pango returns the position "above the baseline". Change its sign to convert | |
| 79 // it to a vertical offset from the baseline. | |
| 80 int position = -pango_font_metrics_get_underline_position(metrics); | |
| 81 pango_quantize_line_geometry(&thickness, &position); | |
|
msw
2012/06/06 18:35:25
Does this work ok with DIP / high dpi?
Alexei Svitkine (slow)
2012/06/06 18:46:23
It shouldn't cause any problems - though it will s
| |
| 82 renderer->SetUnderlineMetrics(PANGO_PIXELS(thickness), | |
|
msw
2012/06/06 18:35:25
Should these still use pango_units_to_double as a
Alexei Svitkine (slow)
2012/06/06 18:46:23
Since pango_quantize_line_geometry() guarantees pi
msw
2012/06/06 18:51:52
I guess my point was why not use pango_units_to_do
Alexei Svitkine (slow)
2012/06/06 19:03:05
I've added a comment about it.
| |
| 83 PANGO_PIXELS(position)); | |
| 84 } | |
| 85 | |
| 73 } // namespace | 86 } // namespace |
| 74 | 87 |
| 75 // TODO(xji): index saved in upper layer is utf16 index. Pango uses utf8 index. | 88 // TODO(xji): index saved in upper layer is utf16 index. Pango uses utf8 index. |
| 76 // Since caret_pos is used internally, we could save utf8 index for caret_pos | 89 // Since caret_pos is used internally, we could save utf8 index for caret_pos |
| 77 // to avoid conversion. | 90 // to avoid conversion. |
| 78 | 91 |
| 79 RenderTextLinux::RenderTextLinux() | 92 RenderTextLinux::RenderTextLinux() |
| 80 : layout_(NULL), | 93 : layout_(NULL), |
| 81 current_line_(NULL), | 94 current_line_(NULL), |
| 82 log_attrs_(NULL), | 95 log_attrs_(NULL), |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 DCHECK_GE(style, 0); | 451 DCHECK_GE(style, 0); |
| 439 DCHECK_LT(style, static_cast<int>(styles.size())); | 452 DCHECK_LT(style, static_cast<int>(styles.size())); |
| 440 if (!IndexInRange(style_ranges_utf8[style], glyph_byte_index)) { | 453 if (!IndexInRange(style_ranges_utf8[style], glyph_byte_index)) { |
| 441 // TODO(asvitkine): For cases like "fi", where "fi" is a single glyph | 454 // TODO(asvitkine): For cases like "fi", where "fi" is a single glyph |
| 442 // but can span multiple styles, Pango splits the | 455 // but can span multiple styles, Pango splits the |
| 443 // styles evenly over the glyph. We can do this too by | 456 // styles evenly over the glyph. We can do this too by |
| 444 // clipping and drawing the glyph several times. | 457 // clipping and drawing the glyph several times. |
| 445 renderer.SetForegroundColor(styles[style].foreground); | 458 renderer.SetForegroundColor(styles[style].foreground); |
| 446 renderer.SetFontFamilyWithStyle(family_name, styles[style].font_style); | 459 renderer.SetFontFamilyWithStyle(family_name, styles[style].font_style); |
| 447 renderer.DrawPosText(&pos[start], &glyphs[start], i - start); | 460 renderer.DrawPosText(&pos[start], &glyphs[start], i - start); |
| 461 if (styles[style].underline) | |
| 462 SetPangoUnderlineMetrics(desc.get(), &renderer); | |
| 448 renderer.DrawDecorations(start_x, y, glyph_x - start_x, styles[style]); | 463 renderer.DrawDecorations(start_x, y, glyph_x - start_x, styles[style]); |
| 449 | 464 |
| 450 start = i; | 465 start = i; |
| 451 start_x = glyph_x; | 466 start_x = glyph_x; |
| 452 // Loop to find the next style, in case the glyph spans multiple styles. | 467 // Loop to find the next style, in case the glyph spans multiple styles. |
| 453 do { | 468 do { |
| 454 style += style_increment; | 469 style += style_increment; |
| 455 } while (style >= 0 && style < static_cast<int>(styles.size()) && | 470 } while (style >= 0 && style < static_cast<int>(styles.size()) && |
| 456 !IndexInRange(style_ranges_utf8[style], glyph_byte_index)); | 471 !IndexInRange(style_ranges_utf8[style], glyph_byte_index)); |
| 457 } | 472 } |
| 458 } | 473 } |
| 459 | 474 |
| 460 // Draw the remaining glyphs. | 475 // Draw the remaining glyphs. |
| 461 renderer.SetForegroundColor(styles[style].foreground); | 476 renderer.SetForegroundColor(styles[style].foreground); |
| 462 renderer.SetFontFamilyWithStyle(family_name, styles[style].font_style); | 477 renderer.SetFontFamilyWithStyle(family_name, styles[style].font_style); |
| 463 renderer.DrawPosText(&pos[start], &glyphs[start], glyph_count - start); | 478 renderer.DrawPosText(&pos[start], &glyphs[start], glyph_count - start); |
| 479 if (styles[style].underline) | |
| 480 SetPangoUnderlineMetrics(desc.get(), &renderer); | |
| 464 renderer.DrawDecorations(start_x, y, glyph_x - start_x, styles[style]); | 481 renderer.DrawDecorations(start_x, y, glyph_x - start_x, styles[style]); |
| 465 x = glyph_x; | 482 x = glyph_x; |
| 466 } | 483 } |
| 467 } | 484 } |
| 468 | 485 |
| 469 GSList* RenderTextLinux::GetRunContainingCaret( | 486 GSList* RenderTextLinux::GetRunContainingCaret( |
| 470 const SelectionModel& caret) const { | 487 const SelectionModel& caret) const { |
| 471 size_t position = TextIndexToLayoutIndex(caret.caret_pos()); | 488 size_t position = TextIndexToLayoutIndex(caret.caret_pos()); |
| 472 LogicalCursorDirection affinity = caret.caret_affinity(); | 489 LogicalCursorDirection affinity = caret.caret_affinity(); |
| 473 GSList* run = current_line_->runs; | 490 GSList* run = current_line_->runs; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 return bounds; | 558 return bounds; |
| 542 } | 559 } |
| 543 | 560 |
| 544 std::vector<Rect> RenderTextLinux::GetSelectionBounds() { | 561 std::vector<Rect> RenderTextLinux::GetSelectionBounds() { |
| 545 if (selection_visual_bounds_.empty()) | 562 if (selection_visual_bounds_.empty()) |
| 546 selection_visual_bounds_ = CalculateSubstringBounds(selection()); | 563 selection_visual_bounds_ = CalculateSubstringBounds(selection()); |
| 547 return selection_visual_bounds_; | 564 return selection_visual_bounds_; |
| 548 } | 565 } |
| 549 | 566 |
| 550 } // namespace gfx | 567 } // namespace gfx |
| OLD | NEW |