Exchanging the font & software render

Discussion and support for general JUCE issues

Re: Exchanging the font & software render

Postby zamrate » Fri Oct 28, 2011 8:54 am

Thanks!
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

Re: Exchanging the font & software render

Postby zamrate » Fri Oct 28, 2011 1:04 pm

I've got a problem: like I said, I wanted to exchange the font rendering. But the render context only has a function drawGlyph() that gets the number of the glyph (In the Glyph Cache I suppose?). How can I transfer this number into the character it represents?
Also, how do I retrieve the font?

In short: the glyph caching is done by my own font rendering system, which implements vertical hinting btw. I just want font name + font size + bold/italic/etc.. + character, that's all. I do not need JUCE's glyph caching and it should be turned off since there's no need for it anymore after I added my changes.
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

Re: Exchanging the font & software render

Postby jules » Fri Oct 28, 2011 1:31 pm

How can I transfer this number into the character it represents?


The character has already been converted to a glyph index by the layout engine - you certainly don't want to convert it back again! You can pass that number to a Typeface object to get the glyph's shape.

Also, how do I retrieve the font?


If you're doing a custom renderer, then presumably it has stored the current font somewhere in there.
User avatar
jules
Fearless Leader
 
Posts: 17209
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Exchanging the font & software render

Postby zamrate » Fri Oct 28, 2011 2:05 pm

Ok, let me ask the question differently:

After the call to Graphics::drawText(), JUCE should not be involved anymore, I want my rendering system to do the rest. How do I achieve that? The whole system of glyph shapes etc.. is already implemented using freetype in my code. I don't need JUCE to do this.
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

Re: Exchanging the font & software render

Postby jules » Fri Oct 28, 2011 2:08 pm

Well then you'd also need to write your own Typeface class, because that's what does the glyph layout.
User avatar
jules
Fearless Leader
 
Posts: 17209
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Exchanging the font & software render

Postby zamrate » Fri Oct 28, 2011 2:30 pm

I just noticed that there's also a setFont() function in the LowLevelGraphicsContext class. Well that's already very good, because then I know what font to use.
Still, the only problem that remains, is that drawGlyph() has a glyph number as parameter. I can't do anything with that information. I need a character number, best would be an uint32 for UTF32 encoding. Is there any way to achieve this?
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

Re: Exchanging the font & software render

Postby jules » Fri Oct 28, 2011 2:36 pm

I think you might have got completely the wrong idea.

If you're trying to do custom layout and glyph rendering, why not just do what TheVinn did a year or so ago, and write a custom typeface class? He didn't need to touch the graphics context at all, and I already added some hooks to do what he needed.

In fact, from the sound of it, you might actually just be re-creating exactly what TheVinn already did!
User avatar
jules
Fearless Leader
 
Posts: 17209
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Exchanging the font & software render

Postby zamrate » Fri Oct 28, 2011 2:39 pm

Ok I think I understand how it works now that I found the setFont() function. Thanks! No I'm not recreating what he is, I'm making a LCD optimized font renderer.
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

Re: Exchanging the font & software render

Postby jules » Fri Oct 28, 2011 2:57 pm

In that case, surely you just need to modify the edgetable rendering to be LCD-optimised, and not worry about fonts or anything?
User avatar
jules
Fearless Leader
 
Posts: 17209
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Exchanging the font & software render

Postby zamrate » Fri Oct 28, 2011 3:02 pm

Sadly not, because the whole point is the vertical hinting of the font.
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

Re: Exchanging the font & software render

Postby TheVinn » Sat Oct 29, 2011 9:36 am

zamrate wrote:Ok I think I understand how it works now that I found the setFont() function. Thanks! No I'm not recreating what he is, I'm making a LCD optimized font renderer.


You do realize that in my code, there is an #ifdef that, while turned off by default, not only creates the outlines but also provides Juce with the bitmap? You could just override that routine and turn the macro on.
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Exchanging the font & software render

Postby TheVinn » Sat Oct 29, 2011 9:37 am

look into

Code: Select all
#define TYPEFACE_BITMAP_RENDERING 1


in the .cpp of my post:

viewtopic.php?f=6&t=6393
Open Source: LayerEffects, VFLib, SimpleDJ, DSP Filters, LuaBridge, JUCE, FreeType, TagLib
"This isn't a big project, it shouldn't take long." - Jules
User avatar
TheVinn
JUCE UberWeenie
 
Posts: 2976
Joined: Sat Aug 29, 2009 11:31 am
Location: Marina del Rey, California

Re: Exchanging the font & software render

Postby zamrate » Sat Oct 29, 2011 11:03 am

Code: Select all
In that case, surely you just need to modify the edgetable rendering to be LCD-optimised, and not worry about fonts or anything?

LCD-optimised glyphs would also need to be represented not as just one alpha bitmap, but 3 alpha bitmaps, one for each channel (RGB).
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

Re: Exchanging the font & software render

Postby jules » Sat Oct 29, 2011 1:11 pm

