mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🎉 Store list-style-type as a paragraph attribute
The bullet list toggle now saves list-style-type ("none" or "disc") on
the selected paragraphs and reads it back. A paragraph without the attr
counts as "none", so a bullet paragraph next to an older one shows as
mixed.
WASM keeps the value on each paragraph: the paragraph bytes grow from
12 to 16, Enter keeps it on the new paragraph, and the v3 editor reports
it in the current styles, so the sidebar shows it while editing too.
Refs #12630
AI-assisted-by: claude-opus-5-5
This commit is contained in:
parent
ce5b22d38f
commit
83dca9775f
@ -128,5 +128,7 @@
|
||||
(merge
|
||||
defaults
|
||||
(get-attrs-multi (->> (txt/node-seq txt/is-root-node? content)) root-attrs)
|
||||
(get-attrs-multi (->> (txt/node-seq txt/is-paragraph-node? content)) paragraph-attrs)
|
||||
(get-attrs-multi (->> (txt/node-seq txt/is-paragraph-node? content)
|
||||
(map #(merge txt/default-list-attrs %)))
|
||||
paragraph-attrs)
|
||||
(get-attrs-multi (->> (txt/node-seq txt/is-text-node? content)) text-node-attrs))))
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
["text-direction" "RawTextDirection"]
|
||||
["text-decoration" "RawTextDecoration"]
|
||||
["text-transform" "RawTextTransform"]
|
||||
["list-style-type" "RawListStyleType"]
|
||||
["multiple-state" "MultipleState"]
|
||||
["transform-entry-kind" "RawTransformEntryKind"]
|
||||
["segment-data" "RawSegmentData"]
|
||||
|
||||
@ -302,6 +302,16 @@
|
||||
[text-direction]
|
||||
(untranslate "text-direction" text-direction "ltr"))
|
||||
|
||||
(defn translate-list-style-type
|
||||
[list-style-type]
|
||||
(let [values (unchecked-get wasm/serializers "list-style-type")
|
||||
default (unchecked-get values "none")]
|
||||
(d/nilv (unchecked-get values (d/name list-style-type)) default)))
|
||||
|
||||
(defn untranslate-list-style-type
|
||||
[list-style-type]
|
||||
(untranslate "list-style-type" list-style-type "none"))
|
||||
|
||||
|
||||
(defn translate-font-style
|
||||
[font-style]
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
[app.common.uuid :as uuid]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(def ^:const PARAGRAPH-ATTR-U8-SIZE 12)
|
||||
(def ^:const PARAGRAPH-ATTR-U8-SIZE 16)
|
||||
(def ^:const SPAN-ATTR-U8-SIZE 64)
|
||||
(def ^:const MAX-TEXT-FILLS types.fills.impl/MAX-FILLS)
|
||||
|
||||
@ -109,7 +109,8 @@
|
||||
text-decoration (sr/translate-text-decoration (get paragraph :text-decoration))
|
||||
text-transform (sr/translate-text-transform (get paragraph :text-transform))
|
||||
line-height (serialize-line-height (get paragraph :line-height))
|
||||
letter-spacing (serialize-letter-spacing (get paragraph :letter-spacing))]
|
||||
letter-spacing (serialize-letter-spacing (get paragraph :letter-spacing))
|
||||
list-style-type (sr/translate-list-style-type (get paragraph :list-style-type))]
|
||||
(-> offset
|
||||
(mem/write-u8 dview text-align)
|
||||
(mem/write-u8 dview text-direction)
|
||||
@ -117,6 +118,11 @@
|
||||
(mem/write-u8 dview text-transform)
|
||||
(mem/write-f32 dview line-height)
|
||||
(mem/write-f32 dview letter-spacing)
|
||||
(mem/write-u8 dview list-style-type)
|
||||
;; padding
|
||||
(mem/write-u8 dview 0)
|
||||
(mem/write-u8 dview 0)
|
||||
(mem/write-u8 dview 0)
|
||||
(mem/assert-written offset PARAGRAPH-ATTR-U8-SIZE))))
|
||||
|
||||
(defn- write-spans
|
||||
|
||||
@ -357,6 +357,8 @@
|
||||
|
||||
:text-direction
|
||||
|
||||
:list-style-type
|
||||
|
||||
:line-height
|
||||
:letter-spacing
|
||||
|
||||
|
||||
@ -43,6 +43,9 @@
|
||||
(def text-direction-attrs
|
||||
[:text-direction])
|
||||
|
||||
(def text-list-attrs
|
||||
[:list-style-type])
|
||||
|
||||
(def text-spacing-attrs
|
||||
[:line-height
|
||||
:letter-spacing])
|
||||
@ -102,7 +105,8 @@
|
||||
(def paragraph-attrs
|
||||
(d/concat-vec
|
||||
text-align-attrs
|
||||
text-direction-attrs))
|
||||
text-direction-attrs
|
||||
text-list-attrs))
|
||||
|
||||
(def text-node-attrs
|
||||
(d/concat-vec
|
||||
@ -138,6 +142,10 @@
|
||||
{:text-align "left"
|
||||
:text-direction "ltr"})
|
||||
|
||||
(def default-list-attrs
|
||||
"Older paragraphs have no list attrs; read them as no list."
|
||||
{:list-style-type "none"})
|
||||
|
||||
(def default-text-attrs
|
||||
{:typography-ref-file nil
|
||||
:typography-ref-id nil
|
||||
|
||||
@ -148,4 +148,26 @@
|
||||
{:x -153}]
|
||||
result (attrs/get-attrs-multi objs [:x])]
|
||||
(t/is (= {:x :multiple} result)
|
||||
"Different positions should be :multiple"))))
|
||||
"Different positions should be :multiple"))))
|
||||
(defn- text-shape-with-paragraphs
|
||||
[& paragraphs]
|
||||
{:content {:type "root"
|
||||
:children [{:type "paragraph-set"
|
||||
:children (mapv #(merge {:type "paragraph"
|
||||
:children [{:text "item"}]}
|
||||
%)
|
||||
paragraphs)}]}})
|
||||
|
||||
(t/deftest get-text-attrs-multi-list-style-type
|
||||
(t/testing "paragraphs with the same list style return it"
|
||||
(let [shape (text-shape-with-paragraphs {:list-style-type "disc"}
|
||||
{:list-style-type "disc"})]
|
||||
(t/is (= "disc" (:list-style-type (attrs/get-text-attrs-multi shape {} [:list-style-type]))))))
|
||||
|
||||
(t/testing "a paragraph without list style counts as no list"
|
||||
(let [shape (text-shape-with-paragraphs {})]
|
||||
(t/is (= "none" (:list-style-type (attrs/get-text-attrs-multi shape {} [:list-style-type]))))))
|
||||
|
||||
(t/testing "a bullet paragraph next to one without list style is mixed"
|
||||
(let [shape (text-shape-with-paragraphs {:list-style-type "disc"} {})]
|
||||
(t/is (= :multiple (:list-style-type (attrs/get-text-attrs-multi shape {} [:list-style-type])))))))
|
||||
|
||||
@ -434,7 +434,9 @@
|
||||
|
||||
(-> (merge default-text-attrs node)
|
||||
(assoc :fills fills)))
|
||||
node))))]
|
||||
(cond->> node
|
||||
(txt/is-paragraph-node? node)
|
||||
(merge txt/default-list-attrs))))))]
|
||||
(attrs/get-attrs-multi nodes attrs)))
|
||||
|
||||
(defn current-root-values
|
||||
|
||||
@ -310,6 +310,8 @@
|
||||
(get n-values :grow-type))
|
||||
(identical? (get o-values :letter-spacing)
|
||||
(get n-values :letter-spacing))
|
||||
(identical? (get o-values :list-style-type)
|
||||
(get n-values :list-style-type))
|
||||
(identical? (get o-values :line-height)
|
||||
(get n-values :line-height))
|
||||
(identical? (get o-values :text-align)
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
(def multiple-state-multiple (sr/translate-multiple-state :multiple))
|
||||
|
||||
(def ^:const TEXT_EDITOR_STYLES_METADATA_SIZE (* 31 4))
|
||||
(def ^:const TEXT_EDITOR_STYLES_METADATA_SIZE (* 33 4))
|
||||
(def ^:const TEXT_EDITOR_STYLES_FILL_SOLID 0)
|
||||
(def ^:const TEXT_EDITOR_STYLES_FILL_LINEAR_GRADIENT 1)
|
||||
(def ^:const TEXT_EDITOR_STYLES_FILL_RADIAL_GRADIENT 2)
|
||||
@ -325,6 +325,8 @@
|
||||
font-weight-value (aget heap-i32 (+ u32-offset 24))
|
||||
line-height-value (aget heap-f32 (+ u32-offset 29))
|
||||
letter-spacing-value (aget heap-f32 (+ u32-offset 30))
|
||||
list-style-type-state (aget heap-u32 (+ u32-offset 31))
|
||||
list-style-type-value (aget heap-u32 (+ u32-offset 32))
|
||||
font-id (fonts/uuid->font-id font-family-id-value)
|
||||
font-style-value (sr/untranslate-font-style (text-editor-get-style-property font-style-state font-style-raw-value))
|
||||
font-variant-id-computed (text-editor-compute-font-variant-id font-id font-weight-value font-style-value)
|
||||
@ -356,6 +358,7 @@
|
||||
:text-direction (sr/untranslate-text-direction (text-editor-get-style-property text-direction-state text-direction-value))
|
||||
:text-decoration (sr/untranslate-text-decoration (text-editor-get-style-property text-decoration-state text-decoration-value))
|
||||
:text-transform (sr/untranslate-text-transform (text-editor-get-style-property text-transform-state text-transform-value))
|
||||
:list-style-type (sr/untranslate-list-style-type (text-editor-get-style-property list-style-type-state list-style-type-value))
|
||||
;; WASM reports size/weight as numbers, but the rest of Penpot (and the backend schema) expects strings.
|
||||
:line-height (let [height (text-editor-get-style-property line-height-state line-height-value)]
|
||||
(if (= height :multiple) height (str height)))
|
||||
|
||||
@ -1396,6 +1396,13 @@ pub enum TextTransform {
|
||||
Capitalize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy, Default)]
|
||||
pub enum ListStyleType {
|
||||
#[default]
|
||||
None,
|
||||
Disc,
|
||||
}
|
||||
|
||||
// FIXME: Rethink this type. We'll probably need to move the serialization to the
|
||||
// wasm module and store here meaningful model values (and/or skia type aliases)
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
@ -1406,6 +1413,7 @@ pub struct Paragraph {
|
||||
text_transform: Option<TextTransform>,
|
||||
line_height: f32,
|
||||
letter_spacing: f32,
|
||||
list_style_type: ListStyleType,
|
||||
children: Vec<TextSpan>,
|
||||
}
|
||||
|
||||
@ -1418,6 +1426,7 @@ impl Default for Paragraph {
|
||||
text_transform: None,
|
||||
line_height: 1.0,
|
||||
letter_spacing: 0.0,
|
||||
list_style_type: ListStyleType::None,
|
||||
children: vec![],
|
||||
}
|
||||
}
|
||||
@ -1441,10 +1450,16 @@ impl Paragraph {
|
||||
text_transform,
|
||||
line_height,
|
||||
letter_spacing,
|
||||
list_style_type: ListStyleType::None,
|
||||
children,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_list_style_type(mut self, list_style_type: ListStyleType) -> Self {
|
||||
self.list_style_type = list_style_type;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn children(&self) -> &[TextSpan] {
|
||||
&self.children
|
||||
}
|
||||
@ -1557,6 +1572,10 @@ impl Paragraph {
|
||||
self.text_transform
|
||||
}
|
||||
|
||||
pub fn list_style_type(&self) -> ListStyleType {
|
||||
self.list_style_type
|
||||
}
|
||||
|
||||
pub fn paragraph_to_style(&self) -> ParagraphStyle {
|
||||
let mut style = ParagraphStyle::default();
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
use macros::ToJs;
|
||||
|
||||
use crate::shapes::{
|
||||
Fill, FontStyle, TextAlign, TextContent, TextDecoration, TextDirection,
|
||||
Fill, FontStyle, ListStyleType, TextAlign, TextContent, TextDecoration, TextDirection,
|
||||
TextPositionWithAffinity, TextTransform, VerticalAlign,
|
||||
};
|
||||
use crate::uuid::Uuid;
|
||||
@ -109,6 +109,7 @@ pub struct TextEditorStyles {
|
||||
pub text_direction: Multiple<TextDirection>, // Multiple
|
||||
pub text_decoration: Multiple<TextDecoration>,
|
||||
pub text_transform: Multiple<TextTransform>,
|
||||
pub list_style_type: Multiple<ListStyleType>,
|
||||
// The font family is decomposed into its independent parts so the family
|
||||
// dropdown shows a single family even when the selection mixes variants of
|
||||
// the same family (e.g. regular + bold italic). The id identifies the
|
||||
@ -232,6 +233,7 @@ impl TextEditorStyles {
|
||||
text_direction: Multiple::empty(),
|
||||
text_decoration: Multiple::empty(),
|
||||
text_transform: Multiple::empty(),
|
||||
list_style_type: Multiple::empty(),
|
||||
font_family_id: Multiple::empty(),
|
||||
font_style: Multiple::empty(),
|
||||
font_size: Multiple::empty(),
|
||||
@ -249,6 +251,7 @@ impl TextEditorStyles {
|
||||
self.text_direction.reset();
|
||||
self.text_decoration.reset();
|
||||
self.text_transform.reset();
|
||||
self.list_style_type.reset();
|
||||
self.font_family_id.reset();
|
||||
self.font_style.reset();
|
||||
self.font_size.reset();
|
||||
@ -638,6 +641,9 @@ impl TextEditorState {
|
||||
self.current_styles
|
||||
.text_align
|
||||
.merge(Some(paragraph.text_align()));
|
||||
self.current_styles
|
||||
.list_style_type
|
||||
.merge(Some(paragraph.list_style_type()));
|
||||
|
||||
let mut char_pos = 0;
|
||||
for span in paragraph.children() {
|
||||
@ -706,6 +712,9 @@ impl TextEditorState {
|
||||
self.current_styles
|
||||
.text_align
|
||||
.set_single(Some(current_paragraph.text_align()));
|
||||
self.current_styles
|
||||
.list_style_type
|
||||
.set_single(Some(current_paragraph.list_style_type()));
|
||||
if let Some((text_span_index, _)) = current_text_span {
|
||||
if let Some(text_span) = current_paragraph.children().get(text_span_index) {
|
||||
self.current_styles
|
||||
@ -1030,6 +1039,34 @@ mod tests {
|
||||
content
|
||||
}
|
||||
|
||||
fn list_content() -> TextContent {
|
||||
let black = Fill::Solid(SolidColor(Color::BLACK));
|
||||
let mut content =
|
||||
TextContent::new(Rect::from_xywh(0.0, 0.0, 200.0, 100.0), GrowType::Fixed);
|
||||
content.add_paragraph(
|
||||
Paragraph::new(
|
||||
TextAlign::Left,
|
||||
TextDirection::LTR,
|
||||
None,
|
||||
None,
|
||||
1.2,
|
||||
0.0,
|
||||
vec![span("Bullet", 14.0, black.clone())],
|
||||
)
|
||||
.with_list_style_type(ListStyleType::Disc),
|
||||
);
|
||||
content.add_paragraph(Paragraph::new(
|
||||
TextAlign::Left,
|
||||
TextDirection::LTR,
|
||||
None,
|
||||
None,
|
||||
1.2,
|
||||
0.0,
|
||||
vec![span("Plain", 14.0, black)],
|
||||
));
|
||||
content
|
||||
}
|
||||
|
||||
fn drain_events(editor: &mut TextEditorState) -> Vec<TextEditorEvent> {
|
||||
let mut events = Vec::new();
|
||||
loop {
|
||||
@ -1046,6 +1083,38 @@ mod tests {
|
||||
TextPositionWithAffinity::new_downstream_affinity(0, offset)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn caret_styles_report_the_paragraph_list_style_type() {
|
||||
let content = list_content();
|
||||
let mut editor = TextEditorState::new();
|
||||
|
||||
editor.place_caret_from_position(
|
||||
&content,
|
||||
&TextPositionWithAffinity::new_downstream_affinity(0, 2),
|
||||
);
|
||||
assert_eq!(
|
||||
editor.current_styles.list_style_type.value(),
|
||||
&Some(ListStyleType::Disc)
|
||||
);
|
||||
|
||||
editor.place_caret_from_position(
|
||||
&content,
|
||||
&TextPositionWithAffinity::new_downstream_affinity(1, 2),
|
||||
);
|
||||
assert_eq!(
|
||||
editor.current_styles.list_style_type.value(),
|
||||
&Some(ListStyleType::None)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_styles_mark_mixed_list_style_types_as_multiple() {
|
||||
let content = list_content();
|
||||
let mut editor = TextEditorState::new();
|
||||
editor.select_all(&content);
|
||||
assert!(editor.current_styles.list_style_type.is_multiple());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_caret_from_position_alone_does_not_emit_styles_changed() {
|
||||
let content = hello_world_content();
|
||||
|
||||
@ -4,7 +4,8 @@ use super::{fills::RawFillData, fonts::RawFontStyle};
|
||||
|
||||
use crate::mem::{self, SerializableResult};
|
||||
use crate::shapes::{
|
||||
self, GrowType, Shape, TextAlign, TextDecoration, TextDirection, TextTransform, Type,
|
||||
self, GrowType, ListStyleType, Shape, TextAlign, TextDecoration, TextDirection, TextTransform,
|
||||
Type,
|
||||
};
|
||||
use crate::utils::{uuid_from_u32, uuid_from_u32_quartet};
|
||||
use crate::{with_current_shape, with_current_shape_mut, with_state};
|
||||
@ -94,6 +95,31 @@ impl From<RawTextTransform> for Option<TextTransform> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy, ToJs)]
|
||||
#[repr(u8)]
|
||||
pub enum RawListStyleType {
|
||||
None = 0,
|
||||
Disc = 1,
|
||||
}
|
||||
|
||||
impl From<RawListStyleType> for ListStyleType {
|
||||
fn from(value: RawListStyleType) -> Self {
|
||||
match value {
|
||||
RawListStyleType::None => ListStyleType::None,
|
||||
RawListStyleType::Disc => ListStyleType::Disc,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ListStyleType> for RawListStyleType {
|
||||
fn from(value: ListStyleType) -> Self {
|
||||
match value {
|
||||
ListStyleType::None => RawListStyleType::None,
|
||||
ListStyleType::Disc => RawListStyleType::Disc,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[repr(align(4))]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@ -105,6 +131,8 @@ pub struct RawParagraphData {
|
||||
text_transform: RawTextTransform,
|
||||
line_height: f32,
|
||||
letter_spacing: f32,
|
||||
list_style_type: RawListStyleType,
|
||||
_padding: [u8; 3],
|
||||
}
|
||||
|
||||
impl From<[u8; RAW_PARAGRAPH_DATA_SIZE]> for RawParagraphData {
|
||||
@ -253,6 +281,7 @@ impl From<RawParagraph> for shapes::Paragraph {
|
||||
value.attrs.letter_spacing,
|
||||
spans,
|
||||
)
|
||||
.with_list_style_type(value.attrs.list_style_type.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -825,6 +825,7 @@ pub fn split_paragraph_at_cursor(
|
||||
let text_transform = para.text_transform();
|
||||
let line_height = para.line_height();
|
||||
let letter_spacing = para.letter_spacing();
|
||||
let list_style_type = para.list_style_type();
|
||||
|
||||
let para = &mut paragraphs[cursor.paragraph];
|
||||
let children = para.children_mut();
|
||||
@ -846,7 +847,8 @@ pub fn split_paragraph_at_cursor(
|
||||
line_height,
|
||||
letter_spacing,
|
||||
new_para_children,
|
||||
);
|
||||
)
|
||||
.with_list_style_type(list_style_type);
|
||||
|
||||
paragraphs.insert(cursor.paragraph + 1, new_para);
|
||||
|
||||
@ -857,7 +859,7 @@ pub fn split_paragraph_at_cursor(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::math::Rect;
|
||||
use crate::shapes::{FontFamily, FontStyle, GrowType, TextAlign, TextSpan};
|
||||
use crate::shapes::{FontFamily, FontStyle, GrowType, ListStyleType, TextAlign, TextSpan};
|
||||
use crate::uuid::Uuid;
|
||||
|
||||
fn span(text: &str) -> TextSpan {
|
||||
@ -951,6 +953,19 @@ mod tests {
|
||||
TextPositionWithAffinity::new_downstream_affinity(paragraph, offset)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn split_paragraph_keeps_the_list_style_type() {
|
||||
let mut content = content(vec![
|
||||
paragraph(&["Hello world"]).with_list_style_type(ListStyleType::Disc)
|
||||
]);
|
||||
assert!(split_paragraph_at_cursor(&mut content, &caret(0, 5)));
|
||||
|
||||
let paragraphs = content.paragraphs();
|
||||
assert_eq!(paragraphs.len(), 2);
|
||||
assert_eq!(paragraphs[0].list_style_type(), ListStyleType::Disc);
|
||||
assert_eq!(paragraphs[1].list_style_type(), ListStyleType::Disc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn delete_char_before_deletes_a_whole_emoji() {
|
||||
for emoji in ["😀", "👍🏽", "👨\u{200d}👩\u{200d}👧", "🇪🇸"] {
|
||||
|
||||
@ -11,7 +11,8 @@ use crate::utils::uuid_to_u32_quartet;
|
||||
use crate::uuid::Uuid;
|
||||
use crate::wasm::fills::RawFillData;
|
||||
use crate::wasm::text::{
|
||||
helpers as text_helpers, RawTextAlign, RawTextDecoration, RawTextDirection, RawTextTransform,
|
||||
helpers as text_helpers, RawListStyleType, RawTextAlign, RawTextDecoration, RawTextDirection,
|
||||
RawTextTransform,
|
||||
};
|
||||
use crate::with_state;
|
||||
use skia_safe::Color;
|
||||
@ -741,6 +742,13 @@ pub extern "C" fn text_editor_get_current_styles() -> *mut u8 {
|
||||
})
|
||||
.unwrap_or(RawTextTransform::None as u32);
|
||||
|
||||
let list_style_type = styles
|
||||
.list_style_type
|
||||
.value()
|
||||
.as_ref()
|
||||
.map(|value| RawListStyleType::from(*value) as u32)
|
||||
.unwrap_or(RawListStyleType::None as u32);
|
||||
|
||||
let font_family_id = styles
|
||||
.font_family_id
|
||||
.value()
|
||||
@ -817,7 +825,9 @@ pub extern "C" fn text_editor_get_current_styles() -> *mut u8 {
|
||||
bytes.extend_from_slice(&font_variant_id[3].to_le_bytes()); // 112 // 28
|
||||
bytes.extend_from_slice(&line_height.to_le_bytes()); // 116 // 29
|
||||
bytes.extend_from_slice(&letter_spacing.to_le_bytes()); // 120 // 30
|
||||
bytes.extend_from_slice(&fill_bytes); // 124
|
||||
bytes.extend_from_slice(&(*styles.list_style_type.state() as u32).to_le_bytes()); // 124 // 31
|
||||
bytes.extend_from_slice(&list_style_type.to_le_bytes()); // 128 // 32
|
||||
bytes.extend_from_slice(&fill_bytes); // 132
|
||||
|
||||
mem::write_bytes(bytes)
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user