servo: Merge #11914 - Text fragment color merge (from notriddle:text_fragment_color_merge); r=jdm
authorMichael Howell <michael@notriddle.com>
Tue, 28 Jun 2016 22:43:07 -0500
changeset 339148 4394ebe6f65096f61e8dcafa7c4e2e2536df0319
parent 339147 4cb9f1e5b190228c087b2e0bb610a88e18c14515
child 339149 88f9c9e6a11c81a3e4e74df60ade498c0953580a
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #11914 - Text fragment color merge (from notriddle:text_fragment_color_merge); r=jdm The display list item for a line of text has a single color assigned for it, so text fragments with different colors cannot be merged. There is no issue number for this, as far as I know. I found this while trying an internal program that uses red asterisks for required text fields. ____________________ - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes do not fix an existing Github issue - [X] There are tests for these changes OR Source-Repo: https://github.com/servo/servo Source-Revision: 5b20673d43dadb86bd1770da89a712f137187331
servo/components/layout/construct.rs
servo/components/layout/fragment.rs
--- a/servo/components/layout/construct.rs
+++ b/servo/components/layout/construct.rs
@@ -944,17 +944,17 @@ impl<'a, ConcreteThreadSafeLayoutNode: T
                 node.opaque(),
                 node.get_pseudo_element_type().strip(),
                 node.style(self.style_context()).clone(),
                 node.restyle_damage()))
         }
 
         // Modify the style as necessary. (See the comment in
         // `properties::modify_style_for_replaced_content()`.)
-        let mut style = (*node.style(self.style_context())).clone();
+        let mut style = node.style(self.style_context()).clone();
         properties::modify_style_for_replaced_content(&mut style);
 
         // If this is generated content, then we need to initialize the accumulator with the
         // fragment corresponding to that content. Otherwise, just initialize with the ordinary
         // fragment that needs to be generated for this inline node.
         let mut fragments = IntermediateInlineFragments::new();
         match (node.get_pseudo_element_type(), node.type_id()) {
             (_, Some(LayoutNodeType::Text)) => {
--- a/servo/components/layout/fragment.rs
+++ b/servo/components/layout/fragment.rs
@@ -33,19 +33,19 @@ use script_layout_interface::HTMLCanvasD
 use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, RestyleDamage};
 use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
 use std::borrow::ToOwned;
 use std::cmp::{max, min};
 use std::collections::LinkedList;
 use std::fmt;
 use std::sync::{Arc, Mutex};
 use style::computed_values::content::ContentItem;
-use style::computed_values::{border_collapse, clear, display, mix_blend_mode, overflow_wrap};
-use style::computed_values::{overflow_x, position, text_decoration, transform_style};
-use style::computed_values::{vertical_align, white_space, word_break, z_index};
+use style::computed_values::{border_collapse, clear, color, display, mix_blend_mode};
+use style::computed_values::{overflow_wrap, overflow_x, position, text_decoration};
+use style::computed_values::{transform_style, vertical_align, white_space, word_break, z_index};
 use style::dom::TRestyleDamage;
 use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
 use style::properties::{ComputedValues, ServoComputedValues};
 use style::values::computed::LengthOrPercentageOrNone;
 use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
 use text;
 use text::TextRunScanner;
 use url::Url;
@@ -1299,16 +1299,20 @@ impl Fragment {
     pub fn selected_style(&self) -> &ServoComputedValues {
         &*self.selected_style
     }
 
     pub fn white_space(&self) -> white_space::T {
         self.style().get_inheritedtext().white_space
     }
 
+    pub fn color(&self) -> color::T {
+        self.style().get_color().color
+    }
+
     /// Returns the text decoration of this fragment, according to the style of the nearest ancestor
     /// element.
     ///
     /// NB: This may not be the actual text decoration, because of the override rules specified in
     /// CSS 2.1 ยง 16.3.1. Unfortunately, computing this properly doesn't really fit into Servo's
     /// model. Therefore, this is a best lower bound approximation, but the end result may actually
     /// have the various decoration flags turned on afterward.
     pub fn text_decoration(&self) -> text_decoration::T {
@@ -2037,17 +2041,18 @@ impl Fragment {
     /// false otherwise.
     pub fn can_merge_with_fragment(&self, other: &Fragment) -> bool {
         match (&self.specific, &other.specific) {
             (&SpecificFragmentInfo::UnscannedText(ref first_unscanned_text),
              &SpecificFragmentInfo::UnscannedText(_)) => {
                 // FIXME: Should probably use a whitelist of styles that can safely differ (#3165)
                 if self.style().get_font() != other.style().get_font() ||
                         self.text_decoration() != other.text_decoration() ||
-                        self.white_space() != other.white_space() {
+                        self.white_space() != other.white_space() ||
+                        self.color() != other.color() {
                     return false
                 }
 
                 if first_unscanned_text.text.ends_with('\n') {
                     return false
                 }
 
                 // If this node has any styles that have border/padding/margins on the following