@a3s-lab/office 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -309,6 +309,18 @@ and [CLI reference](./docs/latest/en/cli-reference.md).
309
309
 
310
310
  ## Current release
311
311
 
312
+ Version `0.45.0` adds bounded Writer picture transforms without introducing a
313
+ second document model or a remote service:
314
+
315
+ - The contextual **Picture** ribbon now exposes quarter-turn rotation plus
316
+ horizontal and vertical reflection with accessible Lucide icons. **Picture
317
+ Properties** keeps the same controls in a responsive dialog, and each
318
+ confirmed change is one undoable, controlled update.
319
+ - The transform is projected consistently into editing, preview, PDF capture,
320
+ and the native DOCX `a:xfrm` fields (`rot`, `flipH`, and `flipV`). Imported
321
+ 90-degree/reflection values reopen as editable state, while arbitrary-angle
322
+ or malformed values produce a compatibility diagnostic and normalize safely.
323
+
312
324
  Version `0.44.0` adds dependent local dropdowns to Spreadsheet Data Validation
313
325
  without introducing a remote service:
314
326
 
package/dist/0~2330.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { documentRunBorderDomAttributes, normalizeDocumentRunBorder, normalizeDocumentParagraphBorder, serializeDocumentRunBorder, serializeDocumentRunShading, documentIndexEntryHtml, attribute as work_ooxml_package_attribute, documentScriptFontFallbackSlots, documentScriptFontsDomAttributes, documentHighlightFromDocxValue, serializeDocxThemeReference, directChildren as work_ooxml_package_directChildren, documentParagraphShadingDomAttributes, documentTableOfContentsHtml, documentParagraphBordersDomAttributes, normalizeDocumentScriptFontHint, normalizeDocumentScriptFonts, DOCUMENT_PARAGRAPH_BORDER_STYLES, normalizeDocumentParagraphBorders as work_document_paragraph_borders_normalizeDocumentParagraphBorders, DOCUMENT_PARAGRAPH_BORDER_EDGES, documentScriptFontFamily, normalizeDocumentThemeFont, normalizeDocumentParagraphId, documentHighlightDomAttributes, descendants, documentIndexHtml, documentHighlightCssColor, xmlNamespacePrefix, normalizeDocumentFontName, documentProofingDomAttributes, work_document_paragraph_shading_DOCUMENT_PARAGRAPH_SHADING_PATTERNS, directChild, documentScriptFontSegments, childPath, parseDocumentTableOfContentsInstruction, documentRunShadingDomAttributes } from "./6968.js";
2
- import { docxThemeFont, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, parseDocumentIndexEntryInstruction, resolveDocxProofing, parseDocumentIndexInstruction, DOCX_WORD_2010_NAMESPACE, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, STRICT_WORDPROCESSING_NAMESPACE, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, xmlAttributeLocalName, resolveDocxOpenTypeFeatures, docxCharacterScalePercentFromProperties, resolveDocxEmphasisMark, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver as work_docx_theme_resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, parseDocxTwipsMeasure } from "./0~5024.js";
2
+ import { docxThemeFont, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, parseDocumentIndexEntryInstruction, resolveDocxProofing, parseDocumentIndexInstruction, DOCX_WORD_2010_NAMESPACE, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, STRICT_WORDPROCESSING_NAMESPACE, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, xmlAttributeLocalName, resolveDocxOpenTypeFeatures, docxCharacterScalePercentFromProperties, resolveDocxEmphasisMark, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver as work_docx_theme_resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, parseDocxTwipsMeasure } from "./0~4042.js";
3
3
  import { normalizeDocumentEmphasisMark, normalizeDocumentPageBorders, documentCharacterPositionDomAttributes, DOCUMENT_PAGE_BORDER_EDGES, normalizeDocumentTabStops, documentTextCaseFromWordFlags, documentStrikeDomAttributes, serializeDocumentNumberingChange, numberingTypeFromFormat, normalizeDocumentUnderlineColor, documentAutoLineHeight, documentKerningDomAttributes, documentCharacterScaleDomAttributes, serializeDocumentParagraphFormatting, normalizeDocumentPaperSource, documentEquationText, documentLegacyTextEffectsDomAttributes, documentLegacyTextEffectsConflict, documentCharacterSpacingDomAttributes, normalizeDocumentParagraphIndent, normalizeDocumentEquation, documentOpenTypeDomAttributes, renderDocumentAutoLineHeight, documentUnderlineDomAttributes, MAX_DOCUMENT_NUMBERING_START, normalizeDocumentUnderlineStyle, applyDocumentTextCaseStyle, documentHiddenTextDomAttributes, importedDocumentCharacterFormatting, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, createDocumentEquationElement, normalizeDocumentPageGeometry, serializeDocumentTabStops, documentWordLineHeightFactor, documentEmphasisMarkDomAttributes, normalizeDocumentPageMargins } from "./4174.js";
