Generate a flex image from a hidden component - apache-flex

I'm trying to put an image, generated from some text, in a RichEditableText. Since it's a styled text, I thought about putting it another RichEditableText, style it, then print it to a Bitmap to use as source for InlineGraphicsElement.
I use the following code to do that
var txt:RichEditableText = new RichEditableText();
txt.text = name;
// Appliy given styles to the text flow of input rich editable text
createApplyNamedStyle(name, styles).call(null, txt.textFlow);
var bitmapData:BitmapData = new BitmapData(txt.width, txt.height);
bitmapData.draw(txt);
var bitmap:Bitmap = new Bitmap(bitmapData);
Unfortunatly, when called, it displays an error stack
ArgumentError: Error #2015: BitmapData non valide.
at flash.display::BitmapData()
at RichTextEditor/getTagImage()[E:\FlexWorkspace\Test\src\RichTextEditor.mxml:74]
at RichTextEditor/insertTag()[E:\FlexWorkspace\Test\src\RichTextEditor.mxml:154]
I suspect it is due to the fact that my RichEditableText, not being in visible component, is not laid out.
How can I ensure it is properly laid out ?
And am i doing the right thing to transform my text into an image ?

You're right; since the text is not on the display list, it is never validated and hence has 0 height and width.
A typical workaround is to add the item to the display list and then remove it immediatley. A little more discussion in this SO question.

You should trace txt.width and txt.height. They must be at least greater or equal to one. It does not matter if a DisplayObject is visible or not.

Related

better way to include anchor in ListItem and adjust item's symbol font in itextSharp

I am using iTextSharp 5.4.4, and i am trying to construct an ordered list of anchors. I am facing 2 problems:
if i pass the anchor directly to the constructor of the ListItem, it gets treated as a Chunk in the rendered output and loses its anchor features.
workaround: I initialize the ListItem using the empty constructor and then I use ListItem.Add to add the anchor.
2.using the workaround above, I try to adjust the font of the list symbol to make match that of the item using
ListItem.AdjustListSymbolFont();
that does not work -i guess it's because to itext, there's no Chunk in the list item to retrieve the font from. So what i did is the following
var listItem = new iTextSharp.text.ListItem(clickAnchor); // clickAnchor is treated as a Chunk
listItem.Add(clickAnchor); // i add the anchor again
listItem.AdjustListSymbolFont();
listItem.Remove(listItem.Chunks[0]); // after the font is adjusted, i remove the first Chunk
so basically i fed it an element that i know it'll treat as a Chunk so that it has one to retrieve the font from then i add that same element to the ListeItem and adjust the font.
I then remove the first Chunk, which it processed and added from the element in the first line of code. This is a very ugly workaound, but it is the only one that worked.
Are there better ways to do the above?
thanks
If I understand your question correctly, clickAnchor is an object of type Anchor. If you pass this to the ListItem as a parameter, it will be treated as a Phrase and all interactivity will be lost.
To avoid this, you shouldn't create an Anchor. Instead you should use a Chunk and make it interactive using the SetAnchor() method. This way, the anchor is preserved when you use it in a ListItem.
Update: Copy/past from the code snippet from kfc's comment:
var clickAnchor = new Chunk(pub.Title, anchorFont);
clickAnchor.SetLocalGoTo(i.ToString());
var listItem = new iTextSharp.text.ListItem(clickAnchor);
listItem.AdjustListSymbolFont();

Determine CSS-styled Text size in JavaFX / force styling?

I have a problem determining the width of a rendered text node in JavaFX 2. When using the standard style, everything works fine:
Text testText = new Text("test");
double width = testText.getLayoutBounds().getWidth();
But if I apply custom CSS styling which sets a different font size like this
.text-class {
-fx-font: 20px "Tahoma Bold";
}
and apply the CSS class to my example above:
Text testText = new Text("test");
testText.getStyleClass().add("text-class");
double width = testText.getLayoutBounds().getWidth();
I will get the same result as in the first case, so obviously styling is delayed to some later point in time.
How do I determine the width of a CSS-styled text in JavaFX 2? Is it possible to somehow force immediate CSS styling?
CSS application is not done immidiately, so, the way to solve the issue, is do your actions, when size of text actually changes.
testText.layoutBoundsProperty()
Is the property, which responds to bounds, and it stores an immutable object. There are also other properties, telling you about size and position. What you can do - is to attach a change listener on this property, and apply changes, when a modification is done.
CSS-Styles are applied on the next so called pulse beside that the layoutBounds are influence by the parent container your put it into.

Flex text inserted into TextArea causes application to hang

