We're working on a huge porting from 100+ MA applications from V8i to Connect Edition.One of the problems we're encountering regards the old mdlText_extract API.In order to determine the size of an existing text element, we so far use the following code:
MSElement* pElement = ...;
char text;TextSize tileSize;TextSize textSize;mdlText_extract(NULL, NULL, NULL, NULL, text, NULL, NULL, NULL, &tileSize, &textSize, pElement);printf("Text '%s' has tileSize (%.1lf, %.1lf) and textSize (%.1lf, %.1lf)\n", text, tileSize.width, tileSize.height, textSize.width, textSize.height);
It has the following output:
Text 'TTF3' has tileSize (525.0, 1200.0) and textSize (1901.5, 1200.0)Text 'ODF10' has tileSize (420.0, 1200.0) and textSize (1785.7, 1200.0)
I tried the code as suggested by the link:
ElementHandle eh(pElement, ACTIVEMODEL);TextBlockPtr textBlock = TextHandlerBase::GetFirstTextPartValue(eh);DPoint2d fontSize = textBlock->GetRunPropertiesForAdd().GetFontSize();DRange3d range = textBlock->GetNominalRange();printf("FontSize of %ls: (%.1lf, %.1lf)\n", textBlock->ToString().GetWCharCP(), fontSize.x, fontSize.y);printf("low/high: (%.1lf, %.1lf) / (%.1lf, %.1lf)\n", range.low.x, range.low.y, range.high.x, range.high.y);printf("doc.width: %.1lf\n", textBlock->GetProperties().GetDocumentWidth());
But this gives me the output:
FontSize of TTF3: (0.0, 12.0)low/high: (0.0, -12.0) / (0.0, 0.0)doc.width: 0.0FontSize of ODF10: (0.0, 12.0)low/high: (0.0, -12.0) / (0.0, 0.0)doc.width: 0.0
In other words, I get the height of the text (expressed as the fontsize) but not the width.
Any idea how to get the actual width and height of an existing text element?I didn't find anything useful within the TextBlock class.
Robert Kock said:Any idea how to get the actual width and height of an existing text element?
Continue to use mdlText_extract until Bentley respond...
Note that its signature has changed from V8.
Regards, Jon Summers LA Solutions
I tried that before but also that function returns 0 for textSize->size.width and the first call returns +Inf as height. Am I doing something wrong?
Furthermore, I don't know whether this parameter returns the tileSize or the textSize. Anyway, I need both of them.
Robert Kock said:I tried that before...
While browsing the help doc I came across mdlText_extractW. That function really is obsolete, because all strings are wide (Unicode) in CONNECT. However, there's this interesting information appended...
ElementHandle eh (...);
TextBlockPtr textBlock = TextHandlerBase::GetFirstTextPartValue (eh);
if (!textBlock.IsValid ())
/* ERROR */
Often, getting the parameters was only required to modify the text and re-create it. If this is your goal, instead of acquiring the properties, mutate the TextBlock in-place and re-generate the element.
There is no direct equivalent to getting the element origin (lower-left) from a TextBlock; only user origin is supported. The user origin is the data point / snap point used to create the text, and affects how it flows and positions itself as its content changes. Element origins were always lower-left, and failure to keep this concept synchronized with the user origin resulted in poorly positioned text.
WString string = textBlock->ToString ();
DPoint3d userOrigin = textBlock->GetUserOrigin ();
RotMatrix rotMatrix = textBlock->GetOrientation ();
If the TextBlock came from a text element, querying the paragraph and run formatting at the beginning is sufficient (since it will not have heterogeneous formatting).
CaretPtr caret = textBlock->CreateStartCaret ();
TextParamWide is split between TextBlockProperties, ParagraphProperties, and RunProperties. TextSizeParam (now simply a DPoint2d in UORs) is on RunProperties (via (Get|Set)FontSize).
textBlock->GetProperties ().Get/Is... ();
caret->GetCurrentParagraphCP ()->GetProperties ().Get/Is... ();
caret->GetCurrentRunCP ()->GetProperties ().Get/Is... ();
There is no direct equivalent to TextEDParam in TextBlock. You must iterate the runs and dynamic_cast to an EdfCharStream to get EDF information.
To mutate the TextBlock, see methods such as TextBlock::Clear (), TextBlock::AppentText (), TextBlock::InsertText (), TextBlock::Remove (), TextBlock::SetParagraphPropertiesForAdd (), and TextBlock::SetRunPropertiesForAdd ().
To create the updated element, see TextHandlerBase::CreateElement, then you can use standard EditElementHandle methods (such as EditElementHandle::ReplaceInModel ()).
Thanks again but I noticed that comment before. Didn't help me any further.
I'm encountering tons of problems while porting old code that interfers with the DGN. Simple dialogs and their management don't give me any trouble (except for a lot of work).
I guess I need to consider to completely rewrite the code that changes the DGN.