No, not at all! A few cunning tweaks in the code that renders an edgetable should be all that's required. The edgetable already contains a high horizontal pixel resolution, so is an ideal source for sub-pixel rendering. There'd be no need to change anything else in the font code to make it work, and it'd also mean that all paths would get rendered at sub-pixel resolution for free too.
User avatar
jules
Fearless Leader
 
Posts: 17209
Joined: Mon Sep 06, 2004 9:03 am
Location: London, UK

Re: Exchanging the font & software render

Postby zamrate » Sat Oct 29, 2011 5:17 pm

OK, interesting, and what about the vertical hinting? Basically, what I implemented (and want to add to JUCE), is some font rendering that works after the scheme described in http://www.antigrain.com/research/font_rasterization/#toc0012

and looks like this:

Image

IMHO the best font rendering I saw. Hinting is only applied vertically (and only on small fonts which look bad without vertical hinting), the rest is merely done via LCD optimized rendering, for which the code is actually very short:

Code: Select all
//=====================================================lcd_distribution_lut
    class lcd_distribution_lut
    {
    public:
        lcd_distribution_lut(double prim, double second, double tert)
        {
            double norm = 1.0 / (prim + second*2 + tert*2);
            prim   *= norm;
            second *= norm;
            tert   *= norm;
            for(unsigned i = 0; i < 256; i++)
            {
                m_primary[i]   = (unsigned char)floor(prim   * i);
                m_secondary[i] = (unsigned char)floor(second * i);
                m_tertiary[i]  = (unsigned char)floor(tert   * i);
            }
        }

        unsigned primary(unsigned v)   const { return m_primary[v];   }
        unsigned secondary(unsigned v) const { return m_secondary[v]; }
        unsigned tertiary(unsigned v)  const { return m_tertiary[v];  }

    private:
        unsigned char m_primary[256];
        unsigned char m_secondary[256];
        unsigned char m_tertiary[256];
    };





    //========================================================pixfmt_rgb24_lcd
    class pixfmt_rgb24_lcd
    {
    public:
        typedef rgba8 color_type;
        typedef rendering_buffer::row_data row_data;
        typedef color_type::value_type value_type;
        typedef color_type::calc_type calc_type;

        //--------------------------------------------------------------------
        pixfmt_rgb24_lcd(rendering_buffer& rb, const lcd_distribution_lut& lut)
            : m_rbuf(&rb),
              m_lut(&lut)
        {
        }

        //--------------------------------------------------------------------
        unsigned width()  const { return m_rbuf->width() * 3;  }
        unsigned height() const { return m_rbuf->height(); }


        //--------------------------------------------------------------------
        void blend_hline(int x, int y,
                         unsigned len,
                         const color_type& c,
                         int8u cover)
        {
            int8u* p = m_rbuf->row_ptr(y) + x + x + x;
            int alpha = int(cover) * c.a;
            do
            {
                p[0] = (int8u)((((c.r - p[0]) * alpha) + (p[0] << 16)) >> 16);
                p[1] = (int8u)((((c.g - p[1]) * alpha) + (p[1] << 16)) >> 16);
                p[2] = (int8u)((((c.b - p[2]) * alpha) + (p[2] << 16)) >> 16);
                p += 3;
            }
            while(--len);
        }


        //--------------------------------------------------------------------
        void blend_solid_hspan(int x, int y,
                               unsigned len,
                               const color_type& c,
                               const int8u* covers)
        {
            int8u c3[2048*3];
            memset(c3, 0, len+4);

            int i;
            for(i = 0; i < int(len); i++)
            {
                c3[i+0] += m_lut->tertiary(covers[i]);
                c3[i+1] += m_lut->secondary(covers[i]);
                c3[i+2] += m_lut->primary(covers[i]);
                c3[i+3] += m_lut->secondary(covers[i]);
                c3[i+4] += m_lut->tertiary(covers[i]);
            }

            x -= 2;
            len += 4;

            if(x < 0)
            {
                len -= x;
                x = 0;
            }

            covers = c3;
            i = x % 3;

            int8u rgb[3] = { c.r, c.g, c.b };
            int8u* p = m_rbuf->row_ptr(y) + x;

            do
            {
                int alpha = int(*covers++) * c.a;
                if(alpha)
                {
                    if(alpha == 255*255)
                    {
                        *p = (int8u)rgb[i];
                    }
                    else
                    {
                        *p = (int8u)((((rgb[i] - *p) * alpha) + (*p << 16)) >> 16);
                    }
                }
                ++p;
                ++i;
                if(i >= 3) i = 0;
            }
            while(--len);
        }


    private:
        rendering_buffer* m_rbuf;
        const lcd_distribution_lut* m_lut;
    };
User avatar
zamrate
JUCE UberWeenie
 
Posts: 1081
Joined: Mon Sep 24, 2007 5:33 pm

PreviousNext

Return to General JUCE discussion

Who is online

Users browsing this forum: Anima, Google [Bot], lukus001 and 0 guests