Skip to main content
February 3, 2011
Question

InlineGraphicElements, ContainerController and SimpleCompose

  • February 3, 2011
  • 2 replies
  • 2610 views

Using Hero (4.5.0.17689)

I've got to a point where I can parse custom XML tags using my own (or rather, extended) HtmlImporter class, but I've run into an error with InlineGraphicElements.

The InlineGraphicElements are correctly parsed (as far as I can tell) and inserted into the flow. I added a StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE event listener to the flow, which then calls textFlow.flowComposer.updateAllControllers(). At this point I get a run-time error at line 1754 in ContainerController.as.

The function in this class is attempting to cast _shapeChildren[0].userData (which is wildcard type) as a TextFlowLine, but the data type is contains is an integer. I've tracked this property assignment to line 151 in the function endLine() in the elusive class SimpleCompose.as, where it overwrites a TextFlowLine object.

I'm not sure whether this is related in some way to https://bugs.adobe.com/jira/browse/SDK-22792.

I'm also using a Configuration object, which contains an inlineGraphicResolverFunction, when converting to a flow with TextConverter.importToFlow(source, myFormat, myConfiguration).

Am I going about this the wrong way? I'm thinking so since I haven't found mention of any other similar problem. Many thanks.

This topic has been closed for replies.

2 replies

Adobe Employee
February 3, 2011

There are two modes of composition: factory, which is for static text; and "standard" which is for interactive text. factory mode uses userData for the position, and standard for the TextFlowLine (an object containing extra info about the line). Somehow the two have gotten mixed up in your example.

Are you using TextContainerManager, or a Flex component, and then calling textFlow.flowComposer.updateAllControllers() directly? Maybe you could share some of the relevant code.

Thanks,

- robin

February 7, 2011

Well for now I need static, if by that you mean non-editable.

My TextFlow is created in a component by:

protected var textFlowContent:TextFlow;

...

textFlowContent = TextConverter.importToFlow(source, XHTMLConverter.MVP_XHTML_FORMAT, MVPPlayerConfiguration.XHTMLConverterConfiguration);
textFlowContent.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, textFlowGraphicChangeHandler, false, 0, true);

...

private function textFlowGraphicChangeHandler( _event:StatusChangeEvent ):void
{
    if (_event.status == InlineGraphicElementStatus.READY)
        textFlowContent.flowComposer.updateAllControllers();
}

The TextFlow object is then bound to a RichText sub-component.

I've reduced this to an isolated example, which excludes my importer and configuration classes:

var source:String = "<p>CT scan of head reveals subdural hematoma on the left side.</p><img src=\"C:/Users/Waj/Documents/IVPs/AnFa/Fig-1.2-Chronic-subdu.jpg\"/>";

var textFlowContent:TextFlow = TextConverter.importToFlow(source, TextConverter.TEXT_FIELD_HTML_FORMAT, new Configuration());
textFlowContent.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE, function( _event:StatusChangeEvent ):void
{
    textFlowContent.flowComposer.updateAllControllers();
});

tempRichText.textFlow = textFlowContent;

Note that this is forced to some degree since the anonymous function never receives a "ready" status for some reason. Any thoughts? Is this problem unique to this build ("139 (755976)")?

Cheers,

Waj

Adobe Employee
February 8, 2011

TCM and RichEditableText take care of recompose of loading ILGs.  This example works for me.  The new Configuration call is redundant.  Change the image to your local image.

Richard

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx">   
    <fx:Script>
        <![CDATA[
            import flashx.textLayout.conversion.TextConverter;
            import flashx.textLayout.elements.Configuration;
            import flashx.textLayout.elements.TextFlow;
            private var source:String = '<p>CT scan of head reveals subdural hematoma on the left side.</p><img src="C:/textflow/argon/test/testFiles/assets/gremlin.jpg"/>' ;
           
            public var textFlowContent:TextFlow = TextConverter.importToFlow(source, TextConverter.TEXT_FIELD_HTML_FORMAT, new Configuration());
        ]]>
    </fx:Script>
    <s:RichEditableText textFlow="{textFlowContent}">
       
    </s:RichEditableText>
   
</s:Application>

February 3, 2011

Note that this also does appear to relate to TLF floating.

It is within updateFloats() in ContainerController.as that the error occurs: the function getFirstVisibleLine() is making a wrong assumption when reading from internal data.

Has this code changed since the Hero build (October)? Unfortunately I can't get the ant task to rebuild the SDK.

Of course it could be another red herring if I'm going about this wrong. How does everybody else get graphics in a text flow import?

Adobe Employee
February 3, 2011

What's odd here is that the SimpleCompose should not be used in the scenario you describe.  Can you reduce this to a small example?  It may have to do with how the customized Configuration is being setup.

Thanks,

Richard

February 3, 2011

Thanks for getting back to me. I'll work on it but I'm shortly leaving the office for a few days.

In the meantime maybe a trace will help:

    flashx.textLayout.compose::SimpleCompose/endLine   
    flashx.textLayout.compose::BaseCompose/composeParagraphElementIntoLines   
    flashx.textLayout.compose::BaseCompose/composeParagraphElement   
    flashx.textLayout.compose::BaseCompose/composeBlockElement   
    flashx.textLayout.compose::BaseCompose/composeInternal   
    flashx.textLayout.compose::BaseCompose/composeTextFlow   
    flashx.textLayout.compose::SimpleCompose/composeTextFlow   
    FactoryDisplayComposer/http://ns.adobe.com/textLayout/internal/2008::callTheComposer   
    flashx.textLayout.compose::StandardFlowComposer/internalCompose   
    flashx.textLayout.compose::StandardFlowComposer/updateToController   
    flashx.textLayout.compose::StandardFlowComposer/updateAllControllers

As explained, updateAllControllers() is called after the inline graphic update. This trace takes us to endLine() in SimpleCompose which replaces the TextLine object's userData TextFlowLine property with a number.

Then when updateCompositionShapes() is called from StandardFlowComposer/updateToController() we end up with a RTE.

I acknowledge that this might be meaningless out of context so I'll work on that reduced example on Monday.

FYI I have not changed the text flow's default flowComposer.