6 Replies Latest reply on Dec 13, 2009 11:15 PM by mrdicamillo

    Textarea BitmapData Clips HTMLtext Italic System Font

    mrdicamillo Level 1

      When using an italic system font, such as BrushScriptStd.otf (pretty standard on Windows PCs - attached if you don't have it), it renders a capital "B" correctly in the textarea:

       

      public var letB:String = '<TEXTFORMAT LEADING="2"><P ALIGN="LEFT"><FONT FACE="BrushScriptStd" SIZE="72" COLOR="#000000" LETTERSPACING="0" KERNING="0">B</FONT></P></TEXTFORMAT>';

      myTextArea.htmlText = letB;

       

      Looks like this in the flash player in Firefox:

       

      B.jpg

       

      When I try to create a bitmap image of the TextArea, the edge of the italic "B" that "overhangs" the next character position gets clipped off in the rendered bitmap:

       

      Bclipped.jpg

       

      I used the BitmapData.draw method to generate the bitmap.  I have also tried ImageSnapShot with the same result.

       

                  myTextArea.setStyle("backgroundAlpha", 0.0);
                  var myBitmap:BitmapData = new BitmapData(myTextArea.width*1, myTextArea.height*1, true, 0x00000000);
                  var m:Matrix = new Matrix();
                  m.scale(1, 1);
                  myBitmap.draw(myTextArea, m);
                  BitmapImageOfB.source = new Bitmap(myBitmap);

       

      BTW - I need to use system fonts (allow the user to be able to create text with any fonts they have on their hard drive.)  However, I have tried this with embedding the BrushScriptStd font just to see if that was the problem, but embedding did not change anything.

       

      Is this a bug?  Or am I doing something really wrong?

        • 1. Re: Textarea BitmapData Clips HTMLtext Italic System Font
          PhilipKeiter Level 2

          Hello mrdicamillo,

           

          Try this: Keep the TextArea there for the user to view. But keep a hidden TextField with the same text and styles applied. Use the hidden TextField for the Bitmap draw. In my experience the low level TextField gives better results for italics than the high level Flex controls.

           

          I don't believe you need to add the TextField as a child for it to be capture-able by draw(), but if you do, add it to the container's rawChildren array collection and make it invisible. (I don't have time to check atm.)

           

          Thanks,

          Philip

          • 2. Re: Textarea BitmapData Clips HTMLtext Italic System Font
            mrdicamillo Level 1

            Thanks for the suggestion.  Sadly, TextField has the same behavior when trying to generate bitmap data using myBitmap.draw(myTextField, m);  Still clips the letter character, just like TextArea does.

             

            My guess is that it is something in the draw method and how it renders fonts.  Not sure if it uses a different rendering engine than the flash player itself (since the flash player renders the characters just fine in the TextArea or TextField itself).

             

            Don't know why (or if) this has never been mentioned before.  The one thing you expect Adobe and Flex to do better than other platforms is to handle fonts.

             

            Any other suggestions?

             

            BTW - using SDK 3.2.0.3794 with Flash 10

            • 3. Re: Textarea BitmapData Clips HTMLtext Italic System Font
              PhilipKeiter Level 2

              mrdicamillo,

               

              It is all about the text character widths. When the text is measured, it adds up the width of each character. But italic text extends outside of its bounding box. So its measurement is accurate from a standard character spacing point of view, but not from a visual point of view.

               

              One thing you can do is pad extra spaces at the end.

               

              Thanks,

              Philip

              • 4. Re: Textarea BitmapData Clips HTMLtext Italic System Font
                mrdicamillo Level 1

                You are quite right about the bounding box.  And I can add an extra space, that will allow the portion of the italic character that extends beyond the bounding box to render.  If my project were only that simple.

                 

                I have discovered that adding a space only works if it is in the same font face as the italic letter being clipped. The ultimate project users often compose type with multiple font faces in a single word (kind of the ransom note effect) as part of their type setting. In addition, some of the font faces have exaggerated swashes that span several letters, which would require you to add several spaces, and on either side since descenders in italic typically run forward under the preceding character.

                 

                My application goes further in that I also allow the user to kern / change the space between the letters by using <FONT LETTERSPACING="-5"> in the HTMLtext.  This also results in clipping.

                 

                So far, the only thing I can come up with, which to my mind is a complete hack, is to take the HTMLtext apart letter by letter.  First determine the standard bounding box dimensions so that I can determine the base line and starting line using: measureHTMLtext().ascent etc., as well as the width of both the character and a standard space in that font.  Then I would do as you suggested use a hidden TextField to render each letter padded by spaces and make a bitmap of the single character.  Then I would position the image in another hidden container, positioning based on the calculated baseline, and substracting the inserted padding spaces to determine the proper x and y for the resulting bitmap.  I would keep repeating this until all the letters have been rendered as individual images (talk about your ransom note).  Once all the characters had been captured as bitmap images, I could make a bitmap of the hidden container I layed them all back out in.

                 

                There has got to be a better way.

                • 5. Re: Textarea BitmapData Clips HTMLtext Italic System Font
                  PhilipKeiter Level 2

                  mrdicamillo,

                   

                  You could ban italics.

                   

                  But more seriously, I think you just need to hack the last letter. Measure that one letter and make the TextField wider by the width equivallent of another of that same character. How many characters more than double their width when italic?

                   

                  You are not having issues with the characters in the middle of the text area are you?

                   

                  Thanks,

                  Philip

                  • 6. Re: Textarea BitmapData Clips HTMLtext Italic System Font
                    mrdicamillo Level 1

                    Oh yes having the same issue in the middle of the text.  Basically, clipping occurs whenever a letter overhangs another character position in the following conditions:

                     

                    1) There is no character following the letter (for italic ascenders - the reverse is true for no character preceeding with an italic descender that would normally flow under the letter before) [Big issue for some fancy fonts that have long swashes that extend over several characters. - For example, if you only added one space, you would see more of the long swash, but it would still be clipped at the end.]

                     

                    2) If the next character is not of the exact same font family as the letter (for example a ScriptBrushStd "B" being followed by a Verdana "e.")

                     

                    3) If you use negative LETTERSPACING (HTMLtext) to bring the letters closer together (like if you were trying to make the 2 "f"'s closer together in "off."  I think that is called a ligature look.

                     

                    Again, I don't fully understand why these letter combinations render perfectly without any clipping in the TextArea in the Flash player, it is just when I try to capture them as bitmaps for the user to use with other images that I have this problem.