Add img js if (#481)

* fix: add image writer in js

* fix: test
main
bokuweb 2022-05-23 16:24:44 +09:00 committed by GitHub
parent dc21e50877
commit 442cbf7857
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 199 additions and 12 deletions

View File

@ -10,7 +10,7 @@ pub fn main() -> Result<(), DocxError> {
let mut buf = Vec::new(); let mut buf = Vec::new();
let _ = img.read_to_end(&mut buf).unwrap(); let _ = img.read_to_end(&mut buf).unwrap();
let pic = Pic::new(buf) let pic = Pic::new(&buf)
.size(320 * 9525, 240 * 9525) .size(320 * 9525, 240 * 9525)
.floating() .floating()
.offset_x(300 * 9525) .offset_x(300 * 9525)

View File

@ -10,7 +10,7 @@ pub fn main() -> Result<(), DocxError> {
let mut buf = Vec::new(); let mut buf = Vec::new();
let _ = img.read_to_end(&mut buf).unwrap(); let _ = img.read_to_end(&mut buf).unwrap();
let pic = Pic::new(buf).size(320 * 9525, 240 * 9525); let pic = Pic::new(&buf).size(320 * 9525, 240 * 9525);
Docx::new() Docx::new()
.add_paragraph(Paragraph::new().add_run(Run::new().add_text("🐱").add_image(pic))) .add_paragraph(Paragraph::new().add_run(Run::new().add_text("🐱").add_image(pic)))
.build() .build()

View File

@ -147,7 +147,7 @@ mod tests {
let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap(); let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap();
let mut buf = Vec::new(); let mut buf = Vec::new();
let _ = img.read_to_end(&mut buf).unwrap(); let _ = img.read_to_end(&mut buf).unwrap();
let d = Box::new(Drawing::new().pic(Pic::new(buf))).build(); let d = Box::new(Drawing::new().pic(Pic::new(&buf))).build();
assert_eq!( assert_eq!(
str::from_utf8(&d).unwrap(), str::from_utf8(&d).unwrap(),
r#"<w:drawing> r#"<w:drawing>

View File

@ -47,13 +47,14 @@ pub struct Pic {
} }
impl Pic { impl Pic {
pub fn new(buf: Vec<u8>) -> Pic { pub fn new(buf: &[u8]) -> Pic {
let id = create_pic_rid(generate_pic_id()); let id = create_pic_rid(generate_pic_id());
let dimg = image::load_from_memory(&buf).unwrap(); let dimg = image::load_from_memory(buf).expect("Should load image from memory.");
let size = dimg.dimensions(); let size = dimg.dimensions();
let mut image = vec![]; let mut image = vec![];
// For now only png supported
dimg.write_to(&mut image, ImageFormat::Png) dimg.write_to(&mut image, ImageFormat::Png)
.expect("Unable to write"); .expect("Unable to write dynamic image");
Self { Self {
id, id,
image, image,
@ -224,7 +225,7 @@ mod tests {
let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap(); let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap();
let mut buf = Vec::new(); let mut buf = Vec::new();
let _ = img.read_to_end(&mut buf).unwrap(); let _ = img.read_to_end(&mut buf).unwrap();
let b = Pic::new(buf).build(); let b = Pic::new(&buf).build();
assert_eq!( assert_eq!(
str::from_utf8(&b).unwrap(), str::from_utf8(&b).unwrap(),
r#"<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"> r#"<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">

View File

@ -856,7 +856,8 @@ impl Docx {
if let Some(DrawingData::Pic(pic)) = &mut d.data { if let Some(DrawingData::Pic(pic)) = &mut d.data {
images.push(( images.push((
pic.id.clone(), pic.id.clone(),
format!("media/{}.jpg", pic.id), // For now only png supported
format!("media/{}.png", pic.id),
)); ));
let b = std::mem::take(&mut pic.image); let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b)); image_bufs.push((pic.id.clone(), b));
@ -881,7 +882,8 @@ impl Docx {
{ {
images.push(( images.push((
pic.id.clone(), pic.id.clone(),
format!("media/{}.jpg", pic.id), // For now only png supported
format!("media/{}.png", pic.id),
)); ));
let b = std::mem::take(&mut pic.image); let b = std::mem::take(&mut pic.image);
image_bufs.push((pic.id.clone(), b)); image_bufs.push((pic.id.clone(), b));

View File

@ -59,7 +59,8 @@ where
if !xml.media.is_empty() { if !xml.media.is_empty() {
zip.add_directory("word/media/", Default::default())?; zip.add_directory("word/media/", Default::default())?;
for m in xml.media { for m in xml.media {
zip.start_file(format!("word/media/image{}.jpg", m.0), options)?; // For now only png supported
zip.start_file(format!("word/media/{}.png", m.0), options)?;
zip.write_all(&m.1)?; zip.write_all(&m.1)?;
} }
} }

View File

@ -0,0 +1,33 @@
export class Image {
data: Uint8Array;
w: number | null = null;
h: number | null = null;
_floating: boolean = false;
_offsetX = 0;
_offsetY = 0;
constructor(data: Uint8Array) {
this.data = data;
}
size = (w: number, h: number) => {
this.w = w;
this.h = h;
return this;
};
floating = () => {
this._floating = true;
return this;
};
offsetX = (x: number) => {
this._offsetX = x;
return this;
};
offsetY = (y: number) => {
this._offsetY = y;
return this;
};
}

View File

@ -25,6 +25,8 @@ import { Styles } from "./styles";
import { WebExtension } from "./webextension"; import { WebExtension } from "./webextension";
import { Footer } from "./footer"; import { Footer } from "./footer";
import { Header } from "./header"; import { Header } from "./header";
import { Image } from "./image";
import { import {
SectionProperty, SectionProperty,
PageMargin, PageMargin,
@ -290,6 +292,21 @@ export class Docx {
} else if (child.type === "textWrapping") { } else if (child.type === "textWrapping") {
run = run.add_break(wasm.BreakType.TextWrapping); run = run.add_break(wasm.BreakType.TextWrapping);
} }
} else if (child instanceof Image) {
let pic = wasm.createPic(child.data);
if (child.w != null && child.h != null) {
pic = pic.size(child.w, child.h);
}
if (child._floating) {
pic = pic.floating();
}
if (child._offsetX != null) {
pic = pic.offset_x(child._offsetX);
}
if (child._offsetY != null) {
pic = pic.offset_x(child._offsetY);
}
run = run.add_image(pic);
} }
}); });
@ -1222,3 +1239,4 @@ export * from "./json";
export * from "./webextension"; export * from "./webextension";
export * from "./header"; export * from "./header";
export * from "./footer"; export * from "./footer";
export * from "./image";

View File

@ -5,8 +5,9 @@ import { DeleteText } from "./delete-text";
import { Tab } from "./tab"; import { Tab } from "./tab";
import { Break, BreakType } from "./break"; import { Break, BreakType } from "./break";
import { BorderType } from "./border"; import { BorderType } from "./border";
import { Image } from "./image";
export type RunChild = Text | DeleteText | Tab | Break; export type RunChild = Text | DeleteText | Tab | Break | Image;
export type TextBorder = { export type TextBorder = {
borderType: BorderType; borderType: BorderType;
@ -150,6 +151,11 @@ export class Run {
return this; return this;
} }
addImage(image: Image) {
this.children.push(image);
return this;
}
addDeleteText(text: string) { addDeleteText(text: string) {
this.children.push(new DeleteText(text)); this.children.push(new DeleteText(text));
return this; return this;

View File

@ -13,6 +13,7 @@ mod line_spacing;
mod numbering; mod numbering;
mod page_margin; mod page_margin;
mod paragraph; mod paragraph;
mod pic;
mod reader; mod reader;
mod run; mod run;
mod run_fonts; mod run_fonts;
@ -40,6 +41,7 @@ pub use line_spacing::*;
pub use numbering::*; pub use numbering::*;
pub use page_margin::*; pub use page_margin::*;
pub use paragraph::*; pub use paragraph::*;
pub use pic::*;
pub use reader::*; pub use reader::*;
pub use run::*; pub use run::*;
pub use run_fonts::*; pub use run_fonts::*;

View File

@ -0,0 +1,42 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug)]
pub struct Pic(docx_rs::Pic);
#[wasm_bindgen(js_name = createPic)]
pub fn create_pic(buf: &[u8]) -> Pic {
Pic(docx_rs::Pic::new(buf))
}
#[wasm_bindgen]
impl Pic {
// unit is emu
pub fn size(mut self, w_emu: u32, h_emu: u32) -> Self {
self.0 = self.0.size(w_emu, h_emu);
self
}
pub fn floating(mut self) -> Pic {
self.0 = self.0.floating();
self
}
pub fn offset_x(mut self, x: i32) -> Pic {
self.0 = self.0.offset_x(x);
self
}
pub fn offset_y(mut self, y: i32) -> Pic {
self.0 = self.0.offset_y(y);
self
}
// TODO: add other fns...
}
impl Pic {
pub fn take(self) -> docx_rs::Pic {
self.0
}
}

View File

@ -18,6 +18,11 @@ impl Run {
self self
} }
pub fn add_image(mut self, pic: Pic) -> Run {
self.0 = self.0.add_image(pic.take());
self
}
pub fn add_delete_text(mut self, text: &str) -> Run { pub fn add_delete_text(mut self, text: &str) -> Run {
self.0 self.0
.children .children

View File

@ -69379,6 +69379,60 @@ exports[`writer should write hyperlink 2`] = `
</w:document>" </w:document>"
`; `;
exports[`writer should write inline image 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
<Relationship Id=\\"rId1\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\\" Target=\\"styles.xml\\" />
<Relationship Id=\\"rId2\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\\" Target=\\"fontTable.xml\\" />
<Relationship Id=\\"rId3\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\\" Target=\\"settings.xml\\" />
<Relationship Id=\\"rId5\\" Type=\\"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\\" Target=\\"commentsExtended.xml\\" />
<Relationship Id=\\"rIdImage1\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\\" Target=\\"media/rIdImage1.png\\" />
</Relationships>"
`;
exports[`writer should write inline image 2`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"yes\\"?>
<w:document xmlns:o=\\"urn:schemas-microsoft-com:office:office\\" xmlns:r=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\\" xmlns:v=\\"urn:schemas-microsoft-com:vml\\" xmlns:w=\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\" xmlns:w10=\\"urn:schemas-microsoft-com:office:word\\" xmlns:wp=\\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\\" xmlns:wps=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\\" xmlns:wpg=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\\" xmlns:mc=\\"http://schemas.openxmlformats.org/markup-compatibility/2006\\" xmlns:wp14=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\\" xmlns:w14=\\"http://schemas.microsoft.com/office/word/2010/wordml\\" xmlns:w15=\\"http://schemas.microsoft.com/office/word/2012/wordml\\" mc:Ignorable=\\"w14 wp14\\">
<w:body><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space=\\"preserve\\">Hello world!!</w:t><w:drawing>
<wp:inline distT=\\"0\\" distB=\\"0\\" distL=\\"0\\" distR=\\"0\\">
<wp:extent cx=\\"3048000\\" cy=\\"2286000\\" />
<wp:effectExtent b=\\"0\\" l=\\"0\\" r=\\"0\\" t=\\"0\\" />
<wp:wrapNone />
<wp:docPr id=\\"1\\" name=\\"Figure\\" />
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a=\\"http://schemas.openxmlformats.org/drawingml/2006/main\\" noChangeAspect=\\"1\\" />
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a=\\"http://schemas.openxmlformats.org/drawingml/2006/main\\">
<a:graphicData uri=\\"http://schemas.openxmlformats.org/drawingml/2006/picture\\"><pic:pic xmlns:pic=\\"http://schemas.openxmlformats.org/drawingml/2006/picture\\">
<pic:nvPicPr>
<pic:cNvPr id=\\"0\\" name=\\"\\" />
<pic:cNvPicPr>
<a:picLocks noChangeAspect=\\"1\\" noChangeArrowheads=\\"1\\" />
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed=\\"rIdImage1\\" />
<a:srcRect />
<a:stretch>
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode=\\"auto\\">
<a:xfrm>
<a:off x=\\"0\\" y=\\"0\\" />
<a:ext cx=\\"3048000\\" cy=\\"2286000\\" />
</a:xfrm>
<a:prstGeom prst=\\"rect\\">
<a:avLst />
</a:prstGeom>
</pic:spPr>
</pic:pic></a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing></w:r></w:p><w:sectPr><w:pgSz w:w=\\"11906\\" w:h=\\"16838\\" /><w:pgMar w:top=\\"1985\\" w:right=\\"1701\\" w:bottom=\\"1701\\" w:left=\\"1701\\" w:header=\\"851\\" w:footer=\\"992\\" w:gutter=\\"0\\" /><w:cols w:space=\\"425\\" /><w:docGrid w:type=\\"lines\\" w:linePitch=\\"360\\" /></w:sectPr></w:body>
</w:document>"
`;
exports[`writer should write line spacing 1`] = ` exports[`writer should write line spacing 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?> "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\"> <Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">

File diff suppressed because one or more lines are too long