Skip to content
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

feat(hwp): ColorFill 파싱 마무리 #75

Merged
merged 1 commit into from
Nov 7, 2022
Merged
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
97 changes: 88 additions & 9 deletions crates/hwp/src/hwp/doc_info/border_fill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,19 +180,38 @@ impl Fill {
pub fn from_reader<T: Read>(reader: &mut T) -> Self {
let kind = FillKind::from_u32(reader.read_u32::<LittleEndian>().unwrap()).unwrap();

// TODO: (@hahnlee) 나머지 채우기
let content = match kind {
FillKind::Color => FillContent::Color(ColorFill::from_reader(reader)),
_ => FillContent::None(()),
FillKind::Gradation => FillContent::Gradation(GradationFill::from_reader(reader)),
FillKind::Image => FillContent::Image(ImageFill::from_reader(reader)),
FillKind::None => {
// NOTE: (@hahnlee) 추가정보의 길이, 항상 0이다
assert_eq!(reader.read_u32::<LittleEndian>().unwrap(), 0);
FillContent::None(())
}
};

Self { kind, content }
}

pub fn as_color_fill(&self) -> &ColorFill {
pub fn as_color_fill(&self) -> Result<&ColorFill, ()> {
match &self.content {
FillContent::Color(color) => color,
_ => panic!("color_fill이 아닙니다"),
FillContent::Color(color) => Ok(color),
_ => Err(()),
}
}

pub fn as_gradation_fill(&self) -> Result<&GradationFill, ()> {
match &self.content {
FillContent::Gradation(gradation) => Ok(gradation),
_ => Err(()),
}
}

pub fn as_image_fill(&self) -> Result<&ImageFill, ()> {
match &self.content {
FillContent::Image(image) => Ok(image),
_ => Err(()),
}
}
}
Expand All @@ -214,19 +233,79 @@ pub enum FillKind {
pub enum FillContent {
None(()),
Color(ColorFill),
Gradation(GradationFill),
Image(ImageFill),
}

#[derive(Debug)]
pub struct ColorFill {
pub background: ColorRef,
pub pattern: ColorRef,
/// 배경색
pub background_color: ColorRef,
/// 무늬색
pub pattern_color: ColorRef,
/// 무늬종류
pub pattern_kind: PatternKind,
/// 투명도
pub alpha: u8,
}

impl ColorFill {
fn from_reader<T: Read>(reader: &mut T) -> Self {
let background_color = ColorRef::from_u32(reader.read_u32::<LittleEndian>().unwrap());
let pattern_color = ColorRef::from_u32(reader.read_u32::<LittleEndian>().unwrap());
let pattern_kind =
PatternKind::from_i32(reader.read_i32::<LittleEndian>().unwrap() + 1).unwrap();

// NOTE: (@hahnlee) HWPX에 정의되어 있음
let alpha = reader.read_u8().unwrap();

// NOTE: (@hahnlee) 추가정보의 길이, 여기서는 무시한다
assert_eq!(reader.read_u32::<LittleEndian>().unwrap(), 0);

Self {
background: ColorRef::from_u32(reader.read_u32::<LittleEndian>().unwrap()),
pattern: ColorRef::from_u32(reader.read_u32::<LittleEndian>().unwrap()),
background_color,
pattern_color,
pattern_kind,
alpha,
}
}
}

/// 채우기 무늬 종류
#[derive(Debug, PartialEq, FromPrimitive)]
pub enum PatternKind {
/// 없음
None,
/// - - - -
Horizontal,
/// |||||
Vertical,
/// \\\\\
BackSlash,
/// /////
Slash,
/// +++++
Cross,
/// xxxxx
CrossDiagonal,
}

#[derive(Debug)]
pub struct GradationFill {}

impl GradationFill {
fn from_reader<T: Read>(_: &mut T) -> Self {
// TODO: (@hahnlee)
Self {}
}
}

#[derive(Debug)]
pub struct ImageFill {}

impl ImageFill {
fn from_reader<T: Read>(_: &mut T) -> Self {
// TODO: (@hahnlee)
Self {}
}
}
2 changes: 1 addition & 1 deletion crates/hwp/src/hwp/paragraph/control/book_mark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl Bookmark {
let child = cursor.current();
let mut data = child.get_data_reader();

// NOTE: (@hahnlee) 실제를 보니
// NOTE: (@hahnlee) 실제를 보니 u16으로 추정
let parameter_set_id = data.read_u16::<LittleEndian>().unwrap();

// NOTE: (@hahnlee) 확인필요. 표준문서에는 WORD로 제시되어 있으나 실제론 2바이트가 남음.
Expand Down
Binary file not shown.
33 changes: 29 additions & 4 deletions crates/hwp/tests/integration/project/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use hwp::HWP;
use hwp::{
hwp::doc_info::border_fill::{FillKind, PatternKind},
HWP,
};
use std::fs;

use crate::utils::get_tests_path;
Expand Down Expand Up @@ -47,7 +50,6 @@ fn check_range_tags() {
assert_eq!(hwp.body_texts.sections[0].paragraphs[0].range_tags.len(), 3);
}


#[test]
fn check_bookmark() {
let path = get_tests_path("integration/project/files/bookmark.hwp");
Expand Down Expand Up @@ -82,7 +84,6 @@ fn check_over_type() {
assert_eq!(hwp.body_texts.sections.len(), 1);
}


#[test]
fn check_dutmal() {
let path = get_tests_path("integration/project/files/dutmal.hwp");
Expand All @@ -98,4 +99,28 @@ fn check_dutmal() {
assert_eq!(hwp.header.license.replication_restrictions, false);

assert_eq!(hwp.body_texts.sections.len(), 1);
}
}

#[test]
fn check_color_fill() {
let path = get_tests_path("integration/project/files/color_fill.hwp");
let file = fs::read(path).unwrap();

let hwp = HWP::from_bytes(&file);

assert_eq!(hwp.header.version.to_string(), "5.1.0.1");
assert_eq!(hwp.header.flags.compressed, true);
assert_eq!(hwp.header.flags.distributed, false);

assert_eq!(hwp.header.license.ccl, false);
assert_eq!(hwp.header.license.replication_restrictions, false);

assert_eq!(hwp.body_texts.sections.len(), 1);

let border_fill = hwp.doc_info.id_mappings.border_fills.last().unwrap();
assert_eq!(border_fill.fill.kind, FillKind::Color);

let color_fill = border_fill.fill.as_color_fill().unwrap();
assert_eq!(color_fill.alpha, 0);
assert_eq!(color_fill.pattern_kind, PatternKind::Vertical);
}