mete0r/pyhwp — Issue #32: 그림 파일 읽어오기
Author: mete0r
Created: 2012-02-05 13:26:09+00:00
State: open
Labels: OXT

그림 파일이 임베드된 hwp를 OXT를 통해 libreoffice에서 읽어오면, 그림이 제대로 읽히지 않음.

oxt/doc/references.txt 중에서 인용:

분석 1
------

ODT 패키지를 로딩할 때, 패키지에 포함된 그림 파일들을 바로 이어서 로딩하거나, LoadOnDemand 할 수 있음.
SvXMLImport::ResolveGraphicObjectURL(url, loadondemand) 참조.

그런데 SdXMLGraphicObjectShapeContext::StartElement()는 (line 2388 부근에서) SvXMLImport::ResolveGraphicObjectURL을 호출할 때
SvXMLImport::IsGraphicLoadOnDemandSupported()를 호출하는데, SvXMLImport는 기본값으로 true를 반환하며, SwXMLImport도 마찬가지인 듯 하다.

그래서 패키지를 처음 로딩할 때 이미지가 로딩되지 않고, 이후에 UI에서 on demand로 이미지를 로딩하는 듯 하다.
(sdr::contact::ViewObjectContactOfGraphic::doAsynchGraphicLoading()에서부터 추적)

그런데 실제로는 load on demand 과정에서 실패하는데, Storage에서 그림 스트림을 얻어내는 과정에서 실패한다.
(comphelper::OStorageHelper::GetStreamAtPackageURL()에서부터 추적)

일단 패키지 Storage가 (hwp에서 odt로 변환한) 임시 파일에 기반해 있기 때문에
추후 on demand 과정에서는 이 파일이 이미 사라졌기 때문이 아닌가 추측해볼 수 있는데,
hwp5file_convert_to_odtpkg_file()에서 임시파일 대신 특정한 위치에 고정된 파일을 만들어서
실험해봤을 때도 역시 그림 스트림을 얻어내는데서 실패하는 것으로 보아, 다른 이유일 수도 있음.

분석 2
------
on demand 로딩을 포기하고 content.xml을 로딩하면서 그림들도 함께 로딩되도록 하면, 그림들이 제대로 로딩되는 것을
확인할 수 있다:

com.sun.star.comp.Writer.XMLOasisContentImporter를 초기화할 때, 필터 인자로 graphic resolver를 다음처럼 초기화하여 넘겨준다.

createInstanceWithArguments('com.sun.star.comp.Svx.GraphicImportHelper', (storage,))

그리고 디버거상에서 SvXMLImporter::initialize()를 수행한 뒤, mbIsGraphicLoadOnDemandSupported = false로 강제로
설정한 뒤 진행하면 그림들이 제대로 로딩됨을 확인할 수 있다.

그런데 문제는 SvXMLImporter::mbIsGraphicLoadOnDemandSupported는 처음에 true로 설정된 뒤, 바뀌지 않는다는 것이다. 위처럼
디버거 상에서 강제로 false로 설정해주지 않는 한, SvXMLImporter::ResolveGraphicObjectURL(url, loadondemand)는 늘 두번째
인자를 true로 불리게 된다. (SdXMLGraphicObjectShapeContext::StartElement()의 라인 2388 부근)