I am attempting to insert text from a database into a custom TextArea component, using the following:
var front:CaptionTextArea = myFlashcardFrontsides[adjIndex] as CaptionTextArea;
var back:CaptionTextArea = myFlashcardBacksides[adjIndex] as CaptionTextArea;
var passage:CaptionTextInput = myVersePassages[adjIndex] as CaptionTextInput;
front.text = passage.text;
back.text = str;
This works 100% of the time for smaller strings. However, if I insert long strings of text, the application will hang consistently. The maxchars for the textarea is set to 1200, and the text that is inserted into the text area is always smaller than the character limit:
backside.maxChars = 1200;
How can this problem be fixed?
I resolved the issue, and all I had to do was change my TextArea from a Spark TextArea to an MX TextArea:
// import spark.components.TextArea; DON'T USE: SPARK TEXT AREA CAUSES A BUG WHEN PROGRAMATICALLY INSERTING LONGER TEXT STRINGS
import mx.controls.TextArea;
public class CaptionTextArea extends TextArea
It seems like there is an Adobe bug that causes my application to freeze when programatically inserting long strings of text into the newer text area.
I am facing this issue myself right now.
I think the problem is, when you add a long text (so long that scrollbars appear) to a TextArea and its not yet on the stage, the error is thrown. I believe the component has problems adding the scrollbar to the container.
mx:TextArea works, but its not good for styling the component, so it would be nice if apache (?) fixed that.

Printing content inside a scroller in Flex 4

I am currently working on an Adobe AIR application that shows the user some graphical data. As this data is more in height to fit the screen height, I've placed it inside a scroller.
Now I want to take a print of this visual data, mostly some charts and lists but I only see a single page containing only the part of the screen that is currently visible to the user. I want to have the entire content inside the scroller to appear on the page.
I tried using both PrintJob and FlexPrintJob but couldn't find a way around. Can anyone please help me by providing an insight, some source code will be greatly appreciated.
Looking forward to your replies,
Thanks
This is apparently a known bug with the Flex printing library and Scroller controls. You can read about my discussions on this here:
http://forums.adobe.com/message/3626759
As a workaround, I did the following:
var printer:FlexPrintJob = new FlexPrintJob();
// Display the print dialog to the user. If they choose a printer
// and click "print", this method will return true, and we will
// spool the job to the printer they selected. If they hit cancel,
// this method will return false, and we will not attempt to send
// anything to the printer.
if(printer.start()){
// Add some padding before spooling the object to the printer.
// This will give it a reasonable margin on the printout.
itemsToPrintContainer.paddingBottom = 100;
itemsToPrintContainer.paddingTop = 100;
itemsToPrintContainer.paddingLeft = 100;
itemsToPrintContainer.paddingRight = 100;
this.removeElement(itemsToPrintContainer);
FlexGlobals.topLevelApplication.addElement(itemsToPrintContainer);
printer.addObject(itemsToPrintContainer);
printer.send();
FlexGlobals.topLevelApplication.removeElement(itemsToPrintContainer);
this.addElement(itemsToPrintContainer);
// Reset the margins to 0 for display on the screen.
itemsToPrintContainer.paddingBottom = 0;
itemsToPrintContainer.paddingTop = 0;
itemsToPrintContainer.paddingLeft = 0;
itemsToPrintContainer.paddingRight = 0;
}
That I'm doing is moving the object I want to print outside of the scroller, printing it, and then moving it back inside the scroller, so the user is unaware of any change. The user might see a brief flash on the screen while things are re-arranged, but for my case that was acceptable.
Also, the padding was an attempt to add a margin to my printed output. It will not work quite right if you have multiple pages. You may not want to add padding in your particular case.
-Josh

AS3: grouping sprites

I have a handful of sprites that I am attempting to group together via addChild().
Here is some pseudo-code demonstrating what I would like to accomplish:
import nav.text.TextSprite;
spr1:Sprite = new Sprite();
spr1.graphics.clear();
spr1.graphics.beginFill(0x000000);
spr1.graphics.drawRect(0,0,100,100);
txt1:TextSprite = new TextSprite;
txt1.text = "hello";
spr1.addChild(txt1);
//this is what isn't working: the sprite is hidden but not the text
spr1.alpha = 0.0;
For some reason I cannot seem to get the TextSprite to draw correctly... All it is is a Sprite with a TextField added to it. I think everything is working there, but I might have something wrong w/r/t making sure all of TextSprites children are grouped correctly.
I should mention that it does position correctly; but the alpha property won't respond in the way I would expect it to. I.E., the sprite that the TextField is attached to will allow it's alpha to be set but the text remains visible.
Any thoughts?
Most likely you just need to embed the font in your textfield. Try changing the x, y of spr1 and see if txt1 moves along with it. If it truly is a child then it will respond to the new position.
You need to embed the font using textfield.embedFonts = true. If your text is disappearing when you do this, how are you going about embedding the font (using the Flex embed meta tag or using the Flash IDE?), check that you are not changing the font weight (setting the text to bold when you have only embedded the normal weight font) and if you are using a text format, be sure to apply the text format AFTER you set the textfield.text property. You can get around this by using textfield.defaultTextFormat.

Resources