Extracting <SHIFT>ed carriage returns from text nodes

Hi folks,

 I have an old problem with text nodes that's been around since I ported to v8. In MicroStation v8.0-v8.9 (have not tested with V8i yet)  there seems to be  a distinct difference between text nodes created by hitting <RETURN> between lines, and hitting <SHIFT><RETURN>.

When you Analyze the element the only difference you notice is that there is an extra space in the selection after the line end when <SHIFT> was used. So it seems that an extra character is used and stored to differentiate a normal carriage return from a shifted one.

 The problem for me comes about when I programmatically  try to process one of these text nodes. What happens is the SHIFT-ed text node gets replaced as a text node with all text on one continuous line. Deeper inspection of the text node reveals that the primary difference between the two node types is that if you held <SHIFT> then the value of the "txtParamWide.exFlags.crCount" is always zero, whereas without <SHIFT> it is always one or more. When the actual text is extracted using "mdlText_extractString()" or "mdlText_extractStringsFromDscr()" or "mdlText_extractWide()", then there is no difference between the two strings, so it seems extracting the text is a dead-end.

So somewhere internally there is this special carriage return stored and I really need to find out how to extract it so I can rebuild the original text node correctly with all lines separated. I have examined all the usual API functions and can not find any flag or structure which might store this information. It does not seem to be stored in the TextParamWide structure, so my only hope is to hack at the raw element structure directly.

 Can anyone shed any light on this <SHIFT> behaviour of text nodes?

Cheers.

 

 

Parents
  • The difference exists because we have some concepts that are per-paragraph (e.g. paragraph first-line indent). The <enter> key by itself will insert a carrirage return, which will start a new paragraph. <shift>+<enter> will insert a line feed, which adds a line to the existing paragraph. Line breaks are one of those things that are not stored well on text nodes (as you've been able to tell) with partial/duplicate information being stored. Newer versions of MicroStation generally rely on a whitespace linkage to determine what and how many tabs, carriage returns, and line feeds exist; the TextParamWide does not capture all of this information; we still write what we can to the TextParamWide for older versions. The whitespace linkage is a bitmask linkage that uses two bits per identifier; an identifier being tab/CR/LF. The bitmask linkage ID is BITMASK_LINKAGE_KEY_TextWhiteSpace, and I believe you have access to the mdlLinkage_*BitMask functions to get at it. The values for each are:

    #define BITMASK_TAB 0
    #define BITMASK_CR 1
    #define BITMASK_LF 2

  • Hi Jeff,

    Thanks very much for the extra info. I did think to look at the Linkage data. I created 2 identical text nodes, one with normal CR's and one with <SHIFTED> CRs. When examined using the Analyze tool, the linkage data shown is identical. I am guessing this is because Analyze under XM only shows the text node header, not the text element components themselves. Is there any way to show the text components in XM, or use the older (and IMHO much better) MS2004 version of Analyze? The XM version is not only less featured but also considerably slower than the original (presumably this is a .NET thing).

     Additionally under XM, the linkage is not able to be selected/copied/pasted, which is a massive pain when trying to view and compare linkage between elements. For this and other reasons I tend to do most of my development in MS2004, and it looks like I will need to again in order to sort out what is happening in the linkage.

     I am also guessing that this is what the text flag "bitMaskContainsTabCRLF" is used for?

     Cheers.

    --
    Piers Porter
    Altiva Software

  • Analyze Element

    Piers:
    Is there any way to show the text components in XM, or use the older (and IMHO much better) MS2004 version of Analyze?

    We can continue to use it, fortunately:
    keyin Analyze Element.

    Piers:
    The XM version is not only less featured but also considerably slower than the original (presumably this is a .NET thing).

    You clearly haven't heeded Microsoft's advice to buy a faster processor and double the size of your memory 8-) For further information, kindly read 'Alice Through the Looking Glass', and pay special attention to the Red Queen's race: "Now, here, you see, it takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!"

    Regards, Jon Summers
    LA Solutions

     
    Regards, Jon Summers
    LA Solutions

  • Hi John,

    Thanks a lot, that makes XM slightly more useful. I've now got around my problem with the whitespace getting lost by extracting and re-applying the linkage to each text component in a node, e.g.:

    if ( mdlLinkage_extractBitMask ( &bitMaskSP, &currElmDSP->el, BITMASK_LINKAGE_KEY_TextWhiteSpace, 0 ) == SUCCESS )
    {

    mdlLinkage_appendBitMask ( &newElmS, BITMASK_LINKAGE_KEY_TextWhiteSpace, bitMaskSP );
    mdlBitMask_free ( &bitMaskSP );

    }

     Since I'm not changing the text itself, this seems to work fine.

    My only remaining questions are:

    1) What other attributes should I be extracting and reapplying to ensure my next text node matches the old one I am replacing? Quick testing reveals that there are also linkages such as: TEXTATTR_ID, TEXT_IndentationLinkage and there is also a LINKAGEID_TextRendering. Are these necessary also and what do they do?

    2) I think more importantly, why are these linkages not reapplied when I create the new text element from the old one as a template passed as the 2nd argument to mdlText_createWide()  ? This function copies everything else, including the text itself, so why does it not copy these extra parameters? If it did then I would not have to concern myself with these and any future undocumented linkages, as I could then just blindly copy what is already there through the template.

    Cheers.

    --
    Piers Porter
    Altiva Software

Reply
  • Hi John,

    Thanks a lot, that makes XM slightly more useful. I've now got around my problem with the whitespace getting lost by extracting and re-applying the linkage to each text component in a node, e.g.:

    if ( mdlLinkage_extractBitMask ( &bitMaskSP, &currElmDSP->el, BITMASK_LINKAGE_KEY_TextWhiteSpace, 0 ) == SUCCESS )
    {

    mdlLinkage_appendBitMask ( &newElmS, BITMASK_LINKAGE_KEY_TextWhiteSpace, bitMaskSP );
    mdlBitMask_free ( &bitMaskSP );

    }

     Since I'm not changing the text itself, this seems to work fine.

    My only remaining questions are:

    1) What other attributes should I be extracting and reapplying to ensure my next text node matches the old one I am replacing? Quick testing reveals that there are also linkages such as: TEXTATTR_ID, TEXT_IndentationLinkage and there is also a LINKAGEID_TextRendering. Are these necessary also and what do they do?

    2) I think more importantly, why are these linkages not reapplied when I create the new text element from the old one as a template passed as the 2nd argument to mdlText_createWide()  ? This function copies everything else, including the text itself, so why does it not copy these extra parameters? If it did then I would not have to concern myself with these and any future undocumented linkages, as I could then just blindly copy what is already there through the template.

    Cheers.

    --
    Piers Porter
    Altiva Software

Children
No Data