Skip to content

Extract text colors per glyph #20245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions crates/bevy_ui_render/src/debug_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,19 @@ pub fn extract_debug_overlay(
render_entity: commands.spawn(TemporaryRenderEntity).id(),
// Add a large number to the UI node's stack index so that the overlay is always drawn on top
z_order: (ui_stack.uinodes.len() as u32 + uinode.stack_index()) as f32,
color: Hsla::sequential_dispersed(entity.index()).into(),
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
clip: maybe_clip
.filter(|_| !debug_options.show_clipped)
.map(|clip| clip.clip),
image: AssetId::default(),
extracted_camera_entity,
transform: transform.into(),
item: ExtractedUiItem::Node {
color: Hsla::sequential_dispersed(entity.index()).into(),
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
atlas_scaling: None,
transform: transform.into(),
flip_x: false,
flip_y: false,
border: BorderRect::all(debug_options.line_width / uinode.inverse_scale_factor()),
Expand Down
12 changes: 6 additions & 6 deletions crates/bevy_ui_render/src/gradient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,22 +400,22 @@ pub fn extract_gradients(
NodeType::Rect => stack_z_offsets::GRADIENT,
NodeType::Border(_) => stack_z_offsets::BORDER_GRADIENT,
},
color: color.into(),
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
image: AssetId::default(),
clip: clip.map(|clip| clip.clip),
extracted_camera_entity,
transform: transform.into(),
item: ExtractedUiItem::Node {
color: color.into(),
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
atlas_scaling: None,
flip_x: false,
flip_y: false,
border_radius: uinode.border_radius,
border: uinode.border,
node_type,
transform: transform.into(),
},
main_entity: entity.into(),
render_entity: commands.spawn(TemporaryRenderEntity).id(),
Expand Down
113 changes: 62 additions & 51 deletions crates/bevy_ui_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,15 +346,14 @@ impl<'w, 's> UiCameraMapper<'w, 's> {

pub struct ExtractedUiNode {
pub z_order: f32,
pub color: LinearRgba,
pub rect: Rect,
pub image: AssetId<Image>,
pub clip: Option<Rect>,
/// Render world entity of the extracted camera corresponding to this node's target camera.
pub extracted_camera_entity: Entity,
pub item: ExtractedUiItem,
pub main_entity: MainEntity,
pub render_entity: Entity,
pub transform: Affine2,
}

/// The type of UI node.
Expand All @@ -367,6 +366,8 @@ pub enum NodeType {

pub enum ExtractedUiItem {
Node {
color: LinearRgba,
rect: Rect,
atlas_scaling: Option<Vec2>,
flip_x: bool,
flip_y: bool,
Expand All @@ -377,7 +378,6 @@ pub enum ExtractedUiItem {
/// Ordering: left, top, right, bottom.
border: BorderRect,
node_type: NodeType,
transform: Affine2,
},
/// A contiguous sequence of text glyphs from the same section
Glyphs {
Expand All @@ -387,7 +387,8 @@ pub enum ExtractedUiItem {
}

pub struct ExtractedGlyph {
pub transform: Affine2,
pub color: LinearRgba,
pub translation: Vec2,
pub rect: Rect,
}

Expand Down Expand Up @@ -465,17 +466,17 @@ pub fn extract_uinode_background_colors(
extracted_uinodes.uinodes.push(ExtractedUiNode {
render_entity: commands.spawn(TemporaryRenderEntity).id(),
z_order: uinode.stack_index as f32 + stack_z_offsets::BACKGROUND_COLOR,
color: background_color.0.into(),
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
clip: clip.map(|clip| clip.clip),
image: AssetId::default(),
extracted_camera_entity,
transform: transform.into(),
item: ExtractedUiItem::Node {
color: background_color.0.into(),
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
atlas_scaling: None,
transform: transform.into(),
flip_x: false,
flip_y: false,
border: uinode.border(),
Expand Down Expand Up @@ -552,14 +553,14 @@ pub fn extract_uinode_images(
extracted_uinodes.uinodes.push(ExtractedUiNode {
z_order: uinode.stack_index as f32 + stack_z_offsets::IMAGE,
render_entity: commands.spawn(TemporaryRenderEntity).id(),
color: image.color.into(),
rect,
clip: clip.map(|clip| clip.clip),
image: image.image.id(),
extracted_camera_entity,
transform: transform.into(),
item: ExtractedUiItem::Node {
color: image.color.into(),
rect,
atlas_scaling,
transform: transform.into(),
flip_x: image.flip_x,
flip_y: image.flip_y,
border: uinode.border,
Expand Down Expand Up @@ -649,17 +650,17 @@ pub fn extract_uinode_borders(

extracted_uinodes.uinodes.push(ExtractedUiNode {
z_order: computed_node.stack_index as f32 + stack_z_offsets::BORDER,
color,
rect: Rect {
max: computed_node.size(),
..Default::default()
},
image,
clip: maybe_clip.map(|clip| clip.clip),
extracted_camera_entity,
transform: transform.into(),
item: ExtractedUiItem::Node {
color,
rect: Rect {
max: computed_node.size(),
..Default::default()
},
atlas_scaling: None,
transform: transform.into(),
flip_x: false,
flip_y: false,
border: computed_node.border(),
Expand All @@ -683,16 +684,16 @@ pub fn extract_uinode_borders(
extracted_uinodes.uinodes.push(ExtractedUiNode {
z_order: computed_node.stack_index as f32 + stack_z_offsets::BORDER,
render_entity: commands.spawn(TemporaryRenderEntity).id(),
color: outline.color.into(),
rect: Rect {
max: outline_size,
..Default::default()
},
image,
clip: maybe_clip.map(|clip| clip.clip),
extracted_camera_entity,
transform: transform.into(),
item: ExtractedUiItem::Node {
transform: transform.into(),
color: outline.color.into(),
rect: Rect {
max: outline_size,
..Default::default()
},
atlas_scaling: None,
flip_x: false,
flip_y: false,
Expand Down Expand Up @@ -874,17 +875,17 @@ pub fn extract_viewport_nodes(
extracted_uinodes.uinodes.push(ExtractedUiNode {
z_order: uinode.stack_index as f32 + stack_z_offsets::IMAGE,
render_entity: commands.spawn(TemporaryRenderEntity).id(),
color: LinearRgba::WHITE,
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
clip: clip.map(|clip| clip.clip),
image: image.id(),
extracted_camera_entity,
transform: transform.into(),
item: ExtractedUiItem::Node {
color: LinearRgba::WHITE,
rect: Rect {
min: Vec2::ZERO,
max: uinode.size,
},
atlas_scaling: None,
transform: transform.into(),
flip_x: false,
flip_y: false,
border: uinode.border(),
Expand All @@ -909,6 +910,7 @@ pub fn extract_text_sections(
Option<&CalculatedClip>,
&ComputedNodeTarget,
&ComputedTextBlock,
&TextColor,
&TextLayoutInfo,
)>,
>,
Expand All @@ -927,6 +929,7 @@ pub fn extract_text_sections(
clip,
camera,
computed_block,
text_color,
text_layout_info,
) in &uinode_query
{
Expand All @@ -941,6 +944,8 @@ pub fn extract_text_sections(

let transform = Affine2::from(*transform) * Affine2::from_translation(-0.5 * uinode.size());

let mut color = text_color.0.to_linear();

for (
i,
PositionedGlyph {
Expand All @@ -957,14 +962,16 @@ pub fn extract_text_sections(
.textures[atlas_info.location.glyph_index]
.as_rect();
extracted_uinodes.glyphs.push(ExtractedGlyph {
transform: transform * Affine2::from_translation(*position),
color,
//transform: transform * Affine2::from_translation(*position),
translation: *position,
rect,
});

if text_layout_info.glyphs.get(i + 1).is_none_or(|info| {
info.span_index != *span_index || info.atlas_info.texture != atlas_info.texture
}) {
let color = text_styles
color = text_styles
.get(
computed_block
.entities()
Expand All @@ -977,13 +984,12 @@ pub fn extract_text_sections(
extracted_uinodes.uinodes.push(ExtractedUiNode {
z_order: uinode.stack_index as f32 + stack_z_offsets::TEXT,
render_entity: commands.spawn(TemporaryRenderEntity).id(),
color,
image: atlas_info.texture,
clip: clip.map(|clip| clip.clip),
extracted_camera_entity,
rect,
item: ExtractedUiItem::Glyphs { range: start..end },
main_entity: entity.into(),
transform,
});
start = end;
}
Expand Down Expand Up @@ -1048,21 +1054,21 @@ pub fn extract_text_shadows(
.textures[atlas_info.location.glyph_index]
.as_rect();
extracted_uinodes.glyphs.push(ExtractedGlyph {
transform: node_transform * Affine2::from_translation(*position),
color: shadow.color.into(),
translation: *position,
rect,
});

if text_layout_info.glyphs.get(i + 1).is_none_or(|info| {
info.span_index != *span_index || info.atlas_info.texture != atlas_info.texture
}) {
extracted_uinodes.uinodes.push(ExtractedUiNode {
transform: node_transform,
z_order: uinode.stack_index as f32 + stack_z_offsets::TEXT,
render_entity: commands.spawn(TemporaryRenderEntity).id(),
color: shadow.color.into(),
image: atlas_info.texture,
clip: clip.map(|clip| clip.clip),
extracted_camera_entity,
rect,
item: ExtractedUiItem::Glyphs { range: start..end },
main_entity: entity.into(),
});
Expand Down Expand Up @@ -1115,17 +1121,17 @@ pub fn extract_text_background_colors(
extracted_uinodes.uinodes.push(ExtractedUiNode {
z_order: uinode.stack_index as f32 + stack_z_offsets::TEXT,
render_entity: commands.spawn(TemporaryRenderEntity).id(),
color: text_background_color.0.to_linear(),
rect: Rect {
min: Vec2::ZERO,
max: rect.size(),
},
clip: clip.map(|clip| clip.clip),
image: AssetId::default(),
extracted_camera_entity,
transform: transform * Affine2::from_translation(rect.center()),
item: ExtractedUiItem::Node {
color: text_background_color.0.to_linear(),
rect: Rect {
min: Vec2::ZERO,
max: rect.size(),
},
atlas_scaling: None,
transform: transform * Affine2::from_translation(rect.center()),
flip_x: false,
flip_y: false,
border: uinode.border(),
Expand Down Expand Up @@ -1396,18 +1402,21 @@ pub fn prepare_uinodes(
border_radius,
border,
node_type,
transform,
rect,
color,
} => {
let mut flags = if extracted_uinode.image != AssetId::default() {
shader_flags::TEXTURED
} else {
shader_flags::UNTEXTURED
};

let mut uinode_rect = extracted_uinode.rect;
let mut uinode_rect = *rect;

let rect_size = uinode_rect.size();

let transform = extracted_uinode.transform;

// Specify the corners of the node
let positions = QUAD_VERTEX_POSITIONS
.map(|pos| transform.transform_point2(pos * rect_size).extend(0.));
Expand Down Expand Up @@ -1515,7 +1524,7 @@ pub fn prepare_uinodes(
.map(|pos| pos / atlas_extent)
};

let color = extracted_uinode.color.to_f32_array();
let color = color.to_f32_array();
if let NodeType::Border(border_flags) = *node_type {
flags |= border_flags;
}
Expand Down Expand Up @@ -1547,16 +1556,18 @@ pub fn prepare_uinodes(

let atlas_extent = image.size_2d().as_vec2();

let color = extracted_uinode.color.to_f32_array();
for glyph in &extracted_uinodes.glyphs[range.clone()] {
let color = glyph.color.to_f32_array();
let glyph_rect = glyph.rect;
let rect_size = glyph_rect.size();

// Specify the corners of the glyph
let positions = QUAD_VERTEX_POSITIONS.map(|pos| {
glyph
extracted_uinode
.transform
.transform_point2(pos * glyph_rect.size())
.transform_point2(
glyph.translation + pos * glyph_rect.size(),
)
.extend(0.)
});

Expand Down Expand Up @@ -1592,7 +1603,7 @@ pub fn prepare_uinodes(

// cull nodes that are completely clipped
let transformed_rect_size =
glyph.transform.transform_vector2(rect_size);
extracted_uinode.transform.transform_vector2(rect_size);
if positions_diff[0].x - positions_diff[1].x
>= transformed_rect_size.x.abs()
|| positions_diff[1].y - positions_diff[2].y
Expand Down
Loading