As the title suggest I'm trying to retrieve what font is being used by a selected `TextElement`. I would have expected this information to be stored in the 'ElementDisplayParameters' or the `TextBlock.Properties`, but this does not seem to be the case.I'm able to retrieve a list of all fonts currently in use using:
var allFonts = DgnFontManager.CreateKnownFontList(Session.Instance.GetActiveDgnFile(), DgnFontFilterFlags.All);
After which I loop through all selected elements (in test case only one element selected) and check if the selected element is of type TextElement.
DgnModelRef modelRef = Session.Instance.GetActiveDgnModelRef(); uint numSelected = SelectionSetManager.NumSelected(); for (uint i = 0; i < numSelected; i++) { Element el = null; var status = SelectionSetManager.GetElement(i, ref el, ref modelRef); if(el.ElementType == MSElementType.Text) { } }
After which I can get the TextBlock properties and the TextElements DisplayProperties:
var textEle = (TextElement)el; var partIDs = textEle.GetTextPartIds(new TextQueryOptions()); foreach (var id in partIDs) { var textPart = textEle.GetTextPart(id); var props = textPart.GetProperties(); } var textEleDisplayParams = textEle.GetElementDisplayParameters(false);
However none of these seem to contain any information on what font was used for the placed text.
Looking at the documentation `ElementDisplayParameters` only contains properties on level, colour and line style weight and transparancy and the TextBlock properties only seems to contain information about the actual textual content and the caret.
There is also the class 'DgnFontNumberMap', but this only maps the names and ID's together.
Is there a way to retrieve the font used from a TextElement?
Regards,Remy
Found it a little while after posting this question, there is also a Method TextBlock.GetRunPropertiesForAdd() which returns a `RunProperties` that contains the `Font` property.
The name sounds very illogical to me, would've expected something like TextRunProperties if anything or it to be in the TextBlock.Properties.
Answer Verified By: Remy Moerland
Remy Moerland said:would've expected something like TextRunProperties if anything or it to be in the TextBlock.Properties
No — a TextBlock can contain multiple pieces of text each having a different style and font. A TextBlock is not a DGN element. It's an abstraction of the data required to build a block of text. The block can contain text of differing sizes, different styles and organized on separate lines.
TextBlock
When you convert a TextBlock to a DGN element, the API decides for you whether that should be a single text element or multiple text elements in a text node.
Regards, Jon Summers LA Solutions
Hi Jon,
Thank you for the additional information!Regards,Remy
Remy,
Did this work for you? I was working on something similar. When I get the Font from the TextBlock for a TextElement that I know the Font is being substituted, the DgnFont.IsPresent value is True, and the DgnFont.Name property shows the substitute font name.
Hi Mike,
Yes for my use case this helped. The complete code I used to get the font of the selected text looks like this:
DgnModelRef modelRef = Session.Instance.GetActiveDgnModelRef(); uint numSelected = SelectionSetManager.NumSelected(); if (numSelected == 0) return "Please Select a text node"; else if (numSelected > 1) return "Please select only one text node"; Element el = null; SelectionSetManager.GetElement(0, ref el, ref modelRef); ParaphFiles parFile = ParaphFiles.NONE; switch (el.ElementType) { case MSElementType.Text: var textEle = (TextElement)el; var partID = textEle.GetTextPartIds(new TextQueryOptions())[0]; TextBlock textPart = textEle.GetTextPart(partID); DgnFont font = textPart.GetRunPropertiesForAdd().Font; break; case MSElementType.TextNode: var node = (TextNodeElement)el; System.Diagnostics.Debug.WriteLine($"Not yet handled"); break; default: System.Diagnostics.Debug.WriteLine($"Element was of type {el.ElementType} which is not a valid text type"); break; }
Hi Remy,
Remy Moerland said:The complete code I used
be aware it is not recommended to use MSElementType. It is not error, but it's quite old C-style concept, that does not work with new elements.
C# and object-thinking allows to write simpler code with the same functionality:
if (el is TextElement textEle) { var partID = textEle.GetTextPartIds(default(TextQueryOptions))[0]; TextBlock textPart = textEle.GetTextPart(partID); DgnFont font = textPart.GetRunPropertiesForAdd().Font; } else if (el is TextNodeElement node) { System.Diagnostics.Debug.WriteLine($"Not yet handled"); } else { System.Diagnostics.Debug.WriteLine($"Element was of type {el.ElementType} which is not a valid text type"); }
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point