SOLVED Get the String of the Font Data?

Hi,

When you retrieve the font from the Motext, it gives you c4d.FontData type.
Is there a way to retrieve the string of that fontdata (i.e. font name)?

I check the documentation but there is no such method for it.
Maybe I'm missing something?

Regards,
Ben

hmm, you have found an interesting behavior.

You can read the font data container just like any other container:

import c4d
from c4d import gui

def main():
    bc = op[c4d.PRIM_TEXT_FONT].GetFont()
    print (bc, len(bc))
    for index, value in bc:
        print ("Index: %i, Value: %s" % (index, str(value)))

if __name__=='__main__':
    main()

resulting in

<c4d.BaseContainer object at 0x000001E012D5B800> 7
Index: 500, Value: Segoe UI
Index: 502, Value: 700
Index: 503, Value: 0
Index: 2, Value: Fett
Index: 509, Value: Segoe UI Fett
Index: 508, Value: SegoeUI-Bold
Index: 501, Value: 11

HOWEVER!

If the MoText has just been created, this BaseContainer is empty. I get the values above only after changing something. It's not the Segue UI font either because you can set it back to the initial values, and the container will be filled.

I don't know how to tell the MoText object to actually fill the container, and I do not see any hint in the documentation how to enforce it.

Hi @bentraje,

thank you for reaching out to us and thank you @Cairyn for stepping in again.

The normal behavior of FontData parameters is not to be initialized in Cinema 4D. For a newly allocated node, they then will return None in Python, indicating that they point to the default system font. In Python this default font has to be retrieved a bit awkwardly via c4d.bitmaps.GeClipMap, which has the static method GetDefaultFont(), returning a font container.

A MoText node is the exception here, as it will then return an empty container. One must still default to the system default font then, but it is just an extra case to handle. Below is an example for that. I have also opened an issue for the inconsistency of MoText in this regard.

Cheers,
Ferdinand

"""Example for retrieving a node's PRIM_TEXT_FONT font container.

For newly allocated nodes this will default to the default font internally,
for nodes where the PRIM_TEXT_FONT parameter has been modified, by setting
the font to bold for example, the font data will be there.

MoText is somewhat a special case, as it does not align with the normal 
behavior of FontData not being initialized.
"""

import c4d

def main():
    """
    """
    # Get the selected object.
    if not op:
        raise TypeError("Please select an object.")

    # Get the node's data container.
    nodeData = op.GetData()
    if nodeData is None:
        raise RuntimeError("")

    # Try to access the PRIM_TEXT_FONT parameter.
    fontData = nodeData[c4d.PRIM_TEXT_FONT]
    # When it is not populated, then fall back to the system font.
    if fontData is None or len(fontData.GetFont()) < 1:
        fontContainer = c4d.bitmaps.GeClipMap.GetDefaultFont(
            c4d.GE_FONT_DEFAULT_SYSTEM)
    # Otherwise get the font container.
    else:
        fontContainer = fontData.GetFont()

    # Go over the font container.
    for cid, value in fontContainer:
        print (f"cid: {cid}, value: {value}")

if __name__=='__main__':
    main()

@Cairyn @ferdinand

Thanks for the response. Printing the base container with their indexes worked in my use case :)