Answered by:
Text Flow around images using wrapPoints (wrapPolygon)
Question

Microsoft Word allows the text flow around images using wrapPoints. According to spec MSODRAW (section 2.3.4.7) the pWrapPolygonVertices property specifies the points of a wrap Polygon. I am trying to read these points from the stream, but what I get does not make correct sense to me as these are very small numbers. The values of the points (x, y) for the particular test file I am reading varies from 034 in xdirection and 033 in the y direction.
It looks like these numbers needs to be translated and scaled. I wonder if this scaling information is provided somewhere in the specs. Or what is the correct way of interpreting those points.
Answers

Farwaha, here is what we have been able to figure out regarding this…
Each OfficeArtSpContainer contains an OfficeArtClientAnchor structure. The value of the clientanchor property specifies the hostapp side “anchor” for the shape. Every host app has different anchor information stored with the shape. Word has the “geometric bounds” of the shape stored its anchor associated with the shape. Looking at a sample that I created with a single text box approximately 2" x 1" in the middle top of the page , I see that the value is 0.
We now need to look at the PlcfSpa structure, which contains an array of Spa structures. Each Spa structure contains an Rca structure. The Rca structure contains values that specify the size of the rectangular area in twips (1" = 1440 twips). In the sample, the values are as follows; Left = 1290, Top = 8, Right = 4138, Bottom = 1376.
Width = (Right  Left) = (4138  1290) = 2848
Height = (Bottom  Top) = (1376  8) = 1376
So, the rectangular area is 2848 x 1368, or 1.98" x 0.95" rounded to 2 decimal places. You can verify that this size matches the size of the shape by opening the file in Word and checking the shape dimensions.
The Points from the pWrapPolygonVertices_complex structure use their own system where 1" = 21600 'Geometric Units'. Each point can be converted to a more useable form using the following formula.
Vertex.X = (actual.x * 21600) / ShapeWidth;
Vertex.Y = (actual.y * 21600) / ShapeHeight;
The scaling factors for X and Y might not be the same since one depends on width and the other on height. You may or may not have noticed that the point values that you get from the pWrapPolygonVerticex_complex data block don't necessarily represent the rectangle shape correctly. The way to convert them would be to use a variation of the above formula…
Actual.x = Vertex.X * shapeWidth / 21600
Actual.Y = Vertex.Y * ShapeHeight / 21600
Looking at my sample, the data blob looks like this...
8E FF FF FF 13 FF FF FF 8E FF FF FF 73 53 00 00 D2 54 00 00 73 53 00 00 D2 54 00 00 13 FF FF FF 8E FF FF FF 13 FF FF FF
When we divide this up into 5 sets of 4byte points we get the following…
P1 x: 0xFFFFFF8E (114)
P1 y: 0xFFFFFF13 (237)
P2 x: 0xFFFFFF8E (114)
P2 y: 0x00005373 (21363)
P3 x: 0x000054D2 (21714)
P3 y: 0x00005373 (21363)
P4 x: 0x000054D2 (21714)
P4 y: 0xFFFFFF13 (237)
P5 x: 0xFFFFFF8E (114)
P5 y: 0xFFFFFF13 (237)
Note that point #5 is a duplicate of point #1. This closes the shape. From those points we can get the following values for the Top, Left, Right and Bottom.
Top = 237
Left = 114
Right = 21714
Bottom = 21363
Then we can plug all of these values into the formula above to get this…
Top = 237 * 1368 / 21600 = 15 twips
Left = 114 * 2848 / 21600 = 15 twips
Right = 21714 * 2848 / 21600 = 2863 twips
Bottom = 21363 * 1368/ 21600 = 1353 twips
So, the wrap polygon is 2878 x 1368.
Please let me know if this sufficiently answers your question.
Josh Curry (jcurry)  Escalation Engineer  USCSS DSC Protocols Team Proposed as answer by JCurryMicrosoft employee, Moderator Tuesday, February 8, 2011 8:17 PM
 Marked as answer by JCurryMicrosoft employee, Moderator Tuesday, February 15, 2011 3:34 PM
All replies



Hi Mark Thanks for replying. I have forwarded a testfile named wrapPoly_test to the above mentioned address. The test file contains two images.
For the first image the maximum value for the point, in any direction (x or y),I see is 21600 in emu's(34 in twips)and for the second image it is 22482. Given that points are represented in geometric coordinate system, is not this true that the maximum allowed value is 21600.



Farwaha, here is what we have been able to figure out regarding this…
Each OfficeArtSpContainer contains an OfficeArtClientAnchor structure. The value of the clientanchor property specifies the hostapp side “anchor” for the shape. Every host app has different anchor information stored with the shape. Word has the “geometric bounds” of the shape stored its anchor associated with the shape. Looking at a sample that I created with a single text box approximately 2" x 1" in the middle top of the page , I see that the value is 0.
We now need to look at the PlcfSpa structure, which contains an array of Spa structures. Each Spa structure contains an Rca structure. The Rca structure contains values that specify the size of the rectangular area in twips (1" = 1440 twips). In the sample, the values are as follows; Left = 1290, Top = 8, Right = 4138, Bottom = 1376.
Width = (Right  Left) = (4138  1290) = 2848
Height = (Bottom  Top) = (1376  8) = 1376
So, the rectangular area is 2848 x 1368, or 1.98" x 0.95" rounded to 2 decimal places. You can verify that this size matches the size of the shape by opening the file in Word and checking the shape dimensions.
The Points from the pWrapPolygonVertices_complex structure use their own system where 1" = 21600 'Geometric Units'. Each point can be converted to a more useable form using the following formula.
Vertex.X = (actual.x * 21600) / ShapeWidth;
Vertex.Y = (actual.y * 21600) / ShapeHeight;
The scaling factors for X and Y might not be the same since one depends on width and the other on height. You may or may not have noticed that the point values that you get from the pWrapPolygonVerticex_complex data block don't necessarily represent the rectangle shape correctly. The way to convert them would be to use a variation of the above formula…
Actual.x = Vertex.X * shapeWidth / 21600
Actual.Y = Vertex.Y * ShapeHeight / 21600
Looking at my sample, the data blob looks like this...
8E FF FF FF 13 FF FF FF 8E FF FF FF 73 53 00 00 D2 54 00 00 73 53 00 00 D2 54 00 00 13 FF FF FF 8E FF FF FF 13 FF FF FF
When we divide this up into 5 sets of 4byte points we get the following…
P1 x: 0xFFFFFF8E (114)
P1 y: 0xFFFFFF13 (237)
P2 x: 0xFFFFFF8E (114)
P2 y: 0x00005373 (21363)
P3 x: 0x000054D2 (21714)
P3 y: 0x00005373 (21363)
P4 x: 0x000054D2 (21714)
P4 y: 0xFFFFFF13 (237)
P5 x: 0xFFFFFF8E (114)
P5 y: 0xFFFFFF13 (237)
Note that point #5 is a duplicate of point #1. This closes the shape. From those points we can get the following values for the Top, Left, Right and Bottom.
Top = 237
Left = 114
Right = 21714
Bottom = 21363
Then we can plug all of these values into the formula above to get this…
Top = 237 * 1368 / 21600 = 15 twips
Left = 114 * 2848 / 21600 = 15 twips
Right = 21714 * 2848 / 21600 = 2863 twips
Bottom = 21363 * 1368/ 21600 = 1353 twips
So, the wrap polygon is 2878 x 1368.
Please let me know if this sufficiently answers your question.
Josh Curry (jcurry)  Escalation Engineer  USCSS DSC Protocols Team Proposed as answer by JCurryMicrosoft employee, Moderator Tuesday, February 8, 2011 8:17 PM
 Marked as answer by JCurryMicrosoft employee, Moderator Tuesday, February 15, 2011 3:34 PM

Hi Josh
Thanks for the detailed explanation of everything. It is very useful. I have better results now but I still have one more
doubt.
I have forwarded a testfile named wrapPoly_test to the above mentioned address before. The test file contains two images.
For the first image the maximum value for the point, in any direction (x or y),I see is 21600 in emu's and for the second image it is 22482. Given that you mentioned that points use their own system where 1" = 21600 'Geometric Units',so is it not true that the maximum allowed value is 21600.
I wonder then what is meaning of a value greater than 21600 as I am seeing in the second image in the file
