mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
gfx: Paint the insertion point as a one-pixel wide line.
This commit is contained in:
parent
357419dc8d
commit
efdf435ba3
1 changed files with 64 additions and 1 deletions
|
@ -34,6 +34,7 @@ use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem};
|
||||||
use gfx::display_list::{OpaqueNode, SolidColorDisplayItem};
|
use gfx::display_list::{OpaqueNode, SolidColorDisplayItem};
|
||||||
use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation};
|
use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation};
|
||||||
use gfx::paint_task::THREAD_TINT_COLORS;
|
use gfx::paint_task::THREAD_TINT_COLORS;
|
||||||
|
use gfx::text::glyph::CharIndex;
|
||||||
use gfx_traits::color;
|
use gfx_traits::color;
|
||||||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
use ipc_channel::ipc::{self, IpcSharedMemory};
|
||||||
use msg::compositor_msg::{ScrollPolicy, LayerId};
|
use msg::compositor_msg::{ScrollPolicy, LayerId};
|
||||||
|
@ -60,15 +61,19 @@ use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercenta
|
||||||
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
|
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::cursor::Cursor;
|
use util::cursor::Cursor;
|
||||||
use util::geometry::{Au, ZERO_POINT};
|
use util::geometry::{AU_PER_PX, Au, ZERO_POINT};
|
||||||
use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
|
||||||
use util::opts;
|
use util::opts;
|
||||||
|
use util::range::Range;
|
||||||
|
|
||||||
/// The fake fragment ID we use to indicate the inner display list for `overflow: scroll`.
|
/// The fake fragment ID we use to indicate the inner display list for `overflow: scroll`.
|
||||||
///
|
///
|
||||||
/// FIXME(pcwalton): This is pretty ugly. Consider modifying `LayerId` somehow.
|
/// FIXME(pcwalton): This is pretty ugly. Consider modifying `LayerId` somehow.
|
||||||
const FAKE_FRAGMENT_ID_FOR_OVERFLOW_SCROLL: u32 = 1000000;
|
const FAKE_FRAGMENT_ID_FOR_OVERFLOW_SCROLL: u32 = 1000000;
|
||||||
|
|
||||||
|
/// The logical width of an insertion point: at the moment, a one-pixel-wide line.
|
||||||
|
const INSERTION_POINT_LOGICAL_WIDTH: Au = Au(1 * AU_PER_PX);
|
||||||
|
|
||||||
/// Whether a stacking context needs a layer or not.
|
/// Whether a stacking context needs a layer or not.
|
||||||
pub enum StackingContextLayerNecessity {
|
pub enum StackingContextLayerNecessity {
|
||||||
Always(LayerId, ScrollPolicy),
|
Always(LayerId, ScrollPolicy),
|
||||||
|
@ -229,6 +234,14 @@ pub trait FragmentDisplayListBuilding {
|
||||||
stacking_relative_border_box: &Rect<Au>)
|
stacking_relative_border_box: &Rect<Au>)
|
||||||
-> ClippingRegion;
|
-> ClippingRegion;
|
||||||
|
|
||||||
|
/// Builds the display items necessary to paint the selection and/or caret for this fragment,
|
||||||
|
/// if any.
|
||||||
|
fn build_display_items_for_selection_if_necessary(&self,
|
||||||
|
display_list: &mut DisplayList,
|
||||||
|
stacking_relative_border_box: &Rect<Au>,
|
||||||
|
level: StackingLevel,
|
||||||
|
clip: &ClippingRegion);
|
||||||
|
|
||||||
/// Creates the text display item for one text fragment. This can be called multiple times for
|
/// Creates the text display item for one text fragment. This can be called multiple times for
|
||||||
/// one fragment if there are text shadows.
|
/// one fragment if there are text shadows.
|
||||||
///
|
///
|
||||||
|
@ -882,6 +895,50 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
(*parent_clip).clone().intersect_rect(&Rect::new(clip_origin, clip_size))
|
(*parent_clip).clone().intersect_rect(&Rect::new(clip_origin, clip_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_display_items_for_selection_if_necessary(&self,
|
||||||
|
display_list: &mut DisplayList,
|
||||||
|
stacking_relative_border_box: &Rect<Au>,
|
||||||
|
level: StackingLevel,
|
||||||
|
clip: &ClippingRegion) {
|
||||||
|
let scanned_text_fragment_info = match self.specific {
|
||||||
|
SpecificFragmentInfo::ScannedText(ref scanned_text_fragment_info) => {
|
||||||
|
scanned_text_fragment_info
|
||||||
|
}
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
let insertion_point_index = match scanned_text_fragment_info.insertion_point {
|
||||||
|
Some(insertion_point_index) => insertion_point_index,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
let range = Range::new(CharIndex(0), insertion_point_index);
|
||||||
|
let advance = scanned_text_fragment_info.run.advance_for_range(&range);
|
||||||
|
|
||||||
|
let insertion_point_bounds;
|
||||||
|
let cursor;
|
||||||
|
if !self.style.writing_mode.is_vertical() {
|
||||||
|
insertion_point_bounds =
|
||||||
|
Rect::new(Point2D::new(stacking_relative_border_box.origin.x + advance,
|
||||||
|
stacking_relative_border_box.origin.y),
|
||||||
|
Size2D::new(INSERTION_POINT_LOGICAL_WIDTH,
|
||||||
|
stacking_relative_border_box.size.height));
|
||||||
|
cursor = Cursor::TextCursor;
|
||||||
|
} else {
|
||||||
|
insertion_point_bounds =
|
||||||
|
Rect::new(Point2D::new(stacking_relative_border_box.origin.x,
|
||||||
|
stacking_relative_border_box.origin.y + advance),
|
||||||
|
Size2D::new(stacking_relative_border_box.size.width,
|
||||||
|
INSERTION_POINT_LOGICAL_WIDTH));
|
||||||
|
cursor = Cursor::VerticalTextCursor;
|
||||||
|
};
|
||||||
|
|
||||||
|
display_list.push(DisplayItem::SolidColorClass(box SolidColorDisplayItem {
|
||||||
|
base: BaseDisplayItem::new(insertion_point_bounds,
|
||||||
|
DisplayItemMetadata::new(self.node, &*self.style, cursor),
|
||||||
|
clip.clone()),
|
||||||
|
color: self.style().get_color().color.to_gfx_color(),
|
||||||
|
}), level);
|
||||||
|
}
|
||||||
|
|
||||||
fn build_display_list(&mut self,
|
fn build_display_list(&mut self,
|
||||||
display_list: &mut DisplayList,
|
display_list: &mut DisplayList,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
|
@ -991,6 +1048,12 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
&stacking_relative_border_box,
|
&stacking_relative_border_box,
|
||||||
&clip);
|
&clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Paint the selection point if necessary.
|
||||||
|
self.build_display_items_for_selection_if_necessary(display_list,
|
||||||
|
&stacking_relative_border_box,
|
||||||
|
level,
|
||||||
|
&clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create special per-fragment-type display items.
|
// Create special per-fragment-type display items.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue