Why does the bounding box from Element.GetBBox jump in size when stroking is on?

38 views
Skip to first unread message

Ryan

unread,
Sep 13, 2017, 6:24:18 PM9/13/17
to PDFTron PDFNet SDK
Question:

I find that the bbox of an ellipse drawn with the path stroke is different from the same ellipse drawn without a path stroke.

For example.
PDFDoc doc;
ElementBuilder builder;
ElementWriter writer;
Page page = doc.PageCreate();
writer
.Begin(page);
Rect bbox;
// create circle with just fill, no stroke
Element* element = builder.CreateEllipse(250, 300, 25, 25);
element
->SetPathFill(true);
element
->GetGState()->SetFillColorSpace(ColorSpace::CreateDeviceRGB());
element
->GetGState()->SetFillColor(ColorPt(1, 0, 1));
element
->GetBBox(bbox);
writer
.WriteElement(element);

// draw bounding box
element
= builder.CreateRect(bbox.x1, bbox.y1, bbox.Width(), bbox.Height());
element
->SetPathFill(false);
element
->SetPathStroke(true);
element
->GetGState()->SetLineWidth(1);
element
->GetGState()->SetStrokeColorSpace(ColorSpace::CreateDeviceRGB());
element
->GetGState()->SetStrokeColor(ColorPt(1, 0, 0));
writer
.WriteElement(element);

// create circle with fill and stroke
element
= builder.CreateEllipse(325, 300, 25, 25);
element
->SetPathFill(true);
element
->GetGState()->SetFillColorSpace(ColorSpace::CreateDeviceRGB());
element
->GetGState()->SetFillColor(ColorPt(1, 0, 1));
element
->SetPathStroke(true);
element
->GetGState()->SetStrokeColorSpace(ColorSpace::CreateDeviceRGB());
element
->GetGState()->SetStrokeColor(ColorPt(0, 0, 1));
element
->GetBBox(bbox);
writer
.WriteElement(element);

// draw bounding box
element
= builder.CreateRect(bbox.x1, bbox.y1, bbox.Width(), bbox.Height());
element
->SetPathFill(false);
element
->SetPathStroke(true);
element
->GetGState()->SetLineWidth(1);
element
->GetGState()->SetStrokeColorSpace(ColorSpace::CreateDeviceRGB());
element
->GetGState()->SetStrokeColor(ColorPt(1, 0, 0));
writer
.WriteElement(element);

writer
.End();
doc
.PagePushBack(page);


Where the red square is the bounding box, and the blue outline is the stroke.

Answer:

This is because by default paths are joined using Miter joints. The other options are Round and Bevel.

If two paths make a sharp angle/point, then a miter joint can stick very far out. Because of this there is another option, miter limit, which is defaults to a ratio of 10, where the miter length can be 10 times larger than the stroke width.

Element.GetBBox is making a best guess, and so simply turning on stroking triggers miter limit as the new edge.


To avoid this you can either set the MiterLimit to 1 (not zero)
element->GetGState()->SetMiterLimit(1);



Or change the join style to Bevel or Round
element->GetGState()->SetLineJoin(GState::e_round_join);






Reply all
Reply to author
Forward
0 new messages