4
4
  function docxCaptionSequenceKind(instruction) {
5
5
  const identifier = /^\s*SEQ\s+([^\s\\]+)/i.exec(instruction)?.[1]?.toLowerCase();
@@ -1,6 +1,6 @@
1
1
  import jszip from "jszip";
2
2
  import { normalizeDocumentIndexEntryDraft, serializeUtf8Xml, directChildren, xmlNamespacePrefix, normalizeDocumentLanguageTag, parseXml, firstDescendant, decodeXmlBytes, directChild, descendants, normalizeDocumentProofingLanguages, attribute as work_ooxml_package_attribute, normalizeDocumentIndexOptions } from "./6968.js";
3
- import { normalizeDocumentEmphasisMark, normalizeDocumentCharacterScalePercent, documentCitationStyle, normalizeDocumentKerningThresholdHalfPoints, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentCharacterSpacingTwips, normalizeDocumentOpenTypeNumberSpacing, createDocumentBibliography, normalizeDocumentOpenTypeNumberForm, normalizeDocumentOpenTypeLigatures, normalizeDocumentTabStops, documentCitationStyleDetails, normalizeDocumentOpenTypeStylisticSets } from "./4174.js";
3
+ import { normalizeDocumentEmphasisMark, normalizeDocumentCharacterScalePercent, documentCitationStyle, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentCharacterSpacingTwips, normalizeDocumentKerningThresholdHalfPoints, normalizeDocumentOpenTypeNumberSpacing, createDocumentBibliography, normalizeDocumentImageTransform, normalizeDocumentOpenTypeLigatures, normalizeDocumentOpenTypeNumberForm, normalizeDocumentTabStops, documentCitationStyleDetails, normalizeDocumentOpenTypeStylisticSets } from "./4174.js";
4
4
  const BIBLIOGRAPHY_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/bibliography';
5
5
  const CUSTOM_XML_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/customXml';
6
6
  const OFFICE_RELATIONSHIPS_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
@@ -708,6 +708,114 @@ function isAllowedExtensionNamespace(namespace, context) {
708
708
  function isNamespacePrefix(value) {
709
709
  return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) && 'xml' !== value;
710
710
  }
711
+ const DOCX_ROTATION_UNITS_PER_DEGREE = 60000;
712
+ const DOCX_QUADRANT_ROTATION_UNITS = 5400000;
713
+ function readDocxImageTransform(drawing) {
714
+ const target = pictureTransform(drawing);
715
+ if (!target) return {
716
+ transform: null,
717
+ supported: true
718
+ };
719
+ const rawRotation = work_ooxml_package_attribute(target, 'rot');
720
+ const rawFlipHorizontal = work_ooxml_package_attribute(target, 'flipH');
721
+ const rawFlipVertical = work_ooxml_package_attribute(target, 'flipV');
722
+ const rotation = parseRotation(rawRotation);
723
+ const flipHorizontal = parseFlip(rawFlipHorizontal);
724
+ const flipVertical = parseFlip(rawFlipVertical);
725
+ const supported = null !== rotation && null !== flipHorizontal && null !== flipVertical && (0 === rotation || rotation % DOCX_QUADRANT_ROTATION_UNITS === 0);
726
+ const normalized = normalizeDocumentImageTransform({
727
+ rotation: null === rotation ? 0 : rotation / DOCX_ROTATION_UNITS_PER_DEGREE,
728
+ flipHorizontal: flipHorizontal ?? false,
729
+ flipVertical: flipVertical ?? false
730
+ });
731
+ return {
732
+ transform: 0 !== normalized.rotation || normalized.flipHorizontal || normalized.flipVertical ? normalized : null,
733
+ supported
734
+ };
735
+ }
736
+ class DocxImageTransformPatchCollector {
737
+ patches = [];
738
+ nextMarker = 1;
739
+ marker(transform) {
740
+ if (!transform) return '';
741
+ const normalized = normalizeDocumentImageTransform(transform);
742
+ if (0 === normalized.rotation && !normalized.flipHorizontal && !normalized.flipVertical) return '';
743
+ const marker = `__A3S_IMAGE_TRANSFORM_${this.nextMarker}__`;
744
+ this.nextMarker += 1;
745
+ this.patches.push({
746
+ marker,
747
+ transform: normalized
748
+ });
749
+ return marker;
750
+ }
751
+ }
752
+ async function patchDocxImageTransforms(buffer, patches) {
753
+ if (!patches.length) return buffer;
754
+ const archive = await jszip.loadAsync(buffer);
755
+ const entries = Object.values(archive.files).filter((entry)=>!entry.dir && /^word\/(?:document|header\d+|footer\d+|footnotes|endnotes|comments)\.xml$/.test(entry.name));
756
+ const byMarker = new Map(patches.map((patch)=>[
757
+ patch.marker,
758
+ patch
759
+ ]));
760
+ for (const entry of entries){
761
+ const document = parseXml(await entry.async('text'), entry.name);
762
+ let changed = false;
763
+ for (const properties of descendants(document, 'docPr')){
764
+ const patch = imageTransformPatch(properties, byMarker);
765
+ if (!patch) continue;
766
+ removeTransformMarker(properties, patch.marker);
767
+ changed = true;
768
+ const drawing = closestDrawing(properties);
769
+ const transform = drawing ? pictureTransform(drawing) : void 0;
770
+ if (transform) applyImageTransform(transform, patch.transform);
771
+ }
772
+ if (changed) archive.file(entry.name, new XMLSerializer().serializeToString(document));
773
+ }
774
+ return archive.generateAsync({
775
+ type: 'arraybuffer'
776
+ });
777
+ }
778
+ function imageTransformPatch(properties, patches) {
779
+ for (const attribute of Array.from(properties.attributes))for (const [marker, patch] of patches)if (attribute.value.includes(marker)) return patch;
780
+ return null;
781
+ }
782
+ function removeTransformMarker(properties, marker) {
783
+ for (const attribute of Array.from(properties.attributes))if (attribute.value.includes(marker)) attribute.value = attribute.value.replace(marker, '');
784
+ }
785
+ function closestDrawing(element) {
786
+ let current = element;
787
+ while(current){
788
+ if ('anchor' === current.localName || 'inline' === current.localName) return current;
789
+ current = current.parentElement;
790
+ }
791
+ return null;
792
+ }
793
+ function pictureTransform(drawing) {
794
+ const picture = descendants(drawing, 'pic')[0];
795
+ const properties = picture ? directChild(picture, 'spPr') : void 0;
796
+ return properties ? directChild(properties, 'xfrm') : descendants(drawing, 'xfrm')[0];
797
+ }
798
+ function parseRotation(value) {
799
+ if (null === value || !value.trim()) return 0;
800
+ const number = Number(value);
801
+ return Number.isInteger(number) && number >= 0 ? number : null;
802
+ }
803
+ function parseFlip(value) {
804
+ if (null === value || !value.trim()) return false;
805
+ const normalized = value.trim().toLowerCase();
806
+ if ('1' === normalized || 'true' === normalized) return true;
807
+ if ('0' === normalized || 'false' === normalized) return false;
808
+ return null;
809
+ }
810
+ function applyImageTransform(target, transform) {
811
+ const normalized = normalizeDocumentImageTransform(transform);
812
+ if (0 === normalized.rotation) target.removeAttribute('rot');
813
+ else target.setAttribute('rot', String(normalized.rotation * DOCX_ROTATION_UNITS_PER_DEGREE));
814
+ if (normalized.flipHorizontal) target.setAttribute('flipH', '1');
815
+ else target.removeAttribute('flipH');
816
+ if (normalized.flipVertical) target.setAttribute('flipV', '1');
817
+ else target.removeAttribute('flipV');
818
+ }
711
819
  function parseDocumentIndexEntryInstruction(instruction) {
712
820
  const command = /^\s*XE\b/i.exec(instruction);
713
821
  if (!command) return {
@@ -2072,4 +2180,4 @@ function isParagraphPartRoot(root, path) {
2072
2180
  const expected = /^word\/header\d*\.xml$/i.test(path) ? 'hdr' : /^word\/footer\d*\.xml$/i.test(path) ? 'ftr' : /^word\/footnotes\.xml$/i.test(path) ? 'footnotes' : /^word\/endnotes\.xml$/i.test(path) ? 'endnotes' : 'document';
2073
2181
  return root.localName === expected && DOCX_WORDPROCESSING_NAMESPACES.has(root.namespaceURI ?? '');
2074
2182
  }
2075
- export { DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DOCX_WORD_2010_NAMESPACE, DocxParagraphDefaultCollapsedPatchCollector, STRICT_WORDPROCESSING_NAMESPACE, XMLNS_NAMESPACE, XML_NAMESPACE, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, documentIndexEntryInstruction, documentIndexInstruction, documentProofingLanguageDocxOptions, docxCharacterPositionHalfPointsFromProperties, docxCharacterPositionValue, docxCharacterScalePercentFromProperties, docxCharacterScaleValue, docxCharacterSpacingTwipsFromProperties, docxCharacterSpacingValue, docxEmphasisMarkRunOptions, docxKerningThresholdValue, docxThemeColor, docxThemeFont, domDirection, hasNonWhitespaceXmlText, inspectDocxEmphasisMark, inspectDocxKerningThresholdHalfPoints, inspectDocxNoProof, inspectDocxProofingLanguages, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseBoundedDocxInteger, parseDocumentIndexEntryInstruction, parseDocumentIndexInstruction, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, parseDocxTwipsMeasure, patchDocxBibliography, patchDocxExplicitZeroCharacterSpacing, patchDocxExplicitZeroKerningThresholds, patchDocxParagraphDefaultCollapsed, readDocxBibliography, resolveDocxEmphasisMark, resolveDocxKerningThresholdHalfPoints, resolveDocxOpenTypeFeatures, resolveDocxProofing, resolveDocxThemeResolver, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };
2183
+ export { DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DOCX_WORD_2010_NAMESPACE, DocxImageTransformPatchCollector, DocxParagraphDefaultCollapsedPatchCollector, STRICT_WORDPROCESSING_NAMESPACE, XMLNS_NAMESPACE, XML_NAMESPACE, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, documentIndexEntryInstruction, documentIndexInstruction, documentProofingLanguageDocxOptions, docxCharacterPositionHalfPointsFromProperties, docxCharacterPositionValue, docxCharacterScalePercentFromProperties, docxCharacterScaleValue, docxCharacterSpacingTwipsFromProperties, docxCharacterSpacingValue, docxEmphasisMarkRunOptions, docxKerningThresholdValue, docxThemeColor, docxThemeFont, domDirection, hasNonWhitespaceXmlText, inspectDocxEmphasisMark, inspectDocxKerningThresholdHalfPoints, inspectDocxNoProof, inspectDocxProofingLanguages, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseBoundedDocxInteger, parseDocumentIndexEntryInstruction, parseDocumentIndexInstruction, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, parseDocxTwipsMeasure, patchDocxBibliography, patchDocxExplicitZeroCharacterSpacing, patchDocxExplicitZeroKerningThresholds, patchDocxImageTransforms, patchDocxParagraphDefaultCollapsed, readDocxBibliography, readDocxImageTransform, resolveDocxEmphasisMark, resolveDocxKerningThresholdHalfPoints, resolveDocxOpenTypeFeatures, resolveDocxProofing, resolveDocxThemeResolver, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };
@@ -6,7 +6,7 @@ import { Fragment as external_react_Fragment, forwardRef, useCallback, useEffect
6
6
  import { Extension, createNodeFromContent } from "@tiptap/core";
7
7
  import { NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
8
8
  import { Decoration, DecorationSet } from "@tiptap/pm/view";
9
- import { AArrowDown, AArrowUp, ALargeSmall, AlignCenter, AlignJustify, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowUp, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, BookMarked, BookOpen, Bookmark, CaseUpper, Check, CheckCheck, CheckCircle2, ChevronDown, ChevronRight, ChevronUp, ClipboardCopy, ClipboardPaste, Cloud, Columns3, Eraser, Eye, FileCheck2, FileDiff, FilePlus2, FileStack, FileText, FileUp, GitCompareArrows, Globe2, Grid2X2, Hash, Highlighter, Image, IndentDecrease, IndentIncrease, Italic, Languages, Link2, List, ListChecks, ListOrdered, ListTree, MessageSquarePlus, MessageSquareReply, MessagesSquare, MoveVertical, Paintbrush, Palette, PanelBottom, PanelBottomOpen, PanelLeftOpen, PanelTop, PanelTopOpen, Pilcrow, PilcrowLeft, PilcrowRight, Plus, Quote, Redo2, RefreshCw, Replace, ReplaceAll, RotateCcw, Rows3, Ruler, Scan, Search, Settings2, Square, StretchHorizontal, Strikethrough, Subscript, Superscript, Table2, TableCellsMerge, TableCellsSplit, TableProperties, Tags, TextWrap, Trash2, TriangleAlert, Type, Underline, Undo2, Unlink, Unlink2, X, XCircle, ZoomIn, ZoomOut } from "lucide-react";
9
+ import { AArrowDown, AArrowUp, ALargeSmall, AlignCenter, AlignJustify, AlignLeft, AlignRight, AlignVerticalJustifyCenter, AlignVerticalJustifyEnd, AlignVerticalJustifyStart, ArrowDown, ArrowUp, BetweenHorizontalEnd, BetweenHorizontalStart, BetweenVerticalEnd, BetweenVerticalStart, Bold, BookMarked, BookOpen, Bookmark, CaseUpper, Check, CheckCheck, CheckCircle2, ChevronDown, ChevronRight, ChevronUp, ClipboardCopy, ClipboardPaste, Cloud, Columns3, Eraser, Eye, FileCheck2, FileDiff, FilePlus2, FileStack, FileText, FileUp, FlipHorizontal2, FlipVertical2, GitCompareArrows, Globe2, Grid2X2, Hash, Highlighter, Image, IndentDecrease, IndentIncrease, Italic, Languages, Link2, List, ListChecks, ListOrdered, ListTree, MessageSquarePlus, MessageSquareReply, MessagesSquare, MoveVertical, Paintbrush, Palette, PanelBottom, PanelBottomOpen, PanelLeftOpen, PanelTop, PanelTopOpen, Pilcrow, PilcrowLeft, PilcrowRight, Plus, Quote, Redo2, RefreshCw, Replace, ReplaceAll, RotateCcw, RotateCw, Rows3, Ruler, Scan, Search, Settings2, Square, StretchHorizontal, Strikethrough, Subscript, Superscript, Table2, TableCellsMerge, TableCellsSplit, TableProperties, Tags, TextWrap, Trash2, TriangleAlert, Type, Underline, Undo2, Unlink, Unlink2, X, XCircle, ZoomIn, ZoomOut } from "lucide-react";
10
10
  import { Fragment as model_Fragment, Node as model_Node } from "@tiptap/pm/model";
11
11
  import extension_color from "@tiptap/extension-color";
12
12
  import { TableKit } from "@tiptap/extension-table";
@@ -16,7 +16,7 @@ import starter_kit from "@tiptap/starter-kit";
16
16
  import { BubbleMenu } from "@tiptap/react/menus";
17
17
  import { TableMap, isInTable, selectedRect } from "@tiptap/pm/tables";
18
18
  import { closeHistory } from "@tiptap/pm/history";
19
- import { documentTableSizing, transferChangedDocumentTextStatistics, documentPageBordersVisible, documentUnderlineStyle, DOCUMENT_PAGE_BORDER_EDGES, documentTableRowOptions, normalizeDocumentColumns, clampDocumentMargin, materializeLazyDocumentEditorRoot, documentKerningThresholdPoints, selectedDocumentIndexOptions, nextDocumentTabAlignment, DOCUMENT_BOOKMARK_DUPLICATE_MESSAGE, normalizedTabPosition, documentCitationCount, resolveDocumentPageBorders, documentLazyHtmlChunkFragment, DocumentFontFamily, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, DOCUMENT_CHUNK_VISIBLE_IDS_META, selectedDocumentIndexDraft, MAX_DOCUMENT_IMAGE_RELATIVE_HEIGHT, retainAnchoredDocumentComments, DocumentTableRowIdentity, work_document_page_margins_twipsToMillimeters, DEFAULT_DOCUMENT_TABLE_CELL_FORMAT, resolveWorkDocumentEditorInput, documentOpenTypeCssProperties, documentBulletListStyle, documentCharacterPositionPoints, collectDocumentTextLayoutParagraphs, readOfficeDocumentCollaboration as readWorkOfficeDocumentCollaboration, normalizeDocumentCharacterScalePercent, DOCUMENT_PARAGRAPH_FORMAT_ATTRIBUTES, documentOrderedListState, normalizeDocumentPageChrome, documentTextStatistics, documentPageMarginsForLayout, invalidateDocumentLazyHtmlProjection, documentTableCellFormat, normalizeDocumentPageGeometry, normalizeDocumentImageLayer, documentImageProperties, isValidDocumentCitationTag, sanitizeDocumentPageChromeHtml, pageTwipsToMillimeters, normalizeDocumentPageBorders, importWorkDocumentFile, DocumentParagraphFormatting, documentModelHasTrustedInitialIntegrityFeatures, normalizeDocumentHtml, documentInitialSectionLayout, activeDocumentSection, documentParagraphDirection, documentParagraphPagination, normalizeDocumentOpenTypeFeatures, isDocumentCharacterFormatMark, documentModelUsesWindowing, documentPageChromeLegacyFields, documentChunkMountedIds, collectDocumentCommentAnchors, documentTextCaseKeyboardShortcuts, DocumentTextStyle, canChangeDocumentIndent, patchDocumentOpenTypeFeatures, normalizeDocumentOpenTypeNumberForm, parseDocumentOpenTypeFeatures, documentCharacterSpacingPoints, documentKerningIsEffective, DocumentSuperscript, documentSectionById, activeDocumentBookmark, DocumentEquation, documentLazyHtmlProjectionFingerprint, documentLazyHtmlProjection, normalizeDocumentParagraphIndent, updateDocumentGutterPosition, DocumentStrike, mountWorkLiveDocumentCapture, registerDocumentPageSurfaceGeometry, documentHiddenTextKeyboardShortcut, documentHasIndex, syncDocumentContentFromHtml, documentLegacyTextEffectsCss, editorDocumentCaptionTargets, resolveDocumentPageChrome, documentImageLayoutOptions, MAX_DOCUMENT_NUMBERING_START, resolveDocumentPageSize, normalizeDocumentOpenTypeNumberSpacing, editorDocumentBookmarkReferenceTargets, serializeWorkDocumentNode, DOCUMENT_CHUNK_PAGINATION_META, documentModelForContent, createOfficeDocumentCollaborationBinding as createWorkOfficeDocumentCollaborationBinding, documentLegacyTextEffectsFromTextStyleAttributes, normalizeDocumentEmphasisMark, selectedDocumentChunkId, documentCommentViews, documentParagraphSpacing, normalizeDocumentTabStops, patchDocumentLazyHtmlProjection, normalizeDocumentTextCase, documentUnderlineColor, documentBookmarkNameExists, collectDocumentChanges, DocumentImage, selectedDocumentTableOfContentsOptions, resolveDocumentPageMargins, updateDocumentPageMarginMode, serializeDocumentParagraphFormatting, canSetDocumentTableRowRepeatHeader, isDocumentOpenTypeFeaturePatch, normalizeDocumentCharacterSpacingTwips, DocumentCharacterFormatting, millimetersToPixels as work_document_layout_millimetersToPixels, DOCUMENT_PARAGRAPH_CHANGE_ATTRIBUTES, serializeDocumentCharacterFormatting, DOCUMENT_CHUNK_HYDRATION_META, documentTabLeaderLabel, createSchemaDerivedWorkDocumentModel, updateDocumentCustomPageMillimeters, DocumentUnderline, documentCommentDraftRange, documentParagraphTabStops, documentTableHorizontalAlignment, documentUnderlineKeyboardShortcuts, documentParagraphIndent, DocumentScriptFontFormatting, canInsertDocumentComment, resolveAllDocumentChanges, serializeDocumentOpenTypeFeatures, documentHasTableOfContents, documentTextLayoutBatches, normalizeDocumentImageWrapSide, updateDocumentPageOrientation, documentCitationStyleDetails, validateDocumentBookmarkName, setCustomDocumentColumns, updateDocumentPageMarginMillimeters, normalizeDocumentCharacterPositionHalfPoints, documentCitationStyle, documentTransactionsOnlyHydrateChunks, normalizeDocumentKerningThresholdHalfPoints, forgetSourceBlob as forgetWorkSourceBlob, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, DOCUMENT_TABLE_STYLE_OPTIONS, updateDocumentColumnWidth, updateDocumentPaperSizePreset, documentPageMetrics, documentStrikeStyle, DocumentHighlight, createDocumentBibliography, DocumentSubscript, normalizeDocumentOpenTypeLigatures, selectedDocumentIndexEntry, updateDocumentPageChromeVariant, updateDocumentMirrorMargins, activeDocumentTableStyle, measureDocumentLayoutBlocksIncrementally, documentWordLineHeightFactor, normalizeDocumentLegacyTextEffect, createWorkDocumentExtensions } from "./4174.js";
19
+ import { documentTableSizing, transferChangedDocumentTextStatistics, documentPageBordersVisible, documentUnderlineStyle, DOCUMENT_PAGE_BORDER_EDGES, documentTableRowOptions, normalizeDocumentColumns, clampDocumentMargin, materializeLazyDocumentEditorRoot, documentKerningThresholdPoints, selectedDocumentIndexOptions, nextDocumentTabAlignment, DOCUMENT_BOOKMARK_DUPLICATE_MESSAGE, normalizedTabPosition, documentCitationCount, resolveDocumentPageBorders, documentLazyHtmlChunkFragment, DocumentFontFamily, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, DOCUMENT_CHUNK_VISIBLE_IDS_META, selectedDocumentIndexDraft, MAX_DOCUMENT_IMAGE_RELATIVE_HEIGHT, retainAnchoredDocumentComments, DocumentTableRowIdentity, work_document_page_margins_twipsToMillimeters, DEFAULT_DOCUMENT_TABLE_CELL_FORMAT, resolveWorkDocumentEditorInput, defaultDocumentImageTransform, documentOpenTypeCssProperties, documentBulletListStyle, documentCharacterPositionPoints, collectDocumentTextLayoutParagraphs, readOfficeDocumentCollaboration as readWorkOfficeDocumentCollaboration, normalizeDocumentCharacterScalePercent, DOCUMENT_PARAGRAPH_FORMAT_ATTRIBUTES, documentOrderedListState, normalizeDocumentPageChrome, documentTextStatistics, documentPageMarginsForLayout, invalidateDocumentLazyHtmlProjection, documentTableCellFormat, normalizeDocumentImageTransform, normalizeDocumentPageGeometry, documentImageProperties, normalizeDocumentImageLayer, isValidDocumentCitationTag, sanitizeDocumentPageChromeHtml, pageTwipsToMillimeters, normalizeDocumentPageBorders, importWorkDocumentFile, DocumentParagraphFormatting, documentModelHasTrustedInitialIntegrityFeatures, normalizeDocumentHtml, documentInitialSectionLayout, activeDocumentSection, documentParagraphDirection, documentParagraphPagination, normalizeDocumentOpenTypeFeatures, isDocumentCharacterFormatMark, documentModelUsesWindowing, documentPageChromeLegacyFields, documentChunkMountedIds, collectDocumentCommentAnchors, documentTextCaseKeyboardShortcuts, DocumentTextStyle, canChangeDocumentIndent, patchDocumentOpenTypeFeatures, normalizeDocumentOpenTypeNumberForm, parseDocumentOpenTypeFeatures, documentCharacterSpacingPoints, documentKerningIsEffective, DocumentSuperscript, documentSectionById, activeDocumentBookmark, DocumentEquation, documentLazyHtmlProjectionFingerprint, documentLazyHtmlProjection, normalizeDocumentParagraphIndent, updateDocumentGutterPosition, DocumentStrike, mountWorkLiveDocumentCapture, registerDocumentPageSurfaceGeometry, documentHiddenTextKeyboardShortcut, documentHasIndex, syncDocumentContentFromHtml, documentLegacyTextEffectsCss, editorDocumentCaptionTargets, resolveDocumentPageChrome, documentImageLayoutOptions, MAX_DOCUMENT_NUMBERING_START, resolveDocumentPageSize, normalizeDocumentOpenTypeNumberSpacing, editorDocumentBookmarkReferenceTargets, serializeWorkDocumentNode, DOCUMENT_CHUNK_PAGINATION_META, documentModelForContent, createOfficeDocumentCollaborationBinding as createWorkOfficeDocumentCollaborationBinding, documentLegacyTextEffectsFromTextStyleAttributes, normalizeDocumentEmphasisMark, selectedDocumentChunkId, documentCommentViews, documentParagraphSpacing, normalizeDocumentTabStops, patchDocumentLazyHtmlProjection, normalizeDocumentTextCase, documentUnderlineColor, documentBookmarkNameExists, collectDocumentChanges, DocumentImage, selectedDocumentTableOfContentsOptions, resolveDocumentPageMargins, updateDocumentPageMarginMode, serializeDocumentParagraphFormatting, canSetDocumentTableRowRepeatHeader, isDocumentOpenTypeFeaturePatch, normalizeDocumentCharacterSpacingTwips, DocumentCharacterFormatting, millimetersToPixels as work_document_layout_millimetersToPixels, DOCUMENT_PARAGRAPH_CHANGE_ATTRIBUTES, serializeDocumentCharacterFormatting, DOCUMENT_CHUNK_HYDRATION_META, documentTabLeaderLabel, createSchemaDerivedWorkDocumentModel, updateDocumentCustomPageMillimeters, DocumentUnderline, documentCommentDraftRange, documentParagraphTabStops, documentTableHorizontalAlignment, documentUnderlineKeyboardShortcuts, documentParagraphIndent, DocumentScriptFontFormatting, canInsertDocumentComment, resolveAllDocumentChanges, serializeDocumentOpenTypeFeatures, documentHasTableOfContents, documentTextLayoutBatches, normalizeDocumentImageWrapSide, updateDocumentPageOrientation, documentCitationStyleDetails, validateDocumentBookmarkName, setCustomDocumentColumns, updateDocumentPageMarginMillimeters, normalizeDocumentCharacterPositionHalfPoints, documentCitationStyle, documentTransactionsOnlyHydrateChunks, normalizeDocumentKerningThresholdHalfPoints, forgetSourceBlob as forgetWorkSourceBlob, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, DOCUMENT_TABLE_STYLE_OPTIONS, updateDocumentColumnWidth, updateDocumentPaperSizePreset, documentPageMetrics, documentStrikeStyle, DocumentHighlight, createDocumentBibliography, DocumentSubscript, normalizeDocumentOpenTypeLigatures, selectedDocumentIndexEntry, updateDocumentPageChromeVariant, updateDocumentMirrorMargins, activeDocumentTableStyle, measureDocumentLayoutBlocksIncrementally, documentWordLineHeightFactor, normalizeDocumentLegacyTextEffect, createWorkDocumentExtensions } from "./4174.js";
20
20
  import { useOfficeTaskPaneEscape, OfficeCheckbox, useOfficeDialog, useOfficeTaskPaneModal, CommittedOfficeNumberField, createOfficeKernelClient, CollectionState, OfficeNumberField } from "./0~7831.js";
21
21
  import { moveOfficeMenuFocus, office_text_field_OfficeTextArea, Popover, officeOverlayPortalRoot, Dialog, button_Button, useOfficePublishPresenceLocation, OfficeTiptapPresenceLayer, icon_button_IconButton, office_text_field_OfficeTextField, useDialogFocusScope, useOfficeEditorWheelZoom, office_text_field_OfficeFileInput } from "./0~8136.js";
22
22
  import { WorkOfficePreviewBar, isWorkspaceContextMenuKeyboardEvent, Tabs, WorkOfficeZoomControls, WorkOfficeStatusBar, WorkOfficeRibbon, workspaceContextMenuPosition, OfficeSelect, WorkspaceContextMenu, WorkOfficeRibbonGroup, WorkOfficeRibbonButton } from "./0~9073.js";
@@ -12689,6 +12689,9 @@ function createDocumentPicturePropertiesDraft(source) {
12689
12689
  cropRight: formatNumber(source.properties.crop?.right ?? 0),
12690
12690
  cropBottom: formatNumber(source.properties.crop?.bottom ?? 0),
12691
12691
  cropLeft: formatNumber(source.properties.crop?.left ?? 0),
12692
+ rotation: (source.properties.transform ?? defaultDocumentImageTransform()).rotation,
12693
+ flipHorizontal: Boolean(source.properties.transform?.flipHorizontal),
12694
+ flipVertical: Boolean(source.properties.transform?.flipVertical),
12692
12695
  relativeHeight: String(layer.relativeHeight),
12693
12696
  behindDocument: layer.behindDocument,
12694
12697
  allowOverlap: layer.allowOverlap,
@@ -12767,6 +12770,14 @@ function documentPicturePropertyChanges(initial, current) {
12767
12770
  };
12768
12771
  changes.crop = Object.values(crop).some((edge)=>edge > 0) ? crop : null;
12769
12772
  }
12773
+ if (initial.rotation !== current.rotation || initial.flipHorizontal !== current.flipHorizontal || initial.flipVertical !== current.flipVertical) {
12774
+ const transform = normalizeDocumentImageTransform({
12775
+ rotation: current.rotation,
12776
+ flipHorizontal: current.flipHorizontal,
12777
+ flipVertical: current.flipVertical
12778
+ });
12779
+ changes.transform = 0 !== transform.rotation || transform.flipHorizontal || transform.flipVertical ? transform : null;
12780
+ }
12770
12781
  if (!sameDraftNumber(initial.relativeHeight, current.relativeHeight) || initial.behindDocument !== current.behindDocument || initial.allowOverlap !== current.allowOverlap || initial.layoutInCell !== current.layoutInCell || initial.lockAnchor !== current.lockAnchor) changes.layer = normalizeDocumentImageLayer({
12771
12782
  relativeHeight: current.relativeHeight,
12772
12783
  behindDocument: current.behindDocument,
@@ -12926,6 +12937,24 @@ const verticalReferenceOptions = [
12926
12937
  label: '页面'
12927
12938
  }
12928
12939
  ];
12940
+ const rotationOptions = [
12941
+ {
12942
+ value: '0',
12943
+ label: '0°(原始)'
12944
+ },
12945
+ {
12946
+ value: '90',
12947
+ label: '90°'
12948
+ },
12949
+ {
12950
+ value: '180',
12951
+ label: '180°'
12952
+ },
12953
+ {
12954
+ value: '270',
12955
+ label: '270°'
12956
+ }
12957
+ ];
12929
12958
  function DocumentPicturePropertiesControl({ editor }) {
12930
12959
  const [source, setSource] = useState(null);
12931
12960
  const triggerRef = useRef(null);
@@ -13029,6 +13058,10 @@ function DocumentPicturePropertiesDialog({ editor, source, restoreFocusTarget, o
13029
13058
  errors: errors,
13030
13059
  onDraftChange: setDraft
13031
13060
  }),
13061
+ /*#__PURE__*/ jsx(PictureTransformSection, {
13062
+ draft: draft,
13063
+ onDraftChange: setDraft
13064
+ }),
13032
13065
  /*#__PURE__*/ jsxs("label", {
13033
13066
  className: "work-document-picture-properties-alt-text",
13034
13067
  htmlFor: alternativeTextId,
@@ -13418,6 +13451,60 @@ function PictureCropSection({ draft, errors, onDraftChange }) {
13418
13451
  ]
13419
13452
  });
13420
13453
  }
13454
+ function PictureTransformSection({ draft, onDraftChange }) {
13455
+ return /*#__PURE__*/ jsxs("fieldset", {
13456
+ className: "work-document-picture-properties-section transform",
13457
+ children: [
13458
+ /*#__PURE__*/ jsx("legend", {
13459
+ children: "变换"
13460
+ }),
13461
+ /*#__PURE__*/ jsxs("div", {
13462
+ className: "work-document-picture-properties-transform-row",
13463
+ children: [
13464
+ /*#__PURE__*/ jsx("span", {
13465
+ children: "旋转"
13466
+ }),
13467
+ /*#__PURE__*/ jsx(OfficeSelect, {
13468
+ ariaLabel: "图片旋转角度",
13469
+ value: String(draft.rotation),
13470
+ options: rotationOptions,
13471
+ onValueChange: (value)=>onDraftChange((current)=>({
13472
+ ...current,
13473
+ rotation: Number(value)
13474
+ }))
13475
+ })
13476
+ ]
13477
+ }),
13478
+ /*#__PURE__*/ jsxs("div", {
13479
+ className: "work-document-picture-properties-transform-options",
13480
+ children: [
13481
+ /*#__PURE__*/ jsx(OfficeCheckbox, {
13482
+ ariaLabel: "水平翻转图片",
13483
+ checked: draft.flipHorizontal,
13484
+ onCheckedChange: (flipHorizontal)=>onDraftChange((current)=>({
13485
+ ...current,
13486
+ flipHorizontal
13487
+ })),
13488
+ children: "水平翻转"
13489
+ }),
13490
+ /*#__PURE__*/ jsx(OfficeCheckbox, {
13491
+ ariaLabel: "垂直翻转图片",
13492
+ checked: draft.flipVertical,
13493
+ onCheckedChange: (flipVertical)=>onDraftChange((current)=>({
13494
+ ...current,
13495
+ flipVertical
13496
+ })),
13497
+ children: "垂直翻转"
13498
+ })
13499
+ ]
13500
+ }),
13501
+ /*#__PURE__*/ jsx("small", {
13502
+ className: "work-document-picture-properties-transform-help",
13503
+ children: "旋转以 90\xb0 为单位;每次确认作为一次可撤销操作保存。"
13504
+ })
13505
+ ]
13506
+ });
13507
+ }
13421
13508
  function PictureNumberRow({ label, ariaLabel, value, unit, min, max, step, disabled = false, invalid, onValueChange }) {
13422
13509
  return /*#__PURE__*/ jsxs("div", {
13423
13510
  className: "work-document-picture-properties-number-row",
@@ -13481,6 +13568,7 @@ const imageWrapDistanceOptions = [
13481
13568
  ];
13482
13569
  function DocumentPictureRibbon({ editor }) {
13483
13570
  const image = documentImageLayoutOptions(editor);
13571
+ const transform = documentImageProperties(editor).transform ?? defaultDocumentImageTransform();
13484
13572
  const imageSelected = editor.isActive('image');
13485
13573
  const wrapDistanceValue = String(image.wrapDistance);
13486
13574
  const updateLayout = (layout)=>editor.commands.setDocumentImageLayoutOptions({
@@ -13489,6 +13577,15 @@ function DocumentPictureRibbon({ editor }) {
13489
13577
  const updateAlignment = (alignment)=>editor.commands.setDocumentImageLayoutOptions({
13490
13578
  alignment
13491
13579
  });
13580
+ const updateTransform = (next)=>{
13581
+ const current = documentImageProperties(editor).transform ?? defaultDocumentImageTransform();
13582
+ return editor.commands.setDocumentImageProperties({
13583
+ transform: {
13584
+ ...current,
13585
+ ...next(current)
13586
+ }
13587
+ });
13588
+ };
13492
13589
  return /*#__PURE__*/ jsxs(Fragment, {
13493
13590
  children: [
13494
13591
  /*#__PURE__*/ jsxs(WorkOfficeRibbonGroup, {
@@ -13582,6 +13679,53 @@ function DocumentPictureRibbon({ editor }) {
13582
13679
  })
13583
13680
  ]
13584
13681
  }),
13682
+ /*#__PURE__*/ jsxs(WorkOfficeRibbonGroup, {
13683
+ label: "变换",
13684
+ children: [
13685
+ /*#__PURE__*/ jsx(PictureButton, {
13686
+ label: "向左旋转",
13687
+ disabled: !imageSelected,
13688
+ onClick: ()=>updateTransform((current)=>({
13689
+ rotation: rotateImage(current.rotation, -90)
13690
+ })),
13691
+ children: /*#__PURE__*/ jsx(RotateCcw, {
13692
+ size: 18
13693
+ })
13694
+ }),
13695
+ /*#__PURE__*/ jsx(PictureButton, {
13696
+ label: "向右旋转",
13697
+ disabled: !imageSelected,
13698
+ onClick: ()=>updateTransform((current)=>({
13699
+ rotation: rotateImage(current.rotation, 90)
13700
+ })),
13701
+ children: /*#__PURE__*/ jsx(RotateCw, {
13702
+ size: 18
13703
+ })
13704
+ }),
13705
+ /*#__PURE__*/ jsx(PictureButton, {
13706
+ label: "水平翻转",
13707
+ active: transform.flipHorizontal,
13708
+ disabled: !imageSelected,
13709
+ onClick: ()=>updateTransform((current)=>({
13710
+ flipHorizontal: !current.flipHorizontal
13711
+ })),
13712
+ children: /*#__PURE__*/ jsx(FlipHorizontal2, {
13713
+ size: 18
13714
+ })
13715
+ }),
13716
+ /*#__PURE__*/ jsx(PictureButton, {
13717
+ label: "垂直翻转",
13718
+ active: transform.flipVertical,
13719
+ disabled: !imageSelected,
13720
+ onClick: ()=>updateTransform((current)=>({
13721
+ flipVertical: !current.flipVertical
13722
+ })),
13723
+ children: /*#__PURE__*/ jsx(FlipVertical2, {
13724
+ size: 18
13725
+ })
13726
+ })
13727
+ ]
13728
+ }),
13585
13729
  /*#__PURE__*/ jsx(WorkOfficeRibbonGroup, {
13586
13730
  label: "与文字距离",
13587
13731
  children: /*#__PURE__*/ jsx(OfficeSelect, {
@@ -13613,6 +13757,10 @@ function DocumentPictureRibbon({ editor }) {
13613
13757
  ]
13614
13758
  });
13615
13759
  }
13760
+ function rotateImage(rotation, delta) {
13761
+ const next = (rotation + delta + 360) % 360;
13762
+ return next;
13763
+ }
13616
13764
  function imageWrapDistanceOptionsForValue(value) {
13617
13765
  if (imageWrapDistanceOptions.some((option)=>option.value === value)) return imageWrapDistanceOptions;
13618
13766
  return [
@@ -1,8 +1,8 @@
1
1
  import jszip from "jszip";
2
- import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, createDocumentImageIdentityRegistry, normalizeDocumentColumns, normalizeDocumentTableVerticalAlign, normalizeDocumentTextCase, documentCharacterSpacingTwipsFromElement, documentCharacterPositionHalfPointsFromElement, documentTableColumnPercentagesFromElement, documentTableCellMarginOverridesFromElement, applyDocumentTableRowIdentityToElement, normalizeDocumentBookmarksHtml, documentImageIdentityFromElement, documentTableGeometryFromElement, normalizeDocumentTableRowHeightRule, documentNoteKey, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, normalizeDocumentTableBorderWidth, normalizeDocumentCharacterSpacingTwips, documentStrikeFormattingFromElement, normalizeDocumentTableBorderStyle, parseDocumentNumberingChange, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, normalizeDocumentUnderlineStyle, normalizeDocumentPageChrome, documentPageMarginsForLayout, normalizeDocumentImageLayer, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, serializeDocumentOpenTypeFeatures, documentCaptionLabel, documentCaptionKind, isContourImageLayout, normalizeDocumentLegacyTextEffects, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, normalizeDocumentImageIdentity, normalizeDocumentStrikeStyle, normalizeTableColor, normalizeDocumentOpenTypeFeatures, documentCitationTags, docxDocumentFieldKind, documentTableBordersFromElement, documentSections, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, parseDocumentOpenTypeFeatures, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, parseDocumentCharacterFormatting, documentLegacyTextEffectsFromElement, documentUnderlineFormattingFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, parseDocumentParagraphFormatting, documentOpenTypeFeaturesFromElement, normalizeDocumentBookmarkNativeId, documentTableRowIdentityFromElement, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, collectDocumentNotes, documentImageLayoutFromElement, documentPageHorizontalMarginTwips, DOCUMENT_OPEN_TYPE_ATTRIBUTE, MAX_DOCUMENT_NUMBERING_START, documentPageGeometryForLayout, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./4174.js";
2
+ import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, createDocumentImageIdentityRegistry, normalizeDocumentColumns, normalizeDocumentTableVerticalAlign, normalizeDocumentTextCase, documentCharacterSpacingTwipsFromElement, documentCharacterPositionHalfPointsFromElement, documentTableColumnPercentagesFromElement, documentTableCellMarginOverridesFromElement, applyDocumentTableRowIdentityToElement, normalizeDocumentBookmarksHtml, documentImageIdentityFromElement, documentTableGeometryFromElement, normalizeDocumentTableRowHeightRule, documentNoteKey, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, normalizeDocumentTableBorderWidth, normalizeDocumentCharacterSpacingTwips, documentStrikeFormattingFromElement, normalizeDocumentTableBorderStyle, parseDocumentNumberingChange, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, normalizeDocumentUnderlineStyle, normalizeDocumentPageChrome, documentPageMarginsForLayout, normalizeDocumentImageLayer, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, serializeDocumentOpenTypeFeatures, documentCaptionLabel, documentCaptionKind, isContourImageLayout, normalizeDocumentLegacyTextEffects, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, normalizeDocumentImageIdentity, normalizeDocumentStrikeStyle, normalizeTableColor, normalizeDocumentOpenTypeFeatures, documentCitationTags, docxDocumentFieldKind, documentTableBordersFromElement, documentSections, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, parseDocumentOpenTypeFeatures, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, documentImageTransformFromElement, parseDocumentCharacterFormatting, documentLegacyTextEffectsFromElement, documentUnderlineFormattingFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, parseDocumentParagraphFormatting, documentOpenTypeFeaturesFromElement, normalizeDocumentBookmarkNativeId, documentTableRowIdentityFromElement, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, collectDocumentNotes, documentImageLayoutFromElement, documentPageHorizontalMarginTwips, DOCUMENT_OPEN_TYPE_ATTRIBUTE, MAX_DOCUMENT_NUMBERING_START, documentPageGeometryForLayout, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./4174.js";
3
3
  import { normalizeDocumentRunBorder, parseDocumentScriptFonts, parseDocxThemeReference, parseXml, parseDocumentRunShading, applyDocumentParagraphIdentityToElement, DOCUMENT_RUN_SHADING_ATTRIBUTE, documentScriptFontSlotFromElement, DOCUMENT_HIGHLIGHT_ATTRIBUTE, normalizeDocumentIndexesHtml, serializeDocumentScriptFonts, attribute as work_ooxml_package_attribute, createDocumentParagraphIdentityRegistry, uniqueDocumentParagraphIdentity, DOCUMENT_NO_PROOF_ATTRIBUTE, documentHighlightForCssColor, directChildren, documentTableOfContentsValueFromElement, DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE, DocxThemePatchCollector, normalizeDocumentScriptFonts, normalizeDocumentParagraphIdentity, normalizeDocumentHighlight, normalizeDocumentParagraphBorders, serializeUtf8Xml, DOCUMENT_PARAGRAPH_BORDER_EDGES, parseDocumentRunBorder, normalizeDocumentNoProof, decodeXmlBytes, documentParagraphIdentityFromElement, normalizeDocumentParagraphId, documentScriptFontFamily, descendants, resolvePartTarget, documentProofingLanguagesFromElement, documentHighlightFromElement, parseDocumentRunShadingElement, parseDocumentProofingLanguages, patchDocxThemeReferences, parseDocumentParagraphBordersElement, DOCUMENT_RUN_BORDER_ATTRIBUTE, parseDocumentRunBorderElement, xmlNamespacePrefix, documentScriptFontSlotFromHint, documentNoProofFromElement, documentScriptFontsFromElement, normalizeDocumentRunShading, normalizeDocumentScriptFontSlot, directChild, documentIndexEntryFromElement, documentIndexValueFromElement, parseDocumentParagraphShadingElement, documentFontNameFromCssFamily } from "./6968.js";
4
4
  import { assignDocxNoteIds, patchDocxPageColor, normalizeDocxCommentId, assignDocxCommentThreads } from "./0~4980.js";
5
- import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, DOCX_WORD_2010_NAMESPACE, docxKerningThresholdValue, patchDocxBibliography, documentIndexInstruction, docxCharacterScaleValue, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, xmlNamespaceUri, paragraphSpacingOptions, docxCharacterPositionValue, documentIndexEntryInstruction, docxEmphasisMarkRunOptions, hasNonWhitespaceXmlText, patchDocxExplicitZeroCharacterSpacing, cloneXmlElement, cssColorToHex, xmlDeclaredPrefix, assertXmlRoot, DOCX_WORDPROCESSING_NAMESPACES, paragraphIndent, domDirection, xmlAttributeNamespace, paragraphBidirectional, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, mergeDocxIgnorableExtensions, DocxParagraphDefaultCollapsedPatchCollector, dataBoolean, patchDocxParagraphDefaultCollapsed, patchDocxExplicitZeroKerningThresholds, parseDocxColorSchemeMappingElement, paragraphPaginationOptions, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, documentProofingLanguageDocxOptions, xmlAttributeLocalName, cssFontSize, paragraphDirectionOptions, cssFontFamily, docxCharacterSpacingValue } from "./0~5024.js";
5
+ import { DocxImageTransformPatchCollector, paragraphTabStops, patchDocxImageTransforms, mergeDocxIgnorableExtensionsAtPairs, DOCX_WORD_2010_NAMESPACE, docxKerningThresholdValue, patchDocxBibliography, documentIndexInstruction, docxCharacterScaleValue, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, xmlNamespaceUri, paragraphSpacingOptions, docxCharacterPositionValue, documentIndexEntryInstruction, docxEmphasisMarkRunOptions, hasNonWhitespaceXmlText, patchDocxExplicitZeroCharacterSpacing, cloneXmlElement, cssColorToHex, xmlDeclaredPrefix, assertXmlRoot, DOCX_WORDPROCESSING_NAMESPACES, paragraphIndent, domDirection, xmlAttributeNamespace, paragraphBidirectional, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, mergeDocxIgnorableExtensions, DocxParagraphDefaultCollapsedPatchCollector, dataBoolean, patchDocxParagraphDefaultCollapsed, patchDocxExplicitZeroKerningThresholds, parseDocxColorSchemeMappingElement, paragraphPaginationOptions, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, documentProofingLanguageDocxOptions, xmlAttributeLocalName, cssFontSize, paragraphDirectionOptions, cssFontFamily, docxCharacterSpacingValue } from "./0~4042.js";
6
6
  import { normalizeDocumentHref } from "./0~work-document-links.js";
7
7
  const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
8
8
  class DocxBookmarkPatchCollector {
@@ -1959,7 +1959,7 @@ function supportedPartRoot(root, path) {
1959
1959
  const expected = /^word\/header\d*\.xml$/i.test(path) ? 'hdr' : /^word\/footer\d*\.xml$/i.test(path) ? 'ftr' : /^word\/footnotes\.xml$/i.test(path) ? 'footnotes' : /^word\/endnotes\.xml$/i.test(path) ? 'endnotes' : 'document';
1960
1960
  return root.localName === expected && DOCX_WORDPROCESSING_NAMESPACES.has(root.namespaceURI ?? '');
1961
1961
  }
1962
- async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches, identityPatches) {
1962
+ async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches, identityPatches, transformPatches) {
1963
1963
  const source = element.getAttribute('src');
1964
1964
  const alt = element.getAttribute('alt') || element.getAttribute('title') || 'Image';
1965
1965
  if (!source) return new docx.TextRun(`[${alt}]`);
@@ -1982,6 +1982,7 @@ async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches
1982
1982
  const wrapMarker = wrapPatches?.marker(imageLayout, documentImageWrapContourFromElement(element));
1983
1983
  const layer = documentImageLayerFromElement(element);
1984
1984
  const layerMarker = layerPatches?.marker(imageLayout.layout, layer);
1985
+ const transformMarker = transformPatches?.marker(documentImageTransformFromElement(element));
1985
1986
  return new docx.ImageRun({
1986
1987
  type,
1987
1988
  data: await blob.arrayBuffer(),
@@ -1990,7 +1991,7 @@ async function imageToDocx(element, docx, cropPatches, wrapPatches, layerPatches
1990
1991
  height: Math.max(24, Math.round(dimensions.height * scale))
1991
1992
  },
1992
1993
  altText: {
1993
- name: `${alt}${cropMarker ?? ''}${wrapMarker ?? ''}${layerMarker ?? ''}${identity?.marker ?? ''}`,
1994
+ name: `${alt}${cropMarker ?? ''}${wrapMarker ?? ''}${layerMarker ?? ''}${identity?.marker ?? ''}${transformMarker ?? ''}`,
1994
1995
  description: alt,
1995
1996
  title: alt,
1996
1997
  id: identity ? String(identity.docPropertiesId) : void 0
@@ -8686,6 +8687,7 @@ async function createDocxBlob(content, sourcePackage) {
8686
8687
  imageIdentityPatches: new DocxImageIdentityPatchCollector(),
8687
8688
  imageLayerPatches: new DocxImageLayerPatchCollector(),
8688
8689
  imageWrapPatches: new DocxImageWrapPatchCollector(),
8690
+ imageTransformPatches: new DocxImageTransformPatchCollector(),
8689
8691
  paragraphBorderPatches: new DocxParagraphBorderPatchCollector(JSON.stringify(normalizedContent)),
8690
8692
  paragraphDefaultCollapsedPatches: new DocxParagraphDefaultCollapsedPatchCollector(),
8691
8693
  paragraphIdentityPatches: new DocxParagraphIdentityPatchCollector(JSON.stringify(normalizedContent)),
@@ -8773,7 +8775,8 @@ async function createDocxBlob(content, sourcePackage) {
8773
8775
  const imageCropPatched = await patchDocxImageCrops(themePatched, noteContext.imageCropPatches.patches);
8774
8776
  const imageWrapPatched = await patchDocxImageWraps(imageCropPatched, noteContext.imageWrapPatches.patches);
8775
8777
  const imageLayerPatched = await patchDocxImageLayers(imageWrapPatched, noteContext.imageLayerPatches.patches);
8776
- const imageIdentityPatched = await patchDocxImageIdentities(imageLayerPatched, noteContext.imageIdentityPatches.patches);
8778
+ const imageTransformPatched = await patchDocxImageTransforms(imageLayerPatched, noteContext.imageTransformPatches.patches);
8779
+ const imageIdentityPatched = await patchDocxImageIdentities(imageTransformPatched, noteContext.imageIdentityPatches.patches);
8777
8780
  const bookmarkPatched = await patchDocxBookmarks(imageIdentityPatched, noteContext.bookmarkPatches.patches);
8778
8781
  const paragraphDefaultCollapsedPatched = await patchDocxParagraphDefaultCollapsed(bookmarkPatched, noteContext.paragraphDefaultCollapsedPatches.patches);
8779
8782
  const paragraphIdentityPatched = await patchDocxParagraphIdentities(paragraphDefaultCollapsedPatched, noteContext.paragraphIdentityPatches.patches);
@@ -8980,7 +8983,7 @@ async function blockToFileChildren(element, docx, noteContext) {
8980
8983
  if ('img' === tag) return [
8981
8984
  new docx.Paragraph({
8982
8985
  children: [
8983
- await imageToDocx(element, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches)
8986
+ await imageToDocx(element, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches, noteContext.imageTransformPatches)
8984
8987
  ]
8985
8988
  })
8986
8989
  ];
@@ -9221,7 +9224,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
9221
9224
  ];
9222
9225
  }
9223
9226
  if ('img' === tag) return [
9224
- await imageToDocx(node, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches)
9227
+ await imageToDocx(node, docx, noteContext.imageCropPatches, noteContext.imageWrapPatches, noteContext.imageLayerPatches, noteContext.imageIdentityPatches, noteContext.imageTransformPatches)
9225
9228
  ];
9226
9229
  if ('span' === tag && 'true' === node.dataset.documentBookmarkBoundary) {
9227
9230
  const marker = noteContext.bookmarkPatches.register(node);
@@ -1,8 +1,8 @@
1
1
  import jszip from "jszip";
2
2
  import { documentRunBorderDomAttributes, contentTypeForPart, bytesToDataUrl, OoxmlPackage, normalizeDocumentIndexesHtml, firstDescendant, normalizeDocumentParagraphId, applyDocumentParagraphIdentityToElement, descendants, documentHighlightDomAttributes, attribute as work_ooxml_package_attribute, documentHighlightFromDocxValue, serializeDocxThemeReference, normalizeDocumentTableOfContentsHtml, directChildren, documentParagraphShadingDomAttributes, documentProofingDomAttributes, documentParagraphBordersDomAttributes, directChild, documentScriptFontSegments, normalizeDocumentParagraphIdentity, documentRunShadingDomAttributes } from "./6968.js";
3
- import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, documentCharacterPositionDomAttributes, createDocumentImageIdentityRegistry, normalizeDocumentColumns, documentStrikeDomAttributes, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, documentCharacterSpacingDomAttributes, normalizeDocumentImageAlignment, applyDocumentImageLayerToElement, normalizeDocumentNotesHtml, normalizeDocumentBookmarkReferencesHtml, documentCitationTagsFromInstruction, applyDocumentImageWrapContourToElement, documentUnderlineDomAttributes, documentHiddenTextDomAttributes, normalizeDocumentPageChrome, normalizeDocumentImageLayoutOptions, applyDocumentImageCropToElement, documentPageMarginsForLayout, applyDocumentPageGeometry, createDocumentNoteElement, normalizeDocumentImageLayer, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, documentBookmarkReferenceInstruction, documentInitialSectionLayout, normalizeDocumentFieldsHtml, documentCaptionLabel, documentTableBordersFromElement, isContourImageLayout, normalizeDocumentCitationsHtml, normalizeDocumentImageIdentity, normalizeDocumentImageWrapSide, documentKerningDomAttributes, docxDocumentFieldKind, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentCharacterScaleDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, documentPageMarginBody, documentLegacyTextEffectsDomAttributes, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, documentOpenTypeDomAttributes, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentEmphasisMarkDomAttributes } from "./4174.js";
3
+ import { normalizeDocumentBookmarkName, renderDocumentTableCellMarginOverrides, applyDocumentImageIdentityToElement, documentCharacterPositionDomAttributes, createDocumentImageIdentityRegistry, normalizeDocumentColumns, documentStrikeDomAttributes, normalizeDocumentImageWrapContour, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, normalizeDocumentBookmarksHtml, applyDocumentTableRowIdentityToElement, normalizeDocumentCaptionsHtml, documentCharacterSpacingDomAttributes, normalizeDocumentImageAlignment, applyDocumentImageLayerToElement, normalizeDocumentNotesHtml, normalizeDocumentBookmarkReferencesHtml, documentCitationTagsFromInstruction, applyDocumentImageWrapContourToElement, documentUnderlineDomAttributes, documentHiddenTextDomAttributes, normalizeDocumentPageChrome, normalizeDocumentImageLayoutOptions, applyDocumentImageCropToElement, documentPageMarginsForLayout, applyDocumentPageGeometry, createDocumentNoteElement, normalizeDocumentImageLayer, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, documentBookmarkReferenceInstruction, applyDocumentImageTransformToElement, documentInitialSectionLayout, normalizeDocumentFieldsHtml, documentCaptionLabel, documentTableBordersFromElement, isContourImageLayout, normalizeDocumentCitationsHtml, normalizeDocumentImageIdentity, normalizeDocumentImageWrapSide, documentKerningDomAttributes, docxDocumentFieldKind, renderDocumentTableBorders, docxBookmarkReferenceTarget, normalizeDocumentImagePosition, wrapsBesideImage, documentPageChromeLegacyFields, documentCharacterScaleDomAttributes, DEFAULT_DOCUMENT_TABLE_GEOMETRY, documentSectionDomAttributes, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, documentPageMarginBody, documentLegacyTextEffectsDomAttributes, normalizeDocumentTableRowIdentity, normalizeDocumentBookmarkNativeId, documentOpenTypeDomAttributes, uniqueDocumentImageIdentity, applyDocumentTableGeometryToElement, normalizeDocumentImageCrop, documentContentLayoutProperties, documentEmphasisMarkDomAttributes } from "./4174.js";
4
4
  import { hasImportedDocxIndexMarkers, markDocxRunFormattingIntoState, applyImportedDocxParagraphSpacingMarkers, hasImportedDocxParagraphDirectionMarkers, hasImportedDocxParagraphIndentMarkers, resolveDocxParagraphBordersForParagraph, applyImportedDocxNumberingChangeMarkers, applyImportedDocxParagraphShadingMarkers, markDocxParagraphSpacing, docxCaptionBookmark, docxFieldResultText, createDocxParagraphStyleResolver, docxTableCellStyleLayers, createImportedDocxRunFormattingMarkerState, parseDocxPaperSource, resolveDocxLegacyTextEffects, markDocxTablesOfContents, hasImportedDocxParagraphSpacingMarkers, applyImportedDocxIndexMarkers, applyImportedDocxTableOfContentsMarkers, markDocxIndexes, parseDocxPageMargins, docxTablePropertySources, parseDirectDocxParagraphShading, markDocxParagraphIndents, markDocxPackageEquations, resolveDocxRunBorder, parseDocxPageGeometry, docxCaptionReferenceTarget, applyImportedDocxEquationMarkers, hasImportedDocxParagraphPaginationMarkers, createDocxTableStyleResolver, hasImportedDocxParagraphShadingMarkers, isDocxEquationLikeRoot, importedDocxStrike, docxTableRunPropertySources, hasImportedDocxNumberingChangeMarkers, inspectDocxPageMarginSettings, hasImportedDocxRunFormattingMarkers, hasImportedDocxTableOfContentsMarkers, applyImportedDocxParagraphFormattingChangeMarkers, hasImportedDocxParagraphTabStopMarkers, resolveDocxRunShading, docxCaptionSequenceKind, applyImportedDocxRunFormattingMarkers, markDocxParagraphAlignments, markDocxParagraphDirections, hasImportedDocxParagraphBorderMarkers, hasImportedDocxParagraphFormattingChangeMarkers, resolveDocxHiddenText, docxEquationHtml, docxFieldOccurrences, hasImportedDocxParagraphAlignmentMarkers, markDocxParagraphTabStops, applyImportedDocxParagraphIndentMarkers, resolveDocxTableStyleResolver, applyImportedDocxParagraphDirectionMarkers, markDocxNumberingChanges, applyImportedDocxParagraphAlignmentMarkers, importedDocxUnderline, markDocxParagraphBorders, markDocxParagraphPagination, applyImportedDocxParagraphTabStopMarkers, applyImportedDocxParagraphPaginationMarkers, docxFieldOccurrenceIsInlineEditable, applyImportedDocxParagraphBorderMarkers, docxRunPropertySources, markDocxParagraphFormattingChanges, markDocxParagraphShading, parseDocxPageBorders } from "./0~2330.js";
5
- import { readDocxBibliography, resolveDocxProofing, XMLNS_NAMESPACE, docxCharacterScalePercentFromProperties, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, resolveDocxOpenTypeFeatures, xmlAttributeLocalName, resolveDocxEmphasisMark, createDocxThemeResolver, docxCharacterPositionHalfPointsFromProperties, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~5024.js";
5
+ import { readDocxBibliography, resolveDocxProofing, XMLNS_NAMESPACE, docxCharacterScalePercentFromProperties, docxCharacterSpacingTwipsFromProperties, parseBoundedDocxInteger, resolveDocxOpenTypeFeatures, xmlAttributeLocalName, resolveDocxEmphasisMark, createDocxThemeResolver, docxCharacterPositionHalfPointsFromProperties, readDocxImageTransform, docxThemeColor, parseDocxParagraphDefaultCollapsed, resolveDocxKerningThresholdHalfPoints, resolveDocxThemeResolver, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace } from "./0~4042.js";
6
6
  import { importDocxPageColor, importedDocumentNoteId } from "./0~4980.js";
7
7
  const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
8
8
  const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
@@ -1039,6 +1039,7 @@ function markDocxImageLayouts(document, state = createImportedDocxImageLayoutMar
1039
1039
  const run = closestAncestor(anchor, 'r');
1040
1040
  if (!run || markedRuns.has(run)) continue;
1041
1041
  const crop = anchorCrop(anchor);
1042
+ const transform = anchorTransform(anchor);
1042
1043
  const layout = 'inline' === anchor.localName ? 'inline' : anchorLayout(anchor);
1043
1044
  if (!layout) continue;
1044
1045
  if (state.nextMarker > MAX_IMPORTED_IMAGE_LAYOUTS) throw new Error('Imported DOCX exceeds the image-layout limit.');
@@ -1060,6 +1061,7 @@ function markDocxImageLayouts(document, state = createImportedDocxImageLayoutMar
1060
1061
  }),
1061
1062
  position: anchorPosition(anchor),
1062
1063
  crop,
1064
+ transform,
1063
1065
  contour: isContourImageLayout(layout) ? anchorWrapContour(anchor, layout) : null,
1064
1066
  layer: 'anchor' === anchor.localName ? anchorLayer(anchor) : null,
1065
1067
  identity: uniqueDocumentImageIdentity(drawingIdentitySource(anchor), state.identityRegistry)
@@ -1098,7 +1100,7 @@ function applyImportedDocxImageLayoutMarkers(document, markers) {
1098
1100
  continue;
1099
1101
  }
1100
1102
  if (!state.applied && state.active && node instanceof HTMLImageElement) {
1101
- applyImageLayout(node, state.active.options, state.active.position, state.active.crop, state.active.contour, state.active.layer, state.active.identity);
1103
+ applyImageLayout(node, state.active.options, state.active.position, state.active.crop, state.active.transform, state.active.contour, state.active.layer, state.active.identity);
1102
1104
  state.applied = true;
1103
1105
  }
1104
1106
  }
@@ -1185,6 +1187,9 @@ function anchorCrop(anchor) {
1185
1187
  cropLeft: cropPercentage(source, 'l')
1186
1188
  });
1187
1189
  }
1190
+ function anchorTransform(anchor) {
1191
+ return readDocxImageTransform(anchor).transform;
1192
+ }
1188
1193
  function anchorLayer(anchor) {
1189
1194
  return normalizeDocumentImageLayer({
1190
1195
  relativeHeight: work_ooxml_package_attribute(anchor, 'relativeHeight'),
@@ -1225,7 +1230,7 @@ function insertMarkerRun(document, run, marker, position) {
1225
1230
  if (!parent) return;
1226
1231
  parent.insertBefore(markerRun, 'before' === position ? run : run.nextSibling);
1227
1232
  }
1228
- function applyImageLayout(image, options, position, crop, contour, layer, identity) {
1233
+ function applyImageLayout(image, options, position, crop, transform, contour, layer, identity) {
1229
1234
  applyDocumentImageIdentityToElement(image, identity);
1230
1235
  image.dataset.officeImageLayout = options.layout;
1231
1236
  image.dataset.officeImageAlignment = options.alignment;
@@ -1246,6 +1251,7 @@ function applyImageLayout(image, options, position, crop, contour, layer, identi
1246
1251
  image.dataset.officeImageVerticalReference = position.verticalReference;
1247
1252
  }
1248
1253
  applyDocumentImageCropToElement(image, crop);
1254
+ applyDocumentImageTransformToElement(image, transform);
1249
1255
  applyDocumentImageWrapContourToElement(image, contour);
1250
1256
  if (layer) applyDocumentImageLayerToElement(image, layer);
1251
1257
  }
@@ -3,7 +3,7 @@ import { contentTypeForPart, directChildren, OoxmlPackage, parseXml, firstDescen
3
3
  import { normalizeDocumentBookmarkName, docxBookmarkReferenceTarget, normalizeDocumentBookmarkNativeId, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, supportedDocxBookmarkReferenceInstruction, documentCitationTagsFromInstruction, docxDocumentFieldKind } from "./4174.js";
4
4
  import { markDocxParagraphShading, inspectDocxPageSize, isSupportedDocxNumberingChange, docxCaptionBookmark, hasInvalidDocxFieldStructure, inspectDocxLegacyTextEffects, inspectDocxPageMargins, inspectDocxPaperSource, createDocxParagraphStyleResolver, supportedDocxTableOfContentsField, docxFieldOccurrences, supportedDocxIndexEntryField, createDocxTableStyleResolver, inspectDocxEquation, inspectDocxPageMarginSettings, inspectDocxRunBorder, inspectDocxRunFonts, inspectDocxRunShading, markDocxParagraphBorders, isSupportedDocxParagraphFormattingChange, docxFieldOccurrenceIsInlineEditable, supportedDocxIndexField, docxCaptionSequenceKind, inspectDocxHiddenText, inspectDocxPageBorders, isSupportedDocxRunFormattingChange, docxFieldInstructions, isSupportedDocxEquationPlacement } from "./0~2330.js";
5
5
  import { normalizeDocumentHref } from "./0~work-document-links.js";
6
- import { xmlAttributeLocalName, resolveDocxOpenTypeFeatures, inspectDocxProofingLanguages, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, DOCX_WORD_2010_NAMESPACE, inspectDocxNoProof, parseDocxParagraphDefaultCollapsed, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~5024.js";
6
+ import { xmlAttributeLocalName, resolveDocxOpenTypeFeatures, inspectDocxProofingLanguages, readDocxBibliography, inspectDocxEmphasisMark, createDocxThemeResolver, DOCX_WORD_2010_NAMESPACE, inspectDocxNoProof, parseDocxParagraphDefaultCollapsed, readDocxImageTransform, DOCX_WORDPROCESSING_NAMESPACES, xmlAttributeNamespace, inspectDocxKerningThresholdHalfPoints } from "./0~4042.js";
7
7
  import { updateSpreadsheetWorksheetCompatibilitySummary, inspectXlsxPivotTables, isSupportedXlsxChartLegend, isSupportedXlsxChartPlotLayout, xlsxChartNodeUsesStackedGrouping, isSupportedXlsxChartSeriesFormatting, readXlsxFormulaFeaturesFromPackage, inspectXlsxHeaderFooterText, emptySpreadsheetWorksheetCompatibilitySummary, isSupportedXlsxWorksheetImageContentType, MAX_XLSX_WORKSHEET_IMAGE_BYTES, xlsxChartSeriesFormattingShapeProperties, diagnoseXlsxProtection, isEditableXlsxPaperSizeCode, isSupportedXlsxCombinationChartNodes } from "./4166.js";
8
8
  import { spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, isSpreadsheetConditionalComparisonOperator, spreadsheetConditionalIconSetCount, xlsxWorksheetCellEntries } from "./9333.js";
9
9
  import { formulaHasStructuredReference, formulaHasExternalReference, parseSpreadsheetPrintTitles, volatileSpreadsheetFormulaFunctions, stripSpreadsheetSheetQualifier } from "./8715.js";
@@ -2191,7 +2191,11 @@ async function analyzeDocxCompatibility(file, messages, sourcePackage) {
2191
2191
  const captionDiagnostics = diagnoseDocxCaptions(document);
2192
2192
  issues.push(...captionDiagnostics.issues);
2193
2193
  if (descendants(document, 'tbl').length) issues.push(work_office_diagnostics_issue('docx.tables', 'Tables', 'Table rows, non-splitting rows, repeated headers, cell shading, vertical alignment, per-edge borders, and paragraph-boundary row continuation remain editable. Native row identities survive body and page-chrome HTML; uniquely matched passive extensions on stable table, row, and cell scopes and their property nodes are retained, while duplicate, cross-kind, relationship-bound, or semantic branches fail closed. Layout algorithm, preferred auto, percentage, or pixel width, alignment, indent, percentage or pixel column widths, table-level cell margins, and cell-level margin overrides are preserved independently across edit, preview, and DOCX export. Percentage column preferences use pixel grid widths as responsive browser fallbacks and remain coherent through merged cells. Nested tables retain independent edit and DOCX geometry, and tall outer rows can paginate at nested-row boundaries. Row-spanning cells continue through every covered physical row with in-cell page breaks and contiguous content ranges; combined row and column spans retain native DOCX merge semantics. Common inherited Word table styles apply whole-table, banded row or column, first or last row or column, corner-cell, border, fill, text-emphasis, paragraph alignment, direction, indents, spacing, line, pagination, and tab-stop rules before direct table, cell, paragraph, and run formatting. Theme tint and shade values resolve to stable RGB for edit and preview, while untouched run colors, run shading, cell fills, and per-edge borders retain their semantic theme references on export; explicit color edits use direct RGB. Less-common conditional paragraph properties may be normalized.'));
2194
- if (descendants(document, 'drawing').length || descendants(document, 'pict').length) issues.push(work_office_diagnostics_issue('docx.images', 'Images', 'Inline images and supported square, tight, through, top-and-bottom, or no-wrap free-floating images remain embedded with editable size, alternative text, alignment, wrap side and distance where applicable, signed horizontal or vertical offsets relative to the column, paragraph, margin, or page, four-edge percentage cropping, and drawing-layer options. Aligned and precise DOCX anchors retain their distinct position semantics; inline and floating crop geometry round-trips as DrawingML source rectangles; tight or through anchors retain their ordered wrap polygons; no-wrap anchors remain outside the body text flow and use behind-text placement to choose their side of the text; and supported floating images preserve relative Z-order, overlap and cell-layout policy, and anchor locking. Inline and floating pictures retain unique drawing-property and anchor IDs together with their edit IDs. Copies receive independent identities while move, delete, undo, and relationship regeneration retain the original object identity. Unsupported drawing types may be normalized.'));
2194
+ if (descendants(document, 'drawing').length || descendants(document, 'pict').length) {
2195
+ const unsupportedImageTransforms = docxUnsupportedImageTransformCount(document);
2196
+ issues.push(work_office_diagnostics_issue('docx.images', 'Images', 'Inline images and supported square, tight, through, top-and-bottom, or no-wrap free-floating images remain embedded with editable size, alternative text, alignment, wrap side and distance where applicable, signed horizontal or vertical offsets relative to the column, paragraph, margin, or page, four-edge percentage cropping, 90-degree rotation, horizontal or vertical reflection, and drawing-layer options. Aligned and precise DOCX anchors retain their distinct position semantics; inline and floating crop geometry round-trips as DrawingML source rectangles; tight or through anchors retain their ordered wrap polygons; no-wrap anchors remain outside the body text flow and use behind-text placement to choose their side of the text; and supported floating images preserve relative Z-order, overlap and cell-layout policy, and anchor locking. Inline and floating pictures retain unique drawing-property and anchor IDs together with their edit IDs. Copies receive independent identities while move, delete, undo, and relationship regeneration retain the original object identity. Arbitrary-angle or malformed picture transforms and unsupported drawing types may be normalized.'));
2197
+ if (unsupportedImageTransforms) issues.push(work_office_diagnostics_issue('docx.images.transform', 'Image transforms', `${unsupportedImageTransforms} picture transform(s) use an arbitrary angle or malformed rotation/reflection value. Work imports the editable 90-degree/reflection subset and normalizes the unsupported transform instead of exposing an inexact control.`));
2198
+ }
2195
2199
  const textRevisions = [
2196
2200
  ...descendants(document, 'ins'),
2197
2201
  ...descendants(document, 'del')
@@ -2349,6 +2353,13 @@ async function inspectXlsxPackage(archive, issues, importedMetadata) {
2349
2353
  })) issues.push(work_office_diagnostics_issue('xlsx.manual-page-breaks', 'Manual page breaks', 'Manual row and column page breaks are preserved, editable, and honored by PDF pagination.', 'info'));
2350
2354
  }
2351
2355
  }
2356
+ function docxUnsupportedImageTransformCount(document) {
2357
+ const drawings = [
2358
+ ...descendants(document, 'anchor'),
2359
+ ...descendants(document, 'inline')
2360
+ ];
2361
+ return drawings.filter((drawing)=>descendants(drawing, 'pic').length > 0 && !readDocxImageTransform(drawing).supported).length;
2362
+ }
2352
2363
  function report(file, sourceFormat, issues) {
2353
2364
  return {
2354
2365
  sourceFormat,
package/dist/4174.js CHANGED
@@ -12711,6 +12711,9 @@ const DEFAULT_IMAGE_ALIGNMENT = 'center';
12711
12711
  const DEFAULT_WRAP_DISTANCE_MILLIMETERS = 3;
12712
12712
  const MAX_WRAP_DISTANCE_MILLIMETERS = 25;
12713
12713
  const DEFAULT_LOCK_ASPECT_RATIO = true;
12714
+ const DEFAULT_IMAGE_ROTATION = 0;
12715
+ const DEFAULT_IMAGE_FLIP_HORIZONTAL = false;
12716
+ const DEFAULT_IMAGE_FLIP_VERTICAL = false;
12714
12717
  const DEFAULT_HORIZONTAL_REFERENCE = 'column';
12715
12718
  const DEFAULT_VERTICAL_REFERENCE = 'paragraph';
12716
12719
  const MAX_IMAGE_OFFSET_MILLIMETERS = 558.7;
@@ -12854,6 +12857,9 @@ const DocumentImage = extension_image.extend({
12854
12857
  cropRight: imageCropNumberAttribute('right'),
12855
12858
  cropBottom: imageCropNumberAttribute('bottom'),
12856
12859
  cropLeft: imageCropNumberAttribute('left'),
12860
+ rotation: imageTransformRotationAttribute(),
12861
+ flipHorizontal: imageTransformBooleanAttribute('flipHorizontal', 'data-office-image-flip-horizontal'),
12862
+ flipVertical: imageTransformBooleanAttribute('flipVertical', 'data-office-image-flip-vertical'),
12857
12863
  wrapPolygon: imageWrapPolygonAttribute(),
12858
12864
  wrapPolygonEdited: {
12859
12865
  default: false,
@@ -12935,6 +12941,7 @@ function documentImageProperties(editor) {
12935
12941
  const layout = normalizeDocumentImageLayoutOptions(attributes);
12936
12942
  const position = normalizeDocumentImagePosition(attributes);
12937
12943
  const crop = normalizeDocumentImageCrop(attributes);
12944
+ const transform = normalizeDocumentImageTransform(attributes);
12938
12945
  const contour = effectiveDocumentImageWrapContour(attributes);
12939
12946
  return {
12940
12947
  ...layout,
@@ -12948,6 +12955,9 @@ function documentImageProperties(editor) {
12948
12955
  ...crop ? {
12949
12956
  crop
12950
12957
  } : {},
12958
+ ...documentImageTransformIsDefault(transform) ? {} : {
12959
+ transform
12960
+ },
12951
12961
  ...contour ? {
12952
12962
  contour
12953
12963
  } : {},
@@ -12986,6 +12996,14 @@ function documentImageCropFromElement(element) {
12986
12996
  cropLeft: element.getAttribute('data-office-image-crop-left')
12987
12997
  });
12988
12998
  }
12999
+ function documentImageTransformFromElement(element) {
13000
+ const transform = normalizeDocumentImageTransform({
13001
+ rotation: element.getAttribute('data-office-image-rotation'),
13002
+ flipHorizontal: element.getAttribute('data-office-image-flip-horizontal'),
13003
+ flipVertical: element.getAttribute('data-office-image-flip-vertical')
13004
+ });
13005
+ return documentImageTransformIsDefault(transform) ? null : transform;
13006
+ }
12989
13007
  function documentImageLayerFromElement(element) {
12990
13008
  return normalizeDocumentImageLayer({
12991
13009
  relativeHeight: element.getAttribute('data-office-image-relative-height'),
@@ -13061,6 +13079,56 @@ function normalizeDocumentImageCropEdge(value) {
13061
13079
  if (!Number.isFinite(number)) return 0;
13062
13080
  return Math.round(100 * Math.min(99.99, Math.max(0, number))) / 100;
13063
13081
  }
13082
+ function defaultDocumentImageTransform() {
13083
+ return {
13084
+ rotation: DEFAULT_IMAGE_ROTATION,
13085
+ flipHorizontal: DEFAULT_IMAGE_FLIP_HORIZONTAL,
13086
+ flipVertical: DEFAULT_IMAGE_FLIP_VERTICAL
13087
+ };
13088
+ }
13089
+ function normalizeDocumentImageTransform(value) {
13090
+ return {
13091
+ rotation: normalizeDocumentImageRotation(value.rotation),
13092
+ flipHorizontal: normalizeDocumentImageTransformBoolean(value.flipHorizontal, DEFAULT_IMAGE_FLIP_HORIZONTAL),
13093
+ flipVertical: normalizeDocumentImageTransformBoolean(value.flipVertical, DEFAULT_IMAGE_FLIP_VERTICAL)
13094
+ };
13095
+ }
13096
+ function normalizeDocumentImageRotation(value) {
13097
+ const number = 'number' == typeof value ? value : 'string' == typeof value && value.trim() ? Number(value) : DEFAULT_IMAGE_ROTATION;
13098
+ if (!Number.isFinite(number)) return DEFAULT_IMAGE_ROTATION;
13099
+ const normalized = (Math.round(number) % 360 + 360) % 360;
13100
+ return 90 === normalized || 180 === normalized || 270 === normalized ? normalized : DEFAULT_IMAGE_ROTATION;
13101
+ }
13102
+ function documentImageTransformIsDefault(transform) {
13103
+ return transform.rotation === DEFAULT_IMAGE_ROTATION && !transform.flipHorizontal && !transform.flipVertical;
13104
+ }
13105
+ function documentImageTransformCss(transform) {
13106
+ const normalized = normalizeDocumentImageTransform(transform);
13107
+ if (documentImageTransformIsDefault(normalized)) return '';
13108
+ return [
13109
+ `--work-document-image-rotation:${normalized.rotation}deg`,
13110
+ `--work-document-image-flip-x:${normalized.flipHorizontal ? -1 : 1}`,
13111
+ `--work-document-image-flip-y:${normalized.flipVertical ? -1 : 1}`
13112
+ ].join(';');
13113
+ }
13114
+ function applyDocumentImageTransformToElement(element, transform) {
13115
+ const normalized = normalizeDocumentImageTransform(transform ?? {});
13116
+ if (normalized.rotation === DEFAULT_IMAGE_ROTATION) delete element.dataset.officeImageRotation;
13117
+ else element.dataset.officeImageRotation = String(normalized.rotation);
13118
+ if (normalized.flipHorizontal) element.dataset.officeImageFlipHorizontal = 'true';
13119
+ else delete element.dataset.officeImageFlipHorizontal;
13120
+ if (normalized.flipVertical) element.dataset.officeImageFlipVertical = 'true';
13121
+ else delete element.dataset.officeImageFlipVertical;
13122
+ if (documentImageTransformIsDefault(normalized)) {
13123
+ element.style.removeProperty('--work-document-image-rotation');
13124
+ element.style.removeProperty('--work-document-image-flip-x');
13125
+ element.style.removeProperty('--work-document-image-flip-y');
13126
+ return;
13127
+ }
13128
+ element.style.setProperty('--work-document-image-rotation', `${normalized.rotation}deg`);
13129
+ element.style.setProperty('--work-document-image-flip-x', normalized.flipHorizontal ? '-1' : '1');
13130
+ element.style.setProperty('--work-document-image-flip-y', normalized.flipVertical ? '-1' : '1');
13131
+ }
13064
13132
  function normalizeDocumentImageLayer(value) {
13065
13133
  return {
13066
13134
  relativeHeight: normalizeDocumentImageRelativeHeight(value.relativeHeight),
@@ -13115,6 +13183,12 @@ function documentImageAttributesForChanges(value) {
13115
13183
  attributes.cropBottom = crop?.bottom ?? 0;
13116
13184
  attributes.cropLeft = crop?.left ?? 0;
13117
13185
  }
13186
+ if (Object.hasOwn(value, 'transform')) {
13187
+ const transform = value.transform ? normalizeDocumentImageTransform(value.transform) : defaultDocumentImageTransform();
13188
+ attributes.rotation = transform.rotation;
13189
+ attributes.flipHorizontal = transform.flipHorizontal;
13190
+ attributes.flipVertical = transform.flipVertical;
13191
+ }
13118
13192
  if (Object.hasOwn(value, 'contour')) {
13119
13193
  const contour = value.contour ? normalizeDocumentImageWrapContour(value.contour) : null;
13120
13194
  attributes.wrapPolygon = contour ? serializeDocumentImageWrapPoints(contour.points) : null;
@@ -13147,6 +13221,7 @@ function syncDocumentImageNodeView(element, container, attributes) {
13147
13221
  const lockAspectRatio = normalizeDocumentImageLockAspectRatio(attributes.lockAspectRatio);
13148
13222
  const position = normalizeDocumentImagePosition(attributes);
13149
13223
  const crop = normalizeDocumentImageCrop(attributes);
13224
+ const transform = normalizeDocumentImageTransform(attributes);
13150
13225
  const wrapSide = normalizeDocumentImageWrapSide(attributes.wrapSide);
13151
13226
  const contour = effectiveDocumentImageWrapContour(attributes);
13152
13227
  const layer = normalizeDocumentImageLayer(attributes);
@@ -13161,6 +13236,7 @@ function syncDocumentImageNodeView(element, container, attributes) {
13161
13236
  element.dataset.officeImageWrapSide = wrapSide;
13162
13237
  syncDocumentImagePosition(element, position);
13163
13238
  applyDocumentImageCropToElement(element, crop);
13239
+ applyDocumentImageTransformToElement(element, transform);
13164
13240
  applyDocumentImageWrapContourToElement(element, contour);
13165
13241
  applyDocumentImageLayerToElement(element, layer);
13166
13242
  if (identity) applyDocumentImageIdentityToElement(element, identity);
@@ -13175,6 +13251,7 @@ function syncDocumentImageNodeView(element, container, attributes) {
13175
13251
  container.dataset.officeImageWrapSide = wrapSide;
13176
13252
  syncDocumentImagePosition(container, position);
13177
13253
  applyDocumentImageCropToElement(container, crop);
13254
+ applyDocumentImageTransformToElement(container, transform);
13178
13255
  applyDocumentImageWrapContourToElement(container, contour);
13179
13256
  applyDocumentImageLayerToElement(container, layer);
13180
13257
  if (identity) applyDocumentImageIdentityToElement(container, identity);
@@ -13219,6 +13296,32 @@ function imageCropNumberAttribute(edge) {
13219
13296
  }
13220
13297
  };
13221
13298
  }
13299
+ function imageTransformRotationAttribute() {
13300
+ return {
13301
+ default: DEFAULT_IMAGE_ROTATION,
13302
+ parseHTML: (element)=>normalizeDocumentImageRotation(element.getAttribute('data-office-image-rotation')),
13303
+ renderHTML: (attributes)=>{
13304
+ const transform = normalizeDocumentImageTransform(attributes);
13305
+ const result = {};
13306
+ if (transform.rotation !== DEFAULT_IMAGE_ROTATION) result['data-office-image-rotation'] = String(transform.rotation);
13307
+ const style = documentImageTransformCss(transform);
13308
+ if (style) result.style = style;
13309
+ return result;
13310
+ }
13311
+ };
13312
+ }
13313
+ function imageTransformBooleanAttribute(key, name) {
13314
+ return {
13315
+ default: false,
13316
+ parseHTML: (element)=>normalizeDocumentImageTransformBoolean(element.getAttribute(name), false),
13317
+ renderHTML: (attributes)=>{
13318
+ const value = normalizeDocumentImageTransformBoolean(attributes[key], false);
13319
+ return value ? {
13320
+ [name]: 'true'
13321
+ } : {};
13322
+ }
13323
+ };
13324
+ }
13222
13325
  function imageWrapPolygonAttribute() {
13223
13326
  return {
13224
13327
  default: null,
@@ -13338,6 +13441,11 @@ function normalizeDocumentImageLayerBoolean(value, fallback) {
13338
13441
  if (false === value || 0 === value || '0' === value || 'false' === value) return false;
13339
13442
  return fallback;
13340
13443
  }
13444
+ function normalizeDocumentImageTransformBoolean(value, fallback) {
13445
+ if (true === value || 1 === value || '1' === value || 'true' === value) return true;
13446
+ if (false === value || 0 === value || '0' === value || 'false' === value) return false;
13447
+ return fallback;
13448
+ }
13341
13449
  function documentImageCropStyle(crop) {
13342
13450
  return documentImageCropStyleEntries(crop).map(([name, value])=>`${name}:${value}`).join(';');
13343
13451
  }
@@ -22003,4 +22111,4 @@ function registerDocumentPageSurfaceGeometry(element, provider) {
22003
22111
  function documentPageSurfaceGeometryForElement(element) {
22004
22112
  return documentPageSurfaceProviders.get(element)?.() ?? null;
22005
22113
  }
22006
- export { DEFAULT_DOCUMENT_TABLE_CELL_FORMAT, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, DEFAULT_DOCUMENT_TABLE_GEOMETRY, DOCUMENT_BOOKMARK_DUPLICATE_MESSAGE, DOCUMENT_CHUNK_HYDRATION_META, DOCUMENT_CHUNK_PAGINATION_META, DOCUMENT_CHUNK_VISIBLE_IDS_META, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, DOCUMENT_OPEN_TYPE_ATTRIBUTE, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_PAGE_MARGIN_KEYS, DOCUMENT_PARAGRAPH_CHANGE_ATTRIBUTES, DOCUMENT_PARAGRAPH_FORMAT_ATTRIBUTES, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, DOCUMENT_TABLE_STYLE_OPTIONS, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, DocumentCharacterFormatting, DocumentEquation, DocumentFontFamily, DocumentHighlight, DocumentImage, DocumentParagraphFormatting, DocumentScriptFontFormatting, DocumentStrike, DocumentSubscript, DocumentSuperscript, DocumentTableRowIdentity, DocumentTextStyle, DocumentUnderline, MAX_DOCUMENT_IMAGE_RELATIVE_HEIGHT, MAX_DOCUMENT_NUMBERING_START, activeDocumentBookmark, activeDocumentSection, activeDocumentTableStyle, applyDocumentImageCropToElement, applyDocumentImageIdentityToElement, applyDocumentImageLayerToElement, applyDocumentImageWrapContourToElement, applyDocumentPageGeometry, applyDocumentTableGeometryToElement, applyDocumentTableRowIdentityToElement, applyDocumentTextCaseStyle, canChangeDocumentIndent, canInsertDocumentComment, canSetDocumentTableRowRepeatHeader, clampDocumentMargin, collectDocumentChanges, collectDocumentCommentAnchors, collectDocumentNotes, collectDocumentTextLayoutParagraphs, createDocumentBibliography, createDocumentEquationElement, createDocumentImageIdentityRegistry, createDocumentNoteElement, createSchemaDerivedWorkDocumentModel, createWorkDocumentBlob, createWorkDocumentExtensions, createWorkDocumentModel, createWorkOfficeDocumentCollaborationBinding as createOfficeDocumentCollaborationBinding, defaultDocumentImageWrapContour, documentAutoLineHeight, documentBookmarkNameExists, documentBookmarkReferenceInstruction, documentBulletListStyle, documentCaptionKind, documentCaptionLabel, documentCharacterPositionDomAttributes, documentCharacterPositionHalfPointsFromElement, documentCharacterPositionPoints, documentCharacterScaleDomAttributes, documentCharacterScalePercentFromElement, documentCharacterSpacingDomAttributes, documentCharacterSpacingPoints, documentCharacterSpacingTwipsFromElement, documentChunkMountedIds, documentCitationCount, documentCitationInstruction, documentCitationStyle, documentCitationStyleDetails, documentCitationTags, documentCitationTagsFromInstruction, documentCommentDraftRange, documentCommentViews, documentContentLayoutProperties, documentEmphasisMarkDomAttributes, documentEmphasisMarkFromElement, documentEquationFromElement, documentEquationText, documentHasIndex, documentHasTableOfContents, documentHiddenTextDomAttributes, documentHiddenTextFromElement, documentHiddenTextKeyboardShortcut, documentImageCropFromElement, documentImageIdentityFromElement, documentImageLayerFromElement, documentImageLayoutFromElement, documentImageLayoutOptions, documentImagePositionFromElement, documentImageProperties, documentImageWrapContourFromElement, documentInitialSectionLayout, documentKerningDomAttributes, documentKerningIsEffective, documentKerningThresholdHalfPointsFromElement, documentKerningThresholdPoints, documentLazyHtmlChunkFragment, documentLazyHtmlProjection, documentLazyHtmlProjectionFingerprint, documentLegacyTextEffectsConflict, documentLegacyTextEffectsCss, documentLegacyTextEffectsDomAttributes, documentLegacyTextEffectsFromElement, documentLegacyTextEffectsFromTextStyleAttributes, documentModelForContent, documentModelForHtml, documentModelHasTrustedInitialIntegrityFeatures, documentModelUsesWindowing, documentNoteKey, documentNoteKind, documentOpenTypeCssProperties, documentOpenTypeDomAttributes, documentOpenTypeFeaturesFromElement, documentOrderedListState, documentPageBordersVisible, documentPageChromeLegacyFields, documentPageGeometryForLayout, documentPageHorizontalMarginTwips, documentPageMarginBody, documentPageMarginsForLayout, documentPageMetrics, documentPageSurfaceGeometryForElement, documentPaperSizeForGeometry, documentParagraphDirection, documentParagraphIndent, documentParagraphPagination, documentParagraphSpacing, documentParagraphTabStops, documentSectionById, documentSectionDomAttributes, documentSections, documentStrikeDomAttributes, documentStrikeFormattingFromElement, documentStrikeStyle, documentTabLeaderLabel, documentTableBordersFromElement, documentTableCellFormat, documentTableCellMarginOverridesFromElement, documentTableColumnPercentagesFromElement, documentTableGeometryFromElement, documentTableHorizontalAlignment, documentTableRowIdentityFromElement, documentTableRowOptions, documentTableSizing, documentTextCaseFromWordFlags, documentTextCaseKeyboardShortcuts, documentTextLayoutBatches, documentTextStatistics, documentTransactionsOnlyHydrateChunks, documentUnderlineColor, documentUnderlineDomAttributes, documentUnderlineFormattingFromElement, documentUnderlineKeyboardShortcuts, documentUnderlineStyle, documentWordLineHeightFactor, docxBookmarkReferenceTarget, docxDocumentFieldKind, editorDocumentBookmarkReferenceTargets, editorDocumentCaptionTargets, fileNameWithoutExtension, forgetWorkSourceBlob as forgetSourceBlob, importWorkDocumentFile, importedDocumentCharacterFormatting, initializeWorkOfficeDocumentCollaboration as initializeOfficeDocumentCollaboration, invalidateDocumentLazyHtmlProjection, isContourImageLayout, isDocumentCharacterFormatMark, isDocumentOpenTypeFeaturePatch, isValidDocumentCitationTag, materializeLazyDocumentEditorRoot, measureDocumentLayoutBlocksIncrementally, millimetersToPixels, mountWorkLiveDocumentCapture, moveWorkSourceBlob, nextDocumentTabAlignment, normalizeDocumentBookmarkName, normalizeDocumentBookmarkNativeId, normalizeDocumentBookmarkReferencesHtml, normalizeDocumentBookmarksHtml, normalizeDocumentCaptionsHtml, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentCharacterScalePercent, normalizeDocumentCharacterSpacingTwips, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentEmphasisMark, normalizeDocumentEquation, normalizeDocumentFieldsHtml, normalizeDocumentHiddenText, normalizeDocumentHtml, normalizeDocumentImageAlignment, normalizeDocumentImageCrop, normalizeDocumentImageIdentity, normalizeDocumentImageLayer, normalizeDocumentImageLayoutOptions, normalizeDocumentImagePosition, normalizeDocumentImageWrapContour, normalizeDocumentImageWrapSide, normalizeDocumentKerningThresholdHalfPoints, normalizeDocumentLegacyTextEffect, normalizeDocumentLegacyTextEffects, normalizeDocumentNotesHtml, normalizeDocumentOpenTypeFeatures, normalizeDocumentOpenTypeLigatures, normalizeDocumentOpenTypeNumberForm, normalizeDocumentOpenTypeNumberSpacing, normalizeDocumentOpenTypeStylisticSets, normalizeDocumentPageBorders, normalizeDocumentPageChrome, normalizeDocumentPageGeometry, normalizeDocumentPageMargins, normalizeDocumentPaperSource, normalizeDocumentParagraphIndent, normalizeDocumentStrikeStyle, normalizeDocumentTabStops, normalizeDocumentTableBorderStyle, normalizeDocumentTableBorderWidth, normalizeDocumentTableRowHeightRule, normalizeDocumentTableRowIdentity, normalizeDocumentTableVerticalAlign, normalizeDocumentTextCase, normalizeDocumentUnderlineColor, normalizeDocumentUnderlineStyle, normalizeTableColor, normalizedTabPosition, numberingTypeFromFormat, pageTwipsToMillimeters, parseDocumentCharacterFormatting, parseDocumentNumberingChange, parseDocumentOpenTypeFeatures, parseDocumentParagraphFormatting, patchDocumentLazyHtmlProjection, patchDocumentOpenTypeFeatures, positionWorkLiveDocumentCapture, readWorkOfficeDocumentCollaboration as readOfficeDocumentCollaboration, readWorkSourceBlob as readSourceBlob, registerDocumentPageSurfaceGeometry, rememberWorkSourceBlob as registerSourceBlob, renderDocumentAutoLineHeight, renderDocumentTableBorders, renderDocumentTableCellMarginOverrides, resolveAllDocumentChanges, resolveDocumentPageBorders, resolveDocumentPageChrome, resolveDocumentPageMargins, resolveDocumentPageSize, resolveWorkDocumentEditorInput, retainAnchoredDocumentComments, sanitizeDocumentPageChromeHtml, selectedDocumentChunkId, selectedDocumentIndexDraft, selectedDocumentIndexEntry, selectedDocumentIndexOptions, selectedDocumentTableOfContentsOptions, serializeDocumentCharacterFormatting, serializeDocumentNumberingChange, serializeDocumentOpenTypeFeatures, serializeDocumentParagraphFormatting, serializeDocumentTabStops, serializeWorkDocumentNode, setCustomDocumentColumns, supportedDocxBookmarkReferenceInstruction, syncDocumentContentFromHtml, transferChangedDocumentTextStatistics, uniqueDocumentImageIdentity, updateDocumentColumnWidth, updateDocumentCustomPageMillimeters, updateDocumentGutterPosition, updateDocumentMirrorMargins, updateDocumentPageChromeVariant, updateDocumentPageMarginMillimeters, updateDocumentPageMarginMode, updateDocumentPageOrientation, updateDocumentPaperSizePreset, validateDocumentBookmarkName, windowDocumentModel, workDocumentSchema, workOfficeDocumentCollaborationFragment as officeDocumentCollaborationFragment, work_document_model_codec_createWorkDocumentModelFromContent as createWorkDocumentModelFromContent, work_document_model_codec_materializeWorkDocumentContent as materializeWorkDocumentContent, work_document_model_createSchemaValidatedWorkDocumentModel as createSchemaValidatedWorkDocumentModel, work_document_page_margins_twipsToMillimeters, work_file_download_downloadBlob, work_file_download_safeFileName, wrapsBesideImage };
22114
+ export { DEFAULT_DOCUMENT_TABLE_CELL_FORMAT, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, DEFAULT_DOCUMENT_TABLE_GEOMETRY, DOCUMENT_BOOKMARK_DUPLICATE_MESSAGE, DOCUMENT_CHUNK_HYDRATION_META, DOCUMENT_CHUNK_PAGINATION_META, DOCUMENT_CHUNK_VISIBLE_IDS_META, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, DOCUMENT_OPEN_TYPE_ATTRIBUTE, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_PAGE_MARGIN_KEYS, DOCUMENT_PARAGRAPH_CHANGE_ATTRIBUTES, DOCUMENT_PARAGRAPH_FORMAT_ATTRIBUTES, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, DOCUMENT_TABLE_ROW_ID_ATTRIBUTE, DOCUMENT_TABLE_ROW_TEXT_ID_ATTRIBUTE, DOCUMENT_TABLE_STYLE_OPTIONS, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, DocumentCharacterFormatting, DocumentEquation, DocumentFontFamily, DocumentHighlight, DocumentImage, DocumentParagraphFormatting, DocumentScriptFontFormatting, DocumentStrike, DocumentSubscript, DocumentSuperscript, DocumentTableRowIdentity, DocumentTextStyle, DocumentUnderline, MAX_DOCUMENT_IMAGE_RELATIVE_HEIGHT, MAX_DOCUMENT_NUMBERING_START, activeDocumentBookmark, activeDocumentSection, activeDocumentTableStyle, applyDocumentImageCropToElement, applyDocumentImageIdentityToElement, applyDocumentImageLayerToElement, applyDocumentImageTransformToElement, applyDocumentImageWrapContourToElement, applyDocumentPageGeometry, applyDocumentTableGeometryToElement, applyDocumentTableRowIdentityToElement, applyDocumentTextCaseStyle, canChangeDocumentIndent, canInsertDocumentComment, canSetDocumentTableRowRepeatHeader, clampDocumentMargin, collectDocumentChanges, collectDocumentCommentAnchors, collectDocumentNotes, collectDocumentTextLayoutParagraphs, createDocumentBibliography, createDocumentEquationElement, createDocumentImageIdentityRegistry, createDocumentNoteElement, createSchemaDerivedWorkDocumentModel, createWorkDocumentBlob, createWorkDocumentExtensions, createWorkDocumentModel, createWorkOfficeDocumentCollaborationBinding as createOfficeDocumentCollaborationBinding, defaultDocumentImageTransform, defaultDocumentImageWrapContour, documentAutoLineHeight, documentBookmarkNameExists, documentBookmarkReferenceInstruction, documentBulletListStyle, documentCaptionKind, documentCaptionLabel, documentCharacterPositionDomAttributes, documentCharacterPositionHalfPointsFromElement, documentCharacterPositionPoints, documentCharacterScaleDomAttributes, documentCharacterScalePercentFromElement, documentCharacterSpacingDomAttributes, documentCharacterSpacingPoints, documentCharacterSpacingTwipsFromElement, documentChunkMountedIds, documentCitationCount, documentCitationInstruction, documentCitationStyle, documentCitationStyleDetails, documentCitationTags, documentCitationTagsFromInstruction, documentCommentDraftRange, documentCommentViews, documentContentLayoutProperties, documentEmphasisMarkDomAttributes, documentEmphasisMarkFromElement, documentEquationFromElement, documentEquationText, documentHasIndex, documentHasTableOfContents, documentHiddenTextDomAttributes, documentHiddenTextFromElement, documentHiddenTextKeyboardShortcut, documentImageCropFromElement, documentImageIdentityFromElement, documentImageLayerFromElement, documentImageLayoutFromElement, documentImageLayoutOptions, documentImagePositionFromElement, documentImageProperties, documentImageTransformFromElement, documentImageWrapContourFromElement, documentInitialSectionLayout, documentKerningDomAttributes, documentKerningIsEffective, documentKerningThresholdHalfPointsFromElement, documentKerningThresholdPoints, documentLazyHtmlChunkFragment, documentLazyHtmlProjection, documentLazyHtmlProjectionFingerprint, documentLegacyTextEffectsConflict, documentLegacyTextEffectsCss, documentLegacyTextEffectsDomAttributes, documentLegacyTextEffectsFromElement, documentLegacyTextEffectsFromTextStyleAttributes, documentModelForContent, documentModelForHtml, documentModelHasTrustedInitialIntegrityFeatures, documentModelUsesWindowing, documentNoteKey, documentNoteKind, documentOpenTypeCssProperties, documentOpenTypeDomAttributes, documentOpenTypeFeaturesFromElement, documentOrderedListState, documentPageBordersVisible, documentPageChromeLegacyFields, documentPageGeometryForLayout, documentPageHorizontalMarginTwips, documentPageMarginBody, documentPageMarginsForLayout, documentPageMetrics, documentPageSurfaceGeometryForElement, documentPaperSizeForGeometry, documentParagraphDirection, documentParagraphIndent, documentParagraphPagination, documentParagraphSpacing, documentParagraphTabStops, documentSectionById, documentSectionDomAttributes, documentSections, documentStrikeDomAttributes, documentStrikeFormattingFromElement, documentStrikeStyle, documentTabLeaderLabel, documentTableBordersFromElement, documentTableCellFormat, documentTableCellMarginOverridesFromElement, documentTableColumnPercentagesFromElement, documentTableGeometryFromElement, documentTableHorizontalAlignment, documentTableRowIdentityFromElement, documentTableRowOptions, documentTableSizing, documentTextCaseFromWordFlags, documentTextCaseKeyboardShortcuts, documentTextLayoutBatches, documentTextStatistics, documentTransactionsOnlyHydrateChunks, documentUnderlineColor, documentUnderlineDomAttributes, documentUnderlineFormattingFromElement, documentUnderlineKeyboardShortcuts, documentUnderlineStyle, documentWordLineHeightFactor, docxBookmarkReferenceTarget, docxDocumentFieldKind, editorDocumentBookmarkReferenceTargets, editorDocumentCaptionTargets, fileNameWithoutExtension, forgetWorkSourceBlob as forgetSourceBlob, importWorkDocumentFile, importedDocumentCharacterFormatting, initializeWorkOfficeDocumentCollaboration as initializeOfficeDocumentCollaboration, invalidateDocumentLazyHtmlProjection, isContourImageLayout, isDocumentCharacterFormatMark, isDocumentOpenTypeFeaturePatch, isValidDocumentCitationTag, materializeLazyDocumentEditorRoot, measureDocumentLayoutBlocksIncrementally, millimetersToPixels, mountWorkLiveDocumentCapture, moveWorkSourceBlob, nextDocumentTabAlignment, normalizeDocumentBookmarkName, normalizeDocumentBookmarkNativeId, normalizeDocumentBookmarkReferencesHtml, normalizeDocumentBookmarksHtml, normalizeDocumentCaptionsHtml, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentCharacterScalePercent, normalizeDocumentCharacterSpacingTwips, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentEmphasisMark, normalizeDocumentEquation, normalizeDocumentFieldsHtml, normalizeDocumentHiddenText, normalizeDocumentHtml, normalizeDocumentImageAlignment, normalizeDocumentImageCrop, normalizeDocumentImageIdentity, normalizeDocumentImageLayer, normalizeDocumentImageLayoutOptions, normalizeDocumentImagePosition, normalizeDocumentImageTransform, normalizeDocumentImageWrapContour, normalizeDocumentImageWrapSide, normalizeDocumentKerningThresholdHalfPoints, normalizeDocumentLegacyTextEffect, normalizeDocumentLegacyTextEffects, normalizeDocumentNotesHtml, normalizeDocumentOpenTypeFeatures, normalizeDocumentOpenTypeLigatures, normalizeDocumentOpenTypeNumberForm, normalizeDocumentOpenTypeNumberSpacing, normalizeDocumentOpenTypeStylisticSets, normalizeDocumentPageBorders, normalizeDocumentPageChrome, normalizeDocumentPageGeometry, normalizeDocumentPageMargins, normalizeDocumentPaperSource, normalizeDocumentParagraphIndent, normalizeDocumentStrikeStyle, normalizeDocumentTabStops, normalizeDocumentTableBorderStyle, normalizeDocumentTableBorderWidth, normalizeDocumentTableRowHeightRule, normalizeDocumentTableRowIdentity, normalizeDocumentTableVerticalAlign, normalizeDocumentTextCase, normalizeDocumentUnderlineColor, normalizeDocumentUnderlineStyle, normalizeTableColor, normalizedTabPosition, numberingTypeFromFormat, pageTwipsToMillimeters, parseDocumentCharacterFormatting, parseDocumentNumberingChange, parseDocumentOpenTypeFeatures, parseDocumentParagraphFormatting, patchDocumentLazyHtmlProjection, patchDocumentOpenTypeFeatures, positionWorkLiveDocumentCapture, readWorkOfficeDocumentCollaboration as readOfficeDocumentCollaboration, readWorkSourceBlob as readSourceBlob, registerDocumentPageSurfaceGeometry, rememberWorkSourceBlob as registerSourceBlob, renderDocumentAutoLineHeight, renderDocumentTableBorders, renderDocumentTableCellMarginOverrides, resolveAllDocumentChanges, resolveDocumentPageBorders, resolveDocumentPageChrome, resolveDocumentPageMargins, resolveDocumentPageSize, resolveWorkDocumentEditorInput, retainAnchoredDocumentComments, sanitizeDocumentPageChromeHtml, selectedDocumentChunkId, selectedDocumentIndexDraft, selectedDocumentIndexEntry, selectedDocumentIndexOptions, selectedDocumentTableOfContentsOptions, serializeDocumentCharacterFormatting, serializeDocumentNumberingChange, serializeDocumentOpenTypeFeatures, serializeDocumentParagraphFormatting, serializeDocumentTabStops, serializeWorkDocumentNode, setCustomDocumentColumns, supportedDocxBookmarkReferenceInstruction, syncDocumentContentFromHtml, transferChangedDocumentTextStatistics, uniqueDocumentImageIdentity, updateDocumentColumnWidth, updateDocumentCustomPageMillimeters, updateDocumentGutterPosition, updateDocumentMirrorMargins, updateDocumentPageChromeVariant, updateDocumentPageMarginMillimeters, updateDocumentPageMarginMode, updateDocumentPageOrientation, updateDocumentPaperSizePreset, validateDocumentBookmarkName, windowDocumentModel, workDocumentSchema, workOfficeDocumentCollaborationFragment as officeDocumentCollaborationFragment, work_document_model_codec_createWorkDocumentModelFromContent as createWorkDocumentModelFromContent, work_document_model_codec_materializeWorkDocumentContent as materializeWorkDocumentContent, work_document_model_createSchemaValidatedWorkDocumentModel as createSchemaValidatedWorkDocumentModel, work_document_page_margins_twipsToMillimeters, work_file_download_downloadBlob, work_file_download_safeFileName, wrapsBesideImage };
@@ -1,4 +1,4 @@
1
- import type { WorkDocumentImageAlignment, WorkDocumentImageHorizontalReference, WorkDocumentImageLayout, WorkDocumentImageProperties, WorkDocumentImageWrapSide, WorkDocumentImageVerticalReference } from '../work-document-image-layout';
1
+ import type { WorkDocumentImageAlignment, WorkDocumentImageHorizontalReference, WorkDocumentImageLayout, WorkDocumentImageProperties, WorkDocumentImageRotation, WorkDocumentImageVerticalReference, WorkDocumentImageWrapSide } from '../work-document-image-layout';
2
2
  export declare const IMAGE_PIXELS_PER_CENTIMETER: number;
3
3
  export interface DocumentPicturePropertiesSource {
4
4
  properties: WorkDocumentImageProperties;
@@ -24,6 +24,9 @@ export interface DocumentPicturePropertiesDraft {
24
24
  cropRight: string;
25
25
  cropBottom: string;
26
26
  cropLeft: string;
27
+ rotation: WorkDocumentImageRotation;
28
+ flipHorizontal: boolean;
29
+ flipVertical: boolean;
27
30
  relativeHeight: string;
28
31
  behindDocument: boolean;
29
32
  allowOverlap: boolean;
@@ -16,6 +16,12 @@ export interface WorkDocumentImageCrop {
16
16
  bottom: number;
17
17
  left: number;
18
18
  }
19
+ export type WorkDocumentImageRotation = 0 | 90 | 180 | 270;
20
+ export interface WorkDocumentImageTransform {
21
+ rotation: WorkDocumentImageRotation;
22
+ flipHorizontal: boolean;
23
+ flipVertical: boolean;
24
+ }
19
25
  export interface WorkDocumentImageLayer {
20
26
  relativeHeight: number;
21
27
  behindDocument: boolean;
@@ -36,6 +42,7 @@ export interface WorkDocumentImageProperties extends WorkDocumentImageLayoutOpti
36
42
  alternativeText: string;
37
43
  position?: WorkDocumentImagePosition | null;
38
44
  crop?: WorkDocumentImageCrop | null;
45
+ transform?: WorkDocumentImageTransform | null;
39
46
  contour?: WorkDocumentImageWrapContour | null;
40
47
  layer?: WorkDocumentImageLayer | null;
41
48
  }
@@ -63,6 +70,7 @@ export declare function documentImageAlternativeText(editor: Editor): string;
63
70
  export declare function documentImageLayoutFromElement(element: Element): WorkDocumentImageLayoutOptions;
64
71
  export declare function documentImagePositionFromElement(element: Element): WorkDocumentImagePosition | null;
65
72
  export declare function documentImageCropFromElement(element: Element): WorkDocumentImageCrop | null;
73
+ export declare function documentImageTransformFromElement(element: Element): WorkDocumentImageTransform | null;
66
74
  export declare function documentImageLayerFromElement(element: Element): WorkDocumentImageLayer;
67
75
  export declare function normalizeDocumentImageLayoutOptions(value: Partial<Record<keyof WorkDocumentImageLayoutOptions, unknown>>): WorkDocumentImageLayoutOptions;
68
76
  export declare function normalizeDocumentImageLayout(value: unknown): WorkDocumentImageLayout;
@@ -76,6 +84,12 @@ export declare function normalizeDocumentImageHorizontalReference(value: unknown
76
84
  export declare function normalizeDocumentImageVerticalReference(value: unknown): WorkDocumentImageVerticalReference;
77
85
  export declare function normalizeDocumentImageCrop(value: Partial<Record<'cropBottom' | 'cropLeft' | 'cropRight' | 'cropTop', unknown>>): WorkDocumentImageCrop | null;
78
86
  export declare function normalizeDocumentImageCropEdge(value: unknown): number;
87
+ export declare function defaultDocumentImageTransform(): WorkDocumentImageTransform;
88
+ export declare function normalizeDocumentImageTransform(value: Partial<Record<keyof WorkDocumentImageTransform, unknown>>): WorkDocumentImageTransform;
89
+ export declare function normalizeDocumentImageRotation(value: unknown): WorkDocumentImageRotation;
90
+ export declare function documentImageTransformIsDefault(transform: WorkDocumentImageTransform): boolean;
91
+ export declare function documentImageTransformCss(transform: WorkDocumentImageTransform): string;
92
+ export declare function applyDocumentImageTransformToElement(element: HTMLElement, transform: WorkDocumentImageTransform | null): void;
79
93
  export declare function normalizeDocumentImageLayer(value: Partial<Record<keyof WorkDocumentImageLayer, unknown>>): WorkDocumentImageLayer;
80
94
  export declare function normalizeDocumentImageRelativeHeight(value: unknown): number;
81
95
  export declare function documentImageLayerCssZIndex(layer: WorkDocumentImageLayer): number;
@@ -2,5 +2,6 @@ import type { ParagraphChild } from 'docx';
2
2
  import type { DocxImageCropPatchCollector } from './work-docx-image-crop';
3
3
  import type { DocxImageIdentityPatchCollector } from './work-docx-image-identity';
4
4
  import type { DocxImageLayerPatchCollector } from './work-docx-image-layer';
5
+ import type { DocxImageTransformPatchCollector } from './work-docx-image-transform';
5
6
  import type { DocxImageWrapPatchCollector } from './work-docx-image-wrap';
6
- export declare function imageToDocx(element: HTMLImageElement, docx: typeof import('docx'), cropPatches?: DocxImageCropPatchCollector, wrapPatches?: DocxImageWrapPatchCollector, layerPatches?: DocxImageLayerPatchCollector, identityPatches?: DocxImageIdentityPatchCollector): Promise<ParagraphChild>;
7
+ export declare function imageToDocx(element: HTMLImageElement, docx: typeof import('docx'), cropPatches?: DocxImageCropPatchCollector, wrapPatches?: DocxImageWrapPatchCollector, layerPatches?: DocxImageLayerPatchCollector, identityPatches?: DocxImageIdentityPatchCollector, transformPatches?: DocxImageTransformPatchCollector): Promise<ParagraphChild>;
@@ -1,5 +1,5 @@
1
1
  import { type WorkDocumentImageIdentity, type WorkDocumentImageIdentityRegistry } from './work-document-image-identity';
2
- import { type WorkDocumentImageCrop, type WorkDocumentImageLayer, type WorkDocumentImageLayoutOptions, type WorkDocumentImagePosition } from './work-document-image-layout';
2
+ import { type WorkDocumentImageCrop, type WorkDocumentImageLayer, type WorkDocumentImageLayoutOptions, type WorkDocumentImagePosition, type WorkDocumentImageTransform } from './work-document-image-layout';
3
3
  import { type WorkDocumentImageWrapContour } from './work-document-image-wrap-contour';
4
4
  export interface ImportedDocxImageLayoutMarker {
5
5
  startMarker: string;
@@ -7,6 +7,7 @@ export interface ImportedDocxImageLayoutMarker {
7
7
  options: WorkDocumentImageLayoutOptions;
8
8
  position: WorkDocumentImagePosition | null;
9
9
  crop: WorkDocumentImageCrop | null;
10
+ transform: WorkDocumentImageTransform | null;
10
11
  contour: WorkDocumentImageWrapContour | null;
11
12
  layer: WorkDocumentImageLayer | null;
12
13
  identity: WorkDocumentImageIdentity;
@@ -0,0 +1,17 @@
1
+ import { type WorkDocumentImageTransform } from './work-document-image-layout';
2
+ interface DocxImageTransformPatch {
3
+ marker: string;
4
+ transform: WorkDocumentImageTransform;
5
+ }
6
+ export interface DocxImageTransformReadResult {
7
+ transform: WorkDocumentImageTransform | null;
8
+ supported: boolean;
9
+ }
10
+ export declare function readDocxImageTransform(drawing: Element): DocxImageTransformReadResult;
11
+ export declare class DocxImageTransformPatchCollector {
12
+ readonly patches: DocxImageTransformPatch[];
13
+ private nextMarker;
14
+ marker(transform: WorkDocumentImageTransform | null): string;
15
+ }
16
+ export declare function patchDocxImageTransforms(buffer: ArrayBuffer, patches: readonly DocxImageTransformPatch[]): Promise<ArrayBuffer>;
17
+ export {};
Binary file
package/dist/styles.css CHANGED
@@ -8383,7 +8383,7 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
8383
8383
  display: grid;
8384
8384
  }
8385
8385
 
8386
- .work-document-picture-properties-section.position, .work-document-picture-properties-section.layer, .work-document-picture-properties-section.crop, .work-document-picture-properties-alt-text {
8386
+ .work-document-picture-properties-section.position, .work-document-picture-properties-section.layer, .work-document-picture-properties-section.crop, .work-document-picture-properties-section.transform, .work-document-picture-properties-alt-text {
8387
8387
  grid-column: 1 / -1;
8388
8388
  }
8389
8389
 
@@ -8448,6 +8448,34 @@ button.work-office-collaboration-participant:hover .work-office-collaboration-lo
8448
8448
  display: grid;
8449
8449
  }
8450
8450
 
8451
+ .work-document-picture-properties-transform-row {
8452
+ min-height: 34px;
8453
+ color: var(--a3s-muted);
8454
+ grid-template-columns: 64px minmax(0, 1fr);
8455
+ align-items: center;
8456
+ gap: 8px;
8457
+ font-size: 11px;
8458
+ display: grid;
8459
+ }
8460
+
8461
+ .work-document-picture-properties-transform-options {
8462
+ grid-template-columns: repeat(2, minmax(0, 1fr));
8463
+ gap: 6px 12px;
8464
+ display: grid;
8465
+ }
8466
+
8467
+ .work-document-picture-properties-transform-options .work-office-checkbox {
8468
+ border-radius: 6px;
8469
+ min-height: 34px;
8470
+ padding: 5px 6px;
8471
+ }
8472
+
8473
+ .work-document-picture-properties-transform-help {
8474
+ color: var(--a3s-faint);
8475
+ font-size: 10px;
8476
+ line-height: 1.4;
8477
+ }
8478
+
8451
8479
  .work-document-picture-properties-layer-options {
8452
8480
  grid-template-columns: repeat(2, minmax(0, 1fr));
8453
8481
  gap: 6px 12px;
@@ -11762,6 +11790,10 @@ sub [data-office-character-position-half-points], sup [data-office-character-pos
11762
11790
  .work-document-page .tiptap [data-resize-container][data-node="image"] {
11763
11791
  width: fit-content;
11764
11792
  max-width: 100%;
11793
+ rotate: var(--work-document-image-rotation, 0deg);
11794
+ scale: var(--work-document-image-flip-x, 1)
11795
+ var(--work-document-image-flip-y, 1);
11796
+ transform-origin: center;
11765
11797
  margin-block: 18px;
11766
11798
  display: block !important;
11767
11799
  }
@@ -12601,8 +12633,12 @@ sub [data-office-character-position-half-points], sup [data-office-character-pos
12601
12633
  }
12602
12634
 
12603
12635
  :is(.work-document-preview-page, .work-pdf-export-page.document) img[data-office-image-layout] {
12604
- border-radius: 4px;
12605
12636
  height: auto;
12637
+ rotate: var(--work-document-image-rotation, 0deg);
12638
+ scale: var(--work-document-image-flip-x, 1)
12639
+ var(--work-document-image-flip-y, 1);
12640
+ transform-origin: center;
12641
+ border-radius: 4px;
12606
12642
  margin-block: 18px;
12607
12643
  display: block;
12608
12644
  }
@@ -836,12 +836,13 @@ stable ProseMirror position, and distribute list-container height without
836
836
  double-counting nested content.
837
837
 
838
838
  Document image nodes carry typed layout, alignment, wrap-distance, alternative
839
- text, size, and per-image aspect-ratio-lock attributes. The contextual Picture
839
+ text, size, per-image aspect-ratio-lock, and bounded transform attributes. The contextual Picture
840
840
  ribbon keeps fast layout actions and opens one responsive Picture Properties
841
841
  dialog for centimeter width and height, aspect-ratio locking, wrapping,
842
842
  alignment, text distance, signed horizontal and vertical offsets, their column,
843
843
  paragraph, margin, or page reference frames, four-edge percentage cropping,
844
- relative drawing order, behind-text placement, overlap and cell-layout policy,
844
+ quarter-turn rotation, horizontal/vertical reflection, relative drawing order,
845
+ behind-text placement, overlap and cell-layout policy,
845
846
  anchor locking, and alternative text. Applying the complete draft
846
847
  updates only changed attributes in one separated TipTap history entry; cancel
847
848
  and Escape preserve the node and return focus to the exact invoker. Dimensions
@@ -865,7 +866,10 @@ and ordered `wrapPolygon` vertices. Aligned anchors remain aligned,
865
866
  while precise offsets preserve `positionH` and `positionV` reference frames
866
867
  through edit, preview, and regenerated DOCX. Four-edge crop geometry remains
867
868
  typed in the controlled model and round-trips as DrawingML `a:srcRect` for
868
- inline and floating pictures. Supported floating pictures also preserve
869
+ inline and floating pictures. Quarter-turn rotation and reflection round-trip
870
+ as DrawingML `a:xfrm` `rot`, `flipH`, and `flipV` values for inline and floating
871
+ pictures. Arbitrary-angle or malformed transform values are diagnosed and
872
+ normalized to the bounded model. Supported floating pictures also preserve
869
873
  drawing-layer relationships through unsigned `relativeHeight`,
870
874
  `behindDoc`, `allowOverlap`, `layoutInCell`, and `locked` anchor attributes.
871
875
  The browser maps the unsigned drawing order into bounded foreground and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a3s-lab/office",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "Open-source collaborative browser editors for documents, Markdown, spreadsheets, presentations, and PDFs.",
5
5
  "keywords": [
6
6
  "office",