• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
Locked
0

How to display only one letter in Flex Text Layout Framework ContainerController?

Community Beginner ,
Apr 23, 2010 Apr 23, 2010

Copy link to clipboard

Copied

I'm trying to implement dropped initials feature into  my Flex application. Since Text Layout Framework does not support  floating, the only known solution is to create additional containers  that will be linked together, displaying the same textflow. Width and  positioning of these containers has to be set in such a way that it will  pretend that it's float.

I'm using the same solution for dropped initials. Basically, I'm  creating three containers, one for the initial letter (first letter in  text flow), the other for text floating around, and the 3rd one to  display text below these two. All these containers share one textflow.

I have big issues with forcing controller to display only one letter  from the text flow, and size it accordingly, so that it wont take any  unnecessary aditional space and won't get any more text into it.

Using ContainerController.getContentBounds() returns me size of whole  sprite of the letter (with ascent/descent empty parts), not the  height/width of the actual rendered letter. I'm using  textFlow.flowComposer.getLineAt(0).getTextLine().getAtomBounds(0), but i  think it's still not right. Also, even if I set container for this  dimensions, it sometimes display additional text in it, especially for  bigger fonts. See screen :

alt text

Also, if I set width to just 1px less that contentBounds, things are  going crazy, containers are moved around, positioned with big margins,  etc.

How should I solve this? Is it a bug in TLF / Player? Can I fix it  somehow?

Can I detect the size of the letter, or make containercontroller  autosize to fit just one letter only?

Why ContainerController has properties like fontSize? If I change them, nothing happens (font stays the same, even if it does not have fontsize set).

TOPICS
Text layout framework

Views

2.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Employee ,
Apr 23, 2010 Apr 23, 2010

Copy link to clipboard

Copied

I would suggest adding a <br/> (or a \u2028) after the "A". That will guarantee that the line breaks after A. It doesn't fix the other problem, where you get an extra line in the drop-cap container though. You can at least detect when you have more than one letter in the container, by checking the controller's textLength, and then adjusting the height. Setting the height to the contentBounds height should work -- the content bounds is not the same as the inked bounds, but is the correct size for fitting the text. If you want more control over the vertical location of the drop cap, you can adjust the firstBaselineOffset, and the controller's contentHeight should change in response. If you have examples where you are setting to the content height and you get more or less lines than before, please let me know and I will look into it. There may be some errors with small fractional values, but it should be very close. Changing the width is, as you point out, more hazardous to the layout -- you are likely to get line breaks in slightly different locations because you get a different set of roundoff errors with a different width, which can lead to a different line ending. The <br/> should help with that.

We do allow setting attributes on the controller, even though some of the attributes are ignored. This is useful for situations where you might want different column settings in different controllers, for example.

Hope this helps,

- robin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Apr 24, 2010 Apr 24, 2010

Copy link to clipboard

Copied

I cannot change data model (textflow), just to display it differently. That's why in HTML we take text but set properties on containers of the text, not on the text itself. It's bad that I cannot do the same in Flex. If ContainerController has properties which are ignored (which is bad design for mre), it should be at least stated in documentation. I cannot add <br />. I also cannot change firstBaselineOffset of the first Container, because letters have to be aligned to the top. But it doesn't matter - if I change baseline to shift letter a bit to the bottom, the wrongly rendered text within that container gets shifted down too (instead of disappear).

"The content bounds is not the same as the inked bounds, but is the  correct size for fitting the text" - that should be true, but it apparently isn't. For bigger fonts, if I set content bounds for one letter, the descent section below capital letter is big enough to fit another line of text from textflow - and somehow flowcomposer allows for that. It looks to me like something is calculated wrong there (leading? baseline?).

If I change the contentbounds height smaller just even fraction of value, it gets crazy :

Untitled.png

textLength then reports that container has 0 characters in it.

The (roughly) code, that I use :


   s = new Sprite();
  cc = new ContainerController(s);
  sd.textFlow.flowComposer.addControllerAt(cc,0);
 
  sd.textFlow.flowComposer.updateAllControllers();
   
  var r:Rectangle = sd.textFlow.flowComposer.getLineAt(0).getTextLine().getAtomBounds(0);
    initalWidth = Math.floor(r.width) + 4; 
    initialHeight = Math.floor(r.height) + 4;
 
  cc.setCompositionSize(initalWidth, initialHeight);
 
  sd.textFlow.flowComposer.updateAllControllers();

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 09, 2010 Aug 09, 2010

Copy link to clipboard

Copied

Hi rattkin,

Just wondered if you managed to work out a solution to this - we are facing exactly the same problem ...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 09, 2010 Aug 09, 2010

Copy link to clipboard

Copied

I've figured out that TLF was never prepared to do this properly. Text controllers / containers are meant for text holding, but they were not designed with char limitation in mind. Therefore, you're doomed to use some wacky ways to maintain that unstable balance within one container. I've simply dropped the need for scaling initial to whatever extent. I've figured out a safe range where it does not break for unknown reason, and just went with that. Can't post you the exact code (too project specific), but some general hints are :

The idea is - get your font size, apply some kind of scale, multiply and that will give you the "container height".

var initialFontSize:Number = Math.round(normalFontSize * scale * 1.2); // the 1.2 is here to tackle the lineheight gaps

Create such ContainerController, but give it (1,1) dimensions first, find first character in your textflow, possibly create a new span just for this one letter (and remove it from following spans). To achieve vertical alignment to the top, for characters that do not have "ascent" part in their spline, I do :

initialTextSpan.dominantBaseline = TextBaseline.ROMAN;
initialTextSpan.alignmentBaseline = TextBaseline.IDEOGRAPHIC_CENTER;

which is a wacky (and absolutely random) trick to align them to the top. Then

textFlow.flowComposer.updateAllControllers();
textFlow.flowComposer.composeToPosition(1);

which is probably a bit redundant, but still...

// get values for first rendered letter
var tl:TextLine = sd.textFlow.flowComposer.getLineAt(0).getTextLine();
var r:Rectangle = tl.getAtomBounds(0);

Now here is the part where you might want to actually influence the height. The problem is that for each letter, flex will return the height of its container (so it will preserve space for ascent/descent parts of letter), never the letter itself. For the font and scale I used, I basically measured the perecentage in spaces taken in top and bottom, and then used that to subtract certain values from the returned height. Then :

containerController.setCompositionSize(r.width, yourCorrectedHeight);
textFlow.flowComposer.updateAllControllers();

And then create another controller to the right, in specific (x + r.width, y) and assign the same text flow. Finally, create controller below and assign the same textflow. Keep in mind that sometimes the initial might be too close to the text below. In this case, you need to allow one line more in the right container (increase height by lineHeight) and move bottom container additionally.You might also want to steer the gaps between left and right container.

My main problem was that for certain scales (when container crossed barrier of about 110 px height) some weird things started to happen and containers were placed completely wrong or unpredictable. Or, the other behaviour, was that the container actually was high enough, to contain not only one letter, but also some text below it, which was not the thing I wanted. I believe some optimizations or addtional checks from TLF kicked in, which prevented one letter in container. Never had the time nor opportunity to dig into TLF and figure out what's going on there. One thing I've learned for sure : if something's displaying not right, you're just using not enough of "textFlow.flowComposer.updateAllControllers();". Really

Hope this helps.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 10, 2010 Aug 10, 2010

Copy link to clipboard

Copied

LATEST

Thanks - that's very helpful, I should be able to hack together something that will suit our app using your sugestions.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines