parent
dc21e50877
commit
442cbf7857
|
@ -10,7 +10,7 @@ pub fn main() -> Result<(), DocxError> {
|
|||
let mut buf = Vec::new();
|
||||
let _ = img.read_to_end(&mut buf).unwrap();
|
||||
|
||||
let pic = Pic::new(buf)
|
||||
let pic = Pic::new(&buf)
|
||||
.size(320 * 9525, 240 * 9525)
|
||||
.floating()
|
||||
.offset_x(300 * 9525)
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn main() -> Result<(), DocxError> {
|
|||
let mut buf = Vec::new();
|
||||
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()
|
||||
.add_paragraph(Paragraph::new().add_run(Run::new().add_text("🐱").add_image(pic)))
|
||||
.build()
|
||||
|
|
|
@ -147,7 +147,7 @@ mod tests {
|
|||
let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap();
|
||||
let mut buf = Vec::new();
|
||||
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!(
|
||||
str::from_utf8(&d).unwrap(),
|
||||
r#"<w:drawing>
|
||||
|
|
|
@ -47,13 +47,14 @@ pub struct 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 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 mut image = vec![];
|
||||
// For now only png supported
|
||||
dimg.write_to(&mut image, ImageFormat::Png)
|
||||
.expect("Unable to write");
|
||||
.expect("Unable to write dynamic image");
|
||||
Self {
|
||||
id,
|
||||
image,
|
||||
|
@ -224,7 +225,7 @@ mod tests {
|
|||
let mut img = std::fs::File::open("../images/cat_min.jpg").unwrap();
|
||||
let mut buf = Vec::new();
|
||||
let _ = img.read_to_end(&mut buf).unwrap();
|
||||
let b = Pic::new(buf).build();
|
||||
let b = Pic::new(&buf).build();
|
||||
assert_eq!(
|
||||
str::from_utf8(&b).unwrap(),
|
||||
r#"<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
|
||||
|
|
|
@ -856,7 +856,8 @@ impl Docx {
|
|||
if let Some(DrawingData::Pic(pic)) = &mut d.data {
|
||||
images.push((
|
||||
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);
|
||||
image_bufs.push((pic.id.clone(), b));
|
||||
|
@ -881,7 +882,8 @@ impl Docx {
|
|||
{
|
||||
images.push((
|
||||
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);
|
||||
image_bufs.push((pic.id.clone(), b));
|
||||
|
|
|
@ -59,7 +59,8 @@ where
|
|||
if !xml.media.is_empty() {
|
||||
zip.add_directory("word/media/", Default::default())?;
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
|
@ -25,6 +25,8 @@ import { Styles } from "./styles";
|
|||
import { WebExtension } from "./webextension";
|
||||
import { Footer } from "./footer";
|
||||
import { Header } from "./header";
|
||||
import { Image } from "./image";
|
||||
|
||||
import {
|
||||
SectionProperty,
|
||||
PageMargin,
|
||||
|
@ -290,6 +292,21 @@ export class Docx {
|
|||
} else if (child.type === "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 "./header";
|
||||
export * from "./footer";
|
||||
export * from "./image";
|
||||
|
|
|
@ -5,8 +5,9 @@ import { DeleteText } from "./delete-text";
|
|||
import { Tab } from "./tab";
|
||||
import { Break, BreakType } from "./break";
|
||||
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 = {
|
||||
borderType: BorderType;
|
||||
|
@ -150,6 +151,11 @@ export class Run {
|
|||
return this;
|
||||
}
|
||||
|
||||
addImage(image: Image) {
|
||||
this.children.push(image);
|
||||
return this;
|
||||
}
|
||||
|
||||
addDeleteText(text: string) {
|
||||
this.children.push(new DeleteText(text));
|
||||
return this;
|
||||
|
|
|
@ -13,6 +13,7 @@ mod line_spacing;
|
|||
mod numbering;
|
||||
mod page_margin;
|
||||
mod paragraph;
|
||||
mod pic;
|
||||
mod reader;
|
||||
mod run;
|
||||
mod run_fonts;
|
||||
|
@ -40,6 +41,7 @@ pub use line_spacing::*;
|
|||
pub use numbering::*;
|
||||
pub use page_margin::*;
|
||||
pub use paragraph::*;
|
||||
pub use pic::*;
|
||||
pub use reader::*;
|
||||
pub use run::*;
|
||||
pub use run_fonts::*;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -18,6 +18,11 @@ impl Run {
|
|||
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 {
|
||||
self.0
|
||||
.children
|
||||
|
|
|
@ -69379,6 +69379,60 @@ exports[`writer should write hyperlink 2`] = `
|
|||
</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`] = `
|
||||
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
|
||||
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue