Skip to content

Commit

Permalink
Flip and rotate images in ODT output
Browse files Browse the repository at this point in the history
Extensive experimentation with LibreOffice 24.8.3.2 on Mac didn't come
up with a way to create an ODT with an image that is displayed
uncropped, at the correct aspect ratio, with the correct size of
bounding box, after rotating 90° or 270°, while anchored "as character".

As of this commit, if the EXIF orientation says an image needs to be
quarter-rotated, the solution chosen has a bounding box the original,
unrotated size of the image, which displays the image correctly rotated
and with the correct aspect ratio, but cropped.  It is unknown to this
author if this looks correct in other software than LibreOffice.

Pandoc doesn't currently pull in any dependencies capable of rotating
the actual pixels in image data. Document authors needing to mitigate
this issue will have to edit their images themselves.
  • Loading branch information
silby committed Nov 22, 2024
1 parent be7e706 commit c5f0190
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 3 deletions.
12 changes: 10 additions & 2 deletions src/Text/Pandoc/Writers/ODT.hs
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,19 @@ transformPicMath opts (Image attr@(id', cls, _) lab (src,t)) = catchError
Left msg -> do
report $ CouldNotDetermineImageSize src msg
return (100, 100)
let (ImageTransform flp rot) = imageTransform img
let xflip NoFlip = ("mirror", "none")
xflip FlipH = ("mirror", "horizontal")
xflip FlipV = ("mirror", "vertical")
let xrotate R0 = ("rotate", "rotate(0)")
xrotate R90 = ("rotate", "rotate(" <> showFl (3*(pi :: Double)/2) <> ")")
xrotate R180 = ("rotate", "rotate(" <> showFl (pi :: Double) <> ")")
xrotate R270 = ("rotate", "rotate(" <> showFl ((pi :: Double) /2) <> ")")
let dims =
case (getDim Width, getDim Height) of
(Just w, Just h) -> [("width", tshow w), ("height", tshow h)]
(Just w@(Percent _), Nothing) -> [("rel-width", tshow w),("rel-height", "scale"),("width", tshow ptX <> "pt"),("height", tshow ptY <> "pt")]
(Nothing, Just h@(Percent _)) -> [("rel-width", "scale"),("rel-height", tshow h),("width", tshow ptX <> "pt"),("height", tshow ptY <> "pt")]
(Nothing, Just h@(Percent _)) -> [("rel-width", "scale"),("rel-height", tshow h),("width", tshow ptY <> "pt"),("height", tshow ptY <> "pt")]
(Just w@(Inch i), Nothing) -> [("width", tshow w), ("height", tshow (i / ratio) <> "in")]
(Nothing, Just h@(Inch i)) -> [("width", tshow (i * ratio) <> "in"), ("height", tshow h)]
_ -> [("width", tshow ptX <> "pt"), ("height", tshow ptY <> "pt")]
Expand All @@ -271,7 +279,7 @@ transformPicMath opts (Image attr@(id', cls, _) lab (src,t)) = catchError
Just (Percent i) -> Just $ Percent i
Just dim -> Just $ Inch $ inInch opts dim
Nothing -> Nothing
let newattr = (id', cls, dims)
let newattr = (id', cls, (xflip flp):(xrotate rot):dims)
src' <- if writerLinkImages opts
then
case T.unpack src of
Expand Down
14 changes: 13 additions & 1 deletion src/Text/Pandoc/Writers/OpenDocument.hs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,15 @@ formulaStyle mt = inTags False "style:style"
,("style:horizontal-rel", "paragraph-content")
,("style:wrap", "none")]

imageStyles :: [Doc Text]
imageStyles = [mirror "horizontal", mirror "vertical"]
where
mirror hv = inTags False "style:style"
[("style:name", "mirror-" <> hv)
,("style:family", "graphic")
,("style:parent-style-name", "Graphics")]
$ selfClosingTag "style:graphic-properties" [("style:mirror", hv)]

inBookmarkTags :: Text -> Doc Text -> Doc Text
inBookmarkTags ident d =
selfClosingTag "text:bookmark-start" [ ("text:name", ident) ]
Expand Down Expand Up @@ -260,7 +269,7 @@ writeOpenDocument opts (Pandoc meta blocks) = do
meta'
b <- blocksToOpenDocument opts blocks
return (b, m)
let styles = stTableStyles s ++ stParaStyles s ++ formulaStyles ++
let styles = stTableStyles s ++ stParaStyles s ++ formulaStyles ++ imageStyles ++
map snd (sortBy (flip (comparing fst)) (
Map.elems (stTextStyles s)))
listStyle (n,l) = inTags True "text:list-style"
Expand Down Expand Up @@ -659,6 +668,9 @@ inlineToOpenDocument o ils
id' <- gets stImageId
modify (\st -> st{ stImageId = id' + 1 })
let getDims [] = []
getDims (("mirror", "none") :xs) = getDims xs
getDims (("mirror", t) :xs) = ("draw:style-name", "mirror-" <> t) : getDims xs
getDims (("rotate", t) :xs) = ("draw:transform", t) : getDims xs
getDims (("width", w) :xs) = ("svg:width", w) : getDims xs
getDims (("rel-width", w):xs) = ("style:rel-width", w) : getDims xs
getDims (("height", h):xs) = ("svg:height", h) : getDims xs
Expand Down
2 changes: 2 additions & 0 deletions test/command/6792.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<style:font-face style:name="Courier New" style:font-family-generic="modern" style:font-pitch="fixed" svg:font-family="'Courier New'" />
</office:font-face-decls>
<office:automatic-styles>
<style:style style:name="mirror-vertical" style:family="graphic" style:parent-style-name="Graphics"><style:graphic-properties style:mirror="vertical" /></style:style>
<style:style style:name="mirror-horizontal" style:family="graphic" style:parent-style-name="Graphics"><style:graphic-properties style:mirror="horizontal" /></style:style>
<style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style>
<style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Table_20_Contents">
Expand Down
2 changes: 2 additions & 0 deletions test/command/8256.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Testing.
</office:font-face-decls>
<office:automatic-styles>
<style:style style:name="T1" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" /></style:style>
<style:style style:name="mirror-vertical" style:family="graphic" style:parent-style-name="Graphics"><style:graphic-properties style:mirror="vertical" /></style:style>
<style:style style:name="mirror-horizontal" style:family="graphic" style:parent-style-name="Graphics"><style:graphic-properties style:mirror="horizontal" /></style:style>
<style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style>
<style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style>
</office:automatic-styles>
Expand Down
2 changes: 2 additions & 0 deletions test/writer.opendocument
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,8 @@
<style:style style:name="T6" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>
<style:style style:name="T7" style:family="text"><style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic" style:text-position="super 58%" /></style:style>
<style:style style:name="T8" style:family="text"><style:text-properties style:text-position="sub 58%" /></style:style>
<style:style style:name="mirror-vertical" style:family="graphic" style:parent-style-name="Graphics"><style:graphic-properties style:mirror="vertical" /></style:style>
<style:style style:name="mirror-horizontal" style:family="graphic" style:parent-style-name="Graphics"><style:graphic-properties style:mirror="horizontal" /></style:style>
<style:style style:name="fr2" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" style:wrap="none" /></style:style>
<style:style style:name="fr1" style:family="graphic" style:parent-style-name="Formula"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" /></style:style>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Quotations">
Expand Down

0 comments on commit c5f0190

Please sign in to comment.