Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

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

43 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