Skip to content

Commit

Permalink
[ve] Combine shape with text to groups (fix compas: text pos on shape…
Browse files Browse the repository at this point in the history
… rotate)
  • Loading branch information
fedek1324 committed Jan 14, 2025
1 parent 021fde8 commit bd2db14
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 76 deletions.
20 changes: 7 additions & 13 deletions visio/model/VisioDocument.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@
shape_drawer.Clear();
graphics.RestoreGrState();


// handle group children
group.spTree.forEach(function(shapeOrGroup) {
drawShapeOrGroupRecursively(graphics, shapeOrGroup, baseMatrix, baseTextMatrix, isRecalculateTextY,
Expand Down Expand Up @@ -526,7 +527,6 @@
let isFlipYMatrix = false;
let isFlipImages = false;


// let pageInfo = visioDocument.pages.page[pageIndex];
// let pageContent = visioDocument.pageContents[pageIndex];
// let topLevelShapesAndGroups = visioDocument.convertToCShapesAndGroups(pageInfo, pageContent);
Expand Down Expand Up @@ -722,20 +722,14 @@
shape.realizeStyleInheritanceRecursively(this.styleSheets, stylesWithRealizedInheritance);

if (shape.type === "Group") {
let cGroupShapeAndText = shape.toCGroupShapeRecursively(this, pageInfo, drawingPageScale);
if (cGroupShapeAndText.cGroupShape) {
topLevelShapesAndGroups.push(cGroupShapeAndText.cGroupShape);
}
if (cGroupShapeAndText.textCShape) {
topLevelShapesAndGroups.push(cGroupShapeAndText.textCShape);
let cGroupShape = shape.convertGroup(this, pageInfo, drawingPageScale);
if (cGroupShape) {
topLevelShapesAndGroups.push(cGroupShape);
}
} else {
let cShapes = shape.toGeometryAndTextCShapes(this, pageInfo, drawingPageScale);
if (cShapes.geometryCShape !== null) {
topLevelShapesAndGroups.push(cShapes.geometryCShape);
}
if (cShapes.textCShape !== null) {
topLevelShapesAndGroups.push(cShapes.textCShape);
let cShapeOrCGroupShape = shape.convertShape(this, pageInfo, drawingPageScale);
if (cShapeOrCGroupShape !== null) {
topLevelShapesAndGroups.push(cShapeOrCGroupShape);
}
}
}
Expand Down
187 changes: 124 additions & 63 deletions visio/model/ooxmlApi/convertFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@
}

/**
* calculateShapeParamsAndConvertToCShape
* calculateShapeParamsAndConvertToCShape or CGroupShape which combines shape and text if Shape has text
* @memberof Shape_Type
* @param {CVisioDocument} visioDocument
* @param {Page_Type} pageInfo
* @param {Number} drawingPageScale
* @param {CGroupShape?} currentGroupHandling
* @return {{geometryCShape: CShape | CImageShape, textCShape: ?CShape}} cShapesObjects
* @return {(CShape | CGroupShape)} cShape or cGroupShape (if shape and text)
*/
Shape_Type.prototype.toGeometryAndTextCShapes = function (visioDocument, pageInfo, drawingPageScale, currentGroupHandling) {
Shape_Type.prototype.convertShape = function (visioDocument, pageInfo, drawingPageScale, currentGroupHandling) {

/**
* handle QuickStyleVariation cell which can change color (but only if color is a result of ThemeVal)
Expand Down Expand Up @@ -977,6 +977,7 @@

// to rotate around point we 1) add one more offset 2) rotate around center
// https://www.figma.com/design/SJSKMY5dGoAvRg75YnHpdX/newRotateScheme?node-id=0-1&node-type=canvas&t=UTtoZyLRItzaQvS9-0

let txtPinX_inch = shape.getCellNumberValueWithScale("TxtPinX", drawingPageScale);
let txtPinY_inch = shape.getCellNumberValueWithScale("TxtPinY", drawingPageScale);

Expand Down Expand Up @@ -1044,11 +1045,11 @@
// start to bottom on shape
localYmm = (-fromBlockToShapeCenter + shapeLocPinY) * g_dKoef_in_to_mm;
}
oXfrm.setRot(shapeAngle - textAngle);
oXfrm.setRot(- textAngle);
} else {
// do calculations
localYmm = (txtPinY_inch - txtLocPinY_inch) * g_dKoef_in_to_mm;
oXfrm.setRot(shapeAngle + textAngle);
oXfrm.setRot(textAngle);
}

let offY = globalYmm + localYmm;
Expand All @@ -1068,9 +1069,9 @@
oXfrm.setOffY(shapeHeight < 0 ? globalYmm + 2 * shapeHeight * g_dKoef_in_to_mm : globalYmm);
oXfrm.setExtX(Math.abs(shapeWidth) * g_dKoef_in_to_mm);
oXfrm.setExtY(Math.abs(shapeHeight) * g_dKoef_in_to_mm);
oXfrm.setRot(shapeAngle);
oXfrm.setRot(0);
}
oSpPr.setXfrm(oXfrm);
oSpPr.setXfrm(oXfrm);
oXfrm.setParent(oSpPr);
oSpPr.setFill(AscFormat.CreateNoFillUniFill());
oSpPr.setLn(AscFormat.CreateNoFillLine());
Expand Down Expand Up @@ -1320,7 +1321,7 @@

let isShapeDeleted = this.del === "1" || this.del === true;
if (isShapeDeleted) {
return {geometryCShape: null, textCShape: null};
return null;
}


Expand All @@ -1344,7 +1345,7 @@
oSpPr.setParent(emptyCShape);
emptyCShape.setParent2(visioDocument);

return {geometryCShape: emptyCShape, textCShape: null};
return emptyCShape;
}

let shapeAngle = this.getCellNumberValue("Angle");
Expand Down Expand Up @@ -1774,7 +1775,60 @@
}
}

return {geometryCShape: cShape, textCShape: textCShape};
// combine textCShape and geometryCShape to group
if (textCShape !== null) {
let groupShape = new AscFormat.CGroupShape();
// this.graphicObjectsController = new AscFormat.DrawingObjectsController();
// let groupShape = AscFormat.builder_CreateGroup();

groupShape.setLocks(0);

groupShape.setBDeleted(false);

// Create CGroupShape with SpPr from cShape but with no fill and line
let noLineFillSpPr = cShape.spPr.createDuplicate();
noLineFillSpPr.setFill(AscFormat.CreateNoFillUniFill());
noLineFillSpPr.setLn(AscFormat.CreateNoFillLine());
// these flips come to group
noLineFillSpPr.xfrm.flipV = false;
noLineFillSpPr.xfrm.flipH = false;

groupShape.setSpPr(noLineFillSpPr);
groupShape.spPr.setParent(groupShape);
// groupShape.rot = 0;
groupShape.brush = cShape.brush;
groupShape.bounds = cShape.bounds;
groupShape.localTransform = cShape.localTransform;
groupShape.pen = cShape.pen;
groupShape.Id = cShape.Id + "ShapeAndText";

groupShape.addToSpTree(groupShape.spTree.length, cShape);
groupShape.spTree[groupShape.spTree.length - 1].setGroup(groupShape);
cShape.spPr.xfrm.setOffX(0);
cShape.spPr.xfrm.setOffY(0);
cShape.spPr.xfrm.rot = 0;


cShape.recalculateLocalTransform(cShape.transform);

groupShape.addToSpTree(groupShape.spTree.length, textCShape);
groupShape.spTree[groupShape.spTree.length - 1].setGroup(groupShape);
textCShape.spPr.xfrm.setOffX(textCShape.spPr.xfrm.offX - groupShape.spPr.xfrm.offX);
textCShape.spPr.xfrm.setOffY(textCShape.spPr.xfrm.offY - groupShape.spPr.xfrm.offY);
textCShape.spPr.xfrm.flipH = false;
textCShape.spPr.xfrm.flipV = false;

textCShape.recalculateLocalTransform(textCShape.transform);
textCShape.recalculateTransformText();
textCShape.recalculateContent();

groupShape.setParent2(visioDocument);
groupShape.recalculate();

return groupShape;
} else {
return cShape;
}
}

/**
Expand All @@ -1785,18 +1839,19 @@
* @param {Page_Type} pageInfo
* @param {Number} drawingPageScale
* @param {CGroupShape?} currentGroupHandling
* @return {{cGroupShape: CGroupShape, textCShape: CShape}}
* @return {CGroupShape}
*/
Shape_Type.prototype.toCGroupShapeRecursively = function (visioDocument, pageInfo,
drawingPageScale, currentGroupHandling) {
Shape_Type.prototype.convertGroup = function (visioDocument, pageInfo,
drawingPageScale, currentGroupHandling) {
// if we need to create CGroupShape create CShape first then copy its properties to CGroupShape object
// so anyway create CShapes
let cShapes = this.toGeometryAndTextCShapes(visioDocument, pageInfo, drawingPageScale, currentGroupHandling);
let cShapeOrCGroupShape = this.convertShape(visioDocument, pageInfo, drawingPageScale, currentGroupHandling);

// if it is group in vsdx
if (this.type === "Group") {
// CGroupShape cant support text. So cShape will represent everything related to Shape Type="Group".
// Let's push cShape into CGroupShape object.
if (cShapes.geometryCShape) {
if (cShapeOrCGroupShape) {
let groupShape = new AscFormat.CGroupShape();
// this.graphicObjectsController = new AscFormat.DrawingObjectsController();
// let groupShape = AscFormat.builder_CreateGroup();
Expand All @@ -1806,27 +1861,27 @@
groupShape.setBDeleted(false);

// Create CGroupShape with SpPr from cShape but with no fill and line
let noLineFillSpPr = cShapes.geometryCShape.spPr.createDuplicate();
let noLineFillSpPr = cShapeOrCGroupShape.spPr.createDuplicate();
noLineFillSpPr.setFill(AscFormat.CreateNoFillUniFill());
noLineFillSpPr.setLn(AscFormat.CreateNoFillLine());

groupShape.setSpPr(noLineFillSpPr);
groupShape.spPr.setParent(groupShape);
groupShape.rot = cShapes.geometryCShape.rot;
groupShape.brush = cShapes.geometryCShape.brush;
groupShape.bounds = cShapes.geometryCShape.bounds;
groupShape.flipH = cShapes.geometryCShape.flipH;
groupShape.flipV = cShapes.geometryCShape.flipV;
groupShape.localTransform = cShapes.geometryCShape.localTransform;
groupShape.pen = cShapes.geometryCShape.pen;
groupShape.Id = cShapes.geometryCShape.Id + "Group";

groupShape.addToSpTree(groupShape.spTree.length, cShapes.geometryCShape);
groupShape.rot = cShapeOrCGroupShape.rot;
groupShape.brush = cShapeOrCGroupShape.brush;
groupShape.bounds = cShapeOrCGroupShape.bounds;
groupShape.flipH = cShapeOrCGroupShape.flipH;
groupShape.flipV = cShapeOrCGroupShape.flipV;
groupShape.localTransform = cShapeOrCGroupShape.localTransform;
groupShape.pen = cShapeOrCGroupShape.pen;
groupShape.Id = cShapeOrCGroupShape.Id + "_Group";

groupShape.addToSpTree(groupShape.spTree.length, cShapeOrCGroupShape);
groupShape.spTree[groupShape.spTree.length - 1].setGroup(groupShape);

cShapes.geometryCShape.spPr.xfrm.setOffX(0);
cShapes.geometryCShape.spPr.xfrm.setOffY(0);
cShapeOrCGroupShape.spPr.xfrm.setOffX(0);
cShapeOrCGroupShape.spPr.xfrm.setOffY(0);

// cShape.setLocks(1)?;

groupShape.setParent2(visioDocument);
Expand All @@ -1837,71 +1892,77 @@
let subShapes = this.getSubshapes();
for (let i = 0; i < subShapes.length; i++) {
const subShape = subShapes[i];
subShape.toCGroupShapeRecursively(visioDocument, pageInfo, drawingPageScale, currentGroupHandling);
subShape.convertGroup(visioDocument, pageInfo, drawingPageScale, currentGroupHandling);
}

// textCShape is returned from this function

} else {

// if currentGroupHandling add groupShape (withShape in it) and textCShape to it
// insert group to currentGroupHandling

currentGroupHandling.addToSpTree(currentGroupHandling.spTree.length, groupShape);
currentGroupHandling.spTree[currentGroupHandling.spTree.length - 1].setGroup(currentGroupHandling);
groupShape.recalculateLocalTransform(groupShape.transform);

if (cShapes.textCShape !== null) {
currentGroupHandling.addToSpTree(currentGroupHandling.spTree.length, cShapes.textCShape);
currentGroupHandling.spTree[currentGroupHandling.spTree.length - 1].setGroup(currentGroupHandling);
// cShapes.textCShape.recalculateLocalTransform(cShapes.textCShape.transform); // exists below
}

// delete bcs textCShape is always null see toGeometryAndTextCShapes
// if (cShapes.textCShape !== null) {
// currentGroupHandling.addToSpTree(currentGroupHandling.spTree.length, cShapes.textCShape);
// currentGroupHandling.spTree[currentGroupHandling.spTree.length - 1].setGroup(currentGroupHandling);
// // cShapes.textCShape.recalculateLocalTransform(cShapes.textCShape.transform); // exists below
// }

currentGroupHandling = groupShape;
let subShapes = this.getSubshapes();
for (let i = 0; i < subShapes.length; i++) {
const subShape = subShapes[i];
subShape.toCGroupShapeRecursively(visioDocument, pageInfo, drawingPageScale, currentGroupHandling);
subShape.convertGroup(visioDocument, pageInfo, drawingPageScale, currentGroupHandling);
}
}
// recalculate positions to local (group) coordinates
cShapes.geometryCShape.recalculateLocalTransform(cShapes.geometryCShape.transform);
cShapeOrCGroupShape.recalculateLocalTransform(cShapeOrCGroupShape.transform);
// cShapes.geometryCShape.recalculateTransformText();
// cShapes.geometryCShape.recalculateContent();
// cShape.recalculate(); // doesnt work here
// cShapes.geometryCShape.recalculate(); // doesnt work here
}

if (cShapes.textCShape !== null) {
// even if not add textCShape to currentGroupHandling above do recalculate just in case
cShapes.textCShape.recalculateLocalTransform(cShapes.textCShape.transform);
cShapes.textCShape.recalculateTransformText();
cShapes.textCShape.recalculateContent();
}
// delete bcs textCShape is always null see toGeometryAndTextCShapes
// if (cShapes.textCShape !== null) {
// // even if not add textCShape to currentGroupHandling above do recalculate just in case
// cShapes.textCShape.recalculateLocalTransform(cShapes.textCShape.transform);
// cShapes.textCShape.recalculateTransformText();
// cShapes.textCShape.recalculateContent();
// }

} else {
// if read cShape not CGroupShape
if (!currentGroupHandling) {
throw new Error("Group handler was called on simple shape");
} else {
// add shape and text to currentGroupHandling
// add shape and text (shapeAndTextGroup or shape) to currentGroupHandling

if (cShapes.geometryCShape) {
currentGroupHandling.addToSpTree(currentGroupHandling.spTree.length, cShapes.geometryCShape);
if (cShapeOrCGroupShape) {
currentGroupHandling.addToSpTree(currentGroupHandling.spTree.length, cShapeOrCGroupShape);
currentGroupHandling.spTree[currentGroupHandling.spTree.length-1].setGroup(currentGroupHandling);

// recalculate positions to local (group) coordinates
cShapes.geometryCShape.recalculateLocalTransform(cShapes.geometryCShape.transform);
// cShapes.geometryCShape.recalculateTransformText();
// cShapes.geometryCShape.recalculateContent();
// cShape.recalculate(); // doesnt work here
}

if (cShapes.textCShape !== null) {
currentGroupHandling.addToSpTree(currentGroupHandling.spTree.length, cShapes.textCShape);
currentGroupHandling.spTree[currentGroupHandling.spTree.length-1].setGroup(currentGroupHandling);

cShapes.textCShape.recalculateLocalTransform(cShapes.textCShape.transform);
cShapes.textCShape.recalculateTransformText();
cShapes.textCShape.recalculateContent();
cShapeOrCGroupShape.recalculateLocalTransform(cShapeOrCGroupShape.transform);
cShapeOrCGroupShape.recalculate();


// is group
if (cShapeOrCGroupShape.Id.endsWith("ShapeAndText")) {
let textShape = cShapeOrCGroupShape.spTree[1];
textShape.recalculateLocalTransform(textShape.transform);
textShape.recalculateTransformText && textShape.recalculateTransformText();
textShape.recalculateContent && textShape.recalculateContent();

let geometryShape = cShapeOrCGroupShape.spTree[0];
geometryShape.recalculateLocalTransform(geometryShape.transform);
geometryShape.recalculateTransformText && geometryShape.recalculateTransformText();
geometryShape.recalculateContent && geometryShape.recalculateContent();
geometryShape.recalculate();
}
}
}
}
Expand All @@ -1910,7 +1971,7 @@
currentGroupHandling.recalculate();
}

return {cGroupShape: currentGroupHandling, textCShape: cShapes.textCShape};
return currentGroupHandling;
}

/**
Expand Down

0 comments on commit bd2db14

Please sign in to comment.